diff --git a/programs/develop/cmm/Makefile b/programs/develop/cmm/Makefile new file mode 100644 index 0000000000..4f7a380282 --- /dev/null +++ b/programs/develop/cmm/Makefile @@ -0,0 +1,104 @@ +Compiler = gcc +Linker = kos32-ld + +Includes = -I d:\TEMP\mprog\kos\includes + +Compiler_Options = -c -fno-exceptions -D_KOS_ + +Exe_file = cmm.kex + + +Path_Libs = -Ld:/TEMP/Dev-Cpp/lib/kos +#-Ld:/TEMP/Dev-Cpp/lib/gcc/mingw32/3.4.2 -Ld:/TEMP/Dev-Cpp/lib/gcc -Ld:/TEMP/Dev-Cpp/lib -Ld:/TEMP/Dev-Cpp/lib + +Add_Libs = + +Link_Libs = -lc -lgcc + +My_Libs = main.o port.o toka.o tokb.o tokc.o toke.o tokr.o errors.o debug.o outobj.o outpe.o disasm.o switch.o outle.o pointer.o new_type.o class.o res.o optreg.o libobj.o + +#################### +## Makefile rules ## +#################### + +all : $(Exe_file) + +$(Exe_file) : $(My_Libs) + $(Linker) -o cmm.kex -static -nostdlib -T static.lds --stack 0x100000 $(Path_Libs) $(Add_Libs) $(My_Libs) $(Link_Libs) + objcopy cmm.kex -O binary + kpack cmm.kex + +clean: + rm *.o + + +# next are the exceptions that don't have to be compiled with the /zu option +# since they will never be called from a interrupt. hey.. I _tried_ to find +# a clean solution.. + +main.o : main.cpp + $(Compiler) $(Compiler_Options) $< + +toka.o : toka.cpp + $(Compiler) $(Compiler_Options) $< + +tokb.o : tokb.cpp + $(Compiler) $(Compiler_Options) $< + +tokc.o : tokc.cpp + $(Compiler) $(Compiler_Options) $< + +toke.o : toke.cpp + $(Compiler) $(Compiler_Options) $< + +tokr.o : tokr.cpp + $(Compiler) $(Compiler_Options) $< + +errors.o :errors.cpp + $(Compiler) $(Compiler_Options) $< + +debug.o : debug.cpp + $(Compiler) $(Compiler_Options) $< + +outobj.o : outobj.cpp + $(Compiler) $(Compiler_Options) $< + +outpe.o : outpe.cpp + $(Compiler) $(Compiler_Options) $< + +disasm.o : disasm.cpp + $(Compiler) $(Compiler_Options) $< + +switch.o : switch.cpp + $(Compiler) $(Compiler_Options) $< + +outle.o : outle.cpp + $(Compiler) $(Compiler_Options) $< + +pointer.o : pointer.cpp + $(Compiler) $(Compiler_Options) $< + +new_type.o : new_type.cpp + $(Compiler) $(Compiler_Options) $< + +class.o : class.cpp + $(Compiler) $(Compiler_Options) $< + +res.o : res.cpp + $(Compiler) $(Compiler_Options) $< + +optreg.o : optreg.cpp + $(Compiler) $(Compiler_Options) $< + +libobj.o : libobj.cpp + $(Compiler) $(Compiler_Options) $< + +port.o: port.cpp + $(Compiler) $(Compiler_Options) $< + +.cpp.o: + $(Compiler) $(Compiler_Options) $< + +.asm.o: + fasm $< + diff --git a/programs/develop/cmm/Makefile.win b/programs/develop/cmm/Makefile.win new file mode 100644 index 0000000000..3898ff6764 --- /dev/null +++ b/programs/develop/cmm/Makefile.win @@ -0,0 +1,110 @@ +Compiler = gcc + +#Compiler_Options = -c -fno-exceptions -D_UNIX_ +Compiler_Options = -c -fno-exceptions -O2 -D_WIN32_ + +#-D: _WIN32_ or _UNIX_ +#-D: for _WIN32_ add -D__CONSOLE__ + +Exe_file = cmm + + + +Path_Libs = -Ld:/TEMP/Dev-Cpp/lib/gcc/mingw32/3.4.2 -Ld:/TEMP/Dev-Cpp/lib/gcc -Ld:/TEMP/Dev-Cpp/lib -Ld:/TEMP/Dev-Cpp/lib + +Add_Libs = d:/TEMP/Dev-Cpp/lib/gcc/mingw32/3.4.2/crtbegin.o d:/TEMP/Dev-Cpp/lib/crt2.o d:/TEMP/Dev-Cpp/lib/gcc/mingw32/3.4.2/crtend.o + +Link_Libs = -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 + +My_Libs = main.o toka.o tokb.o tokc.o toke.o tokr.o errors.o debug.o outobj.o outpe.o disasm.o switch.o outle.o pointer.o new_type.o class.o res.o optreg.o libobj.o port.o + + +#Link_Libs = -lmingw32 -lgcc -lmoldname -lmingwex -lmingw32 -lmoldname -lmingwex -lmsvcrt -lgcc -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 + +#################### +## Makefile rules ## +#################### + +all : $(Exe_file) + +$(Exe_file) : $(My_Libs) + ld -o cmm.exe $(Path_Libs) $(Add_Libs) $(My_Libs) $(Link_Libs) +# $(Compiler) -o $(Exe_file) $(All_Libs) +# ld -o cmm.exe -Bdynamic d:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/crtend.o d:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../crt2.o d:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/crtbegin.o -Ld:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2 -Ld:/TEMP/Dev-Cpp/bin/../lib/gcc -Ld:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../.. -Ld:/TEMP/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../.. main.o toka.o tokb.o tokc.o toke.o tokr.o errors.o debug.o outobj.o outpe.o disasm.o switch.o outle.o pointer.o new_type.o class.o res.o optreg.o libobj.o port.o -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lmoldname -lmingwex -lmsvcrt -lgcc + + + + +clean: + rm *.o + + +# next are the exceptions that don't have to be compiled with the /zu option +# since they will never be called from a interrupt. hey.. I _tried_ to find +# a clean solution.. + +main.o : main.cpp + $(Compiler) $(Compiler_Options) $< + +toka.o : toka.cpp + $(Compiler) $(Compiler_Options) $< + +tokb.o : tokb.cpp + $(Compiler) $(Compiler_Options) $< + +tokc.o : tokc.cpp + $(Compiler) $(Compiler_Options) $< + +toke.o : toke.cpp + $(Compiler) $(Compiler_Options) $< + +tokr.o : tokr.cpp + $(Compiler) $(Compiler_Options) $< + +errors.o :errors.cpp + $(Compiler) $(Compiler_Options) $< + +debug.o : debug.cpp + $(Compiler) $(Compiler_Options) $< + +outobj.o : outobj.cpp + $(Compiler) $(Compiler_Options) $< + +outpe.o : outpe.cpp + $(Compiler) $(Compiler_Options) $< + +disasm.o : disasm.cpp + $(Compiler) $(Compiler_Options) $< + +switch.o : switch.cpp + $(Compiler) $(Compiler_Options) $< + +outle.o : outle.cpp + $(Compiler) $(Compiler_Options) $< + +pointer.o : pointer.cpp + $(Compiler) $(Compiler_Options) $< + +new_type.o : new_type.cpp + $(Compiler) $(Compiler_Options) $< + +class.o : class.cpp + $(Compiler) $(Compiler_Options) $< + +res.o : res.cpp + $(Compiler) $(Compiler_Options) $< + +optreg.o : optreg.cpp + $(Compiler) $(Compiler_Options) $< + +libobj.o : libobj.cpp + $(Compiler) $(Compiler_Options) $< + +port.o: port.cpp + $(Compiler) $(Compiler_Options) $< + +.cpp.o: + $(Compiler) $(Compiler_Options) $< + +.asm.o: + fasm $< diff --git a/programs/develop/cmm/asm.h b/programs/develop/cmm/asm.h new file mode 100644 index 0000000000..dee5b06854 --- /dev/null +++ b/programs/develop/cmm/asm.h @@ -0,0 +1,568 @@ +#define NUM_ASM_MODIF 12 + +char *asmmodif[]={ + "FAR", "SHORT", "NEAR", "DUP", "INT","WORD","LONG","DWORD", + "TBYTE","LDOUBLE","QWORD","DOUBLE" +}; +//᫮ 䨪 +#define m_far 1 +#define m_short 2 +#define m_near 4 +#define m_dup 8 +#define m_int 16 +#define m_word 32 +#define m_long 64 +#define m_dword 128 +#define m_tbyte 256 +#define m_ldouble 512 +#define m_qword 1024 +#define m_double 2048 + +//஫ ࠧ襭 ॣ஢ +#define d1par 256 // ࢮ ࠭ +#define d2par 512 // 2 ࠭ + +struct ASMPAR +{ + unsigned char num; //᫮ ࠭ 訥 4 쭮 ᫮, + // 訥 4 ᨬ쭮, ᫨ 0, ⮫쪮 襥, + // ᫨ 15, ࠭祭 + unsigned char chip; // 室 cpu + unsigned short reg; // ࠧ蠥 ॣ + unsigned short mod; // ᫮-䨪 +}asmpar[]={ + 2,0,d1par,0, //a_add + 2,0,d1par,0, //a_or + 2,0,d1par,0, //a_adc + 2,0,d1par,0, //a_sbb + 2,0,d1par,0, //a_and + 2,0,d1par,0, //a_sub + 2,0,d1par,0, //a_xor + 2,0,d1par,0, //a_cmp + 1,0,d1par,0, //a_not + 1,0,d1par,0, //a_neg + 1,0,dEAX|dEDX,0, //a_mul + 0,0,0,0, + 1,0,dEAX|dEDX,0, //a_div=a_mul+2 + 1,0,dEAX|dEDX,0, //a_idiv + 2,0,d1par,0, //a_rol + 2,0,d1par,0, //a_ror + 2,0,d1par,0, //a_rcl + 2,0,d1par,0, //a_rcr + 2,0,d1par,0, //a_shl + 2,0,d1par,0, //a_shr + 0,0,0,0, + 2,0,d1par,0, //a_sar=a_shr+2 + 2,3,0,0, //a_bt + 2,3,d1par,0, //a_bts + 2,3,d1par,0, //a_btr + 2,3,d1par,0, //a_btc + 1,0,d1par,0, //a_inc + 1,0,d1par,0, //a_dec + 2,0,0,0, //a_test + 0x31,0,d1par|dEAX|dEDX,0, //a_imul + 3,3,d1par,0, //a_shld + 3,3,d1par,0, //a_shrd + 0,0,dEAX,0, //a_daa + 0,0,dEAX,0, //a_das + 0,0,dEAX,0, //a_aaa + 0,0,dEAX,0, //a_aas + 0x10,0,dEAX,0, //a_aam + 0x10,0,dEAX,0, //a_aad + 2,3,d1par,0, //a_movzx + 2,3,d1par,0, //a_movsx + 0,0,dEAX,0, //a_cbw + 0,3,dEAX,0, //a_cwde + 0,0,dEDX,0, //a_cwd + 0,3,dEDX,0, //a_cdq, + 1,4,d1par,0, //a_bswap + 0,0,dEAX,0, //a_xlat + 2,3,d1par,0, //a_bsf + 2,3,d1par,0, //a_bsr + 2,4,d1par|dEAX,0, //a_cmpxchg + 1,5,d1par|dEDX|dEAX,0, //a_cmpxchg8b + 2,4,d1par|d2par,0, //a_xadd + 0,0,0,0, //a_nop + 0,0,0,0, //a_wait + 0,0,0,0, //a_lock + 0,0,0,0, //a_hlt + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_int + 0,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_into + 0,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_iret + 0,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_iretd + 0,0,0,0, //a_popf + 0,3,0,0, //a_popfd + 0,0,0,0, //a_pushf + 0,3,0,0, //a_pushfd + 0,0,0,0, //a_sahf + 0,0,dEAX,0, //a_lahf + 0,0,0,0, //a_cmc + 0,0,0,0, //a_clc + 0,0,0,0, //a_stc + 0,0,0,0, //a_cli + 0,0,0,0, //a_sti + 0,0,0,0, //a_cld + 0,0,0,0, //a_std + 0xF1,0,0,m_int|m_word|m_long|m_dword, //a_push + 0,2,0,0, //a_pusha + 0,3,0,0, //a_pushad + 0xF1,0,d1par,0, //a_pop + 0,2,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_popa + 0,3,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_popad + 2,0,d1par|d2par,0, //a_xchg + 2,0,d1par,0, //a_mov + 2,0,d1par,0, //a_lea + 2,3,d1par,0, //a_lfs + 2,3,d1par,0, //a_lgs + 2,3,d1par,0, //a_lss + 2,0,d1par,0, //a_les + 2,0,d1par,0, //a_lds + 0,3,0,0, //a_adrsiz + 2,0,dEAX,0, //a_in + 2,0,0,0, //a_out + 0,2,dEAX|dEDI,0, //a_insb + 0,2,dEAX|dEDI,0, //a_insw + 0,3,dEAX|dEDI,0, //a_insd + 0,2,dESI,0, //a_outsb + 0,2,dESI,0, //a_outsw + 0,3,dESI,0, //a_outsd + 0,0,dEDI|dESI,0, //a_movsb + 0,0,dEDI|dESI,0, //a_movsw + 0x20,3,dEDI|dESI,0, //a_movsd + 0,0,dEDI|dESI,0, //a_cmpsb + 0,0,dEDI|dESI,0, //a_cmpsw + 0x20,3,dEDI|dESI,0, //a_cmpsd + 0,0,dEDI,0, //a_stosb + 0,0,dEDI,0, //a_stosw + 0,3,dEDI,0, //a_stosd + 0,0,dEAX|dESI,0, //a_lodsb + 0,0,dEAX|dESI,0, //a_lodsw + 0,3,dEAX|dESI,0, //a_lodsd + 0,0,dEDI,0, //a_scasb + 0,0,dEDI,0, //a_scasw + 0,3,dEDI,0, //a_scasd + 0,0,dECX,0, //a_repnz + 0,0,dECX,0, //a_rep + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jcxz + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jecxz + 1,0,dECX,0, //a_loop + 1,3,dECX,0, //a_loopd + 1,0,dECX,0, //a_loopz + 1,0,dECX,0, //a_loopnz + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jo + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jno + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jc + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jnc + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jz + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jnz + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jna + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_ja + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_js + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jns + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jp + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jnp + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jl + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jnl + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jng + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jg + 1,3,d1par,0, //a_seto + 1,3,d1par,0, //a_setno + 1,3,d1par,0, //a_setc + 1,3,d1par,0, //a_setnc + 1,3,d1par,0, //a_setz + 1,3,d1par,0, //a_setnz + 1,3,d1par,0, //a_setna + 1,3,d1par,0, //a_seta + 1,3,d1par,0, //a_sets + 1,3,d1par,0, //a_setns + 1,3,d1par,0, //a_setp + 1,3,d1par,0, //a_setnp + 1,3,d1par,0, //a_setl + 1,3,d1par,0, //a_setnl + 1,3,d1par,0, //a_setng + 1,3,d1par,0, //a_setg + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near|m_short, //a_jmp + 1,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,m_far|m_near, //a_call/*a_callf,*/ + 0x10,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_ret + 0x10,0,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_retf + 2,2,dEBP|dESP,0, //a_enter + 0,2,dEBP|dESP,0, //a_leave + 2,2,dEAX|dEBX|dECX|dEDX|dESI|dEDI|dEBP|dESP,0, //a_bound + 2,2,d1par,0, //a_arpl + 1,2,d1par,0, //a_sldt + 1,2,d1par,0, //a_str + 1,2,0,0, //a_lldt + 1,2,0,0, //a_ltr + 1,2,0,0, //a_verr + 1,2,0,0, //a_verw + 2,2,d1par,0, //a_lar + 2,2,d1par,0, //a_lsl + 1,2,d1par,0, //a_sgdt + 1,2,d1par,0, //a_sidt + 1,2,0,0, //a_lgdt + 1,2,0,0, //a_lidt + 1,2,d1par,0, //a_smsw + 1,2,0,0, //a_lmsw + 0,2,0,0, //a_clts + 0,4,0,0, //a_invd + 0,4,0,0, //a_wbinvd + //a_invlpd, + 0,5,0,0, //a_wrmsr + 0,5,dEAX|dEBX|dECX|dEDX,0, //a_cpuid + 0,5,dEAX|dEDX,0, //a_rdmsr + 0,5,dEAX|dEDX,0, //a_rdtsc + 0,5,0,0, //a_rsm + 0,7,dEAX|dEDX,0, //a_rdpmc + 0,7,0,0, //a_ud2 + /*a_emmx,a_setalc,*/ + 2,8,0,0, //a_punpcklbw + 2,8,0,0, //a_punpcklwd + 2,8,0,0, //a_punpckldq + 2,8,0,0, //a_packsswb + 2,8,0,0, //a_pcmpgtb + 2,8,0,0, //a_pcmpgtw + 2,8,0,0, //a_pcmpgtd + 2,8,0,0, //a_packuswb + 2,8,0,0, //a_punpckhbw + 2,8,0,0, //a_punpckhwd + 2,8,0,0, //a_punpckhdq + 2,8,0,0, //a_packssdw + 2,6,0,0, //a_psrlw + 2,6,0,0, //a_psrld + 2,6,0,0, //a_psrlq + 2,6,0,0, //a_psraw + 2,6,0,0, //a_psrad + 2,6,0,0, //a_psllw + 2,6,0,0, //a_pslld + 2,6,0,0, //a_psllq + 2,8,0,0, //a_pcmpeqb + 2,8,0,0, //a_pcmpeqw + 2,8,0,0, //a_pcmpeqd + 2,8,0,0, //a_pmullw + 2,6,d1par,0, //a_movd + 2,6,d1par,0, //a_movq + 2,8,0,0, //a_psubusb + 2,8,0,0, //a_psubusw + 0,6,0,0, //a_emms + 2,8,0,0, //a_pand + 2,8,0,0, //a_paddusb + 2,8,0,0, //a_paddusw + 2,8,0,0, //a_pandn + 2,8,0,0, //a_pmulhw + 2,8,0,0, //a_psubsb + 2,8,0,0, //a_psubsw + 2,8,0,0, //a_por + 2,8,0,0, //a_paddsb + 2,8,0,0, //a_paddsw + 2,8,0,0, //a_pxor + 2,8,0,0, //a_pmaddwd + 2,8,0,0, //a_psubb + 2,8,0,0, //a_psubw + 2,8,0,0, //a_psubd + 2,8,0,0, //a_paddb + 2,8,0,0, //a_paddw + 2,8,0,0, //a_paddd + 0xF1,0,0,m_dup, //a_db + 0xF1,0,0,m_dup, //a_dw + 0xF1,3,0,m_dup, //a_dd + 1,4,0,0, //a_invlpg + 0,2,0,0, //a_loadall + 0,3,0,0, //a_opsiz + 0,2,0,0, //a_f2xm1 + 0,0,0,0, //a_fabs + 0x21,0,0,m_double, //a_fadd + 0x20,0,0,0, //a_faddp + 1,0,0,m_qword|m_tbyte, //a_fbld + 1,0,d1par,m_qword|m_tbyte, //a_fbstp + 0,0,0,0, //a_fchs + 0,0,0,0, //a_fclex + 0x10,0,0,m_double, //a_fcom + 0x10,0,0,m_double, //a_fcomp + 0,0,0,0, //a_fnclex + 0,0,0,0, //a_fcompp + 0,3,0,0, //a_fcos + 0,0,0,0, //a_fdecstr + 0,0,0,0, //a_fdisi + 0x21,0,0,m_double, //a_fdiv + 0x20,0,0,0, //a_fdivp + 0x21,0,0,m_double, //a_fdivr + 0x20,0,0,0, //a_fdivrp + 1,0,0,0, //a_ffree + 1,0,0,0, //a_fiadd + 1,0,0,0, //a_ficom + 1,0,0,0, //a_ficomp + 1,0,0,0, //a_fidiv + 1,0,0,0, //a_fidivr + 1,0,0,0, //a_fild + 1,0,0,m_qword|m_tbyte, //a_fildq + 1,0,0,0, //a_fimul + 1,0,d1par,0, //a_fist + 1,0,d1par,0, //a_fistp + 1,0,0,0, //a_fisub + 1,0,0,0, //a_fisubr + 0,0,0,0, //a_feni + 0,0,0,0, //a_fincstr + 0,0,0,0, //a_finit + 0,0,0,0, //a_fninit + 1,0,0,m_qword|m_double|m_tbyte|m_ldouble, //a_fld + 1,0,0,0, //a_fldcw + 1,0,0,m_tbyte|m_qword, //a_fldenv + 0,0,0,0, //a_fldlg2 + 0,0,0,0, //a_fldln2 + 0,0,0,0, //a_fldl2e + 0,0,0,0, //a_fldl2t + 0,0,0,0, //a_fldpi + 0,0,0,0, //a_fldz + 0,0,0,0, //a_fld1 + 0x21,0,0,0, //a_fmul + 0x20,0,0,0, //a_fmulp + 0,0,0,0, //a_fnop + 0,0,0,0, //a_fpatan + 0,0,0,0, //a_fprem + 0,3,0,0, //a_fprem1 + 0,0,0,0, //a_fptan + 0,0,0,0, //a_frndint + 0,2,0,0, //a_fsetpm + 1,0,0,m_tbyte|m_qword, //a_frstor + 1,0,d1par,m_tbyte|m_qword, //a_fsave + 1,0,d1par,m_tbyte|m_qword, //a_fnsave + 0,0,0,0, //a_fscale + 0,3,0,0, //a_fsin + 0,3,0,0, //a_fsincos + 0,0,0,0, //a_fsqrt + 1,0,d1par,m_qword|m_double|m_tbyte|m_ldouble, //a_fst + 1,0,d1par,0, //a_fstcw + 1,0,d1par,0, //a_fnstcw + 1,0,d1par,m_qword|m_double|m_tbyte|m_ldouble, //a_fstp + 1,0,d1par,0, //a_fstsw + 1,0,d1par,0, //a_fnstsw + 1,0,d1par,m_tbyte|m_qword, //a_fstenv + 1,0,d1par,m_tbyte|m_qword, //a_fnstenv + 0x21,0,0,m_double, //a_fsub + 0x20,0,0,0, //a_fsubp + 0x21,0,0,m_double, //a_fsubr + 0x20,0,0,0, //a_fsubrp + 0,0,0,0, //a_ftst + 0x10,0,0,0, //a_fucom + 0x10,0,0,0, //a_fucomp + 0,3,0,0, //a_fucompp + 0x10,0,0,0, //a_fxch + 0,0,0,0, //a_fwait + 0,0,0,0, //a_fxam + 0,0,0,0, //a_fxtract + 0,0,0,0, //a_fyl2x + 0,0,0,0, //a_fyl2xp1 + 0,7,0,0, //a_sysenter + 0,7,0,0, //a_sysexit + 0x21,7,0,0, //a_fcmovb + 0x21,7,0,0, //a_fcmove + 0x21,7,0,0, //a_fcmovbe + 0x21,7,0,0, //a_fcmovu + 0x21,7,0,0, //a_fcmovnb + 0x21,7,0,0, //a_fcmovne + 0x21,7,0,0, //a_fcmovnbe + 0x21,7,0,0, //a_fcmovnu + 0x21,7,0,0, //a_fcomi + 0x21,7,0,0, //a_fcomip + 0x21,7,0,0, //a_fucomi + 0x21,7,0,0, //a_fucomip + 1,8,0,0, //a_fxrstor + 1,8,d1par,0, //a_fxsave + 0,0,0,0, //a_fndisi + 0,0,0,0, //a_fneni + 0,2,0,0, //a_fnsetpm + 2,7,d1par,0, //a_cmovo + 2,7,d1par,0, //a_cmovno + 2,7,d1par,0, //a_cmovc + 2,7,d1par,0, //a_cmovnc + 2,7,d1par,0, //a_cmovz + 2,7,d1par,0, //a_cmovnz + 2,7,d1par,0, //a_cmovna + 2,7,d1par,0, //a_cmova + 2,7,d1par,0, //a_cmovs + 2,7,d1par,0, //a_cmovns + 2,7,d1par,0, //a_cmovp + 2,7,d1par,0, //a_cmovnp + 2,7,d1par,0, //a_cmovl + 2,7,d1par,0, //a_cmovnl + 2,7,d1par,0, //a_cmovng + 2,7,d1par,0, //a_cmovg + 2,8,dEDI,0, //a_maskmovq + 2,8,d1par,0, //a_movntq + 2,8,0,0, //a_pavgb + 2,8,0,0, //a_pavgw + 3,8,d1par,0, //a_pextrw + 3,8,0,0, //a_pinsrw + 2,8,0,0, //a_pmaxub + 2,8,0,0, //a_pmaxsw + 2,8,0,0, //a_pminub + 2,8,0,0, //a_pminsw + 2,8,d1par,0, //a_pmovmskb + 2,8,0,0, //a_pmulhuw + 1,8,0,0, //a_prefetcht0 + 1,8,0,0, //a_prefetcht1 + 1,8,0,0, //a_prefetcht2 + 1,8,0,0, //a_prefetchnta + 0,8,0,0, //a_sfence + 2,8,0,0, //a_psadbw + 3,8,0,0, //a_pshufw + 2,8,0,0, //a_addps + 2,8,0,0, //a_addss + 2,8,0,0, //a_andnps + 2,8,0,0, //a_andps + 3,8,0,0, //a_cmpps + 3,8,0,0, //a_cmpss + 2,8,0,0, //a_comiss + 2,8,0,0, //a_cvtpi2ps + 2,8,0,0, //a_cvtps2pi + 2,8,0,0, //a_cvtsi2ss + 2,8,d1par,0, //a_cvtss2si + 2,8,0,0, //a_cvttps2pi + 2,8,d1par,0, //a_cvttss2si + 2,8,0,0, //a_divps + 2,8,0,0, //a_divss + 1,8,0,0, //a_ldmxcsr + 2,8,0,0, //a_maxps + 2,8,0,0, //a_maxss + 2,8,0,0, //a_minps + 2,8,0,0, //a_minss + 2,8,d1par,0, //a_movaps + 2,8,0,0, //a_movhlps + 2,8,d1par,0, //a_movhps + 2,8,0,0, //a_movlhps + 2,8,d1par,0, //a_movlps + 2,8,d1par,0, //a_movmskps + 2,8,d1par,0, //a_movss + 2,8,d1par,0, //a_movups + 2,8,0,0, //a_mulps + 2,8,0,0, //a_mulss, + 2,8,d1par,0, //a_movntps + 2,8,0,0, //a_orps + 2,8,0,0, //a_rcpps + 2,8,0,0, //a_rcpss + 2,8,0,0, //a_rsqrtps + 2,8,0,0, //a_rsqrtss + 3,8,0,0, //a_shufps + 2,8,0,0, //a_sqrtps + 2,8,0,0, //a_sqrtss + 1,8,d1par,0, //a_stmxcsr + 2,8,0,0, //a_subps + 2,8,0,0, //a_subss + 2,8,0,0, //a_ucomiss + 2,8,0,0, //a_unpckhps + 2,8,0,0, //a_unpcklps + 2,8,0,0, //a_xorps +// Pentium IV + 0,9,0,0, //a_lfence + 0,9,0,0, //a_mfence + 2,9,0,0, //a_addpd + 2,9,0,0, //a_addsd + 2,9,0,0, //a_andpd + 2,9,0,0, //a_andnpd + 3,9,0,0, //a_cmppd + 2,9,0,0, //a_comisd + 2,9,0,0, //a_cvtdq2pd + 2,9,0,0, //a_cvtdq2ps + 2,9,0,0, //a_cvtpd2dq + 2,9,0,0, //a_cvtpd2pi + 2,9,0,0, //a_cvtpd2ps + 2,9,0,0, //a_cvtpi2pd + 2,9,0,0, //a_cvtps2dq + 2,9,0,0, //a_cvtps2pd + 2,9,d1par,0, //a_cvtsd2si + 2,9,0,0, //a_cvtsd2ss + 2,9,0,0, //a_cvtsi2sd + 2,9,0,0, //a_cvtss2sd + 2,9,0,0, //a_cvttpd2pi + 2,9,0,0, //a_cvttpd2dq + 2,9,0,0, //a_cvttps2dq + 2,9,d1par,0, //a_cvttsd2si + 2,9,0,0, //a_divpd + 2,9,0,0, //a_divsd + 2,9,0,0, //a_maskmovdqu + 2,9,0,0, //a_maxpd + 2,9,0,0, //a_maxsd + 2,9,0,0, //a_minpd + 2,9,0,0, //a_minsd + 2,9,d1par,0, //a_movapd + 2,9,d1par,0, //a_movdqa + 2,9,d1par,0, //a_movdqu + 2,9,0,0, //a_movdq2q + 2,9,d1par,0, //a_movhpd + 2,9,d1par,0, //a_movlpd + 2,9,d1par,0, //a_movmskpd + 2,9,d1par,0, //a_movntdq + 2,9,d1par,0, //a_movntpd + 2,9,d1par,0, //a_movnti + 2,9,0,0, //a_movq2dq + 2,9,0,0, //a_movupd + 2,9,0,0, //a_mulpd + 2,9,0,0, //a_mulsd + 2,9,0,0, //a_orpd + 3,9,0,0, //a_pshufd, + 3,9,0,0, //a_pshufhw + 3,9,0,0, //a_pshuflw + 2,9,0,0, //a_pslldq + 2,9,0,0, //a_psrldq + 3,9,0,0, //a_shufpd + 2,9,0,0, //a_sqrtpd + 2,9,0,0, //a_sqrtsd + 2,9,0,0, //a_subpd + 2,9,0,0, //a_subsd + 2,9,0,0, //a_ucomisd + 2,9,0,0, //a_unpckhpd + 2,9,0,0, //a_unpcklpd + 2,9,0,0, //a_xorpd + 2,9,0,0, //a_paddq + 2,9,0,0, //a_pmuludq + 2,9,0,0, //a_psubq + 2,9,0,0, //a_punpckhqdq + 2,9,0,0, //a_punpcklqdq + 1,9,0,0, //a_clflush + 0,9,0,0, //a_monitor + 0,9,0,0, //a_mwait + 2,9,0,0, //a_addsubpd + 2,9,0,0, //a_addsubps + 2,9,0,0, //a_cmpeqsd + 2,9,0,0, //a_cmpltsd + 2,9,0,0, //a_cmplesd + 2,9,0,0, //a_cmpunordsd + 2,9,0,0, //a_cmpneqsd + 2,9,0,0, //a_cmpnltsd + 2,9,0,0, //a_cmpnlesd + 2,9,0,0, //a_cmpordsd + 2,9,0,0, //a_cmpeqpd + 2,9,0,0, //a_cmpltpd + 2,9,0,0, //a_cmplepd + 2,9,0,0, //a_cmpunordpd + 2,9,0,0, //a_cmpneqpd + 2,9,0,0, //a_cmpnltpd + 2,9,0,0, //a_cmpnlepd + 2,9,0,0, //a_cmpordpd + 2,9,0,0, //a_cmpeqps + 2,9,0,0, //a_cmpltps + 2,9,0,0, //a_cmpleps + 2,9,0,0, //a_cmpunordps + 2,9,0,0, //a_cmpneqps + 2,9,0,0, //a_cmpnltps + 2,9,0,0, //a_cmpnleps + 2,9,0,0, //a_cmpordps + 2,9,0,0, //a_cmpeqss + 2,9,0,0, //a_cmpltss + 2,9,0,0, //a_cmpless + 2,9,0,0, //a_cmpunordss + 2,9,0,0, //a_cmpneqss + 2,9,0,0, //a_cmpnltss + 2,9,0,0, //a_cmpnless + 2,9,0,0, //a_cmpordss + 2,9,0,0, //a_haddpd + 2,9,0,0, //a_haddps + 2,9,0,0, //a_hsubpd + 2,9,0,0, //a_hsubps + 2,9,0,0, //a_lddqu + 2,9,0,0, //a_movddup + 2,9,0,0, //a_movshdup + 2,9,0,0, //a_movsldup + 0,9,0,0 //a_pause +}; + diff --git a/programs/develop/cmm/asm_name.h b/programs/develop/cmm/asm_name.h new file mode 100644 index 0000000000..5112217622 --- /dev/null +++ b/programs/develop/cmm/asm_name.h @@ -0,0 +1,144 @@ +char *Mnemonics[]={ +// FIRST OF ALL THE COMMANDS WITH A P-FLAG. THIS"LL MAKE THINGS EASIER FOR +// COMPARISON IN THE PARSE ENGINE + //P1=0-7 + "ADD","OR","ADC","SBB/BC","AND","SUB","XOR","CMP", + //P2=4-7 + "NOT","NEG","MUL","-","DIV","IDIV", + // IMUL ENTFERNT + //P3=0-5/7 + "ROL","ROR","RCL","RCR","SHL/AL","SHR","-","SAR", + //P4=4-7 + "BT","BTS","BTR","BTC", + // USUAL COMMANDS + "INC","DEC","TEST", "IMUL","SHLD","SHRD", + "DAA","DAS","AAA","AAS","AAM","AAD", + "MOVZX","MOVSX","CBW","CWDE","CWD","CDQ", + "BSWAP","XLAT/LATB","BSF","BSR", + "CMPXCHG","CMPXCHG8B","XADD", + "NOP","WAIT","LOCK","HLT/ALT","INT", + "INTO","IRET","IRETD", + "POPF","POPFD","PUSHF","PUSHFD","SAHF","LAHF", + "CMC","CLC","STC","CLI","STI","CLD","STD", + "PUSH","PUSHA","PUSHAD","POP","POPA","POPAD", + "XCHG","MOV","LEA", + "LFS","LGS","LSS", + "LES","LDS", + "ADRSIZE", + "IN","OUT","INSB","INSW","INSD","OUTSB","OUTSW","OUTSD", + "MOVSB","MOVSW","MOVSD","CMPSB","CMPSW","CMPSD", + "STOSB","STOSW","STOSD","LODSB","LODSW","LODSD", + "SCASB","SCASW","SCASD","REPNE/EPNZ","REP/EPE/EPZ", + "JCXZ","JECXZ","LOOP/OOPW","LOOPD","LOOPZ/OOPE","LOOPNZ/OOPNE", + "JO","JNO","JC/B/NAE","JNC/AE/NB", + "JE/Z","JNE/NZ","JBE/NA","JA/NBE", + "JS","JNS","JP/PE","JNP/PO","JL/NGE","JGE/NL", + "JLE/NG","JG/NLE", + "SETO","SETNO","SETC/ETB/ETNAE","SETNC/ETAE/ETNB", + "SETE/ETZ","SETNE/ETNZ","SETBE/ETNA","SETA/ETNBE", + "SETS","SETNS","SETP/ETPE","SETNP/ETPO","SETL/ETNGE","SETGE/ETNL", + "SETLE/ETNG","SETG/ETNLE", + /*"JMPS","JMPN","JMPF",*/"JMP", + "CALL",/*"CALLF",*/"RET","RETF", + "ENTER","LEAVE","BOUND","ARPL", + "SLDT","STR","LLDT","LTR","VERR","VERW","LAR","LSL", + "SGDT","SIDT","LGDT","LIDT","SMSW","LMSW","CLTS", + "INVD","WBINVD",//"INVLPD", + //INTEL PENTIUM COMMANDS + "WRMSR","CPUID","RDMSR","RDTSC","RSM", + //INTEL PENTIUM PRO INSTRUCTIONS + "RDPMC","UD2",/*"EMMX","SETALC",*/ + //MMX INSTRUCTIONS + + "PUNPCKLBW","PUNPCKLWD","PUNPCKLDQ", //UNPACK LOW ORDER 60 - + "PACKSSWB", + "PCMPGTB","PCMPGTW","PCMPGTD", + "PACKUSWB", //PACK MMX REG WITH UNSIGNED SATURATION + "PUNPCKHBW","PUNPCKHWD","PUNPCKHDQ", //UNPACK HIGH ORDER + "PACKSSDW", //PACK MMX REG WITH SIGNED SATURATION - 6B + + "PSRLW","PSRLD","PSRLQ", + "PSRAW","PSRAD", + "PSLLW","PSLLD","PSLLQ", + + "PCMPEQB","PCMPEQW","PCMPEQD",//74-76 + "PMULLW", //d5 + + "MOVD","MOVQ", //MOVE MMX REG + + "PSUBUSB","PSUBUSW",//d8-d9 + + "EMMS", + + "PAND", //db + "PADDUSB","PADDUSW", //" WITH UNSIGNED SATURATION + "PANDN", //df + "PMULHW", //e5 + "PSUBSB","PSUBSW", //e8-e9 + "POR", //eb + "PADDSB","PADDSW", //" WITH SIGNED SATURATION + "PXOR", //ef + "PMADDWD", //f5 + "PSUBB","PSUBW","PSUBD", //SUBTRACT MMX REG f8-fa + "PADDB","PADDW","PADDD", //ADD MMX REG WITH WRAP-AROUND fc-fe + + + "DB","DW","DD","INVLPG","LOADALL","OPSIZE", + + "F2XM1","FABS","FADD","FADDP","FBLD","FBSTP","FCHS","FCLEX","FCOM", + "FCOMP","FNCLEX","FCOMPP","FCOS","FDECSTP","FDISI","FDIV","FDIVP", + "FDIVR","FDIVRP","FFREE","FIADD","FICOM","FICOMP","FIDIV","FIDIVR", + "FILD","FILDQ","FIMUL","FIST","FISTP","FISUB","FISUBR","FENI","FINCSTP", + "FINIT","FNINIT","FLD","FLDCW","FLDENV","FLDLG2","FLDLN2","FLDL2E", + "FLDL2T","FLDPI","FLDZ","FLD1","FMUL","FMULP","FNOP","FPATAN","FPREM", + "FPREM1","FPTAN","FRNDINT","FSETPM","FRSTOR","FSAVE","FNSAVE","FSCALE", + "FSIN","FSINCOS","FSQRT","FST","FSTCW","FNSTCW","FSTP","FSTSW","FNSTSW", + "FSTENV","FNSTENV","FSUB","FSUBP","FSUBR","FSUBRP","FTST","FUCOM","FUCOMP", + "FUCOMPP","FXCH","FWAIT","FXAM","FXTRACT","FYL2X","FYL2XP1", + "SYSENTER","SYSEXIT","FCMOVB","FCMOVE","FCMOVBE","FCMOVU","FCMOVNB", + "FCMOVNE","FCMOVNBE","FCMOVNU","FCOMI","FCOMIP","FUCOMI","FUCOMIP", + "FXRSTOR","FXSAVE", "FNDISI", "FNENI", "FNSETPM", + + "CMOVO","CMOVNO","CMOVB/MOVNAE/MOVC","CMOVAE/MOVNB/MOVNC","CMOVE/MOVZ", + "CMOVNE/MOVNZ","CMOVBE/MOVNA","CMOVA/MOVNBE","CMOVS","CMOVNS", + "CMOVP/MOVPE","CMOVNP/MOVPO","CMOVL/MOVNGE","CMOVGE/MOVNL", + "CMOVLE/MOVNG","CMOVG/MOVNLE", + +//MMX Pentium III extention + "MASKMOVQ", "MOVNTQ", "PAVGB", "PAVGW", "PEXTRW", "PINSRW", + "PMAXUB", "PMAXSW", "PMINUB", "PMINSW", "PMOVMSKB","PMULHUW", + "PREFETCHT0","PREFETCHT1","PREFETCHT2","PREFETCHNTA","SFENCE", "PSADBW", + "PSHUFW", +//XMM extentions Pentium III + "ADDPS", "ADDSS", "ANDNPS", "ANDPS", "CMPPS", "CMPSS", + "COMISS", "CVTPI2PS","CVTPS2PI","CVTSI2SS","CVTSS2SI","CVTTPS2PI", + "CVTTSS2SI","DIVPS", "DIVSS", "LDMXCSR", "MAXPS", "MAXSS", + "MINPS", "MINSS", "MOVAPS", "MOVHLPS", "MOVHPS", "MOVLHPS", + "MOVLPS", "MOVMSKPS","MOVSS", "MOVUPS", "MULPS", "MULSS", + "MOVNTPS", "ORPS", "RCPPS", "RCPSS", "RSQRTPS", "RSQRTSS", + "SHUFPS", "SQRTPS", "SQRTSS", "STMXCSR", "SUBPS", "SUBSS", + "UCOMISS", "UNPCKHPS","UNPCKLPS","XORPS", + +// Pentium IV + "LFENCE", "MFENCE", "ADDPD", "ADDSD", "ANDPD", "ANDNPD", + "CMPPD", "COMISD", "CVTDQ2PD", "CVTDQ2PS", "CVTPD2DQ", "CVTPD2PI", + "CVTPD2PS","CVTPI2PD", "CVTPS2DQ", "CVTPS2PD", "CVTSD2SI", "CVTSD2SS", + "CVTSI2SD","CVTSS2SD", "CVTTPD2PI", "CVTTPD2DQ", "CVTTPS2DQ", "CVTTSD2SI", + "DIVPD", "DIVSD", "MASKMOVDQU","MAXPD", "MAXSD", "MINPD", + "MINSD", "MOVAPD", "MOVDQA", "MOVDQU", "MOVDQ2Q", "MOVHPD", + "MOVLPD", "MOVMSKPD", "MOVNTDQ", "MOVNTPD", "MOVNTI", "MOVQ2DQ", + "MOVUPD", "MULPD", "MULSD", "ORPD", "PSHUFD", "PSHUFHW", + "PSHUFLW", "PSLLDQ", "PSRLDQ", "SHUFPD", "SQRTPD", "SQRTSD", + "SUBPD", "SUBSD", "UCOMISD", "UNPCKHPD", "UNPCKLPD", "XORPD", + "PADDQ", "PMULUDQ", "PSUBQ", "PUNPCKHQDQ","PUNPCKLQDQ","CLFLUSH", + "MONITOR", "MWAIT", "ADDSUBPD", "ADDSUBPS", "CMPEQSD", "CMPLTSD", + "CMPLESD", "CMPUNORDSD","CMPNEQSD", "CMPNLTSD", "CMPNLESD", "CMPORDSD", + "CMPEQPD", "CMPLTPD", "CMPLEPD", "CMPUNORDPD","CMPNEQPD", "CMPNLTPD", + "CMPNLEPD","CMPORDPD", "CMPEQPS", "CMPLTPS", "CMPLEPS", "CMPUNORDPS", + "CMPNEQPS","CMPNLTPS", "CMPNLEPS", "CMPORDPS", "CMPEQSS", "CMPLTSS", + "CMPLESS", "CMPUNORDSS","CMPNEQSS", "CMPNLTSS", "CMPNLESS", "CMPORDSS", + "HADDPD", "HADDPS", "HSUBPD", "HSUBPS", "LDDQU", "MOVDDUP", + "MOVSHDUP","MOVSLDUP", "PAUSE", + + NULL}; + diff --git a/programs/develop/cmm/asmnemon.h b/programs/develop/cmm/asmnemon.h new file mode 100644 index 0000000000..03b5a75638 --- /dev/null +++ b/programs/develop/cmm/asmnemon.h @@ -0,0 +1,620 @@ +/* 䠩 ᣥ஢ ணࠬ 'FASTLIST.EXE' */ + +short ofsmnem[26]={ + 0x0000,0x0082, //A B + 0x00AF,0x0451, //C D + 0x048F,0x049E, //E F + 0xFFFF,0x078A, //G H + 0x07B7,0x0806, //I J + 0xFFFF,0x08AA, //K L + 0x096C,0x0B00, //M N + 0x0B11,0x0B45, //O P + 0xFFFF,0x0DE9, //Q R + 0x0E63,0x102C, //S T + 0x1034,0x1075, //U V + 0x1083,0x109A, //W X + 0xFFFF,0xFFFF}; //Y Z + +unsigned char asmMnem[]={ + 0x22,0x00,0x41,0x41,0, // AAA + 0x25,0x00,0x41,0x44,0, // AAD + 0x24,0x00,0x41,0x4D,0, // AAM + 0x23,0x00,0x41,0x53,0, // AAS + 0x02,0x00,0x44,0x43,0, // ADC + 0x00,0x00,0x44,0x44,0, // ADD + 0xA5,0x01,0x44,0x44,0x50,0x44,0, // ADDPD + 0x75,0x01,0x44,0x44,0x50,0x53,0, // ADDPS + 0xA6,0x01,0x44,0x44,0x53,0x44,0, // ADDSD + 0x76,0x01,0x44,0x44,0x53,0x53,0, // ADDSS + 0xE7,0x01,0x44,0x44,0x53,0x55,0x42,0x50,0x44,0, // ADDSUBPD + 0xE8,0x01,0x44,0x44,0x53,0x55,0x42,0x50,0x53,0, // ADDSUBPS + 0x56,0x00,0x44,0x52,0x53,0x49,0x5A,0x45,0, // ADRSIZE + 0x04,0x00,0x4E,0x44,0, // AND + 0xA8,0x01,0x4E,0x44,0x4E,0x50,0x44,0, // ANDNPD + 0x77,0x01,0x4E,0x44,0x4E,0x50,0x53,0, // ANDNPS + 0xA7,0x01,0x4E,0x44,0x50,0x44,0, // ANDPD + 0x78,0x01,0x4E,0x44,0x50,0x53,0, // ANDPS + 0x9D,0x00,0x52,0x50,0x4C,0, // ARPL + 0xFF,0xFF, // end char 'A' + 0x9C,0x00,0x4F,0x55,0x4E,0x44,0, // BOUND + 0x2E,0x00,0x53,0x46,0, // BSF + 0x2F,0x00,0x53,0x52,0, // BSR + 0x2C,0x00,0x53,0x57,0x41,0x50,0, // BSWAP + 0x16,0x00,0x54,0, // BT + 0x19,0x00,0x54,0x43,0, // BTC + 0x18,0x00,0x54,0x52,0, // BTR + 0x17,0x00,0x54,0x53,0, // BTS + 0xFF,0xFF, // end char 'B' + 0x97,0x00,0x41,0x4C,0x4C,0, // CALL + 0x28,0x00,0x42,0x57,0, // CBW + 0x2B,0x00,0x44,0x51,0, // CDQ + 0x42,0x00,0x4C,0x43,0, // CLC + 0x46,0x00,0x4C,0x44,0, // CLD + 0xE4,0x01,0x4C,0x46,0x4C,0x55,0x53,0x48,0, // CLFLUSH + 0x44,0x00,0x4C,0x49,0, // CLI + 0xAC,0x00,0x4C,0x54,0x53,0, // CLTS + 0x41,0x00,0x4D,0x43,0, // CMC + 0x59,0x01,0x4D,0x4F,0x56,0x41,0, // CMOVA + 0x55,0x01,0x4D,0x4F,0x56,0x41,0x45,0, // CMOVAE + 0x54,0x01,0x4D,0x4F,0x56,0x42,0, // CMOVB + 0x58,0x01,0x4D,0x4F,0x56,0x42,0x45,0, // CMOVBE + 0x54,0x01,0x4D,0x4F,0x56,0x43,0, // CMOVC + 0x56,0x01,0x4D,0x4F,0x56,0x45,0, // CMOVE + 0x61,0x01,0x4D,0x4F,0x56,0x47,0, // CMOVG + 0x5F,0x01,0x4D,0x4F,0x56,0x47,0x45,0, // CMOVGE + 0x5E,0x01,0x4D,0x4F,0x56,0x4C,0, // CMOVL + 0x60,0x01,0x4D,0x4F,0x56,0x4C,0x45,0, // CMOVLE + 0x58,0x01,0x4D,0x4F,0x56,0x4E,0x41,0, // CMOVNA + 0x54,0x01,0x4D,0x4F,0x56,0x4E,0x41,0x45,0, // CMOVNAE + 0x55,0x01,0x4D,0x4F,0x56,0x4E,0x42,0, // CMOVNB + 0x59,0x01,0x4D,0x4F,0x56,0x4E,0x42,0x45,0, // CMOVNBE + 0x55,0x01,0x4D,0x4F,0x56,0x4E,0x43,0, // CMOVNC + 0x57,0x01,0x4D,0x4F,0x56,0x4E,0x45,0, // CMOVNE + 0x60,0x01,0x4D,0x4F,0x56,0x4E,0x47,0, // CMOVNG + 0x5E,0x01,0x4D,0x4F,0x56,0x4E,0x47,0x45,0, // CMOVNGE + 0x5F,0x01,0x4D,0x4F,0x56,0x4E,0x4C,0, // CMOVNL + 0x61,0x01,0x4D,0x4F,0x56,0x4E,0x4C,0x45,0, // CMOVNLE + 0x53,0x01,0x4D,0x4F,0x56,0x4E,0x4F,0, // CMOVNO + 0x5D,0x01,0x4D,0x4F,0x56,0x4E,0x50,0, // CMOVNP + 0x5B,0x01,0x4D,0x4F,0x56,0x4E,0x53,0, // CMOVNS + 0x57,0x01,0x4D,0x4F,0x56,0x4E,0x5A,0, // CMOVNZ + 0x52,0x01,0x4D,0x4F,0x56,0x4F,0, // CMOVO + 0x5C,0x01,0x4D,0x4F,0x56,0x50,0, // CMOVP + 0x5C,0x01,0x4D,0x4F,0x56,0x50,0x45,0, // CMOVPE + 0x5D,0x01,0x4D,0x4F,0x56,0x50,0x4F,0, // CMOVPO + 0x5A,0x01,0x4D,0x4F,0x56,0x53,0, // CMOVS + 0x56,0x01,0x4D,0x4F,0x56,0x5A,0, // CMOVZ + 0x07,0x00,0x4D,0x50,0, // CMP + 0xF1,0x01,0x4D,0x50,0x45,0x51,0x50,0x44,0, // CMPEQPD + 0xF9,0x01,0x4D,0x50,0x45,0x51,0x50,0x53,0, // CMPEQPS + 0xE9,0x01,0x4D,0x50,0x45,0x51,0x53,0x44,0, // CMPEQSD + 0x01,0x02,0x4D,0x50,0x45,0x51,0x53,0x53,0, // CMPEQSS + 0xF3,0x01,0x4D,0x50,0x4C,0x45,0x50,0x44,0, // CMPLEPD + 0xFB,0x01,0x4D,0x50,0x4C,0x45,0x50,0x53,0, // CMPLEPS + 0xEB,0x01,0x4D,0x50,0x4C,0x45,0x53,0x44,0, // CMPLESD + 0x03,0x02,0x4D,0x50,0x4C,0x45,0x53,0x53,0, // CMPLESS + 0xF2,0x01,0x4D,0x50,0x4C,0x54,0x50,0x44,0, // CMPLTPD + 0xFA,0x01,0x4D,0x50,0x4C,0x54,0x50,0x53,0, // CMPLTPS + 0xEA,0x01,0x4D,0x50,0x4C,0x54,0x53,0x44,0, // CMPLTSD + 0x02,0x02,0x4D,0x50,0x4C,0x54,0x53,0x53,0, // CMPLTSS + 0xF5,0x01,0x4D,0x50,0x4E,0x45,0x51,0x50,0x44,0, // CMPNEQPD + 0xFD,0x01,0x4D,0x50,0x4E,0x45,0x51,0x50,0x53,0, // CMPNEQPS + 0xED,0x01,0x4D,0x50,0x4E,0x45,0x51,0x53,0x44,0, // CMPNEQSD + 0x05,0x02,0x4D,0x50,0x4E,0x45,0x51,0x53,0x53,0, // CMPNEQSS + 0xF7,0x01,0x4D,0x50,0x4E,0x4C,0x45,0x50,0x44,0, // CMPNLEPD + 0xFF,0x01,0x4D,0x50,0x4E,0x4C,0x45,0x50,0x53,0, // CMPNLEPS + 0xEF,0x01,0x4D,0x50,0x4E,0x4C,0x45,0x53,0x44,0, // CMPNLESD + 0x07,0x02,0x4D,0x50,0x4E,0x4C,0x45,0x53,0x53,0, // CMPNLESS + 0xF6,0x01,0x4D,0x50,0x4E,0x4C,0x54,0x50,0x44,0, // CMPNLTPD + 0xFE,0x01,0x4D,0x50,0x4E,0x4C,0x54,0x50,0x53,0, // CMPNLTPS + 0xEE,0x01,0x4D,0x50,0x4E,0x4C,0x54,0x53,0x44,0, // CMPNLTSD + 0x06,0x02,0x4D,0x50,0x4E,0x4C,0x54,0x53,0x53,0, // CMPNLTSS + 0xF8,0x01,0x4D,0x50,0x4F,0x52,0x44,0x50,0x44,0, // CMPORDPD + 0x00,0x02,0x4D,0x50,0x4F,0x52,0x44,0x50,0x53,0, // CMPORDPS + 0xF0,0x01,0x4D,0x50,0x4F,0x52,0x44,0x53,0x44,0, // CMPORDSD + 0x08,0x02,0x4D,0x50,0x4F,0x52,0x44,0x53,0x53,0, // CMPORDSS + 0xA9,0x01,0x4D,0x50,0x50,0x44,0, // CMPPD + 0x79,0x01,0x4D,0x50,0x50,0x53,0, // CMPPS + 0x62,0x00,0x4D,0x50,0x53,0x42,0, // CMPSB + 0x64,0x00,0x4D,0x50,0x53,0x44,0, // CMPSD + 0x7A,0x01,0x4D,0x50,0x53,0x53,0, // CMPSS + 0x63,0x00,0x4D,0x50,0x53,0x57,0, // CMPSW + 0xF4,0x01,0x4D,0x50,0x55,0x4E,0x4F,0x52,0x44,0x50,0x44,0, // CMPUNORDPD + 0xFC,0x01,0x4D,0x50,0x55,0x4E,0x4F,0x52,0x44,0x50,0x53,0, // CMPUNORDPS + 0xEC,0x01,0x4D,0x50,0x55,0x4E,0x4F,0x52,0x44,0x53,0x44,0, // CMPUNORDSD + 0x04,0x02,0x4D,0x50,0x55,0x4E,0x4F,0x52,0x44,0x53,0x53,0, // CMPUNORDSS + 0x30,0x00,0x4D,0x50,0x58,0x43,0x48,0x47,0, // CMPXCHG + 0x31,0x00,0x4D,0x50,0x58,0x43,0x48,0x47,0x38,0x42,0, // CMPXCHG8B + 0xAA,0x01,0x4F,0x4D,0x49,0x53,0x44,0, // COMISD + 0x7B,0x01,0x4F,0x4D,0x49,0x53,0x53,0, // COMISS + 0xB0,0x00,0x50,0x55,0x49,0x44,0, // CPUID + 0xAB,0x01,0x56,0x54,0x44,0x51,0x32,0x50,0x44,0, // CVTDQ2PD + 0xAC,0x01,0x56,0x54,0x44,0x51,0x32,0x50,0x53,0, // CVTDQ2PS + 0xAD,0x01,0x56,0x54,0x50,0x44,0x32,0x44,0x51,0, // CVTPD2DQ + 0xAE,0x01,0x56,0x54,0x50,0x44,0x32,0x50,0x49,0, // CVTPD2PI + 0xAF,0x01,0x56,0x54,0x50,0x44,0x32,0x50,0x53,0, // CVTPD2PS + 0xB0,0x01,0x56,0x54,0x50,0x49,0x32,0x50,0x44,0, // CVTPI2PD + 0x7C,0x01,0x56,0x54,0x50,0x49,0x32,0x50,0x53,0, // CVTPI2PS + 0xB1,0x01,0x56,0x54,0x50,0x53,0x32,0x44,0x51,0, // CVTPS2DQ + 0xB2,0x01,0x56,0x54,0x50,0x53,0x32,0x50,0x44,0, // CVTPS2PD + 0x7D,0x01,0x56,0x54,0x50,0x53,0x32,0x50,0x49,0, // CVTPS2PI + 0xB3,0x01,0x56,0x54,0x53,0x44,0x32,0x53,0x49,0, // CVTSD2SI + 0xB4,0x01,0x56,0x54,0x53,0x44,0x32,0x53,0x53,0, // CVTSD2SS + 0xB5,0x01,0x56,0x54,0x53,0x49,0x32,0x53,0x44,0, // CVTSI2SD + 0x7E,0x01,0x56,0x54,0x53,0x49,0x32,0x53,0x53,0, // CVTSI2SS + 0xB6,0x01,0x56,0x54,0x53,0x53,0x32,0x53,0x44,0, // CVTSS2SD + 0x7F,0x01,0x56,0x54,0x53,0x53,0x32,0x53,0x49,0, // CVTSS2SI + 0xB8,0x01,0x56,0x54,0x54,0x50,0x44,0x32,0x44,0x51,0, // CVTTPD2DQ + 0xB7,0x01,0x56,0x54,0x54,0x50,0x44,0x32,0x50,0x49,0, // CVTTPD2PI + 0xB9,0x01,0x56,0x54,0x54,0x50,0x53,0x32,0x44,0x51,0, // CVTTPS2DQ + 0x80,0x01,0x56,0x54,0x54,0x50,0x53,0x32,0x50,0x49,0, // CVTTPS2PI + 0xBA,0x01,0x56,0x54,0x54,0x53,0x44,0x32,0x53,0x49,0, // CVTTSD2SI + 0x81,0x01,0x56,0x54,0x54,0x53,0x53,0x32,0x53,0x49,0, // CVTTSS2SI + 0x2A,0x00,0x57,0x44,0, // CWD + 0x29,0x00,0x57,0x44,0x45,0, // CWDE + 0xFF,0xFF, // end char 'C' + 0x20,0x00,0x41,0x41,0, // DAA + 0x21,0x00,0x41,0x53,0, // DAS + 0xE5,0x00,0x42,0, // DB + 0xE7,0x00,0x44,0, // DD + 0x1B,0x00,0x45,0x43,0, // DEC + 0x0C,0x00,0x49,0x56,0, // DIV + 0xBB,0x01,0x49,0x56,0x50,0x44,0, // DIVPD + 0x82,0x01,0x49,0x56,0x50,0x53,0, // DIVPS + 0xBC,0x01,0x49,0x56,0x53,0x44,0, // DIVSD + 0x83,0x01,0x49,0x56,0x53,0x53,0, // DIVSS + 0xE6,0x00,0x57,0, // DW + 0xFF,0xFF, // end char 'D' + 0xD2,0x00,0x4D,0x4D,0x53,0, // EMMS + 0x9A,0x00,0x4E,0x54,0x45,0x52,0, // ENTER + 0xFF,0xFF, // end char 'E' + 0xEB,0x00,0x32,0x58,0x4D,0x31,0, // F2XM1 + 0xEC,0x00,0x41,0x42,0x53,0, // FABS + 0xED,0x00,0x41,0x44,0x44,0, // FADD + 0xEE,0x00,0x41,0x44,0x44,0x50,0, // FADDP + 0xEF,0x00,0x42,0x4C,0x44,0, // FBLD + 0xF0,0x00,0x42,0x53,0x54,0x50,0, // FBSTP + 0xF1,0x00,0x43,0x48,0x53,0, // FCHS + 0xF2,0x00,0x43,0x4C,0x45,0x58,0, // FCLEX + 0x41,0x01,0x43,0x4D,0x4F,0x56,0x42,0, // FCMOVB + 0x43,0x01,0x43,0x4D,0x4F,0x56,0x42,0x45,0, // FCMOVBE + 0x42,0x01,0x43,0x4D,0x4F,0x56,0x45,0, // FCMOVE + 0x45,0x01,0x43,0x4D,0x4F,0x56,0x4E,0x42,0, // FCMOVNB + 0x47,0x01,0x43,0x4D,0x4F,0x56,0x4E,0x42,0x45,0, // FCMOVNBE + 0x46,0x01,0x43,0x4D,0x4F,0x56,0x4E,0x45,0, // FCMOVNE + 0x48,0x01,0x43,0x4D,0x4F,0x56,0x4E,0x55,0, // FCMOVNU + 0x44,0x01,0x43,0x4D,0x4F,0x56,0x55,0, // FCMOVU + 0xF3,0x00,0x43,0x4F,0x4D,0, // FCOM + 0x49,0x01,0x43,0x4F,0x4D,0x49,0, // FCOMI + 0x4A,0x01,0x43,0x4F,0x4D,0x49,0x50,0, // FCOMIP + 0xF4,0x00,0x43,0x4F,0x4D,0x50,0, // FCOMP + 0xF6,0x00,0x43,0x4F,0x4D,0x50,0x50,0, // FCOMPP + 0xF7,0x00,0x43,0x4F,0x53,0, // FCOS + 0xF8,0x00,0x44,0x45,0x43,0x53,0x54,0x50,0, // FDECSTP + 0xF9,0x00,0x44,0x49,0x53,0x49,0, // FDISI + 0xFA,0x00,0x44,0x49,0x56,0, // FDIV + 0xFB,0x00,0x44,0x49,0x56,0x50,0, // FDIVP + 0xFC,0x00,0x44,0x49,0x56,0x52,0, // FDIVR + 0xFD,0x00,0x44,0x49,0x56,0x52,0x50,0, // FDIVRP + 0x0B,0x01,0x45,0x4E,0x49,0, // FENI + 0xFE,0x00,0x46,0x52,0x45,0x45,0, // FFREE + 0xFF,0x00,0x49,0x41,0x44,0x44,0, // FIADD + 0x00,0x01,0x49,0x43,0x4F,0x4D,0, // FICOM + 0x01,0x01,0x49,0x43,0x4F,0x4D,0x50,0, // FICOMP + 0x02,0x01,0x49,0x44,0x49,0x56,0, // FIDIV + 0x03,0x01,0x49,0x44,0x49,0x56,0x52,0, // FIDIVR + 0x04,0x01,0x49,0x4C,0x44,0, // FILD + 0x05,0x01,0x49,0x4C,0x44,0x51,0, // FILDQ + 0x06,0x01,0x49,0x4D,0x55,0x4C,0, // FIMUL + 0x0C,0x01,0x49,0x4E,0x43,0x53,0x54,0x50,0, // FINCSTP + 0x0D,0x01,0x49,0x4E,0x49,0x54,0, // FINIT + 0x07,0x01,0x49,0x53,0x54,0, // FIST + 0x08,0x01,0x49,0x53,0x54,0x50,0, // FISTP + 0x09,0x01,0x49,0x53,0x55,0x42,0, // FISUB + 0x0A,0x01,0x49,0x53,0x55,0x42,0x52,0, // FISUBR + 0x0F,0x01,0x4C,0x44,0, // FLD + 0x18,0x01,0x4C,0x44,0x31,0, // FLD1 + 0x10,0x01,0x4C,0x44,0x43,0x57,0, // FLDCW + 0x11,0x01,0x4C,0x44,0x45,0x4E,0x56,0, // FLDENV + 0x14,0x01,0x4C,0x44,0x4C,0x32,0x45,0, // FLDL2E + 0x15,0x01,0x4C,0x44,0x4C,0x32,0x54,0, // FLDL2T + 0x12,0x01,0x4C,0x44,0x4C,0x47,0x32,0, // FLDLG2 + 0x13,0x01,0x4C,0x44,0x4C,0x4E,0x32,0, // FLDLN2 + 0x16,0x01,0x4C,0x44,0x50,0x49,0, // FLDPI + 0x17,0x01,0x4C,0x44,0x5A,0, // FLDZ + 0x19,0x01,0x4D,0x55,0x4C,0, // FMUL + 0x1A,0x01,0x4D,0x55,0x4C,0x50,0, // FMULP + 0xF5,0x00,0x4E,0x43,0x4C,0x45,0x58,0, // FNCLEX + 0x4F,0x01,0x4E,0x44,0x49,0x53,0x49,0, // FNDISI + 0x50,0x01,0x4E,0x45,0x4E,0x49,0, // FNENI + 0x0E,0x01,0x4E,0x49,0x4E,0x49,0x54,0, // FNINIT + 0x1B,0x01,0x4E,0x4F,0x50,0, // FNOP + 0x24,0x01,0x4E,0x53,0x41,0x56,0x45,0, // FNSAVE + 0x51,0x01,0x4E,0x53,0x45,0x54,0x50,0x4D,0, // FNSETPM + 0x2B,0x01,0x4E,0x53,0x54,0x43,0x57,0, // FNSTCW + 0x30,0x01,0x4E,0x53,0x54,0x45,0x4E,0x56,0, // FNSTENV + 0x2E,0x01,0x4E,0x53,0x54,0x53,0x57,0, // FNSTSW + 0x1C,0x01,0x50,0x41,0x54,0x41,0x4E,0, // FPATAN + 0x1D,0x01,0x50,0x52,0x45,0x4D,0, // FPREM + 0x1E,0x01,0x50,0x52,0x45,0x4D,0x31,0, // FPREM1 + 0x1F,0x01,0x50,0x54,0x41,0x4E,0, // FPTAN + 0x20,0x01,0x52,0x4E,0x44,0x49,0x4E,0x54,0, // FRNDINT + 0x22,0x01,0x52,0x53,0x54,0x4F,0x52,0, // FRSTOR + 0x23,0x01,0x53,0x41,0x56,0x45,0, // FSAVE + 0x25,0x01,0x53,0x43,0x41,0x4C,0x45,0, // FSCALE + 0x21,0x01,0x53,0x45,0x54,0x50,0x4D,0, // FSETPM + 0x26,0x01,0x53,0x49,0x4E,0, // FSIN + 0x27,0x01,0x53,0x49,0x4E,0x43,0x4F,0x53,0, // FSINCOS + 0x28,0x01,0x53,0x51,0x52,0x54,0, // FSQRT + 0x29,0x01,0x53,0x54,0, // FST + 0x2A,0x01,0x53,0x54,0x43,0x57,0, // FSTCW + 0x2F,0x01,0x53,0x54,0x45,0x4E,0x56,0, // FSTENV + 0x2C,0x01,0x53,0x54,0x50,0, // FSTP + 0x2D,0x01,0x53,0x54,0x53,0x57,0, // FSTSW + 0x31,0x01,0x53,0x55,0x42,0, // FSUB + 0x32,0x01,0x53,0x55,0x42,0x50,0, // FSUBP + 0x33,0x01,0x53,0x55,0x42,0x52,0, // FSUBR + 0x34,0x01,0x53,0x55,0x42,0x52,0x50,0, // FSUBRP + 0x35,0x01,0x54,0x53,0x54,0, // FTST + 0x36,0x01,0x55,0x43,0x4F,0x4D,0, // FUCOM + 0x4B,0x01,0x55,0x43,0x4F,0x4D,0x49,0, // FUCOMI + 0x4C,0x01,0x55,0x43,0x4F,0x4D,0x49,0x50,0, // FUCOMIP + 0x37,0x01,0x55,0x43,0x4F,0x4D,0x50,0, // FUCOMP + 0x38,0x01,0x55,0x43,0x4F,0x4D,0x50,0x50,0, // FUCOMPP + 0x3A,0x01,0x57,0x41,0x49,0x54,0, // FWAIT + 0x3B,0x01,0x58,0x41,0x4D,0, // FXAM + 0x39,0x01,0x58,0x43,0x48,0, // FXCH + 0x4D,0x01,0x58,0x52,0x53,0x54,0x4F,0x52,0, // FXRSTOR + 0x4E,0x01,0x58,0x53,0x41,0x56,0x45,0, // FXSAVE + 0x3C,0x01,0x58,0x54,0x52,0x41,0x43,0x54,0, // FXTRACT + 0x3D,0x01,0x59,0x4C,0x32,0x58,0, // FYL2X + 0x3E,0x01,0x59,0x4C,0x32,0x58,0x50,0x31,0, // FYL2XP1 + 0xFF,0xFF, // end char 'F' + 0x09,0x02,0x41,0x44,0x44,0x50,0x44,0, // HADDPD + 0x0A,0x02,0x41,0x44,0x44,0x50,0x53,0, // HADDPS + 0x36,0x00,0x41,0x4C,0x54,0, // HALT + 0x36,0x00,0x4C,0x54,0, // HLT + 0x0B,0x02,0x53,0x55,0x42,0x50,0x44,0, // HSUBPD + 0x0C,0x02,0x53,0x55,0x42,0x50,0x53,0, // HSUBPS + 0xFF,0xFF, // end char 'H' + 0x0D,0x00,0x44,0x49,0x56,0, // IDIV + 0x1D,0x00,0x4D,0x55,0x4C,0, // IMUL + 0x57,0x00,0x4E,0, // IN + 0x1A,0x00,0x4E,0x43,0, // INC + 0x59,0x00,0x4E,0x53,0x42,0, // INSB + 0x5B,0x00,0x4E,0x53,0x44,0, // INSD + 0x5A,0x00,0x4E,0x53,0x57,0, // INSW + 0x37,0x00,0x4E,0x54,0, // INT + 0x38,0x00,0x4E,0x54,0x4F,0, // INTO + 0xAD,0x00,0x4E,0x56,0x44,0, // INVD + 0xE8,0x00,0x4E,0x56,0x4C,0x50,0x47,0, // INVLPG + 0x39,0x00,0x52,0x45,0x54,0, // IRET + 0x3A,0x00,0x52,0x45,0x54,0x44,0, // IRETD + 0xFF,0xFF, // end char 'I' + 0x7D,0x00,0x41,0, // JA + 0x79,0x00,0x41,0x45,0, // JAE + 0x78,0x00,0x42,0, // JB + 0x7C,0x00,0x42,0x45,0, // JBE + 0x78,0x00,0x43,0, // JC + 0x70,0x00,0x43,0x58,0x5A,0, // JCXZ + 0x7A,0x00,0x45,0, // JE + 0x71,0x00,0x45,0x43,0x58,0x5A,0, // JECXZ + 0x85,0x00,0x47,0, // JG + 0x83,0x00,0x47,0x45,0, // JGE + 0x82,0x00,0x4C,0, // JL + 0x84,0x00,0x4C,0x45,0, // JLE + 0x96,0x00,0x4D,0x50,0, // JMP + 0x7C,0x00,0x4E,0x41,0, // JNA + 0x78,0x00,0x4E,0x41,0x45,0, // JNAE + 0x79,0x00,0x4E,0x42,0, // JNB + 0x7D,0x00,0x4E,0x42,0x45,0, // JNBE + 0x79,0x00,0x4E,0x43,0, // JNC + 0x7B,0x00,0x4E,0x45,0, // JNE + 0x84,0x00,0x4E,0x47,0, // JNG + 0x82,0x00,0x4E,0x47,0x45,0, // JNGE + 0x83,0x00,0x4E,0x4C,0, // JNL + 0x85,0x00,0x4E,0x4C,0x45,0, // JNLE + 0x77,0x00,0x4E,0x4F,0, // JNO + 0x81,0x00,0x4E,0x50,0, // JNP + 0x7F,0x00,0x4E,0x53,0, // JNS + 0x7B,0x00,0x4E,0x5A,0, // JNZ + 0x76,0x00,0x4F,0, // JO + 0x80,0x00,0x50,0, // JP + 0x80,0x00,0x50,0x45,0, // JPE + 0x81,0x00,0x50,0x4F,0, // JPO + 0x7E,0x00,0x53,0, // JS + 0x7A,0x00,0x5A,0, // JZ + 0xFF,0xFF, // end char 'J' + 0x40,0x00,0x41,0x48,0x46,0, // LAHF + 0xA4,0x00,0x41,0x52,0, // LAR + 0x0D,0x02,0x44,0x44,0x51,0x55,0, // LDDQU + 0x84,0x01,0x44,0x4D,0x58,0x43,0x53,0x52,0, // LDMXCSR + 0x55,0x00,0x44,0x53,0, // LDS + 0x50,0x00,0x45,0x41,0, // LEA + 0x9B,0x00,0x45,0x41,0x56,0x45,0, // LEAVE + 0x54,0x00,0x45,0x53,0, // LES + 0xA3,0x01,0x46,0x45,0x4E,0x43,0x45,0, // LFENCE + 0x51,0x00,0x46,0x53,0, // LFS + 0xA8,0x00,0x47,0x44,0x54,0, // LGDT + 0x52,0x00,0x47,0x53,0, // LGS + 0xA9,0x00,0x49,0x44,0x54,0, // LIDT + 0xA0,0x00,0x4C,0x44,0x54,0, // LLDT + 0xAB,0x00,0x4D,0x53,0x57,0, // LMSW + 0xE9,0x00,0x4F,0x41,0x44,0x41,0x4C,0x4C,0, // LOADALL + 0x35,0x00,0x4F,0x43,0x4B,0, // LOCK + 0x68,0x00,0x4F,0x44,0x53,0x42,0, // LODSB + 0x6A,0x00,0x4F,0x44,0x53,0x44,0, // LODSD + 0x69,0x00,0x4F,0x44,0x53,0x57,0, // LODSW + 0x72,0x00,0x4F,0x4F,0x50,0, // LOOP + 0x73,0x00,0x4F,0x4F,0x50,0x44,0, // LOOPD + 0x74,0x00,0x4F,0x4F,0x50,0x45,0, // LOOPE + 0x75,0x00,0x4F,0x4F,0x50,0x4E,0x45,0, // LOOPNE + 0x75,0x00,0x4F,0x4F,0x50,0x4E,0x5A,0, // LOOPNZ + 0x72,0x00,0x4F,0x4F,0x50,0x57,0, // LOOPW + 0x74,0x00,0x4F,0x4F,0x50,0x5A,0, // LOOPZ + 0xA5,0x00,0x53,0x4C,0, // LSL + 0x53,0x00,0x53,0x53,0, // LSS + 0xA1,0x00,0x54,0x52,0, // LTR + 0xFF,0xFF, // end char 'L' + 0xBD,0x01,0x41,0x53,0x4B,0x4D,0x4F,0x56,0x44,0x51,0x55,0, // MASKMOVDQU + 0x62,0x01,0x41,0x53,0x4B,0x4D,0x4F,0x56,0x51,0, // MASKMOVQ + 0xBE,0x01,0x41,0x58,0x50,0x44,0, // MAXPD + 0x85,0x01,0x41,0x58,0x50,0x53,0, // MAXPS + 0xBF,0x01,0x41,0x58,0x53,0x44,0, // MAXSD + 0x86,0x01,0x41,0x58,0x53,0x53,0, // MAXSS + 0xA4,0x01,0x46,0x45,0x4E,0x43,0x45,0, // MFENCE + 0xC0,0x01,0x49,0x4E,0x50,0x44,0, // MINPD + 0x87,0x01,0x49,0x4E,0x50,0x53,0, // MINPS + 0xC1,0x01,0x49,0x4E,0x53,0x44,0, // MINSD + 0x88,0x01,0x49,0x4E,0x53,0x53,0, // MINSS + 0xE5,0x01,0x4F,0x4E,0x49,0x54,0x4F,0x52,0, // MONITOR + 0x4F,0x00,0x4F,0x56,0, // MOV + 0xC2,0x01,0x4F,0x56,0x41,0x50,0x44,0, // MOVAPD + 0x89,0x01,0x4F,0x56,0x41,0x50,0x53,0, // MOVAPS + 0xCE,0x00,0x4F,0x56,0x44,0, // MOVD + 0x0E,0x02,0x4F,0x56,0x44,0x44,0x55,0x50,0, // MOVDDUP + 0xC5,0x01,0x4F,0x56,0x44,0x51,0x32,0x51,0, // MOVDQ2Q + 0xC3,0x01,0x4F,0x56,0x44,0x51,0x41,0, // MOVDQA + 0xC4,0x01,0x4F,0x56,0x44,0x51,0x55,0, // MOVDQU + 0x8A,0x01,0x4F,0x56,0x48,0x4C,0x50,0x53,0, // MOVHLPS + 0xC6,0x01,0x4F,0x56,0x48,0x50,0x44,0, // MOVHPD + 0x8B,0x01,0x4F,0x56,0x48,0x50,0x53,0, // MOVHPS + 0x8C,0x01,0x4F,0x56,0x4C,0x48,0x50,0x53,0, // MOVLHPS + 0xC7,0x01,0x4F,0x56,0x4C,0x50,0x44,0, // MOVLPD + 0x8D,0x01,0x4F,0x56,0x4C,0x50,0x53,0, // MOVLPS + 0xC8,0x01,0x4F,0x56,0x4D,0x53,0x4B,0x50,0x44,0, // MOVMSKPD + 0x8E,0x01,0x4F,0x56,0x4D,0x53,0x4B,0x50,0x53,0, // MOVMSKPS + 0xC9,0x01,0x4F,0x56,0x4E,0x54,0x44,0x51,0, // MOVNTDQ + 0xCB,0x01,0x4F,0x56,0x4E,0x54,0x49,0, // MOVNTI + 0xCA,0x01,0x4F,0x56,0x4E,0x54,0x50,0x44,0, // MOVNTPD + 0x93,0x01,0x4F,0x56,0x4E,0x54,0x50,0x53,0, // MOVNTPS + 0x63,0x01,0x4F,0x56,0x4E,0x54,0x51,0, // MOVNTQ + 0xCF,0x00,0x4F,0x56,0x51,0, // MOVQ + 0xCC,0x01,0x4F,0x56,0x51,0x32,0x44,0x51,0, // MOVQ2DQ + 0x5F,0x00,0x4F,0x56,0x53,0x42,0, // MOVSB + 0x61,0x00,0x4F,0x56,0x53,0x44,0, // MOVSD + 0x0F,0x02,0x4F,0x56,0x53,0x48,0x44,0x55,0x50,0, // MOVSHDUP + 0x10,0x02,0x4F,0x56,0x53,0x4C,0x44,0x55,0x50,0, // MOVSLDUP + 0x8F,0x01,0x4F,0x56,0x53,0x53,0, // MOVSS + 0x60,0x00,0x4F,0x56,0x53,0x57,0, // MOVSW + 0x27,0x00,0x4F,0x56,0x53,0x58,0, // MOVSX + 0xCD,0x01,0x4F,0x56,0x55,0x50,0x44,0, // MOVUPD + 0x90,0x01,0x4F,0x56,0x55,0x50,0x53,0, // MOVUPS + 0x26,0x00,0x4F,0x56,0x5A,0x58,0, // MOVZX + 0x0A,0x00,0x55,0x4C,0, // MUL + 0xCE,0x01,0x55,0x4C,0x50,0x44,0, // MULPD + 0x91,0x01,0x55,0x4C,0x50,0x53,0, // MULPS + 0xCF,0x01,0x55,0x4C,0x53,0x44,0, // MULSD + 0x92,0x01,0x55,0x4C,0x53,0x53,0, // MULSS + 0xE6,0x01,0x57,0x41,0x49,0x54,0, // MWAIT + 0xFF,0xFF, // end char 'M' + 0x09,0x00,0x45,0x47,0, // NEG + 0x33,0x00,0x4F,0x50,0, // NOP + 0x08,0x00,0x4F,0x54,0, // NOT + 0xFF,0xFF, // end char 'N' + 0xEA,0x00,0x50,0x53,0x49,0x5A,0x45,0, // OPSIZE + 0x01,0x00,0x52,0, // OR + 0xD0,0x01,0x52,0x50,0x44,0, // ORPD + 0x94,0x01,0x52,0x50,0x53,0, // ORPS + 0x58,0x00,0x55,0x54,0, // OUT + 0x5C,0x00,0x55,0x54,0x53,0x42,0, // OUTSB + 0x5E,0x00,0x55,0x54,0x53,0x44,0, // OUTSD + 0x5D,0x00,0x55,0x54,0x53,0x57,0, // OUTSW + 0xFF,0xFF, // end char 'O' + 0xC1,0x00,0x41,0x43,0x4B,0x53,0x53,0x44,0x57,0, // PACKSSDW + 0xB9,0x00,0x41,0x43,0x4B,0x53,0x53,0x57,0x42,0, // PACKSSWB + 0xBD,0x00,0x41,0x43,0x4B,0x55,0x53,0x57,0x42,0, // PACKUSWB + 0xE2,0x00,0x41,0x44,0x44,0x42,0, // PADDB + 0xE4,0x00,0x41,0x44,0x44,0x44,0, // PADDD + 0xDF,0x01,0x41,0x44,0x44,0x51,0, // PADDQ + 0xDB,0x00,0x41,0x44,0x44,0x53,0x42,0, // PADDSB + 0xDC,0x00,0x41,0x44,0x44,0x53,0x57,0, // PADDSW + 0xD4,0x00,0x41,0x44,0x44,0x55,0x53,0x42,0, // PADDUSB + 0xD5,0x00,0x41,0x44,0x44,0x55,0x53,0x57,0, // PADDUSW + 0xE3,0x00,0x41,0x44,0x44,0x57,0, // PADDW + 0xD3,0x00,0x41,0x4E,0x44,0, // PAND + 0xD6,0x00,0x41,0x4E,0x44,0x4E,0, // PANDN + 0x11,0x02,0x41,0x55,0x53,0x45,0, // PAUSE + 0x64,0x01,0x41,0x56,0x47,0x42,0, // PAVGB + 0x65,0x01,0x41,0x56,0x47,0x57,0, // PAVGW + 0xCA,0x00,0x43,0x4D,0x50,0x45,0x51,0x42,0, // PCMPEQB + 0xCC,0x00,0x43,0x4D,0x50,0x45,0x51,0x44,0, // PCMPEQD + 0xCB,0x00,0x43,0x4D,0x50,0x45,0x51,0x57,0, // PCMPEQW + 0xBA,0x00,0x43,0x4D,0x50,0x47,0x54,0x42,0, // PCMPGTB + 0xBC,0x00,0x43,0x4D,0x50,0x47,0x54,0x44,0, // PCMPGTD + 0xBB,0x00,0x43,0x4D,0x50,0x47,0x54,0x57,0, // PCMPGTW + 0x66,0x01,0x45,0x58,0x54,0x52,0x57,0, // PEXTRW + 0x67,0x01,0x49,0x4E,0x53,0x52,0x57,0, // PINSRW + 0xDE,0x00,0x4D,0x41,0x44,0x44,0x57,0x44,0, // PMADDWD + 0x69,0x01,0x4D,0x41,0x58,0x53,0x57,0, // PMAXSW + 0x68,0x01,0x4D,0x41,0x58,0x55,0x42,0, // PMAXUB + 0x6B,0x01,0x4D,0x49,0x4E,0x53,0x57,0, // PMINSW + 0x6A,0x01,0x4D,0x49,0x4E,0x55,0x42,0, // PMINUB + 0x6C,0x01,0x4D,0x4F,0x56,0x4D,0x53,0x4B,0x42,0, // PMOVMSKB + 0x6D,0x01,0x4D,0x55,0x4C,0x48,0x55,0x57,0, // PMULHUW + 0xD7,0x00,0x4D,0x55,0x4C,0x48,0x57,0, // PMULHW + 0xCD,0x00,0x4D,0x55,0x4C,0x4C,0x57,0, // PMULLW + 0xE0,0x01,0x4D,0x55,0x4C,0x55,0x44,0x51,0, // PMULUDQ + 0x4B,0x00,0x4F,0x50,0, // POP + 0x4C,0x00,0x4F,0x50,0x41,0, // POPA + 0x4D,0x00,0x4F,0x50,0x41,0x44,0, // POPAD + 0x3B,0x00,0x4F,0x50,0x46,0, // POPF + 0x3C,0x00,0x4F,0x50,0x46,0x44,0, // POPFD + 0xDA,0x00,0x4F,0x52,0, // POR + 0x71,0x01,0x52,0x45,0x46,0x45,0x54,0x43,0x48,0x4E,0x54,0x41,0, // PREFETCHNTA + 0x6E,0x01,0x52,0x45,0x46,0x45,0x54,0x43,0x48,0x54,0x30,0, // PREFETCHT0 + 0x6F,0x01,0x52,0x45,0x46,0x45,0x54,0x43,0x48,0x54,0x31,0, // PREFETCHT1 + 0x70,0x01,0x52,0x45,0x46,0x45,0x54,0x43,0x48,0x54,0x32,0, // PREFETCHT2 + 0x73,0x01,0x53,0x41,0x44,0x42,0x57,0, // PSADBW + 0xD1,0x01,0x53,0x48,0x55,0x46,0x44,0, // PSHUFD + 0xD2,0x01,0x53,0x48,0x55,0x46,0x48,0x57,0, // PSHUFHW + 0xD3,0x01,0x53,0x48,0x55,0x46,0x4C,0x57,0, // PSHUFLW + 0x74,0x01,0x53,0x48,0x55,0x46,0x57,0, // PSHUFW + 0xC8,0x00,0x53,0x4C,0x4C,0x44,0, // PSLLD + 0xD4,0x01,0x53,0x4C,0x4C,0x44,0x51,0, // PSLLDQ + 0xC9,0x00,0x53,0x4C,0x4C,0x51,0, // PSLLQ + 0xC7,0x00,0x53,0x4C,0x4C,0x57,0, // PSLLW + 0xC6,0x00,0x53,0x52,0x41,0x44,0, // PSRAD + 0xC5,0x00,0x53,0x52,0x41,0x57,0, // PSRAW + 0xC3,0x00,0x53,0x52,0x4C,0x44,0, // PSRLD + 0xD5,0x01,0x53,0x52,0x4C,0x44,0x51,0, // PSRLDQ + 0xC4,0x00,0x53,0x52,0x4C,0x51,0, // PSRLQ + 0xC2,0x00,0x53,0x52,0x4C,0x57,0, // PSRLW + 0xDF,0x00,0x53,0x55,0x42,0x42,0, // PSUBB + 0xE1,0x00,0x53,0x55,0x42,0x44,0, // PSUBD + 0xE1,0x01,0x53,0x55,0x42,0x51,0, // PSUBQ + 0xD8,0x00,0x53,0x55,0x42,0x53,0x42,0, // PSUBSB + 0xD9,0x00,0x53,0x55,0x42,0x53,0x57,0, // PSUBSW + 0xD0,0x00,0x53,0x55,0x42,0x55,0x53,0x42,0, // PSUBUSB + 0xD1,0x00,0x53,0x55,0x42,0x55,0x53,0x57,0, // PSUBUSW + 0xE0,0x00,0x53,0x55,0x42,0x57,0, // PSUBW + 0xBE,0x00,0x55,0x4E,0x50,0x43,0x4B,0x48,0x42,0x57,0, // PUNPCKHBW + 0xC0,0x00,0x55,0x4E,0x50,0x43,0x4B,0x48,0x44,0x51,0, // PUNPCKHDQ + 0xE2,0x01,0x55,0x4E,0x50,0x43,0x4B,0x48,0x51,0x44,0x51,0, // PUNPCKHQDQ + 0xBF,0x00,0x55,0x4E,0x50,0x43,0x4B,0x48,0x57,0x44,0, // PUNPCKHWD + 0xB6,0x00,0x55,0x4E,0x50,0x43,0x4B,0x4C,0x42,0x57,0, // PUNPCKLBW + 0xB8,0x00,0x55,0x4E,0x50,0x43,0x4B,0x4C,0x44,0x51,0, // PUNPCKLDQ + 0xE3,0x01,0x55,0x4E,0x50,0x43,0x4B,0x4C,0x51,0x44,0x51,0, // PUNPCKLQDQ + 0xB7,0x00,0x55,0x4E,0x50,0x43,0x4B,0x4C,0x57,0x44,0, // PUNPCKLWD + 0x48,0x00,0x55,0x53,0x48,0, // PUSH + 0x49,0x00,0x55,0x53,0x48,0x41,0, // PUSHA + 0x4A,0x00,0x55,0x53,0x48,0x41,0x44,0, // PUSHAD + 0x3D,0x00,0x55,0x53,0x48,0x46,0, // PUSHF + 0x3E,0x00,0x55,0x53,0x48,0x46,0x44,0, // PUSHFD + 0xDD,0x00,0x58,0x4F,0x52,0, // PXOR + 0xFF,0xFF, // end char 'P' + 0x10,0x00,0x43,0x4C,0, // RCL + 0x95,0x01,0x43,0x50,0x50,0x53,0, // RCPPS + 0x96,0x01,0x43,0x50,0x53,0x53,0, // RCPSS + 0x11,0x00,0x43,0x52,0, // RCR + 0xB1,0x00,0x44,0x4D,0x53,0x52,0, // RDMSR + 0xB4,0x00,0x44,0x50,0x4D,0x43,0, // RDPMC + 0xB2,0x00,0x44,0x54,0x53,0x43,0, // RDTSC + 0x6F,0x00,0x45,0x50,0, // REP + 0x6F,0x00,0x45,0x50,0x45,0, // REPE + 0x6E,0x00,0x45,0x50,0x4E,0x45,0, // REPNE + 0x6E,0x00,0x45,0x50,0x4E,0x5A,0, // REPNZ + 0x6F,0x00,0x45,0x50,0x5A,0, // REPZ + 0x98,0x00,0x45,0x54,0, // RET + 0x99,0x00,0x45,0x54,0x46,0, // RETF + 0x0E,0x00,0x4F,0x4C,0, // ROL + 0x0F,0x00,0x4F,0x52,0, // ROR + 0xB3,0x00,0x53,0x4D,0, // RSM + 0x97,0x01,0x53,0x51,0x52,0x54,0x50,0x53,0, // RSQRTPS + 0x98,0x01,0x53,0x51,0x52,0x54,0x53,0x53,0, // RSQRTSS + 0xFF,0xFF, // end char 'R' + 0x3F,0x00,0x41,0x48,0x46,0, // SAHF + 0x12,0x00,0x41,0x4C,0, // SAL + 0x15,0x00,0x41,0x52,0, // SAR + 0x03,0x00,0x42,0x42,0, // SBB + 0x03,0x00,0x42,0x43,0, // SBC + 0x6B,0x00,0x43,0x41,0x53,0x42,0, // SCASB + 0x6D,0x00,0x43,0x41,0x53,0x44,0, // SCASD + 0x6C,0x00,0x43,0x41,0x53,0x57,0, // SCASW + 0x8D,0x00,0x45,0x54,0x41,0, // SETA + 0x89,0x00,0x45,0x54,0x41,0x45,0, // SETAE + 0x88,0x00,0x45,0x54,0x42,0, // SETB + 0x8C,0x00,0x45,0x54,0x42,0x45,0, // SETBE + 0x88,0x00,0x45,0x54,0x43,0, // SETC + 0x8A,0x00,0x45,0x54,0x45,0, // SETE + 0x95,0x00,0x45,0x54,0x47,0, // SETG + 0x93,0x00,0x45,0x54,0x47,0x45,0, // SETGE + 0x92,0x00,0x45,0x54,0x4C,0, // SETL + 0x94,0x00,0x45,0x54,0x4C,0x45,0, // SETLE + 0x8C,0x00,0x45,0x54,0x4E,0x41,0, // SETNA + 0x88,0x00,0x45,0x54,0x4E,0x41,0x45,0, // SETNAE + 0x89,0x00,0x45,0x54,0x4E,0x42,0, // SETNB + 0x8D,0x00,0x45,0x54,0x4E,0x42,0x45,0, // SETNBE + 0x89,0x00,0x45,0x54,0x4E,0x43,0, // SETNC + 0x8B,0x00,0x45,0x54,0x4E,0x45,0, // SETNE + 0x94,0x00,0x45,0x54,0x4E,0x47,0, // SETNG + 0x92,0x00,0x45,0x54,0x4E,0x47,0x45,0, // SETNGE + 0x93,0x00,0x45,0x54,0x4E,0x4C,0, // SETNL + 0x95,0x00,0x45,0x54,0x4E,0x4C,0x45,0, // SETNLE + 0x87,0x00,0x45,0x54,0x4E,0x4F,0, // SETNO + 0x91,0x00,0x45,0x54,0x4E,0x50,0, // SETNP + 0x8F,0x00,0x45,0x54,0x4E,0x53,0, // SETNS + 0x8B,0x00,0x45,0x54,0x4E,0x5A,0, // SETNZ + 0x86,0x00,0x45,0x54,0x4F,0, // SETO + 0x90,0x00,0x45,0x54,0x50,0, // SETP + 0x90,0x00,0x45,0x54,0x50,0x45,0, // SETPE + 0x91,0x00,0x45,0x54,0x50,0x4F,0, // SETPO + 0x8E,0x00,0x45,0x54,0x53,0, // SETS + 0x8A,0x00,0x45,0x54,0x5A,0, // SETZ + 0x72,0x01,0x46,0x45,0x4E,0x43,0x45,0, // SFENCE + 0xA6,0x00,0x47,0x44,0x54,0, // SGDT + 0x12,0x00,0x48,0x4C,0, // SHL + 0x1E,0x00,0x48,0x4C,0x44,0, // SHLD + 0x13,0x00,0x48,0x52,0, // SHR + 0x1F,0x00,0x48,0x52,0x44,0, // SHRD + 0xD6,0x01,0x48,0x55,0x46,0x50,0x44,0, // SHUFPD + 0x99,0x01,0x48,0x55,0x46,0x50,0x53,0, // SHUFPS + 0xA7,0x00,0x49,0x44,0x54,0, // SIDT + 0x9E,0x00,0x4C,0x44,0x54,0, // SLDT + 0xAA,0x00,0x4D,0x53,0x57,0, // SMSW + 0xD7,0x01,0x51,0x52,0x54,0x50,0x44,0, // SQRTPD + 0x9A,0x01,0x51,0x52,0x54,0x50,0x53,0, // SQRTPS + 0xD8,0x01,0x51,0x52,0x54,0x53,0x44,0, // SQRTSD + 0x9B,0x01,0x51,0x52,0x54,0x53,0x53,0, // SQRTSS + 0x43,0x00,0x54,0x43,0, // STC + 0x47,0x00,0x54,0x44,0, // STD + 0x45,0x00,0x54,0x49,0, // STI + 0x9C,0x01,0x54,0x4D,0x58,0x43,0x53,0x52,0, // STMXCSR + 0x65,0x00,0x54,0x4F,0x53,0x42,0, // STOSB + 0x67,0x00,0x54,0x4F,0x53,0x44,0, // STOSD + 0x66,0x00,0x54,0x4F,0x53,0x57,0, // STOSW + 0x9F,0x00,0x54,0x52,0, // STR + 0x05,0x00,0x55,0x42,0, // SUB + 0xD9,0x01,0x55,0x42,0x50,0x44,0, // SUBPD + 0x9D,0x01,0x55,0x42,0x50,0x53,0, // SUBPS + 0xDA,0x01,0x55,0x42,0x53,0x44,0, // SUBSD + 0x9E,0x01,0x55,0x42,0x53,0x53,0, // SUBSS + 0x3F,0x01,0x59,0x53,0x45,0x4E,0x54,0x45,0x52,0, // SYSENTER + 0x40,0x01,0x59,0x53,0x45,0x58,0x49,0x54,0, // SYSEXIT + 0xFF,0xFF, // end char 'S' + 0x1C,0x00,0x45,0x53,0x54,0, // TEST + 0xFF,0xFF, // end char 'T' + 0xDB,0x01,0x43,0x4F,0x4D,0x49,0x53,0x44,0, // UCOMISD + 0x9F,0x01,0x43,0x4F,0x4D,0x49,0x53,0x53,0, // UCOMISS + 0xB5,0x00,0x44,0x32,0, // UD2 + 0xDC,0x01,0x4E,0x50,0x43,0x4B,0x48,0x50,0x44,0, // UNPCKHPD + 0xA0,0x01,0x4E,0x50,0x43,0x4B,0x48,0x50,0x53,0, // UNPCKHPS + 0xDD,0x01,0x4E,0x50,0x43,0x4B,0x4C,0x50,0x44,0, // UNPCKLPD + 0xA1,0x01,0x4E,0x50,0x43,0x4B,0x4C,0x50,0x53,0, // UNPCKLPS + 0xFF,0xFF, // end char 'U' + 0xA2,0x00,0x45,0x52,0x52,0, // VERR + 0xA3,0x00,0x45,0x52,0x57,0, // VERW + 0xFF,0xFF, // end char 'V' + 0x34,0x00,0x41,0x49,0x54,0, // WAIT + 0xAE,0x00,0x42,0x49,0x4E,0x56,0x44,0, // WBINVD + 0xAF,0x00,0x52,0x4D,0x53,0x52,0, // WRMSR + 0xFF,0xFF, // end char 'W' + 0x32,0x00,0x41,0x44,0x44,0, // XADD + 0x4E,0x00,0x43,0x48,0x47,0, // XCHG + 0x2D,0x00,0x4C,0x41,0x54,0, // XLAT + 0x2D,0x00,0x4C,0x41,0x54,0x42,0, // XLATB + 0x06,0x00,0x4F,0x52,0, // XOR + 0xDE,0x01,0x4F,0x52,0x50,0x44,0, // XORPD + 0xA2,0x01,0x4F,0x52,0x50,0x53,0, // XORPS + 0xFF,0xFF // end char 'X' +}; diff --git a/programs/develop/cmm/c--.ini b/programs/develop/cmm/c--.ini new file mode 100644 index 0000000000..a114e82c05 --- /dev/null +++ b/programs/develop/cmm/c--.ini @@ -0,0 +1,14 @@ +; . +J0 ; jump main() +8 ; Pentium II . +r- ; *.com +X ; SPHINXC-- +oc ; +w ; +wf=warning.txt ; warning +nw=1 ; - warning.txt +nw=2 ; - warning.txt +;de ; +;ON ; +;ost ; +IP=..\lib \ No newline at end of file diff --git a/programs/develop/cmm/class.cpp b/programs/develop/cmm/class.cpp new file mode 100644 index 0000000000..7611cee1da --- /dev/null +++ b/programs/develop/cmm/class.cpp @@ -0,0 +1,88 @@ +#define _CLASS_ + +#include "tok.h" + +structteg *searchteg=NULL; +int destructor=FALSE; + +void notclassname(char *name) +{ +char buf[90]; + sprintf(buf,"'%s' not class name",name); + preerror(buf); + nexttok(); //ய :: + nexttok(); +} + +void notclassproc(char *classname, char* procname) +{ +char buf[160]; + sprintf(buf,"'%s' not member class '%s'",procname,classname); + preerror(buf); +} + +void AddThis() +{ + int lsize=(am32==TRUE?4:2); + localrec *lrec=addlocalvar("this",(am32==TRUE?tk_dwordvar:tk_wordvar),paramsize); + lrec->rec.recsize=lsize; + lrec->rec.type=tp_paramvar; + lrec->fuse=USEDVAR; + paramsize+=lsize; +} + +void doclassproc(unsigned int tproc) +{ +int type=itok.rm; //⨯ +unsigned int flag=itok.flag; +unsigned int npointr=itok.npointr; +char classname[IDLENGTH]; + if((searchteg=FindTeg(TRUE,itok.name))!=NULL){ + strcpy(classname,itok.name); + nexttok(); //ய :: + if(tok2==tk_tilda){ + nexttok(); + destructor=TRUE; + flag|=fs_destructor; + type=tk_void; + } + nexttok(); + char *tn; + char name[IDLENGTH]; + strcpy(name,itok.name); + if((tn=strchr(name,'@'))!=NULL)*tn=0; + + if(strcmp(classname,name)==0&&(flag&fs_destructor)==0)flag|=fs_constructor; + if((tok!=tk_declare&&tok!=tk_undefproc)||(itok.flag&f_classproc)==0){ + notclassproc(classname,name); + searchteg=NULL; + define_procedure(); + return; + } + if(tproc==0){ + if(CidOrID()==tk_ID)tproc=tk_fastcall; + else tproc=(comfile==file_w32?tk_stdcall:tk_pascal); + } + flag|=(tproc-tk_pascal)*2; + if(type==tokens)type=am32==FALSE?tk_word:tk_dword; + if(flag!=itok.flag||type!=itok.rm||(unsigned short)npointr!=itok.npointr){ +// printf("flag %08X - %08X\n",flag,itok.flag); +// printf("type %u - %u\n",type,itok.rm); + redeclare(name); + } + if(dynamic_flag){ + dynamic_proc(); + searchteg=NULL; + return; + } +// if(itok.flag&f_static)searchteg=NULL; + if(AlignProc!=FALSE)AlignCD(CS,alignproc); + if(dbg)AddLine(); + setproc(1); + } + else{ + notclassname(itok.name); + setproc(0); + } + dopoststrings(); +} diff --git a/programs/develop/cmm/coff.h b/programs/develop/cmm/coff.h new file mode 100644 index 0000000000..545002cb63 --- /dev/null +++ b/programs/develop/cmm/coff.h @@ -0,0 +1,106 @@ +// +// Section characteristics. +// +// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. +// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. +// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. +// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. +// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +// IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. +// 0x00002000 // Reserved. +// IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000 +#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. +#define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP +#define IMAGE_SCN_MEM_FARDATA 0x00008000 +// IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // +// Unused 0x00F00000 +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// I386 relocation types. +// +#define IMAGE_REL_I386_ABSOLUTE 0x0000 //Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 0x0001 //Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 0x0002 //PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 0x0006 //Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 0x0007 //Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 0x0009 //Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 0x000A +#define IMAGE_REL_I386_SECREL 0x000B +#define IMAGE_REL_I386_REL32 0x0014 //PC-relative 32-bit reference to the symbols virtual address + +typedef struct _COFF_HEADER_ +{ + short cpu; // ⨯ CPU - ᥣ 0x14C + short numobj; //᫮ 室 ⠡ ꥪ⮢ + long date_time; // 䨪樨 ஬ + long pCOFF; + long COFFsize; + short SizeOfOptionalHeader; + short Characteristics; +}COFF_HEADER; + +typedef struct _IMAGE_SYMBOL +{ + union{ + char sname[8]; + struct{ + unsigned long Short; + unsigned long Long; + }Name; + char *LongName[2]; + }N; + unsigned long Value; + short SectionNumber; + unsigned short Type; + unsigned char StorageClass; + unsigned char NumberOfAuxSymbols; +}IMAGE_SYMBOL; + +typedef struct _IMAGE_RELOCATION { + union { + unsigned long VirtualAddress; + unsigned long RelocCount; // Set to the real count when IMAGE_SCN_LNK_NRELOC_OVFL is set + }; + unsigned long SymbolTableIndex; + unsigned short Type; +}IMAGE_RELOCATION; + diff --git a/programs/develop/cmm/const.h b/programs/develop/cmm/const.h new file mode 100644 index 0000000000..ab9903d48a --- /dev/null +++ b/programs/develop/cmm/const.h @@ -0,0 +1,513 @@ +#define FALSE 0 +#define TRUE 1 +#define LOCAL -1 +#define DYNAMIC_POST 2 +#define DYNAMIC_VAR 3 +#define USED_DIN_VAR 4 + +#define r_undef 0 +#define r8 1 +#define r16 2 +#define r32 4 +#define r64 8 +#define r128 16 + +#define CODE16 0x100 +#define CODE32 0x200 +#define THIS_PARAM 0x300 +#define THIS_REG 0x400 +#define THIS_NEW 0x500 +#define THIS_ZEROSIZE 0x600 + +enum{ + dm_other, + dm_none, + dm_def0, + dm_def, + dm_if, +}; + +enum{ + STDLEX, + RESLEX, + DEFLEX, + DEFLEX2, + ASMLEX, +}; + +enum{ + zero_term, + dos_term, + no_term, + s_unicod=4 +}; + +enum{ + NOTINITVAR, + INITVAR, + USEDVAR, + INITUSEVAR +}; + +enum{ + tp_ucnovn, + tp_declare, + tp_localvar, + tp_paramvar, + tp_postvar, + tp_gvar, + tp_label, + tp_stopper, + tp_opperand, + tp_compare, + tp_modif, + tp_ofs, + tp_classvar, +}; + +enum{ + stdcompr, + voidcompr=4, + zerocompr=8, + ecxzcompr=0xc, + cxzcompr=0x10, + ecxnzcompr=0x14, + cxnzcompr=0x18 +}; + +enum{ + tk_eof, tk_number, tk_string, tk_id, tk_ID, + tk_assign, tk_swap, tk_minus, tk_plus, tk_minusminus, + tk_plusplus, tk_mult, tk_div, tk_mod, tk_multminus, + tk_divminus, tk_modminus, tk_rr, tk_ll, tk_rrminus, + tk_llminus, tk_minusequals, tk_plusequals, tk_rrequals, tk_llequals, + tk_or, tk_and, tk_xor, tk_not, tk_orminus, + tk_andminus, tk_xorminus, tk_orequals, tk_andequals, tk_xorequals, + tk_equalto, tk_notequal, tk_greater, tk_greaterequal,tk_less, +//40 + tk_lessequal, tk_oror, tk_andand, tk_openbrace, tk_closebrace, + tk_openbracket, tk_closebracket,tk_openblock, tk_closeblock, tk_colon, + + tk_semicolon, tk_camma, tk_period, tk_at, tk_numsign, + tk_dollar, tk_question, tk_tilda, + tk_void, tk_char, +//60 + tk_byte, tk_int, tk_word, tk_long, tk_dword, + tk_float, tk_qword, tk_double, + tk_if, tk_IF, + tk_else, tk_ELSE, tk_loop, tk_do, tk_while, + tk_return, tk_from, tk_extract, tk_interrupt, tk_far, +//80 + tk_enum, tk_seg, tk_debugreg, tk_controlreg, tk_testreg, + tk_undefproc, tk_proc, tk_interruptproc, + tk_bits, tk_charvar, +//90 + tk_bytevar, tk_intvar, tk_wordvar, tk_longvar, tk_dwordvar, + tk_floatvar, tk_qwordvar, tk_doublevar, tk_reg, tk_beg, +//100 + tk_reg32, tk_rmnumber, tk_postnumber, tk_locallabel, tk_overflowflag, + tk_notoverflowflag,tk_carryflag,tk_notcarryflag,tk_zeroflag, tk_notzeroflag, +//110 + tk_comment1, tk_comment2, tk_minusflag, tk_plusflag, tk_RETURN, + tk_dataptr, tk_codeptr, tk_postptr, tk_stackstart, tk_inline, +//120 + tk_GOTO, tk_goto, tk_BREAK, tk_break, tk_CONTINUE, + tk_continue, tk_WHILE, tk_FOR, tk_for, tk_asm, +//130 + tk_switch, tk_case, tk_default, tk_mmxreg, tk_fpust, + tk_multequals, tk_divequals, tk_struct, tk_structvar, tk_sizeof, +//140 + tk_undefofs, tk_pointer, tk_localpointer,tk_parampointer,tk_apiproc, + tk_extern, tk_declare, tk_pascal, tk_cdecl, tk_stdcall, +//150 + tk_fastcall, tk_union, tk_export, tk_multipoint, tk_LOOPNZ, + tk_loopnz, tk_idasm, tk_short, tk_unsigned, tk_signed, +//160 + tk_file, tk_line, tk_SWITCH, tk_CASE, tk_xmmreg, + tk_dblcolon, tk_static, tk_baseclass, tk_rescommand, tk_endline, +//170 + tk_singlquote, tk_new, tk_delete, tk_macro, tk_reg64, + tk_newline, tk_apioffset, tokens +}; + +// 16-bit word regs +#define AX 0 +#define CX 1 +#define DX 2 +#define BX 3 +#define SP 4 +#define BP 5 +#define SI 6 +#define DI 7 + +// 8-bit byte regs +#define AL 0 +#define CL 1 +#define DL 2 +#define BL 3 +#define AH 4 +#define CH 5 +#define DH 6 +#define BH 7 + +// 386+ 32-bit regs +#define EAX 0 +#define ECX 1 +#define EDX 2 +#define EBX 3 +#define ESP 4 +#define EBP 5 +#define ESI 6 +#define EDI 7 + +//஫ ࠧ襭 ॣ஢ +#define dEAX 1 +#define dECX 2 +#define dEDX 4 +#define dEBX 8 +#define dESP 16 +#define dEBP 32 +#define dESI 64 +#define dEDI 128 + +#define ES 0 +#define CS 1 +#define SS 2 +#define DS 3 +#define FS 4 +#define GS 5 +#define VARPOST 9 +#define USEDSTR 10 +// 386+ control regs +#define CR0 0 +#define CR1 1 +#define CR2 2 +#define CR3 3 +#define CR4 4 +#define CR5 5 +#define CR6 6 +#define CR7 7 + +// 386+ test regs +#define TR0 0 +#define TR1 1 +#define TR2 2 +#define TR3 3 +#define TR4 4 +#define TR5 5 +#define TR6 6 +#define TR7 7 + +// 386+ debug regs +#define DR0 0 +#define DR1 1 +#define DR2 2 +#define DR3 3 +#define DR4 4 +#define DR5 5 +#define DR6 6 +#define DR7 7 + +//६, 㪠⥫, 쭨 㪠⥫,ᥣ 㪠⥫. +#define variable 0 +#define pointer 1 +//#define farpointer 2 + +// define exit codes +#define e_ok 0 +#define e_outofmemory 1 +#define e_cannotopeninput 2 +#define e_toomanyerrors 3 +#define e_internalerror 4 +#define e_noinputspecified 5 +#define e_unknowncommandline 6 +#define e_entrynotfound 7 +#define e_outputtoobig 8 +#define e_notcreateoutput 9 +#define e_preprocess 10 +#define e_someerrors 13 +#define e_badinputfilename 14 +#define e_symbioerror 15 +#define e_manyinclude 16 + +#define rm_mod00 0 +#define rm_mod01 64 +#define rm_mod10 128 +#define rm_mod11 192 +#define rm_d16 6 +#define rm_BXSI 0 +#define rm_BXDI 1 +#define rm_BPSI 2 +#define rm_BPDI 3 +#define rm_SI 4 +#define rm_DI 5 +#define rm_BP 6 +#define rm_BX 7 +#define rm_sib 4 +#define rm_d32 5 +#define rm_EBP 5 + +// posttype values for call or jump types or post variables +enum{ +CALL_NONE, //0 +CALL_SHORT, // 1 +BREAK_SHORT, // 2 +CONTINUE_SHORT, // 3 +CALL_NEAR, // 4 +//CALL_NEARD, +JMP_NEAR, // 5 +BREAK_NEAR, // 6 +CONTINUE_NEAR, // 7 + +CALL_32, //8 +//CALL_32D, +JMP_32, // 9 +BREAK_32, // 10 +CONTINUE_32, // 11 +UNDEF_OFSET, //12 +POST_STRING, //13 +POST_STRING32, +CALL_EXT, // 14 +EXT_VAR, // 15 + +CALL_32I, // 16 + +POST_VAR, // 17 +FIX_VAR, // 18 +FIX_CODE, // 19 + +POST_VAR32, // 20 +FIX_VAR32, // 21 +FIX_CODE32, // 22 + +POST_FLOATNUM, // 23 +DATABLOCK_VAR, //24 +DATABLOCK_VAR32, //25 +DIN_VAR, //26 +DIN_VAR32, //27 + +CODE_SIZE, +CODE_SIZE32, +DATA_SIZE, +DATA_SIZE32, +POST_SIZE, +POST_SIZE32, +STACK_SIZE, +STACK_SIZE32, + +FIX_CODE_ADD, +//DATABLOCK_STRING, // 26 +//DATABLOCK_STRING32 // 27 +}; + +#define POINTER 0x8000 +#define NOTPOINTER (~POINTER) + +// format of output file +#define file_exe 0 +#define file_com 1 +#define file_sys 2 +#define file_rom 3 +#define file_w32 4 +#define file_d32 5 +#define file_meos 6 +#define file_bin 7 + +//⨯ +#define TINY 0 +#define SMALL 1 + + +//䫠 +#define f_reloc 1 // +#define f_typeproc 6 //⨯ 맮 楤 +#define f_far 8 // 楤 +#define f_extern 0x10 // 楤, ६ +#define f_interrupt 0x20 //뢠 +#define f_export 0x40 //ᯮ㥬 楤 +#define f_inline 0x80 //inline 楤 +#define f_retproc 0xf00 // 䫠 楤 +#define f_static 0x1000 // +#define f_classproc 0x2000 //楤 +//䫠 楤 +#define fs_constructor 0x4000 +#define fs_destructor 0x8000 + +#define f_useidx 0x10000 //६ ᯮ [] + +//⨯ 楤 +#define tp_pascal 0 +#define tp_cdecl 2 +#define tp_stdcall 4 +#define tp_fastcall 6 + +//⨯ 맮 API 楤 +#define API_FAST 1 +#define API_JMP 2 + +#define USEALLREG 8//0 +//#define USEFIRST4REG 1 +//#define USEONLY_AX 2 + +//㬥 ᯨ᪠ ४⨢ +enum{ + d_ctrl, d_jump, d_command,d_argc, d_resize, + d_resmes,d_stack,d_start, d_atr, d_name, + d_com, d_atex, d_dseg, d_rsize,d_mdr, + d_stm, d_fca, d_suv, d_us, d_ib, + d_end1, + + d_align=d_end1, d_aligner,d_alignw, //d_beep, + d_code, d_define, d_DOS, d_endif, d_ifdef, + d_ifndef,d_incl, d_error, /*d_pause,*/ d_print, + d_prnex, d_random, d_speed, d_8086, d_8088, + d_80186, d_80286, d_80386, d_80486, d_80586, + d_80686, d_80786, d_sdp, d_warning,d_ip, + d_iav, d_am32, d_undef, d_alignc, + d_fut, d_dstr, d_cv, d_else, d_wmb, + d_pragma,d_inline, d_if, d_elif, d_end}; + +enum{ + a_add,a_or, a_adc,a_sbb,a_and, a_sub, a_xor, a_cmp, + a_not,a_neg,a_mul,a_div=a_mul+2,a_idiv, + + a_rol,a_ror,a_rcl,a_rcr,a_shl, a_shr, a_sar=a_shr+2, + + a_bt, a_bts,a_btr,a_btc, + + a_inc,a_dec, + + a_test,a_imul, + + a_shld,a_shrd, + + a_daa,a_das,a_aaa,a_aas,a_aam, a_aad, + a_movzx,a_movsx,a_cbw,a_cwde,a_cwd,a_cdq, + a_bswap,a_xlat, + + a_bsf,a_bsr, + + a_cmpxchg,a_cmpxchg8b,a_xadd, + a_nop,a_wait,a_lock,a_hlt,a_int, + a_into,a_iret,a_iretd, + a_popf,a_popfd,a_pushf,a_pushfd,a_sahf,a_lahf, + a_cmc,a_clc,a_stc,a_cli,a_sti,a_cld,a_std, + a_push,a_pusha,a_pushad,a_pop,a_popa,a_popad, + a_xchg,a_mov,a_lea, + + a_lfs,a_lgs,a_lss, + + a_les,a_lds, + + a_adrsiz, + a_in,a_out,a_insb,a_insw,a_insd,a_outsb,a_outsw,a_outsd, + a_movsb,a_movsw,a_movsd,a_cmpsb,a_cmpsw,a_cmpsd, + a_stosb,a_stosw,a_stosd,a_lodsb,a_lodsw,a_lodsd, + a_scasb,a_scasw,a_scasd,a_repnz,a_rep, + a_jcxz,a_jecxz,a_loop,a_loopd,a_loopz,a_loopnz, + + a_jo,a_jno,a_jc,a_jnc,a_jz,a_jnz,a_jna,a_ja, + a_js,a_jns,a_jp,a_jnp,a_jl,a_jnl,a_jng,a_jg, + + a_seto,a_setno,a_setc,a_setnc,a_setz,a_setnz,a_setna,a_seta, + a_sets,a_setns,a_setp,a_setnp,a_setl,a_setnl,a_setng,a_setg, + + /*a_jmps,a_jmpn,a_jmpf,*/a_jmp, + a_call,/*a_callf,*/a_ret,a_retf, + a_enter,a_leave,a_bound,a_arpl, + a_sldt,a_str,a_lldt,a_ltr,a_verr,a_verw, + + a_lar,a_lsl, + + a_sgdt,a_sidt,a_lgdt,a_lidt,a_smsw,a_lmsw,a_clts, + a_invd,a_wbinvd,//a_invlpd, + a_wrmsr,a_cpuid,a_rdmsr,a_rdtsc,a_rsm, + a_rdpmc,a_ud2,/*a_emmx,a_setalc,*/ + + a_punpcklbw,a_punpcklwd,a_punpckldq, + a_packsswb, + a_pcmpgtb,a_pcmpgtw,a_pcmpgtd, + a_packuswb, + a_punpckhbw,a_punpckhwd,a_punpckhdq, + a_packssdw, + a_psrlw,a_psrld,a_psrlq, + a_psraw,a_psrad, + a_psllw,a_pslld,a_psllq, + a_pcmpeqb,a_pcmpeqw,a_pcmpeqd, + a_pmullw, + a_movd,a_movq, + a_psubusb,a_psubusw, + a_emms, + a_pand, + a_paddusb,a_paddusw, + a_pandn,a_pmulhw, + a_psubsb,a_psubsw, + a_por, + a_paddsb,a_paddsw, + a_pxor, + a_pmaddwd, + a_psubb,a_psubw,a_psubd, + a_paddb,a_paddw,a_paddd, + + a_db,a_dw,a_dd,a_invlpg,a_loadall,a_opsiz, + a_f2xm1,a_fabs,a_fadd,a_faddp,a_fbld,a_fbstp,a_fchs,a_fclex,a_fcom, + a_fcomp,a_fnclex,a_fcompp,a_fcos,a_fdecstr,a_fdisi,a_fdiv,a_fdivp, + a_fdivr,a_fdivrp,a_ffree,a_fiadd,a_ficom,a_ficomp,a_fidiv,a_fidivr, + a_fild,a_fildq,a_fimul,a_fist,a_fistp,a_fisub,a_fisubr,a_feni,a_fincstr, + a_finit,a_fninit,a_fld,a_fldcw,a_fldenv,a_fldlg2,a_fldln2,a_fldl2e, + a_fldl2t,a_fldpi,a_fldz,a_fld1,a_fmul,a_fmulp,a_fnop,a_fpatan,a_fprem, + a_fprem1,a_fptan,a_frndint,a_fsetpm,a_frstor,a_fsave,a_fnsave,a_fscale, + a_fsin,a_fsincos,a_fsqrt,a_fst,a_fstcw,a_fnstcw,a_fstp,a_fstsw,a_fnstsw, + a_fstenv,a_fnstenv,a_fsub,a_fsubp,a_fsubr,a_fsubrp,a_ftst,a_fucom,a_fucomp, + a_fucompp,a_fxch,a_fwait,a_fxam,a_fxtract,a_fyl2x,a_fyl2xp1, + a_sysenter,a_sysexit,a_fcmovb,a_fcmove,a_fcmovbe,a_fcmovu,a_fcmovnb, + a_fcmovne,a_fcmovnbe,a_fcmovnu,a_fcomi,a_fcomip,a_fucomi,a_fucomip, + a_fxrstor,a_fxsave,a_fndisi,a_fneni,a_fnsetpm, + + a_cmovo,a_cmovno,a_cmovc,a_cmovnc,a_cmovz,a_cmovnz,a_cmovna,a_cmova, + a_cmovs,a_cmovns,a_cmovp,a_cmovnp,a_cmovl,a_cmovnl,a_cmovng,a_cmovg, + +//MMX Pentium III extention + a_maskmovq, a_movntq, a_pavgb, a_pavgw, a_pextrw, a_pinsrw, + a_pmaxub, a_pmaxsw, a_pminub, a_pminsw, a_pmovmskb,a_pmulhuw, + a_prefetcht0,a_prefetcht1,a_prefetcht2, a_prefetchnta,a_sfence, a_psadbw, + a_pshufw, +//XMM extentions Pentium III + a_addps, a_addss, a_andnps, a_andps, a_cmpps, a_cmpss, + a_comiss, a_cvtpi2ps,a_cvtps2pi,a_cvtsi2ss,a_cvtss2si,a_cvttps2pi, + a_cvttss2si,a_divps, a_divss, a_ldmxcsr, a_maxps, a_maxss, + a_minps, a_minss, a_movaps, a_movhlps, a_movhps, a_movlhps, + a_movlps, a_movmskps,a_movss, a_movups, a_mulps, a_mulss, + a_movntps, a_orps, a_rcpps, a_rcpss, a_rsqrtps, a_rsqrtss, + a_shufps, a_sqrtps, a_sqrtss, a_stmxcsr, a_subps, a_subss, + a_ucomiss, a_unpckhps,a_unpcklps,a_xorps, + +// Pentium IV + a_lfence, a_mfence, a_addpd, a_addsd, a_andpd, a_andnpd, + a_cmppd, a_comisd, a_cvtdq2pd, a_cvtdq2ps, a_cvtpd2dq, a_cvtpd2pi, + a_cvtpd2ps,a_cvtpi2pd, a_cvtps2dq, a_cvtps2pd, a_cvtsd2si, a_cvtsd2ss, + a_cvtsi2sd,a_cvtss2sd, a_cvttpd2pi, a_cvttpd2dq, a_cvttps2dq, a_cvttsd2si, + a_divpd, a_divsd, a_maskmovdqu,a_maxpd, a_maxsd, a_minpd, + a_minsd, a_movapd, a_movdqa, a_movdqu, a_movdq2q, a_movhpd, + a_movlpd, a_movmskpd, a_movntdq, a_movntpd, a_movnti, a_movq2dq, + a_movupd, a_mulpd, a_mulsd, a_orpd, a_pshufd, a_pshufhw, + a_pshuflw, a_pslldq, a_psrldq, a_shufpd, a_sqrtpd, a_sqrtsd, + a_subpd, a_subsd, a_ucomisd, a_unpckhpd, a_unpcklpd, a_xorpd, + a_paddq, a_pmuludq, a_psubq, a_punpckhqdq,a_punpcklqdq,a_clflush, + a_monitor, a_mwait, a_addsubpd, a_addsubps, a_cmpeqsd, a_cmpltsd, + a_cmplesd, a_cmpunordsd,a_cmpneqsd, a_cmpnltsd, a_cmpnlesd, a_cmpordsd, + a_cmpeqpd, a_cmpltpd, a_cmplepd, a_cmpunordpd,a_cmpneqpd, a_cmpnltpd, + a_cmpnlepd,a_cmpordpd, a_cmpeqps, a_cmpltps, a_cmpleps, a_cmpunordps, + a_cmpneqps,a_cmpnltps, a_cmpnleps, a_cmpordps, a_cmpeqss, a_cmpltss, + a_cmpless, a_cmpunordss,a_cmpneqss, a_cmpnltss, a_cmpnless, a_cmpordss, + a_haddpd, a_haddps, a_hsubpd, a_hsubps, a_lddqu, a_movddup, + a_movshdup,a_movsldup, a_pause, + + a_end}; + +enum{ + pF3=1, + pF2, + p66 +}; + diff --git a/programs/develop/cmm/debug.cpp b/programs/develop/cmm/debug.cpp new file mode 100644 index 0000000000..1d37ba3776 --- /dev/null +++ b/programs/develop/cmm/debug.cpp @@ -0,0 +1,1410 @@ +#include "tok.h" + + + +#define _DEBUG_ + + + +#define MAXDBGS 1000 + +#define MAXNUMSYM 500 + +#define MAXLSTSTR 128 // + + + +void AddNameToTable(char *name); + +void AddSymbolList(struct idrec *ptr); + +int CreateDosDebug(); + +int CreateW32Debug(); + +void GeneratLst(); + + + +unsigned int *dbgloc=NULL; // + +unsigned int *dbgnum; // + +unsigned short *dbgmod; // + +char **lststring; // + +unsigned char *lstflag=NULL; // + +unsigned int *lstend; + + + +unsigned int pdbg=0; /* number of post entrys */ + +unsigned int pdbgmax=MAXDBGS; /* max number of post entrys */ + +static unsigned int oline=0,omodule=0xFFFFFFFF; + +unsigned int ooutptr=0xffffffff; + +char lsttypedata=0; // , + +unsigned int outputcodestart=0; + + + +struct D16START{ + + unsigned long sign; //0 Signify & Version + + unsigned long pol_size; //4 Name Pool Size (in bytes) + + unsigned long numname; //8 Number of Names + + unsigned long numtentr; //12 Number of Type Entries + + unsigned long nummentr; //16 Number of Member Entries + + unsigned long numsymbl; //20 Number of Symbols + + unsigned long numgsymb; //24 Number of Global Symbols + + unsigned long numsours; //28 Number of Source Modules + + unsigned long numlsumb; //32 Number of Local Symbols + + unsigned long numscop; //36 Number of Scopes + + unsigned long numline; //40 Number of Line Number Entries + + unsigned long numincl; //44 Number of Include Files + + unsigned long numseg; //48 Number of Segments + + unsigned long numcorrel; //52 Number of Correlation Entries + + unsigned long imagesize; //56 Image Size + + unsigned short data[2]; //60 Basic RTL String Segment Offset & Data Count + + unsigned long casesensiv;//64 Case Sensivitive Link + + unsigned long ucnovn; + +// 128- + + unsigned long ucnovn1[6]; + + unsigned long sizeblock; // + + unsigned long ucnovn2[2]; + + unsigned short fdebug; //Debug Flags + + unsigned long reftsize; //Reference Information Table Size (in bytes) + + unsigned long numnamesp; //Number of Namespace Entries + + unsigned long numunamesp; //Number of Namespace Using Entries + + unsigned long ucnovn3; + + unsigned short ucnovn4; + +//////////////////////////////// + +}; + + + +struct MODULE{ + + unsigned long name; + + unsigned char language; + + unsigned char memmodel; + + unsigned long symindex; + + unsigned short symcount; + + unsigned short sourindex; + + unsigned short sourcount; + + unsigned short corindex; + + unsigned short corcount; + +}; + + + +typedef struct _SFT_ + +{ + + unsigned long idx; + + struct ftime time; + +}SFT; + + + +typedef struct _LT_ + +{ + + unsigned short line; + + unsigned short ofs; + +}LT; + + + +typedef struct _CT_ + +{ + + unsigned short segidx; + + unsigned short filidx; + + unsigned long beg; + + unsigned short count; + +}CT; + + + +static struct _SMB_ + +{ + + unsigned long idxname; + + unsigned long type; + + unsigned short ofs; + + unsigned short seg; + + unsigned short clas; + +}*symbols; + + + +static struct SEGMENT{ + + unsigned short idx; + + unsigned short segm; + + unsigned short ofs; + + unsigned short size; + + unsigned short scopei; + + unsigned short scopec; + + unsigned short correli; + + unsigned short correlc; + +}*segment; + + + +unsigned char dbg=FALSE,dbgact; + +static short numsymbols=0; + +static int sizetabsym=MAXNUMSYM; + +static unsigned short numcorrel; + +static unsigned char *bufname; + +static int lastofspul=0; + +static int segcode; + + + +static struct _COR_INFO_ + +{ + + unsigned int ofs; // + + unsigned int end; // + + unsigned int startline; // + + unsigned short count; // + + unsigned short file; // + +}*corinfo=NULL; + + + +void InitDbg() + +{ + + if(fobj)dbg&=0xFE; + + if(dbg&&(dbgloc==NULL)){ + + dbgloc=(unsigned int *)MALLOC(MAXDBGS*sizeof(unsigned int)); + + dbgnum=(unsigned int *)MALLOC(MAXDBGS*sizeof(unsigned int)); + + dbgmod=(unsigned short *)MALLOC(MAXDBGS*sizeof(unsigned short)); + + dbgact=1; // + + } + + if((dbg&2)&&lstflag==NULL){ + + lststring=(char **)MALLOC(MAXDBGS*sizeof(char *)); + + lstflag=(unsigned char *)MALLOC(MAXDBGS*sizeof(char)); + + lstend=(unsigned int *)MALLOC(MAXDBGS*sizeof(unsigned int)); + + memset((char *)lstflag,-1,MAXDBGS*sizeof(char)); + + memset((unsigned int *)lstend,0,MAXDBGS*sizeof(unsigned int)); + + } + +} + + + +void AddDataLine(char ssize/*,char typev*/) + +{ + +/* if(typev==pointer||typev==farpointer)ssize=(typev==pointer?(char)2:(char)4); + + else*/ //if(tok==tk_string)ssize=(char)3; + + lsttypedata=(unsigned char)(ssize<<1); + + AddLine(); + + lsttypedata=0; + +} + + + +void AddDataNullLine(char ssize,char *name) + +{ + + oline--; + + + + lsttypedata=(unsigned char)(ssize<<1); + + AddLine(TRUE); + + lsttypedata=0; + + dbgnum[pdbg-1]=0; // + +//new !!! + + if(name!=NULL)lststring[pdbg-1]=BackString(name); + +} + + + +void AddCodeNullLine(char *name) + +{ + + oline--; + + AddLine(TRUE); + + dbgnum[pdbg-1]=0; // + + if(name!=NULL)lststring[pdbg-1]=BackString(name); + + oline--; + +} + + + +void AddEndLine() + +{ + + if(pdbg/*&&lstend[pdbg-1]==0*/)lstend[pdbg-1]=outptr; + +} + + + +void AddLine(int SkipLineInfo) + +{ + + if(/*ooutptr!=outptr&&*/dbgact==0&&(oline!=linenumber||omodule!=currentfileinfo)){ + + while(ooutptr>outptr&&pdbg!=0&&ooutptr!=0xffffffff)KillLastLine(); + + if(pdbg==pdbgmax){ + + pdbgmax+=MAXDBGS; + + dbgloc=(unsigned int *) REALLOC(dbgloc,pdbgmax*sizeof(unsigned int)); + + dbgnum=(unsigned int *) REALLOC(dbgnum,pdbgmax*sizeof(unsigned int)); + + dbgmod=(unsigned short *)REALLOC(dbgmod,pdbgmax*sizeof(unsigned short)); + + if(lstflag){ + + lststring=(char **)REALLOC(lststring,pdbgmax*sizeof(char *)); + + lstflag=(unsigned char *)REALLOC(lstflag,pdbgmax*sizeof(char)); + + lstend=(unsigned int *)REALLOC(lstend,pdbgmax*sizeof(unsigned int)); + + memset((char *)lstflag+(pdbgmax-MAXDBGS),-1,MAXDBGS*sizeof(char)); + + memset((unsigned int *)lstend+(pdbgmax-MAXDBGS),0,MAXDBGS*sizeof(unsigned int)); + + } + + } + + dbgloc[pdbg]=ooutptr=outptr; + + dbgnum[pdbg]=oline=linenumber; + + dbgmod[pdbg]=(unsigned short)currentfileinfo; + + omodule=currentfileinfo; + + if(dbg&2){ + + if(SkipLineInfo)lststring[pdbg]=NULL; + + else{ + + char *ofs=startline; + + char c; + + int sizestring=0; + + char buf[MAXLSTSTR]; + + for(;sizestring<(MAXLSTSTR-1);sizestring++){ + + c=*ofs; + + ofs=ofs+1; + + if(c==13||ofs==endinput)break; + + buf[sizestring]=c; + + } + + buf[sizestring]=0; + + strbtrim(buf); + + if((sizestring=strlen(buf))==0)lststring[pdbg]=NULL; + + else{ + + lststring[pdbg]=(char *)MALLOC(sizestring+1); + + strcpy(lststring[pdbg],buf); + + } + + } + + lstflag[pdbg]=(unsigned char)(am32|lsttypedata); + + AddEndLine(); + +// printf("%s(%d) outptr=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,outptr); + + } + + pdbg++; + + (startfileinfo+currentfileinfo)->numdline++; + + } + +} + + + +void KillLastLine() + +{ + +// printf("dbgact=%d pdbg=%d outptr=%08X ooutptr=%08X\n",dbgact,pdbg,outptr,ooutptr); + + if(outptr==0&&ooutptr==0x100){ + + ooutptr=0; + + return; + + } + + if(dbgact==0&&pdbg!=0){ + +// printf("pdbg=%d dbgmod=%d currentfileinfo=%d\n",pdbg,dbgmod[0],currentfileinfo); + + if(pdbg==1&&dbgmod[0]!=(unsigned short)currentfileinfo)return; + + pdbg--; + + if(pdbg==0){ + + oline=0; + + omodule=ooutptr=0xFFFFFFFF; + + } + + else{ + + oline=dbgnum[pdbg]; + + omodule=dbgmod[pdbg]; + + ooutptr=dbgloc[pdbg]; + + } + +// printf("%s(%d) pdbg=%d oline=%d ooutptr=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,pdbg,oline,ooutptr); + + (startfileinfo+dbgmod[pdbg])->numdline--; + + } + +} + + + +// + +void DoTDS() + +{ + +int retcode; + +unsigned int i,j; + +// + + if(lstflag)GeneratLst(); + + if(dbg&1){ + +// + + for(i=0;inumdline==0){ + + totalmodule--; + + if(totalmodule!=i){ + + memcpy(&(startfileinfo+i)->filename, + + &(startfileinfo+totalmodule)->filename,sizeof(FILEINFO)); + +// + + for(j=0;jofs=dbgloc[0]; + + corinfo->startline=0; + + omodule=corinfo->file=dbgmod[0]; + + numcorrel=0; + + for(j=1;jcount=(unsigned short)(j-(corinfo+numcorrel)->startline); + + (corinfo+numcorrel)->end=dbgloc[j]-1; + + numcorrel++; + + corinfo=(struct _COR_INFO_ *)REALLOC(corinfo,sizeof(_COR_INFO_)*(numcorrel+1)); + + (corinfo+numcorrel)->ofs=dbgloc[j]; + + (corinfo+numcorrel)->startline=j; + + omodule=(corinfo+numcorrel)->file=dbgmod[j]; + + } + + } + + (corinfo+numcorrel)->count=(unsigned short)(pdbg-(corinfo+numcorrel)->startline); + + (corinfo+numcorrel)->end=dbgloc[j-1]+1; + + numcorrel++; + + hout=CreateOutPut("tds","wb"); + + if(am32)retcode=CreateW32Debug(); + + else retcode=CreateDosDebug(); + + if(retcode==0&&fwrite(output,outptr,1,hout)!=1)retcode=-1; + + if(retcode!=0)ErrWrite(); + + fclose(hout); + + hout=NULL; + + } + +} + + + +void AddNameToTable(char *name) + +{ + +int i=0; + +char c; + + do{ + + c=name[i++]; + + op(c); + + }while(c!=0); + +} + + + +void AddSymbolList(struct idrec *ptr) + +{ + + if(ptr!=NULL){ + + AddSymbolList(ptr->right); + + if((ptr->rectok==tk_proc&&ptr->recsegm>=NOT_DYNAMIC)|| + + (ptr->rectok==tk_interruptproc&&ptr->recsegm>=NOT_DYNAMIC)|| + + (ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar&&modelmem!=SMALL)|| + + (ptr->rectok==tk_structvar&&modelmem!=SMALL)){ + + AddNameToTable(ptr->recid); + + (symbols+numsymbols)->idxname=numsymbols+1; + + (symbols+numsymbols)->ofs=(unsigned short)(ptr->recpost==0? + + (unsigned short)ptr->recnumber: + + (unsigned short)ptr->recnumber+ooutptr); + + if(modelmem==TINY&&comfile==file_exe)(symbols+numsymbols)->ofs-=(unsigned short)0x100; + +// if(ptr->rectok==tk_proc)(symbols+numsymbols)->clas=0x18; + + numsymbols++; + + if(numsymbols==sizetabsym){ + + symbols=(_SMB_ *)REALLOC(symbols,(sizetabsym+MAXNUMSYM)*sizeof(_SMB_)); + + memset(&(symbols+sizetabsym)->idxname,0,sizeof(_SMB_)*MAXNUMSYM); + + sizetabsym+=MAXNUMSYM; + + } + + } + + AddSymbolList(ptr->left); + + } + +} + + + +void AddNameToPul(char *name) + +{ + +static int sizebuf=0; + +int i; + + i=strlen(name); + + if((lastofspul+i+2)>=sizebuf){ + + sizebuf+=STRLEN; + + if(sizebuf==STRLEN)bufname=(unsigned char *)MALLOC(sizebuf); + + else bufname=(unsigned char *)REALLOC(bufname,sizebuf); + + } + + bufname[lastofspul++]=(unsigned char)i; + + strcpy((char *)(bufname+lastofspul),name); + + lastofspul+=++i; + +} + + + +void AddGlobalName(struct idrec *ptr) + +{ + + if(ptr!=NULL){ + + AddGlobalName(ptr->right); + + if((ptr->rectok==tk_proc&&ptr->recsegm>=NOT_DYNAMIC)|| + + (ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)|| + + (ptr->rectok==tk_structvar)){ + + AddNameToPul(ptr->recid); + + numsymbols++; + + if(ptr->rectok==tk_proc){ + + outword(0x1c); //size + + outdword(0x20); //type + + } + + else{ + + outword(0x18); + + outdword(0x21); + + } + + outword(0); + + outdword(0); + + outdword(numsymbols); //name + + outdword(0); + + if(ptr->recpost==0){ + + outdword(ptr->recnumber); //offset + + outword(segcode); //segm + + } + + else{ + + outdword(ptr->recnumber+(wbss!=FALSE?0:ooutptr)); + + outword(1); + + } + + if(ptr->rectok==tk_proc)outdword(0); + + } + + AddGlobalName(ptr->left); + + } + +} + + + +int CreateW32Debug() + +{ + +int sstNames,sstDirectory; + +int startcode=outptr; + +int sstGlobalSym; + +int sstsrc; + +unsigned int i,j,jj,ofs; + + for(;numsymbols<(short)totalmodule;numsymbols++)AddNameToPul((startfileinfo+numsymbols)->filename); + + segcode=(wbss==FALSE?1:2); + + outptr=0; + + outdword(0x41304246); // TDS - signature + + outdword(0); // offset of Subsection Directory (fill later) + +//sstModule subsection + + outdword(0); // OvlNum=0 & LibIndex=0 + + outword(segcode); // SegCount + + outword(0x5643); // CV-style + + outdword(1); // Name + + for(i=0;i<4;i++)outdword(0); + +// outdword(0); //Time + +// outdword(0); + +// outdword(0); + +// outdword(0); + + if(wbss){ + + outword(0x0001); // SegNumber + + outword(0); // flag + + outdword(0); // start + + outdword(postsize); // len + + } + + outword(segcode); // SegNumber + + outword(0x0001); // flag + + outdword(startptr); // start + + outdword(startcode); // len + + sstsrc=outptr; + +//sstSrcModule subsection + + outword((short)numcorrel); //cFile - SRC-() + + outword((short)numcorrel); // SegCount (see SegCount in sstModule + + ofs=14*numcorrel+4; + + for(i=0,jj=0;i<(unsigned int)numcorrel;i++){ + + if(i!=0)jj=jj+((corinfo+i-1)->count+1)*6+22; + + outdword(ofs+jj); + + } + + for(i=0;i<(unsigned int)numcorrel;i++){ + + outdword((corinfo+i)->ofs); + + outdword((corinfo+i)->end); + + } + + for(i=0;i<(unsigned int)numcorrel;i++)outword(segcode); // + + for(i=0;i<(unsigned int)numcorrel;i++){ + + outword(1); // Segm# + + outdword((corinfo+i)->file+1);// File# + + outdword(outptr-sstsrc+12); + + outdword((corinfo+i)->ofs); + + outdword((corinfo+i)->end); + + outword(segcode); //Segm# + + jj=(corinfo+i)->count; + + outword(jj+1); // Lines count + + ofs=(corinfo+i)->startline; + + for(j=0;jend); + + for(j=0;jfilename); + + strcpy((char *)string3,(startfileinfo+i)->filename); + + char *str=strrchr((char *)string3,'.'); + + if(str!=0){ + + str[0]=0; + + str=strrchr((char *)string3,'\\'); + + if(str==NULL)str=(char *)string3; + + else str++; + + } + + else str=(char *)string3; + + AddNameToTable(str); + +// + + (module+i)->name=i*2+2+numsymbols; + + (module+i)->language=1; + + (module+i)->memmodel=8;//modelmem==SMALL&&comfile==file_exe?9:8; + + (module+i)->sourcount=1;//(unsigned short)totalmodule; + + (module+i)->sourindex=(unsigned short)(i+1); + +// + + (sft+i)->idx=i*2+1+numsymbols; + + (sft+i)->time=(startfileinfo+i)->time; + + count=0; // + + for(ii=0;iifile==(unsigned short)i){ // + + if(count==0){ // + + (segment+i)->ofs=beg=(unsigned short)(corinfo+ii)->ofs; + + (segment+i)->correli=(unsigned short)(corrnum+1); //correlation index + + (module+i)->corindex=(unsigned short)(corrnum+1); + + } + + (ct+corrnum)->beg=(corinfo+ii)->startline+1; + + (ct+corrnum)->segidx=(unsigned short)(1+i); //segment idx + + (ct+corrnum)->filidx=(unsigned short)(i+1); //file idx + + (ct+corrnum)->count=(corinfo+ii)->count; // + + end=(unsigned short)(corinfo+ii)->end; + + corrnum++; + + count++; + + } + + } + +// + + (segment+i)->idx=(unsigned short)(i+1); //segment index + + (segment+i)->size=(unsigned short)(end-beg);//length + + (segment+i)->correlc=(unsigned short)count;//(unsigned short)totalmodule; //correlation count + + (module+i)->corcount=(unsigned short)count; + + if(modelmem==TINY&&comfile==file_exe)(segment+i)->segm=0xfff0; + + } + + d16header.pol_size=outptr; + + if(fwrite(&d16header,sizeof(D16START),1,hout)!=1)return -1; + + if(fwrite(symbols,sizeof(_SMB_)*numsymbols,1,hout)!=1)return -1; + + if(fwrite(module,sizeof(MODULE)*totalmodule,1,hout)!=1)return -1; + + free(module); + + if(fwrite(sft,sizeof(SFT)*totalmodule,1,hout)!=1)return -1; + + free(sft); + +//line table + + lt=(LT *)MALLOC(sizeof(LT)*pdbg); + + for(j=0;(unsigned int)jline=(unsigned short)dbgnum[j]; + + (lt+j)->ofs=(unsigned short)dbgloc[j]; + + } + + if(fwrite(lt,sizeof(LT)*pdbg,1,hout)!=1)return -1; + + free(lt); + + if(fwrite(segment,sizeof(SEGMENT)*totalmodule,1,hout)!=1)return -1; + + free(segment); + + if(fwrite(ct,sizeof(CT)*numcorrel,1,hout)!=1)return -1; + + free(ct); + +// if(fwrite(types,NUMTYPES*12,1,hout)!=1)return -1; + + memset(&string3,0,6*totalmodule); + + if(fwrite(&string3,6*totalmodule,1,hout)!=1)return -1; + +/* if(numsymbols){ + + memset(symbols,0,4*numsymbols); + + if(fwrite(symbols,4*numsymbols,1,hout)!=1)return -1; + + }*/ + + free(symbols); + + return 0; + +} + + + +void KillDataLine(int line) + +{ + + (startfileinfo+dbgmod[line])->numdline--; + + for(unsigned int j=line;(j+1)filename,line); + + if(lststring[j]!=NULL)printf(" %s\n",lststring[j]); + + else if(line!=0)printf("\n"); + + */ + + fprintf(hout,"\n"); + + if(line!=0)fprintf(hout,"%s %u:",(startfileinfo+dbgmod[j])->filename,line); + + if(lststring[j]!=NULL)fprintf(hout," %s\n",lststring[j]); + + else if(line!=0)fprintf(hout,"\n"); + + while(outptr>1)&15); + + else unassemble(instruction_offset); + + } + + } + + if((dbg&1)!=0&&((flag&0xe)!=0||line==0)){ + + KillDataLine(j); + + j--; + + } + + } + + } + + fclose(hout); + + hout=NULL; + +} + + + +#ifdef DEBUGMODE + +void printdebuginfo() + +{ + +static FILE *df=NULL; + + if((df=fopen("debug.tmp","w+t"))==NULL)df=stdout; + + fprintf(df,"%s(%d)> %08X %08X tok=%d num=%08X flag=%08X scanmode=%d %s\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,input,inptr2,tok,itok.number,itok.flag,scanlexmode,itok.name); + + fflush(df); + +} + +#endif + diff --git a/programs/develop/cmm/dirlist.h b/programs/develop/cmm/dirlist.h new file mode 100644 index 0000000000..f85f74c992 --- /dev/null +++ b/programs/develop/cmm/dirlist.h @@ -0,0 +1,94 @@ +/* 䠩 ᣥ஢ ணࠬ 'FASTLIST.EXE' */ + +short ofsdir[27]={ + 0x0000,0x000F, //D a + 0xFFFF,0x0045, //b c + 0x0072,0x0090, //d e + 0x00A5,0xFFFF, //f g + 0xFFFF,0x00C0, //h i + 0x010A,0xFFFF, //j k + 0xFFFF,0x0118, //l m + 0xFFFF,0xFFFF, //n o + 0x0132,0xFFFF, //p q + 0x015F,0x0184, //r s + 0xFFFF,0x01F6, //t u + 0xFFFF,0x0263, //v w + 0xFFFF,0xFFFF, //x y + 0xFFFF}; //z + +unsigned char dirlist[]={ + 0x19,0x00,0x4F,0x53,0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,0, // DOSrequired + 0xFF,0xFF, // end char 'D' + 0x14,0x00,0x6C,0x69,0x67,0x6E,0, // align + 0x32,0x00,0x6C,0x69,0x67,0x6E,0x63,0x6F,0x64,0x65,0, // aligncode + 0x15,0x00,0x6C,0x69,0x67,0x6E,0x65,0x72,0, // aligner + 0x16,0x00,0x6C,0x69,0x67,0x6E,0x77,0x6F,0x72,0x64,0, // alignword + 0x03,0x00,0x72,0x67,0x63,0, // argc + 0x0B,0x00,0x74,0x65,0x78,0x69,0x74,0, // atexit + 0xFF,0xFF, // end char 'a' + 0x30,0x00,0x6F,0x64,0x65,0x33,0x32,0, // code32 + 0x17,0x00,0x6F,0x64,0x65,0x73,0x69,0x7A,0x65,0, // codesize + 0x35,0x00,0x6F,0x6D,0x70,0x69,0x6C,0x65,0x72,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0, // compilerversion + 0x00,0x00,0x74,0x72,0x6C,0x5F,0x63,0, // ctrl_c + 0xFF,0xFF, // end char 'c' + 0x0C,0x00,0x61,0x74,0x61,0x73,0x65,0x67,0, // dataseg + 0x18,0x00,0x65,0x66,0x69,0x6E,0x65,0, // define + 0x34,0x00,0x6F,0x73,0x73,0x74,0x72,0x69,0x6E,0x67,0, // dosstring + 0xFF,0xFF, // end char 'd' + 0x3B,0x00,0x6C,0x69,0x66,0, // elif + 0x36,0x00,0x6C,0x73,0x65,0, // else + 0x1A,0x00,0x6E,0x64,0x69,0x66,0, // endif + 0xFF,0xFF, // end char 'e' + 0x10,0x00,0x61,0x73,0x74,0x63,0x61,0x6C,0x6C,0x61,0x70,0x69,0, // fastcallapi + 0x33,0x00,0x69,0x78,0x75,0x70,0x74,0x61,0x62,0x6C,0x65,0, // fixuptable + 0xFF,0xFF, // end char 'f' + 0x3A,0x00,0x66,0, // if + 0x1B,0x00,0x66,0x64,0x65,0x66,0, // ifdef + 0x1C,0x00,0x66,0x6E,0x64,0x65,0x66,0, // ifndef + 0x13,0x00,0x6D,0x61,0x67,0x65,0x62,0x61,0x73,0x65,0, // imagebase + 0x1D,0x00,0x6E,0x63,0x6C,0x75,0x64,0x65,0, // include + 0x2E,0x00,0x6E,0x63,0x6C,0x75,0x64,0x65,0x70,0x61,0x74,0x68,0, // includepath + 0x2F,0x00,0x6E,0x69,0x74,0x61,0x6C,0x6C,0x76,0x61,0x72,0, // initallvar + 0x39,0x00,0x6E,0x6C,0x69,0x6E,0x65,0, // inline + 0xFF,0xFF, // end char 'i' + 0x01,0x00,0x75,0x6D,0x70,0x74,0x6F,0x6D,0x61,0x69,0x6E,0, // jumptomain + 0xFF,0xFF, // end char 'j' + 0x1E,0x00,0x61,0x78,0x65,0x72,0x72,0x6F,0x72,0x73,0, // maxerrors + 0x0E,0x00,0x6F,0x76,0x65,0x64,0x61,0x74,0x61,0x72,0x6F,0x6D,0, // movedatarom + 0xFF,0xFF, // end char 'm' + 0x02,0x00,0x61,0x72,0x73,0x65,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x6C,0x69,0x6E,0x65,0, // parsecommandline + 0x38,0x00,0x72,0x61,0x67,0x6D,0x61,0, // pragma + 0x1F,0x00,0x72,0x69,0x6E,0x74,0, // print + 0x20,0x00,0x72,0x69,0x6E,0x74,0x68,0x65,0x78,0, // printhex + 0xFF,0xFF, // end char 'p' + 0x21,0x00,0x61,0x6E,0x64,0x6F,0x6D,0x62,0x79,0x74,0x65,0, // randombyte + 0x04,0x00,0x65,0x73,0x69,0x7A,0x65,0, // resize + 0x05,0x00,0x65,0x73,0x69,0x7A,0x65,0x6D,0x65,0x73,0x73,0x61,0x67,0x65,0, // resizemessage + 0xFF,0xFF, // end char 'r' + 0x2C,0x00,0x65,0x74,0x64,0x69,0x6E,0x70,0x72,0x6F,0x63,0, // setdinproc + 0x0D,0x00,0x69,0x7A,0x65,0x72,0x6F,0x6D,0, // sizerom + 0x22,0x00,0x70,0x65,0x65,0x64,0, // speed + 0x06,0x00,0x74,0x61,0x63,0x6B,0, // stack + 0x07,0x00,0x74,0x61,0x72,0x74,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0, // startaddress + 0x0F,0x00,0x74,0x61,0x72,0x74,0x75,0x70,0x74,0x6F,0x6D,0x61,0x69,0x6E,0, // startuptomain + 0x11,0x00,0x74,0x61,0x72,0x74,0x75,0x73,0x65,0x76,0x61,0x72,0, // startusevar + 0x08,0x00,0x79,0x73,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0, // sysattribute + 0x0A,0x00,0x79,0x73,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0, // syscommand + 0x09,0x00,0x79,0x73,0x6E,0x61,0x6D,0x65,0, // sysname + 0xFF,0xFF, // end char 's' + 0x31,0x00,0x6E,0x64,0x65,0x66,0, // undef + 0x25,0x00,0x73,0x65,0x38,0x30,0x31,0x38,0x36,0, // use80186 + 0x26,0x00,0x73,0x65,0x38,0x30,0x32,0x38,0x36,0, // use80286 + 0x27,0x00,0x73,0x65,0x38,0x30,0x33,0x38,0x36,0, // use80386 + 0x28,0x00,0x73,0x65,0x38,0x30,0x34,0x38,0x36,0, // use80486 + 0x2B,0x00,0x73,0x65,0x38,0x30,0x37,0x38,0x36,0, // use80786 + 0x23,0x00,0x73,0x65,0x38,0x30,0x38,0x36,0, // use8086 + 0x24,0x00,0x73,0x65,0x38,0x30,0x38,0x38,0, // use8088 + 0x2A,0x00,0x73,0x65,0x4D,0x4D,0x58,0, // useMMX + 0x29,0x00,0x73,0x65,0x50,0x65,0x6E,0x74,0x69,0x75,0x6D,0, // usePentium + 0x12,0x00,0x73,0x65,0x73,0x74,0x61,0x72,0x74,0x75,0x70,0, // usestartup + 0xFF,0xFF, // end char 'u' + 0x2D,0x00,0x61,0x72,0x6E,0x69,0x6E,0x67,0, // warning + 0x37,0x00,0x69,0x6E,0x6D,0x6F,0x6E,0x6F,0x62,0x6C,0x6F,0x63,0x6B,0, // winmonoblock + 0xFF,0xFF // end char 'w' +}; diff --git a/programs/develop/cmm/disasm.cpp b/programs/develop/cmm/disasm.cpp new file mode 100644 index 0000000000..0caf293d90 --- /dev/null +++ b/programs/develop/cmm/disasm.cpp @@ -0,0 +1,2928 @@ +#include "tok.h" + +#include "table.h" + +#include + +#define _DISASM_ + + + +/* Percent tokens in strings: + + First char after '%': + + A - direct address + + C - reg of r/m picks control register + + D - reg of r/m picks debug register + + E - r/m picks operand + + F - second operand for mmx instruction reg/mem + + G - reg of r/m picks general register + + I - immediate data + + J - relative IP offset + ++ K - call/jmp distance + + L - first operand for mmx instruction + + M - r/m picks memory + + O - no r/m, offset only + + R - mod of r/m picks register only + + S - reg of r/m picks segment register + + T - reg of r/m picks test register + + X - DS:ESI + + Y - ES:EDI + + 2 - prefix of two-byte opcode + ++ e - put in 'e' if use32 (second char is part of reg name) + ++ put in 'w' for use16 or 'd' for use32 (second char is 'w') + ++ j - put in 'e' in jcxz if prefix==0x66 + + f - floating point (second char is esc value) + + g - do r/m group 'n', n==0..7 + + p - prefix + + s - size override (second char is a,o) + ++ d - put d if double arg, nothing otherwise (pushfd, popfd &c) + ++ w - put w if word, d if double arg, nothing otherwise (lodsw/lodsd) + ++ P - simple prefix + + + + Second char after '%': + + a - two words in memory (BOUND) + + b - byte + + c - byte or word + + d - dword + ++ f - far call/jmp + ++ n - near call/jmp + + p - 32 or 48 bit pointer + ++ q - byte/word thingy + + s - six byte pseudo-descriptor + + v - word or dword + + w - word + ++ x - sign extended byte + + y - qword + + F - use floating regs in mod/rm + + M - use MMX regs + + 1-8 - group number, esc value, etc + + m - no size memory operand + +*/ + + + +/* watch out for aad && aam with odd operands */ + +char *opmap1[256]={ + +/* 0 */ + + "add %Eb,%Rb", "add %Ev,%Rv", "add %Rb,%Eb", "add %Rv,%Ev", + + "add al,%Ib", "add %eax,%Iv", "push es", "pop es", + + "or %Eb,%Rb", "or %Ev,%Rv", "or %Rb,%Eb", "or %Rv,%Ev", + + "or al,%Ib", "or %eax,%Iv", "push cs", "%2 ", + +/* 1 */ + + "adc %Eb,%Rb", "adc %Ev,%Rv", "adc %Rb,%Eb", "adc %Rv,%Ev", + + "adc al,%Ib", "adc %eax,%Iv", "push ss", "pop ss", + + "sbb %Eb,%Rb", "sbb %Ev,%Rv", "sbb %Rb,%Eb", "sbb %Rv,%Ev", + + "sbb al,%Ib", "sbb %eax,%Iv", "push ds", "pop ds", + +/* 2 */ + + "and %Eb,%Rb", "and %Ev,%Rv", "and %Rb,%Eb", "and %Rv,%Ev", + + "and al,%Ib", "and %eax,%Iv", "%pe", "daa", + + "sub %Eb,%Rb", "sub %Ev,%Rv", "sub %Rb,%Eb", "sub %Rv,%Ev", + + "sub al,%Ib", "sub %eax,%Iv", "%pc", "das", + +/* 3 */ + + "xor %Eb,%Rb", "xor %Ev,%Rv", "xor %Rb,%Eb", "xor %Rv,%Ev", + + "xor al,%Ib", "xor %eax,%Iv", "%ps", "aaa", + + "cmp %Eb,%Rb", "cmp %Ev,%Rv", "cmp %Rb,%Eb", "cmp %Rv,%Ev", + + "cmp al,%Ib", "cmp %eax,%Iv", "%pd", "aas", + +/* 4 */ + + "inc %eax", "inc %ecx", "inc %edx", "inc %ebx", + + "inc %esp", "inc %ebp", "inc %esi", "inc %edi", + + "dec %eax", "dec %ecx", "dec %edx", "dec %ebx", + + "dec %esp", "dec %ebp", "dec %esi", "dec %edi", + +/* 5 */ + + "push %eax", "push %ecx", "push %edx", "push %ebx", + + "push %esp", "push %ebp", "push %esi", "push %edi", + + "pop %eax", "pop %ecx", "pop %edx", "pop %ebx", + + "pop %esp", "pop %ebp", "pop %esi", "pop %edi", + +/* 6 */ + + "pusha%d ", "popa%d ", "bound %Rv,%Ma", "arpl %Ew,%Rw", + + "%pf", "%pg", "%so", "%sa", + + "push %Iv", "imul %Rv,%Ev,%Iv","push %Ix", "imul %Rv,%Ev,%Ib", + + "insb", "ins%ew", "outsb", "outs%ew", + +/* 7 */ + + "jo %Jb", "jno %Jb", "jc %Jb", "jnc %Jb", + + "je %Jb", "jne %Jb", "jbe %Jb", "ja %Jb", + + "js %Jb", "jns %Jb", "jpe %Jb", "jpo %Jb", + + "jl %Jb", "jge %Jb", "jle %Jb", "jg %Jb", + +/* 8 */ + +/* "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ib", "%g0 %Ev,%Ib", */ + + "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ix", "%g0 %Ev,%Ix", + + "test %Eb,%Rb", "test %Ev,%Rv", "xchg %Eb,%Rb", "xchg %Ev,%Rv", + + "mov %Eb,%Rb", "mov %Ev,%Rv", "mov %Rb,%Eb", "mov %Rv,%Ev", + + "mov %Ew,%Sw", "lea %Rv,%M ", "mov %Sw,%Ew", "pop %Ev", + +/* 9 */ + + "nop", "xchg %ecx,%eax", "xchg %edx,%eax", "xchg %ebx,%eax", + + "xchg %esp,%eax", "xchg %ebp,%eax", "xchg %esi,%eax", "xchg %edi,%eax", + + "cbw", "cwd", "call %Ap", "fwait", + + "pushf%d ", "popf%d ", "sahf", "lahf", + +/* a */ + + "mov al,%Oc", "mov %eax,%Ov", "mov %Oc,al", "mov %Ov,%eax", + + "%P movsb", "%P movs%w", "%P cmpsb", "%P cmps%w ", + + "test al,%Ib", "test %eax,%Iv", "%P stosb", "%P stos%w ", + + "%P lodsb", "%P lods%w ", "%P scasb", "%P scas%w ", + +/* b */ + + "mov al,%Ib", "mov cl,%Ib", "mov dl,%Ib", "mov bl,%Ib", + + "mov ah,%Ib", "mov ch,%Ib", "mov dh,%Ib", "mov bh,%Ib", + + "mov %eax,%Iv", "mov %ecx,%Iv", "mov %edx,%Iv", "mov %ebx,%Iv", + + "mov %esp,%Iv", "mov %ebp,%Iv", "mov %esi,%Iv", "mov %edi,%Iv", + +/* c */ + + "%g1 %Eb,%Ib", "%g1 %Ev,%Ib", "ret %Iw", "ret", + + "les %Rv,%Mp", "lds %Rv,%Mp", "mov %Eb,%Ib", "mov %Ev,%Iv", + + "enter %Iw,%Ib", "leave", "retf %Iw", "retf", + + "int 03", "int %Ib", "into", "iret", + +/* d */ + + "%g1 %Eb,1", "%g1 %Ev,1", "%g1 %Eb,cl", "%g1 %Ev,cl", + + "aam ; %Ib", "aad ; %Ib", "setalc", "xlat", + +/*#if 0 + + "esc 0,%Ib", "esc 1,%Ib", "esc 2,%Ib", "esc 3,%Ib", + + "esc 4,%Ib", "esc 5,%Ib", "esc 6,%Ib", "esc 7,%Ib", + +#else */ + + "%f0", "%f1", "%f2", "%f3", + + "%f4", "%f5", "%f6", "%f7", + +//#endif + +/* e */ + + "loopne %Jb", "loope %Jb", "loop %Jb", "j%j cxz %Jb", + + "in al,%Ib", "in %eax,%Ib", "out %Ib,al", "out %Ib,%eax", + + "call %Jv", "jmp %Jv", "jmp %Ap", "jmp %Ks%Jb", + + "in al,dx", "in %eax,dx", "out dx,al", "out dx,%eax", + +/* f */ + + "lock %p ", 0, "repne %p ", "repe %p ", + + "hlt", "cmc", "%g2", "%g2", + + "clc", "stc", "cli", "sti", + + "cld", "std", "%g3", "%g4" + +}; + + + +char *second[] = { + +/* 0 */ + + "%g5", "%g6", "lar %Rv,%Ew", "lsl %Rv,%Ew", + + 0, "loadall", "clts", "loadall", + + "invd", "wbinvd", 0, "ud2", + + 0, 0, 0, 0, + +/* 1 */ + + "movups %RX,%EX", "movups %Md,%RX", "%x0", "movlps %Md,%RX", + + "unpcklps %RX,%EX", "unpckhps %RX,%EX","%x1", "movhps %Md,%RX", + + "%g7", 0, 0, 0, + + 0, 0, 0, 0, + +/* 2 */ + + "mov %Ed,%Cd", "mov %Ed,%Dd", "mov %Cd,%Ed", "mov %Dd,%Ed", + + "mov %Ed,%Td", 0, "mov %Td,%Ed", 0, + + "movaps %RX,%EX", "movaps %Md,%RX", "cvtpi2ps %RX,%EM","movntps %Md,%RX", + + "cvttps2pi %RM,%EX","cvtps2pi %RM,%EX","ucomiss %RX,%EX", "comiss %RX,%EX", + +/* 3 */ + + "wrmsr", "rdtsc", "rdmsr", "rdpmc", "sysenter", "sysexit", 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + +/* 4 */ + + "cmovo %Rv,%Ev", "cmovno %Rv,%Ev", "cmovc %Rv,%Ev", "cmovnc %Rv,%Ev", + + "cmovz %Rv,%Ev", "cmovnz %Rv,%Ev", "cmovbe %Rv,%Ev", "cmovnbe %Rv,%Ev", + + "cmovs %Rv,%Ev", "cmovns %Rv,%Ev", "cmovp %Rv,%Ev", "cmovnp %Rv,%Ev", + + "cmovl %Rv,%Ev", "cmovge %Rv,%Ev", "cmovle %Rv,%Ev", "cmovg %Rv,%Ev", + +/* 5 */ + + "movmskps %Rd,%GX", "sqrtps %RX,%EX", "rsqrtps %RX,%EX", "rcpps %RX,%EX", + + "andps %RX,%EX", "andnps %RX,%EX", "orps %RX,%EX", "xorps %RX,%EX", + + "addps %RX,%EX", "mulps %RX,%EX", "cvtps2pd %RX,%EX","cvtdq2ps %RX,%EX", + + "subps %RX,%EX", "minps %RX,%EX", "divps %RX,%EX", "maxps %RX,%EX", + +/* 6 */ + + "punpcklbw %RM,%EM", "punpcklwd %RM,%EM", "punpckldq %RM,%EM", "packsswb %RM,%EM", + + "pcmpgtb %RM,%EM", "pcmpgtw %RM,%EM", "pcmpgtd %RM,%EM", "packuswb %RM,%EM", + + "punpckhbw %RM,%EM", "punpckhwd %RM,%EM", "punpckhdq %RM,%EM", "packssdw %RM,%EM", + + 0, 0, "movd %RM,%Md", "movq %RM,%EM", + +/* 7 */ + + "pshufw %LM,%FM,%Ib","%g3w %EM,%Ib", "%g3d %EM,%Ib", "%g3q %EM,%Ib", + + "pcmpeqb %RM,%EM", "pcmpeqw %RM,%EM", "pcmpeqd %RM,%EM", "emms", + + 0, 0, 0, 0, + + 0, 0, "movd %Md,%RM", "movq %Md,%RM", + +/* 8 */ + + "jo %Jv", "jno %Jv", "jb %Jv", "jnb %Jv", + + "jz %Jv", "jnz %Jv", "jbe %Jv", "ja %Jv", + + "js %Jv", "jns %Jv", "jp %Jv", "jnp %Jv", + + "jl %Jv", "jge %Jv", "jle %Jv", "jg %Jv", + +/* 9 */ + + "seto %Eb", "setno %Eb", "setc %Eb", "setnc %Eb", + + "setz %Eb", "setnz %Eb", "setbe %Eb", "setnbe %Eb", + + "sets %Eb", "setns %Eb", "setp %Eb", "setnp %Eb", + + "setl %Eb", "setge %Eb", "setle %Eb", "setg %Eb", + +/* a */ + + "push fs", "pop fs", "cpuid", "bt %Ev,%Rv", + + "shld %Ev,%Rv,%Ib", "shld %Ev,%Rv,cl", 0, 0, + + "push gs", "pop gs", "rsm", "bts %Ev,%Rv", + + "shrd %Ev,%Rv,%Ib", "shrd %Ev,%Rv,cl", "%g8", "imul %Rv,%Ev", + +/* b */ + + "cmpxchg %Eb,%Rb", "cmpxchg %Ev,%Rv", "lss %Rv,%Mp", "btr %Ev,%Rv", + + "lfs %Rv,%Mp", "lgs %Rv,%Mp", "movzx %Rv,%Eb", "movzx %Rv,%Ew", + + 0, 0, "%g7 %Ev,%Ib", "btc %Ev,%Rv", + + "bsf %Rv,%Ev", "bsr %Rv,%Ev", "movsx %Rv,%Eb", "movsx %Rv,%Ew", + +/* c */ + + "xadd %Eb,%Rb", "xadd %Ev,%Rv", "cmpps %RX,%EX,%Ib","movnti %Md,%Rd", + + "pinsrw %LM,%Fd,%Ib","pextrw %Gd,%RM,%Ib","shufps %RX,%EX,%Ib","cmpxchg8b %Myv", + + "bswap eax", "bswap ecx", "bswap edx", "bswap ebx", + + "bswap esp", "bswap ebp", "bswap esi", "bswap edi", + +/* d */ + + 0, "psrlw %RM,%EM", "psrld %RM,%EM", "psrlq %RM,%EM", + + "paddq %RM,%EM", "pmullw %RM,%EM", 0, "pmovmskb %Rd,%GM", + + "psubusb %RM,%EM", "psubusw %RM,%EM", "pminub %RM,%EM", "pand %RM,%EM", + + "paddusb %RM,%EM", "paddusw %RM,%EM", "pmaxub %RM,%EM", "pandn %RM,%EM", + +/* e */ + + "pavgb %RM,%EM", "psraw %RM,%EM", "psrad %RM,%EM", "pavgw %RM,%EM", + + "pmulhuw %RM,%EM", "pmulhw %RM,%EM", 0, "movntq %Myv,%RM", + + "psubsb %RM,%EM", "psubsw %RM,%EM", "pminsw %RM,%EM", "por %RM,%EM", + + "paddsb %RM,%EM", "paddsw %RM,%EM", "pmaxsw %RM,%EM", "pxor %RM,%EM", + +/* f */ + + 0, "psllw %RM,%EM", "pslld %RM,%EM", "psllq %RM,%EM", + + "pmuludq %RM,%EM", "pmaddwd %RM,%EM", "psadbw %RM,%EM", "maskmovq %GM,%RM", + + "psubb %RM,%EM", "psubw %RM,%EM", "psubd %RM,%EM", "psubq %RM,%EM", + + "paddb %RM,%EM", "paddw %RM,%EM", "paddd %RM,%EM", 0 + +}; + + + +char *second_f30f[]={ + +// 0 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 1 + + "movss %RX,%EX","movss %Md,%RX","movsldup %RX,%MX",0, + + 0,0,"movshdup %RX,%MX",0, + + 0,0,0,0,0,0,0,0, + +// 2 + + 0,0,0,0, + + 0,0,0,0, + + 0, 0, "cvtsi2ss %RX,%Ed",0, + + "cvttss2si %Rd,%EX","cvtss2si %Rd,%EX",0, 0, + +// 3 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 4 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 5 + + 0, "sqrtss %RX,%EX","rsqrtss %RX,%EX", "rcpss %RX,%EX", + + 0, 0, 0, 0, + + "addss %RX,%EX","mulss %RX,%EX", "cvtss2sd %RX,%EX","cvttps2dq %RX,%EX", + + "subss %RX,%EX","minss %RX,%EX", "divss %RX,%EX", "maxss %RX,%EX", + +// 6 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,"movdqu %RX,%EX", + +// 7 + + "pshufhw %RX,%EX,%Ib",0,0,0, + + 0,0,0,0, + + 0,0,0,0, + + 0,0,"movq %RX,%EX","movdqu %Md,%RX", + +// 8 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 9 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// a + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// b + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// c + + 0,0,"cmpss %RX,%EX,%Ib",0, + + 0,0,0, 0, + + 0,0,0, 0, + + 0,0,0, 0, + +// d + + 0,0,0,0, + + 0,0,"movq2dq RX,RM",0, + + 0,0,0,0,0,0,0,0, + +// e + + 0,0,0,0, + + 0,0,"cvtdq2pd %RX,%EX",0, + + 0,0,0,0,0,0,0,0, + +// f + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0 + +}; + + + +char *second_f20f[]={ + +// 0 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 1 + + "movsd %RX,%Md","movsd %Md,%RX","movddup %RX,%MX",0, + + 0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 2 + + 0,0,0,0, + + 0,0,0,0, + + 0,0,"cvtsi2sd %RX,%Md",0, + + "cvttsd2si %Rd,%EX","cvtsd2si %Rd,%EX",0,0, + +// 3 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 4 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 5 + + 0,"sqrtsd %RX,%EX",0,0, + + 0,0,0,0, + + "addsd %RX,%EX","mulsd %RX,%MX","cvtsd2ss %RX,%EX",0, + + "subsd %RX,%EX","minsd %RX,%EX","divsd %RX,%EX","maxsd %RX,%EX", + +// 6 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 7 + + "pshuflw %RX,%EX,%Ib",0,0,0, + + 0,0,0,0, + + 0,0,0,0, + + "haddps %RX,%EX","hsubps %RX,%EX",0,0, + +// 8 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 9 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// a + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// b + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// c + + 0,0,"cmpsd %RX,%EX,%Ib",0, + + 0,0,0,0, + + 0,0,0,0, + + 0,0,0,0, + +// d + + "addsubps %RX,%EX",0,0,0, + + 0,0,"movdq2q %RM,%RX",0, + + 0,0,0,0, + + 0,0,0,0, + +// e + + 0,0,0,0, + + 0,0,"cvtpd2dq %RX,%EX",0, + + 0,0,0,0,0,0,0,0, + +// f + + "lddqu %Md,%RX",0,0,0, + + 0,0,0,0, + + 0,0,0,0, + + 0,0,0,0 + +}; + + + +char *second_660f[]={ + +// 0 + + 0,0,0,0, + + 0,0,0,0, + + 0,0,0,0, + + 0,0,0,0, + +// 1 + + "movupd %RX,%Md","movupd %Md,%RX","movlpd %RX,%Md","movlpd %Md,%RX", + + "unpcklpd %RX,%EX","unpckhpd %RX,%EX","movhpd %RX,%Md","movhpd %Md,%RX", + + 0,0,0,0, + + 0,0,0,0, + +// 2 + + 0,0,0,0, + + 0,0,0,0, + + "movapd %RX,%EX", "movapd %Md,%RX", "cvtpi2pd %RX,%EM","movntpd %Md,%RX", + + "cvttpd2pi %RM,%EX","cvtpd2pi %RM,%EX","ucomisd %RX,%EX","comisd %RX,%EX", + +// 3 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 4 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 5 + + "movmskpd %Rd,%GX","sqrtpd %RX,%EX",0,0, + + "andpd %RX,%EX","andnpd %RX,%EX","orpd %RX,%MX","xorpd %RX,%EX", + + "addpd %RX,%EX","mulpd %RX,%MX","cvtpd2ps %RX,%EX","cvtps2dq %RX,%EX", + + "subpd %RX,%EX","minpd %RX,%EX","divpd %RX,%EX","maxpd %RX,%EX", + +// 6 + + "punpcklbw %RX,%EX", "punpcklwd %RX,%EX", "punpckldq %RX,%EX","packsswb %RX,%EX", + + "pcmpgtb %RX,%EX", "pcmpgtw %RX,%EX", "pcmpgtd %RX,%EX", "packuswb %RX,%EX", + + "punpckhbw %RX,%EX", "punpckhwd %RX,%EX", "punpckhdq %RX,%EX","packssdw %RX,%EX", + + "punpcklqdq %RX,%EX","punpckhqdq %RX,%EX","movd %RX,%Md", "movdqa %RX,%EX", + +// 7 + + "pshufd %RX,%EX,%Ib","%g3w %EX,%Ib", "%g3d %EX,%Ib","%g9", + + "pcmpeqb %RX,%EX", "pcmpeqw %RX,%EX", "pcmpeqd %RX,%EX",0, + + 0,0,0,0, + + "haddpd %RX,%EX","hsubpd %RX,%EX","movd %Md,%RX","movdqa %Md,%RX", + +// 8 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// 9 + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// a + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// b + + 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, + +// c + + 0,0,"cmppd %RX,%EX,%Ib",0, + + "pinsrw %LX,%Fd,%Ib","pextrw %Gd,%RX,%Ib","shufpd %RX,%EX,%Ib",0, + + 0,0,0,0, + + 0,0,0,0, + +// d + + "addsubpd %RX,%EX","psrlw %RX,%EX", "psrld %RX,%EX", "psrlq %RX,%EX", + + "paddq %RX,%EX", "pmullw %RX,%EX", "movq %Md,%RX", "pmovmskb %Rd,%GX", + + "psubusb %RX,%EX", "psubusw %RX,%EX","pminub %RX,%EX","pand %RX,%EX", + + "paddusb %RX,%EX", "paddusw %RX,%EX","pmaxub %RX,%EX","pandn %RX,%EX", + +// e + + "pavgb %RX,%EX", "psraw %RX,%EX", "psrad %RX,%EX", "pavgw %RX,%EX", + + "pmulhuw %RX,%EX", "pmulhw %RX,%EX","cvttpd2dq %RX,%EX","movntdq %Md,%RX", + + "psubsb %RX,%EX", "psubsw %RX,%EX","pminsw %RX,%EX", "por %RX,%EX", + + "paddsb %RX,%EX", "paddsw %RX,%EX","pmaxsw %RX,%EX", "pxor %RX,%EX", + +// f + + 0, "psllw %RX,%EX", "pslld %RX,%EX", "psllq %RX,%EX", + + "pmuludq %RX,%EX", "pmaddwd %RX,%EX","psadbw %RX,%EX","maskmovdqu %RX,%RX", + + "psubb %RX,%EX", "psubw %RX,%EX", "psubd %RX,%EX", "psubq %RX,%EX", + + "paddb %RX,%EX", "paddw %RX,%EX", "paddd %RX,%EX", 0 + +}; + + + +char *groups[][8] = { /* group 0 is group 3 for %Ev set */ + +/* 0 */ + + { "add", "or", "adc", "sbb", + + "and", "sub", "xor", "cmp" }, + +/* 1 */ + + { "rol", "ror", "rcl", "rcr", + + "shl", "shr", "shl", "sar" }, + +/* 2 */ /* v v*/ + + { "test %Eq,%Iq", 0/*"test %Eq,%Iq"*/, "not %Ec", "neg %Ec", + + "mul %Ec", "imul %Ec", "div %Ec", "idiv %Ec" }, + +/* 3 */ + + { "inc %Eb", "dec %Eb", "psrl", 0, + + "psra", 0, "psll", 0 }, + +/* 4 */ + + { "inc %Ev", "dec %Ev", "call %Kn%Ev", "call %Kf%Ep", + + "jmp %Kn%Ev", "jmp %Kf%Ep", "push %Ev", 0 }, + +/* 5 */ + + { "sldt %Ew", "str %Ew", "lldt %Ew", "ltr %Ew", + + "verr %Ew", "verw %Ew", 0, 0 }, + +/* 6 */ + + { "sgdt %Ms", "sidt %Ms", "lgdt %Ms", "lidt %Ms", + + "smsw %Ew", 0, "lmsw %Ew", "invlpg %Em" }, + +/* 7 */ + + { "prefetchnta %Em","prefetcht0 %Em", "prefetcht1 %Em", "prefetcht2 %Em", + + "bt", "bts", "btr", "btc" }, + +/* 8 */ + + { "fxsave %Em", "fxrstor %Em", "ldmxcsr %Em", "stmxcsr %Em", + + 0, "lfence", "mfence", "%x2" }, + +/* 9 */ + + { + + 0,0,"psrlq %RX,%Ib","psrldq %RX,%Ib", + + 0,0,"psllq %RX,%Ib","pslldq %RX,%Ib" + + } + + + +}; + + + +/* zero here means invalid. If first entry starts with '*', use st(i) */ + +/* no assumed %EFs here. Indexed by RM(modrm()) */ + +char *f0[] = { 0, 0, 0, 0, 0, 0, 0, 0}; + +char *fop_9[] = { "*fxch st,%GF",0,0,0,0,0,0,0 }; + +char *fop_10[] = { "fnop", 0, 0, 0, 0, 0, 0, 0 }; + +char *fop_12[] = { "fchs", "fabs", 0, 0, "ftst", "fxam", 0, 0 }; + +char *fop_13[] = { "fld1", "fldl2t", "fldl2e", "fldpi", + + "fldlg2", "fldln2", "fldz", 0 }; + +char *fop_14[] = { "f2xm1", "fyl2x", "fptan", "fpatan", + + "fxtract", "fprem1", "fdecstp", "fincstp" }; + +char *fop_15[] = { "fprem", "fyl2xp1", "fsqrt", "fsincos", + + "frndint", "fscale", "fsin", "fcos" }; + +char *fop_21[] = { 0, "fucompp", 0, 0, 0, 0, 0, 0 }; + +char *fop_28[] = { "fneni", "fndisi", "fnclex", "fninit", "fnsetpm", 0, 0, 0 }; + +char *fop_32[] = { "*fadd %GF,st",0,0,0,0,0,0,0 }; + +char *fop_33[] = { "*fmul %GF,st",0,0,0,0,0,0,0 }; + +char *fop_36[] = { "*fsubr %GF,st",0,0,0,0,0,0,0 }; + +char *fop_37[] = { "*fsub %GF,st",0,0,0,0,0,0,0 }; + +char *fop_38[] = { "*fdivr %GF,st",0,0,0,0,0,0,0 }; + +char *fop_39[] = { "*fdiv %GF,st",0,0,0,0,0,0,0 }; + +char *fop_40[] = { "*ffree %GF",0,0,0,0,0,0,0 }; + +char *fop_42[] = { "*fst %GF",0,0,0,0,0,0,0 }; + +char *fop_43[] = { "*fstp %GF",0,0,0,0,0,0,0 }; + +char *fop_44[] = { "*fucom %GF",0,0,0,0,0,0,0 }; + +char *fop_45[] = { "*fucomp %GF",0,0,0,0,0,0,0 }; + +char *fop_48[] = { "*faddp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_49[] = { "*fmulp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_51[] = { 0, "fcompp", 0, 0, 0, 0, 0, 0 }; + +char *fop_52[] = { "*fsubrp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_53[] = { "*fsubp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_54[] = { "*fdivrp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_55[] = { "*fdivp %GF,st",0,0,0,0,0,0,0 }; + +char *fop_60[] = { "fnstsw ax", 0, 0, 0, 0, 0, 0, 0 }; + +char *fop_16[]={"*fcmovb st,%GF",0,0,0,0,0,0,0}; + +char *fop_17[]={"*fcmove st,%GF",0,0,0,0,0,0,0}; + +char *fop_18[]={"*fcmovbe st,%GF",0,0,0,0,0,0,0}; + +char *fop_19[]={"*fcmovu st,%GF",0,0,0,0,0,0,0}; + +char *fop_24[]={"*fcmovnb st,%GF",0,0,0,0,0,0,0}; + +char *fop_25[]={"*fcmovne st,%GF",0,0,0,0,0,0,0}; + +char *fop_26[]={"*fcmovnbe st,%GF",0,0,0,0,0,0,0}; + +char *fop_27[]={"*fcmovnu st,%GF",0,0,0,0,0,0,0}; + +char *fop_29[]={"*fucomi st,%GF",0,0,0,0,0,0,0}; + +char *fop_30[]={"*fcomi st,%GF",0,0,0,0,0,0,0}; + +char *fop_61[]={"*fucomip st,%GF",0,0,0,0,0,0,0}; + +char *fop_62[]={"*fcomip st,%GF",0,0,0,0,0,0,0}; + + + +char **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */ + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, fop_9, fop_10, 0, fop_12, fop_13, fop_14, fop_15, + + fop_16, fop_17, fop_18, fop_19, f0, fop_21, f0, f0, + + fop_24, fop_25, fop_26, fop_27, fop_28, fop_29, fop_30, f0, + + fop_32, fop_33, f0, f0, fop_36, fop_37, fop_38, fop_39, + + fop_40, f0, fop_42, fop_43, fop_44, fop_45, f0, f0, + + fop_48, fop_49, f0, fop_51, fop_52, fop_53, fop_54, fop_55, + + f0, f0, f0, f0, fop_60, fop_61, fop_62, f0 + +}; + + + +char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */ + +/*00*/ "fadd", "fmul", "fcom", "fcomp", + + "fsub", "fsubr", "fdiv", "fdivr", + +/*08*/ "fld", 0, "fst", "fstp", + + "fldenv", "fldcw", "fnstenv", "fnstcw", + +/*16*/ "fiadd", "fimul", "ficomw", "ficompw", + + "fisub", "fisubr", "fidiv", "fidivr", + +/*24*/ "fild", 0, "fist", "fistp", + + "frstor", "fldt", 0, "fstpt", + +/*32*/ "faddq", "fmulq", "fcomq", "fcompq", + + "fsubq", "fsubrq", "fdivq", "fdivrq", + +/*40*/ "fldq", 0, "fstq", "fstpq", + + 0, 0, "fnsave", "fnstsw", + +/*48*/ "fiaddw", "fimulw", "ficomw", "ficompw", + + "fisubw", "fisubrw", "fidivw", "fidivr", + +/*56*/ "fildw", 0, "fistw", "fistpw", + + "fbldt", "fildq", "fbstpt", "fistpq" + +}; + + + +/* variables controlled by command line flags */ + +unsigned char seg_size=16; /* default size is 16 */ + +unsigned char must_do_size; + + + +unsigned int wordop,qwordop; /* dealing with word or byte operand */ + +unsigned long instruction_offset; + +unsigned short done_space; /* for opcodes with > one space */ + + + +char ubuf[100],*ubufp; + +int col; /* output column */ + +unsigned int prefix; /* segment override prefix byte */ + +unsigned int modrmv; /* flag for getting modrm byte */ + +unsigned int sibv; /* flag for getting sib byte */ + +unsigned int opsize; /* just like it says ... */ + +unsigned int addrsize; + + + +void printbyte(unsigned char c) + +{ + + if(c<10)uprintf("%u",(unsigned char)c); + + else if(c<16||c>0x9F)uprintf("0%Xh",(unsigned char)c); + + else uprintf("%Xh",(unsigned char)c); + +} + + + +void printword(unsigned short c) + +{ + + if(c<256)printbyte(c); + + else if(c<0xA00||(c>0xFFF&&c<0xA000))uprintf("%Xh",c); + + else uprintf("0%Xh",c); + +} + + + +void printdword(unsigned int c) + +{ + + if(c<65536)printword((unsigned short)c); + + else if(c<0xA0000L||(c>0xFFFFFL&&c<0xA00000L)||(c>0xFFFFFFL&&c<0xA000000L)|| + + (c>0xFFFFFFFL&&c<0xA0000000L))uprintf("%lXh",c); + + else uprintf("0%lXh",c); + +} + + + +void addr_to_hex(long addr, unsigned char splitup) + +{ + +static char buffer[11]; + +WORD32 adr; + + adr.dword=addr; + + if(splitup){ + + if(adr.w.seg==0/*||adr.w.seg==0xffff*/)printword(adr.w.ofs);//sprintf(buffer,"%04Xh",adr.w.ofs); + + else{ + + sprintf(buffer,"%04Xh:%04Xh",adr.w.seg,adr.w.ofs); + + uprintf("%s",buffer); + + } + + } + + else{ + + if(adr.w.seg==0/*||adr.w.seg==0xffff*/)printword(adr.w.ofs);//sprintf(buffer,"%04Xh",adr.w.ofs); + + else printdword(addr);//sprintf(buffer, "%08lXh",addr); + + } + +} + + + +unsigned char getbyte(void) + +{ + +short c; + + c=output[outptr++]; + + fprintf(hout,"%02X", c); /* print out byte */ + + col+=2; + + instruction_offset++; + + return c; + +} + + + +int modrm() + +{ + + if (modrmv == -1) modrmv = getbyte(); + + return modrmv; + +} + + + +int sib() + +{ + + if (sibv == -1) sibv = getbyte(); + + return sibv; + +} + + + +/*------------------------------------------------------------------------*/ + +void uprintf(char *s, ...) + +{ + +va_list argptr; + + va_start(argptr,s); + + vsprintf(ubufp,s,argptr); + + va_end(argptr); + + while (*ubufp) ubufp++; + +} + + + +void uputchar(char c) + +{ + + if (c == '\t') { + + if(done_space)uputchar(' '); + + else { + + done_space=1; + + do { + + *ubufp++ = ' '; + + } while ((ubufp-ubuf) % 8); + + } + + } + + else *ubufp++ = c; + + *ubufp = 0; + +} + + + +/*------------------------------------------------------------------------*/ + +int bytes(char c) + +{ + + switch (c){ + + case 'b': return 1; + + case 'w': return 2; + + case 'd': return 4; + + case 'v': + + if (opsize == 32) return 4; + + else return 2; + + } + + return 0; + +} + + + +/*------------------------------------------------------------------------*/ + +void outhex(char subtype, int extend, int optional, int defsize, int sign) + +{ + +int n=0, s=0, i; + +long delta; + +unsigned char buff[6]; + +//char *name; + +char signchar; + + switch (subtype) { + + case 'q': + + if (wordop) { + + if (opsize==16) n = 2; + + else n = 4; + + } + + else n = 1; + + break; + + + + case 'a': break; + + case 'x': + + extend = defsize/8;//2; + + n = 1; + + break; + + case 'b': + + n = 1; + + break; + + case 'w': + + n = 2; + + break; + + case 'd': + + n = 4; + + break; + + case 's': + + n = 6; + + break; + + case 'c': + + case 'v': + + if (defsize == 32) n = 4; + + else n = 2; + + break; + + case 'p': + + if (defsize == 32) n = 6; + + else n = 4; + + s = 1; + + break; + + } + + for (i=0; i n) { + + if (subtype!='x') { + + if ((long)delta<0) { + + delta = -delta; + + signchar = '-'; + + } + + else signchar = '+'; + + if (delta || !optional){ + + uprintf("%c",signchar); + + printdword(delta); + +// uprintf("%c%0*lXh", signchar, extend+1, delta); + + } + + } + + else { + + if (extend==2) + + delta = (unsigned short) delta; + + printdword(delta); + +// uprintf("%0.*lXh", 2*extend+1, delta); + + } + + return; + + } + + if ((n == 4) && !sign) { + + addr_to_hex(delta, 0); + + return; + + } + + switch (n) { + + case 1: + + if (sign && (char)delta<0) { + + delta = -delta; + + signchar = '-'; + + } + + else signchar = '+'; + + if(sign)uprintf("%c",signchar); + + printbyte((unsigned char)delta); + +// if (sign)uprintf("%c%03Xh",signchar,(unsigned char)delta); + +// else uprintf("%03Xh", (unsigned char)delta); + + break; + + case 2: + + if (sign && (int)delta<0) { + + signchar = '-'; + + delta = -delta; + + } + + else signchar = '+'; + + if(sign)uprintf("%c",signchar); + + printword((unsigned short)delta); + +// if (sign) uprintf("%c%05Xh", signchar,(int)delta); + +// else uprintf("%05Xh", (unsigned int)delta); + + break; + + case 4: + + if (sign && (long)delta<0) { + + delta = -delta; + + signchar = '-'; + + } + + else signchar = '+'; + + if(sign)uprintf("%c",signchar); + + printdword(delta); + +// if (sign)uprintf("%c%09lXh", signchar, (unsigned long)delta); + +// else uprintf("%09lXh", (unsigned long)delta); + + break; + + } + +} + + + +/*------------------------------------------------------------------------*/ + +void reg_name(int regnum, char size) + +{ + + if (size == 'F') { /* floating point register? */ + + uprintf("st(%d)", regnum); + + return; + + } + + if (size == 'M') { /* multimedia register? */ + + uprintf("mm%d", regnum); + + return; + + } + + if(size=='X'){ /* xmm register? */ + + uprintf("xmm%d",regnum); + + return; + + } + + if (((size == 'v') && (opsize == 32)) || + + (size == 'd')|| + + ((size=='c'||size=='q')&&wordop&&opsize==32) + + ) uputchar('e'); + +// printf("size=%c wordop=%d opsize=%d\n",size,wordop,opsize); + + if(size=='b'||((size=='q'||size=='c')&&!wordop)){ + + uputchar("acdbacdb"[regnum]); + + uputchar("llllhhhh"[regnum]); + + } + + else { + + uputchar("acdbsbsd"[regnum]); + + uputchar("xxxxppii"[regnum]); + + } + +} + + + +/*------------------------------------------------------------------------*/ + +void do_sib(int m) + +{ + +int s, i, b; + + s = SCALE(sib()); + + i = INDEX(sib()); + + b = BASE(sib()); + + switch (b) { /* pick base */ + + case 0: ua_str("%p:[eax"); break; + + case 1: ua_str("%p:[ecx"); break; + + case 2: ua_str("%p:[edx"); break; + + case 3: ua_str("%p:[ebx"); break; + + case 4: ua_str("%p:[esp"); break; + + case 5: + + if (m == 0) { + + ua_str("%p:["); + + outhex('d', 4, 0, addrsize, 0); + + } + + else ua_str("%p:[ebp"); + + break; + + case 6: ua_str("%p:[esi"); break; + + case 7: ua_str("%p:[edi"); break; + + } + + switch (i) { /* and index */ + + case 0: uprintf("+eax"); break; + + case 1: uprintf("+ecx"); break; + + case 2: uprintf("+edx"); break; + + case 3: uprintf("+ebx"); break; + + case 4: break; + + case 5: uprintf("+ebp"); break; + + case 6: uprintf("+esi"); break; + + case 7: uprintf("+edi"); break; + + } + + if (i != 4) { + + switch (s) { /* and scale */ + + case 0: uprintf(""); break; + + case 1: uprintf("*2"); break; + + case 2: uprintf("*4"); break; + + case 3: uprintf("*8"); break; + + } + + } + +} + + + +/*------------------------------------------------------------------------*/ + +void do_modrm(char subtype) + +{ + +int mod = MOD(modrm()); + +int rm = RM(modrm()); + +int extend = (addrsize == 32) ? 4 : 2; + + if (mod == 3) { /* specifies two registers */ + + reg_name(rm, subtype); + + return; + + } + + if (must_do_size) { + + if(qwordop)ua_str("qword ptr "); + + else{ + + if (wordop) { + + if (/*addrsize==32 ||*/ opsize==32) { /* then must specify size */ + + ua_str("dword ptr "); + + } + + else ua_str("word ptr "); + + } + + else ua_str("byte ptr "); + + } + + } + + if ((mod == 0) && (rm == 5) && (addrsize == 32)) {/* mem operand with 32 bit ofs */ + + ua_str("%p:["); + + outhex('d', extend, 0, addrsize, 0); + + uputchar(']'); + + return; + + } + + if ((mod == 0) && (rm == 6) && (addrsize == 16)) { /* 16 bit dsplcmnt */ + + ua_str("%p:["); + + outhex('w', extend, 0, addrsize, 0); + + uputchar(']'); + + return; + + } + + if ((addrsize != 32) || (rm != 4)) ua_str("%p:["); + + if (addrsize == 16) { + + switch (rm) { + + case 0: uprintf("bx+si"); break; + + case 1: uprintf("bx+di"); break; + + case 2: uprintf("bp+si"); break; + + case 3: uprintf("bp+di"); break; + + case 4: uprintf("si"); break; + + case 5: uprintf("di"); break; + + case 6: uprintf("bp"); break; + + case 7: uprintf("bx"); break; + + } + + } + + else { + + switch (rm) { + + case 0: uprintf("eax"); break; + + case 1: uprintf("ecx"); break; + + case 2: uprintf("edx"); break; + + case 3: uprintf("ebx"); break; + + case 4: do_sib(mod); break; + + case 5: uprintf("ebp"); break; + + case 6: uprintf("esi"); break; + + case 7: uprintf("edi"); break; + + } + + } + + switch (mod) { + + case 1: + + outhex('b', extend, 1, addrsize, 0); + + break; + + case 2: + + outhex('v', extend, 1, addrsize, 1); + + break; + + } + + uputchar(']'); + +} + + + +/*------------------------------------------------------------------------*/ + +void floating_point(int e1) + +{ + +int esc = e1*8 + REG(modrm()); + + if(MOD(modrm())==3){ //2- >C0 + + if (fspecial[esc]) { + + if (fspecial[esc][0]!=NULL&&fspecial[esc][0][0] == '*')ua_str(fspecial[esc][0]+1); + + else ua_str(fspecial[esc][RM(modrm())]); + + } + + else { + + ua_str(floatops[esc]); + + ua_str(" %EF"); + + } + + } + + else { + + ua_str(floatops[esc]); + + ua_str(" %EF"); + + } + +} + + + +/*------------------------------------------------------------------------*/ + +/* Main table driver */ + +void percent(char type, char subtype) + +{ + +long vofs; + +int extend =(addrsize==32)?4:2; + +unsigned char c; + + switch (type) { + + case 'A': /* direct address */ + + outhex(subtype,extend,0,addrsize,0); + + break; + + case 'C': /* reg(r/m) picks control reg */ + + uprintf("CR%d",REG(modrm())); + + must_do_size=0; + + break; + + case 'D': /* reg(r/m) picks debug reg */ + + uprintf("DR%d", REG(modrm())); + + must_do_size = 0; + + break; + + case 'E': /* r/m picks operand */ + + if(subtype=='m')must_do_size=0; + + do_modrm(subtype); + + break; + + case 'F': + + if(MOD(modrm())!=3)do_modrm(subtype); + + else reg_name(REG(modrm()),subtype); + + break; + + case 'G': /* reg(r/m) picks register */ + +/* if (subtype == 'F'||subtype == 'M') + + reg_name(RM(modrm()), subtype); + + else reg_name(REG(modrm()), subtype);*/ + + reg_name(RM(modrm()),subtype); + + must_do_size = 0; + + break; + + case 'I': /* immed data */ + + outhex(subtype, 0, 0, opsize, 0); + + break; + + case 'J': /* relative IP offset */ + + switch(bytes(subtype)) { /* sizeof offset value */ + + case 1: + + vofs=(signed char)getbyte(); + + break; + + case 2: + + vofs = getbyte(); + + vofs += getbyte()<<8; + + vofs = (short)vofs; + + break; + + case 4: + + vofs = (unsigned long)getbyte(); /* yuk! */ + + vofs |= (unsigned long)getbyte() << 8; + + vofs |= (unsigned long)getbyte() << 16; + + vofs |= (unsigned long)getbyte() << 24; + + break; + + } + + addr_to_hex(vofs+instruction_offset,seg_size==16?(unsigned char)1:(unsigned char)0); + + break; + + case 'K': + + if(seg_size==16){ + + switch(subtype){ + + case 'f': + + ua_str("far "); + + break; + + case 'n': + + ua_str("near "); + + break; + + case 's': + + ua_str("short "); + + break; + + } + + } + + else if(subtype=='s')ua_str("short "); + + break; + + case 'L': + + if(MOD(modrm())!=3)reg_name(REG(modrm()),subtype); + + else reg_name(RM(modrm()),subtype); + + break; + + case 'M': /* r/m picks memory */ + + do_modrm(subtype); + + break; + + case 'O': /* offset only */ + + ua_str("%p:["); + + outhex(subtype, extend, 0, addrsize, 0); + + uputchar(']'); + + break; + + case 'P': /* prefix byte (rh) */ + + ua_str("%p:"); + + break; + + case 'R': /* mod(r/m) picks register */ + + reg_name(REG(modrm()), subtype); /* rh */ + + must_do_size = 0; + + break; + + case 'S': /* reg(r/m) picks segment reg */ + + uputchar("ecsdfg"[REG(modrm())]); + + uputchar('s'); + + must_do_size = 0; + + break; + + case 'T': /* reg(r/m) picks T reg */ + + uprintf("tr%d", REG(modrm())); + + must_do_size = 0; + + break; + + case 'X': /* ds:si type operator */ + + uprintf("ds:["); + + if (addrsize == 32) uputchar('e'); + + uprintf("si]"); + + break; + + case 'Y': /* es:di type operator */ + + uprintf("es:["); + + if (addrsize == 32) uputchar('e'); + + uprintf("di]"); + + break; + + case '2': + + c=getbyte(); /* old [pop cs]! now indexes */ + + wordop = c & 1; + + ua_str(second[c]); /* instructions in 386/486 */ + + break; + + case 'd': /* sizeof operand==dword? */ + + if (opsize == 32) uputchar('d'); + + uputchar(subtype); + + break; + + case 'e': /* extended reg name */ + + if (opsize == 32) { + + if (subtype == 'w')uputchar('d'); + + else { + + uputchar('e'); + + uputchar(subtype); + + } + + } + + else uputchar(subtype); + + break; + + case 'f': /* '87 opcode */ + + floating_point(subtype-'0'); + + break; + + case 'j': + + if (/*addrsize==32 ||*/ opsize==32) /* both of them?! */ + + uputchar('e'); + + break; + + case 'g': /* modrm group `subtype' (0--7) */ + + switch(subtype){ + + case '9': + + vofs=REG(modrm()); + + modrmv=(modrmv&0xC7)|((modrmv&7)<<3); + + ua_str(groups[9][vofs]); + + break; + + case '6': + + if(MOD(modrm())!=3)goto defg; + + switch(modrmv){ + + case 0xc8: + + ua_str("monitor"); + + break; + + case 0xc9: + + ua_str("mwait"); + + break; + + default: + + uprintf(""); + + break; + + } + + break; + + case '5': + + opsize=16; + + case '7': + + wordop=1; + + default: + +defg: + + ua_str(groups[subtype-'0'][REG(modrm())]); + + break; + + } + + break; + + case 'p': /* prefix byte */ + + switch (subtype) { + + case 'c': + + case 'd': + + case 'e': + + case 'f': + + case 'g': + + case 's': + + prefix = subtype; + + c = getbyte(); + + wordop = c & 1; + + ua_str(opmap1[c]); + + break; + + case ':': + + if (prefix) uprintf("%cs:", prefix); + + break; + + case ' ': + + c = getbyte(); + + wordop = c & 1; + + ua_str(opmap1[c]); + + break; + + } + + break; + + case 's': /* size override */ + + switch (subtype) { + + case 'a': + + addrsize = 48 - addrsize; + + c = getbyte(); + + wordop = c & 1; + + ua_str(opmap1[c]); + + break; + + case 'o': + + opsize = 48 - opsize; + + c = getbyte(); + + wordop = c & 1; + + ua_str(opmap1[c]); + + break; + + } + + break; + + case 'w': /* insert explicit size specifier */ + + if (opsize == 32)uputchar('d'); + + else uputchar('w'); + + uputchar(subtype); + + break; + + case 'x': + + if(MOD(modrm())==3){ + + switch(subtype-'0'){ + + case 0: + + ua_str("movhlps %RX,%GX"); + + break; + + case 1: + + ua_str("movlhps %RX,%GX"); + + break; + + case 2: + + ua_str("sfence"); + + break; + + } + + } + + else{ + + switch(subtype-'0'){ + + case 0: + + ua_str("movlps %RX,%Md"); + + break; + + case 1: + + ua_str("movhps %RX,%Md"); + + break; + + case 2: + + ua_str("clflush %Em"); + + break; + + } + + } + + break; + + default: + + preerror("uncnown operand for dizassemler"); + + break; + + } + +} + + + +void ua_str(char *str) + +{ + +char c; + + if (str == NULL) { + + uprintf(""); + + return; + + } + + if (strpbrk(str, "CDFGRST")) /* specifiers for registers=>no size 2b specified */ + + must_do_size = 0; + + while ((c = *str++) != 0) { + + if (c == '%') { + + c = *str++; + + if(*str=='y'){ + + qwordop=1; + + str++; + + } + + percent(c,*str++); + + } + + else { + + if (c == ' ') uputchar('\t'); + + else uputchar(c); + + } + + } + +} + + + +void unassemble(unsigned long ofs) + +{ + +char *str; + +int c; + + fprintf(hout,seg_size==16?"%04X ":"%08lX ",ofs); + + prefix = 0; + + modrmv = sibv = 0xFFFFFFFF; /* set modrm and sib flags */ + + opsize = addrsize = seg_size; + + col = 0; + + ubufp = ubuf; + + done_space = 0; + + c = getbyte(); + + if(c==0x9B){ + + switch(*(short *)&output[outptr]){ + + case 0xE0DB: + + case 0xE1DB: + + case 0xE2DB: + + case 0xE3DB: + + case 0xE4DB: + + getbyte(); + + c=getbyte(); + + switch(c){ + + case 0xE0: + + ua_str("feni"); + + break; + + case 0xE1: + + ua_str("fdisi"); + + break; + + case 0xE2: + + ua_str("fclex"); + + break; + + case 0xE3: + + ua_str("finit"); + + break; + + case 0xE4: + + ua_str("fsetpm"); + + break; + + } + + goto endp; + + } + + } + + else if(c==0x98){ + + if(am32){ + + ua_str("cwde"); + + goto endp; + + } + + } + + else if(c==0x99){ + + if(am32){ + + ua_str("cdq"); + + goto endp; + + } + + } + + else if(c==0x66&&am32==0){ + + if(output[outptr]==0x98){ + + ua_str("cwde"); + + getbyte(); + + goto endp; + + } + + if(output[outptr]==0x99){ + + ua_str("cdq"); + + getbyte(); + + goto endp; + + } + + } + + else if(c==0xF3&&output[outptr]==0x90){ + + ua_str("pause"); + + getbyte(); + + goto endp; + + } + + if(output[outptr]==0x0f){ + + int c2=output[outptr+1]; + + switch(c){ + + case 0x66: + + if(second_660f[c2]){ + + getbyte(); + + ua_str(second_660f[getbyte()]); + + goto endp; + + } + + break; + + case 0xf2: + + if(second_f20f[c2]){ + + getbyte(); + + ua_str(second_f20f[getbyte()]); + + goto endp; + + } + + break; + + case 0xf3: + + if(second_f30f[c2]){ + + getbyte(); + + ua_str(second_f30f[getbyte()]); + + goto endp; + + } + + break; + + } + + } + + wordop = c & 1; + + qwordop=0; + + must_do_size = 1; + + if ((str = opmap1[c])==NULL) { /* invalid instruction? */ + + uputchar('d'); /* then output byte defines */ + + uputchar('b'); + + uputchar('\t'); + + uprintf("%02Xh",c); + + } + + else ua_str(str); /* valid instruction */ + +endp: + + fprintf(hout,"%*s", 25-col, " "); + + fprintf(hout,"%s\n", ubuf); + +} + + + +#define MAXSTR 12 + + + +void undata(unsigned ofs,unsigned long len,unsigned int type) + +{ + +unsigned int sizet,c,i,j; + +unsigned long total,d; + +unsigned char data[MAXSTR]; + + if(type==3)sizet=1; + + else sizet=type; + + for(total=0;totallen){ + + type=sizet=1; + + } + + for(i=0;ilen)break; + + if(sizet==8)break; + + } + + uputchar(sizet==8?'q':'d'); + + switch(sizet){ + + case 1: + + uputchar('b'); + + break; + + case 2: + + case 8: + + uputchar('w'); + + break; + + case 4: + + uputchar('d'); + + break; + + } + + done_space=0; + + uputchar('\t'); + + switch(type){ + + case 1: + + for(j=0;j=0x20){ + + if(c==0){ + + c++; + + if(j!=0)uputchar(','); + + uputchar(0x27); + + } + + uputchar(data[j]); + + } + + else{ + + if(c!=0){ + + c=0; + + uputchar(0x27); + + } + + if(j!=0)uputchar(','); + + printbyte(data[j]); + + } + + } + + if(c)uputchar(0x27); + + break; + + case 4: + + for(j=0;j %s.\n",startfileinfo==NULL?"":(startfileinfo+file)->filename,line,error,str); + printf((char *)string3); + if(errfile.file==NULL)errfile.file=fopen(errfile.name,"w+t"); + if(errfile.file!=NULL)fprintf(errfile.file,(char *)string3); + } + else exit(e_toomanyerrors); +} + +void internalerror (char *str)// serious internal compiler error message +{ +char buf[200]; + sprintf(buf,"*** SERIOUS COMPILER INTERNAL ERROR ***\n>%s",str); + preerror(buf); + printf("STRING:%s\nIDNAME:%s\n",string,itok.name); + printf("TOK:%d SEGM:%d POST:%d RM:%d number:%ld\n",tok,itok.segm,itok.post,itok.rm,itok.number); + printf("STRING2:%s\nIDNAME2:%s\n",string2,itok2.name); + printf("TOK2:%d SEGM2:%d POST2:%d RM2:%d number2:%ld\n",tok2,itok2.segm,itok2.post,itok2.rm,itok2.number); + printf("Out position:%04X\n",outptr); + exit(e_internalerror); +} + +char *getnumoperand(int type,char *name) +{ + switch(type){ + case 0: + return ""; + case 1: + strcpy(buferr,"1-st "); + break; + case 2: + strcpy(buferr,"2-nd "); + break; + case 3: + strcpy(buferr,"3-rd "); + break; + default: + sprintf(buferr,"%d-th ",type%256); + break; + } + strcat(buferr,name); + return buferr; +} + +void expected (char ch) +{ +char holdstr[80]; + sprintf(holdstr,"'%c' expected",ch); + preerror(holdstr); +} + +void numexpected(int type) +{ +char buf[40]; + sprintf(buf,"%snumber expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void varexpected(int type) +{ +char buf[45]; + sprintf(buf,"%svariable expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void stringexpected() +{ + preerror("string expected"); +} + +void valueexpected() +{ + preerror("value expected"); +} + +void wordvalexpected() +{ + preerror("word value expected"); +} + +void dwordvalexpected() +{ + preerror("dword value expected"); +} + +void qwordvalexpected() +{ + preerror("qword value expected"); +} + +void codeexpected() +{ + preerror("assembly opcode expected"); +} + +void operatorexpected() +{ + preerror("operator identifier expected"); +} + +void unexpectedeof() +{ + preerror("unexpected END OF FILE"); +} + +void swaperror() +{ + preerror("invalid or incompatable swap item"); +} + +void notexternfun() +{ + preerror("Do not insert extern function"); +} + +void idalreadydefined() +{ +char holdstr[80]; + sprintf(holdstr,"identifier '%s' already defined",itok.name); + preerror(holdstr); + FindStopTok(); +// nexttok(); +} + +void jumperror(unsigned int line,char *type) +{ +char smalltype[IDLENGTH]; +char buf[80]; + strcpy(smalltype,type); + strlwr(smalltype); + sprintf(buf,"'%s' jump distance too large, use '%s'",type,smalltype); + preerror3(buf,line); +} + +void unknowncompop() +{ + preerror("unknown comparison operator"); +} + +void maxoutputerror() +{ + preerror("maximum output code size exceeded"); + exit( e_outputtoobig ); +} + +void unableopenfile(char *name) +{ +char holdstr[256]; + sprintf(holdstr,"unable to open file '%s'",name); + preerror(holdstr); +} + +void shortjumptoolarge() +{ + preerror(shorterr); +} + +void thisundefined(char *str,int next) +{ +char holdstr[80]; + sprintf(holdstr,"'%s' undefined",str); + preerror(holdstr); + + if(next)FindStopTok(); +} + +void datatype_expected(int type) +{ +char buf[45]; + sprintf(buf,"%smemory variable expected",getnumoperand(type,"operand ")); + preerror(buf); + FindStopTok(); +} + +void illegalfloat() +{ + preerror("illegal use of float point"); +} + +void tobigpost() +{ + preerror("maximum size of post variables exceeded"); + postsize=0xFFFF; +} + +void unuseableinput() +{ + preerror("unuseable input"); + FindStopTok(); +} + +void ManyLogicCompare() +{ + preerror("to many use logic compare"); +} + +void ZeroMassiv() +{ + preerror("size massiv unknown or zero"); +} + +void maxdataerror() +{ + preerror("maximum output data size exceeded"); + exit( e_outputtoobig ); +} + +void errorreadingfile(char *name) +{ +char buf[256]; + sprintf(buf,"error reading from file '%s'",name); + preerror(buf); +} + +void badinfile(char *name) +{ +char buf[256]; + sprintf(buf,"bad input file '%s'",name); + preerror(buf); +} + +void edpip(int num) +{ +char buf[64]; +// preerror("error declare parameters in function"); + sprintf(buf,"error declare %sparameters in function",getnumoperand(num,"")); + preerror(buf); +} + +void CompareOr() +{ + preerror("compare logic OR or AND to big distance"); +} + +void dynamiclabelerror() +{ + preerror("global labels illegal within dynamic functions"); +} + +void OnlyComFile() +{ + preerror("this option only for COM output files"); +} + +void redeclare(char *name) +{ +char buf[120]; + sprintf(buf,"error redeclare function \"%s\"",name); + preerror(buf); +} + +void retvoid() +{ + preerror("function has return type of void"); +} + +void extraparam(char *name) +{ +char buf[120]; + sprintf(buf,"extra parameter in function %s",name); + preerror(buf); +} + +void blockerror() +{ + preerror("illegal syntax within [ ]"); +} + +void block16_32error() +{ + preerror("only one of 16 or 32 bit allowed within [ ]"); +} + +void notstructname() +{ + preerror("unique struct name expected"); +} + +void badtoken() +{ +char buf[80]; + if(displaytokerrors){ + sprintf(buf,"tokenizer: bad character value - '%c'",cha); + preerror(buf); + } +} + +void expectederror(char *str) +{ +char holdstr[80]; + if(displaytokerrors){ + sprintf(holdstr,"%s expected",str); + preerror(holdstr); + } +} + +void declareanonim() +{ + preerror("Error declare anonimus union"); +} + +void declareunion() +{ + preerror("Error declare union"); +} +/* +void not_union_static() +{ + preerror("'static' not use in 'union'"); +} */ + +void segoperror() +{ + preerror("only '=' or '><' operands valid with segment register"); +} + +void segbyteerror() +{ + preerror("segment registers can not be used in byte or char math"); +} + +void regmathoperror() +{ + preerror("invalid operation for non-AX register math"); +} + +void begmathoperror() +{ + preerror("invalid operation for non-AL register math"); +} + +void negregerror() +{ + preerror("negative non-constant invalid for non-AX register math"); +} + +void regbyteerror() +{ + preerror("byte or char operands invalid for non-AX register math"); +} + +void begworderror() +{ + preerror("specified 16 bit operand invalid for non-AL register math"); +} + +void regshifterror() +{ + preerror("only CL or 1 valid for non AX or AL register bit shifting"); +} + +void regmatherror() +{ + preerror("invalid operand for non-AX register math"); +} + +void DevideZero() +{ + preerror("impossible to divide into ZERO"); +} + +void wordnotoper() +{ + preerror("word or int operands invalid for non-EAX register math"); +} + +void regexpected(int type) +{ +char buf[50]; + sprintf(buf,"%sword register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void bytevalexpected(int type) +{ +char buf[50]; + sprintf(buf,"%sbyte value expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void shortjumperror() +{ + preerror("invalid operand for SHORT jump"); +} + +void invalidfarjumpitem() +{ + preerror("invalid operand for FAR jump"); +} + +void invalidfarcallitem() +{ + preerror("invalid operand for FAR call"); +} + +void begexpected(int type) +{ +char buf[50]; + sprintf(buf,"%sbyte register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void reg32expected(int type) +{ +char buf[50]; + sprintf(buf,"%s32 bit register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void reg32regexpected(int type) +{ +char buf[50]; + sprintf(buf,"%s16 or 32 bit register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void regBXDISIBPexpected() +{ + preerror("use only one of BX, DI, SI or BP register"); +} + +void bytedxexpected() +{ + preerror("byte constant or DX expected"); +} + +void axalexpected() +{ + preerror("EAX, AX or AL expected"); +} + +void invalidoperand(int type) +{ +char buf[25]; + sprintf(buf,"%sinvalid",getnumoperand(type,"operand ")); + preerror(buf); +} + +void mmxregexpected(int type) +{ +char buf[50]; + sprintf(buf,"%sMMX register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void xmmregexpected(int type) +{ +char buf[50]; + sprintf(buf,"%sXMM register expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void xmmregorvarexpected(int type) +{ +char buf[60]; + sprintf(buf,"%sXMM register or memory varible expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void mmxregordwordexpected(int type) +{ +char buf[60]; + sprintf(buf,"%sMMX register or memory varible expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void clornumberexpected() +{ + preerror("CL or constant expected"); +} + +void fpuvarexpected(int type) +{ +char buf[70]; + sprintf(buf,"%sexpected FPU register|long|dword|float var",getnumoperand(type,"operand ")); + preerror(buf); +} + +void fpustakexpected(int type) +{ +char buf[40]; + sprintf(buf,"%sexpected FPU register",getnumoperand(type,"operand ")); + preerror(buf); +} + +void fpu0expected() +{ + preerror("2-nd expected only st(0) fpu register"); +} + +void fpustdestroed() +{ + preerror("FPU register more 6 destroed"); +} + +void errstruct() +{ + preerror("illegal use of struct"); +} + +void tegnotfound() +{ + preerror("tag struct not found"); +} + +void ErrWrite() +{ + //fprintf(stderr,"unable to write output file.\n"); printf("unable to write output file.\n"); +} + +void ErrReadStub() +{ + //fprintf(stderr,"unable to read stubfile\n"); printf("unable to read stubfile\n"); +} + +void InvOperComp() +{ + preerror("invalid operation for compare"); +} + +void mmxormem(int type) +{ +char buf[60]; + sprintf(buf,"%sexpected mmx register or memory variable",getnumoperand(type,"operand ")); + preerror(buf); +} + +void reg32orword(int type) +{ +char buf[60]; + sprintf(buf,"%s32 bit register or word variable expected",getnumoperand(type,"operand ")); + preerror(buf); +} + +void undefclass(char *name) +{ +char buf[30+IDLENGTH]; + sprintf(buf,"Base class '%s' not defined",name); + preerror(buf); +} + +void unknowntype() +{ + preerror("unknown type"); +} + +void destrdestreg() +{ + preerror("destroyed destination register"); +} + +void unknownstruct (char *name,char *sname) +{ +char buf[IDLENGTH*2+30]; + sprintf(buf,"unknown member '%s' in struct '%s'",name,sname); + preerror(buf); +} + +void unknowntagstruct(char *name) +{ +char buf[IDLENGTH+16]; + sprintf(buf,"unknown tag '%s'",name); + preerror(buf); +} + +void unknownobj(char *name) +{ +char buf[IDLENGTH+32]; + sprintf(buf,"unknown object for member '%s'",name); + preerror(buf); +} +void q(); +void unknownpragma(char *name) +{ +char buf[IDLENGTH+32]; + sprintf(buf,"unknown parametr for #pragma %s",name); + preerror(buf); +} + +/*-----------------08.08.00 22:49------------------- + ।० + --------------------------------------------------*/ + +void warningoptnum() +{ + if(wact[0].usewarn)wact[0].fwarn("Optimize numerical expressions",linenumber,currentfileinfo); +} + +void warningreg(char *str2) +{ +char buf[50]; + if(wact[1].usewarn){ + sprintf(buf,"%s has been used by compiler",str2); wact[1].fwarn(buf,linenumber,currentfileinfo); + } +} + +void warningjmp(char *str2,int line,int file) +{ +char buf[50]; + if(wact[2].usewarn){ + sprintf(buf,"Short operator '%s' may be used",str2); + wact[2].fwarn(buf,line,file); + } +} + +void warningstring() +{ + if(wact[3].usewarn){ + sprintf((char *)string2,"String \"%s\" repeated",string3); + wact[3].fwarn((char *)string2,linenumber,currentfileinfo); + } +} + +void warningexpand() +{ + if(wact[4].usewarn)wact[4].fwarn("Expansion variable",linenumber,currentfileinfo); +} + +void warningretsign() +{ + if(wact[5].usewarn)wact[5].fwarn("Signed value returned",linenumber,currentfileinfo); +} + +void warningprint(char *str,unsigned int line,unsigned int file) +{ + if(warning==TRUE){ + //if(wartype.name!=NULL&&wartype.file==stdout){ + // if((wartype.file=fopen(wartype.name,"w+t"))==NULL)wartype.file=stdout; + //} + //fprintf(wartype.file,"%s(%d)> Warning! %s.\n",startfileinfo==NULL?"":(startfileinfo+file)->filename,line,str); printf("%s(%d)> Warning! %s.\n",startfileinfo==NULL?"":(startfileinfo+file)->filename,line,str); + } +} + +void warningdefined(char *name) +{ +char buf[IDLENGTH+30]; + if(wact[6].usewarn){ + sprintf(buf,"'%s' defined above, therefore skipped",name); + wact[6].fwarn(buf,linenumber,currentfileinfo); + } +} + +void warningnotused(char *name,int type) +{ +char buf[IDLENGTH+40]; +char *typenames[]={"Variable","Structure","Function","Local variable", +"Parameter variable","Local structure"}; + if(wact[7].usewarn){ + sprintf(buf,"%s '%s' possible not used",(char *)typenames[type],name); + wact[7].fwarn(buf,linenumber,currentfileinfo); + } +} + +void warningusenotintvar(char *name) +{ +char buf[IDLENGTH+50]; + if(wact[8].usewarn){ + sprintf(buf,"Non-initialized variable '%s' may have been used",name); + wact[8].fwarn(buf,linenumber,currentfileinfo); + } +} + +void warningdestroyflags() +{ + if(wact[9].usewarn)wact[9].fwarn("Return flag was destroyed",linenumber,currentfileinfo); +} + +void warningunreach() +{ + if(wact[10].usewarn)wact[10].fwarn("Code may not be executable",linenumber,currentfileinfo); +} + +void warninline() +{ + if(wact[11].usewarn)wact[11].fwarn("Don't use local/parametric values in inline functions",linenumber,currentfileinfo); +} + +void warnsize() +{ + if(wact[12].usewarn)wact[12].fwarn("Sources size exceed destination size",linenumber,currentfileinfo); +} + +void waralreadinit(char *reg) +{ +#ifdef BETTA +char buf[IDLENGTH+50]; + sprintf(buf,"Register %s already initialized",reg); + warningprint(buf,linenumber,currentfileinfo); +#endif +} + +void waralreadinitreg(char *reg,char *reg2) +{ +#ifdef BETTA +char buf[IDLENGTH+50]; + sprintf(buf,"Register %s same as %s",reg,reg2); + warningprint(buf,linenumber,currentfileinfo); +#endif +} + +void warpragmapackpop() +{ + if(wact[13].usewarn)wact[13].fwarn("Pragma pack pop with no matching pack push",linenumber,currentfileinfo); +} + +void missingpar(char *name) +{ +char buf[120]; + if(wact[14].usewarn){ + sprintf(buf,"Missing parameter in function %s",name); + wact[14].fwarn(buf,linenumber,currentfileinfo); + } +// preerror(buf); +} + +void warreplasevar(char *name) +{ +char buf[120]; +// if(usewarn[14]){ + if(displaytokerrors){ + sprintf(buf,"Variable %s is replased on constant",name); + warningprint(buf,linenumber,currentfileinfo); + } +// } +// preerror(buf); +} + +void waralreadinitvar(char *name,unsigned int num) +{ +char buf[120]; +// if(usewarn[14]){ + if(displaytokerrors){ + sprintf(buf,"Variable %s already initialized by constant %d",name,num); + warningprint(buf,linenumber,currentfileinfo); + } +// } +// preerror(buf); +} + +void warcompneqconst() +{ + warningprint("Comparison not equal constant. Skipped code",linenumber,currentfileinfo); +} + +void warcompeqconst() +{ + warningprint("Comparison equal constant. Skipped compare",linenumber,currentfileinfo); +} + +void warpointerstruct() +{ + warningprint("Compiler not support pointers on structure",linenumber,currentfileinfo); +} + +void warESP() +{ + warningprint("ESP has ambiguous value",linenumber,currentfileinfo); +} + +/* ***************** map file *************** */ + +void OpenMapFile() +{ +char buf[256]; + sprintf(buf,"%s.map",rawfilename); + hmap=fopen(buf,"w+t"); +} + +char *GetRetType(int type,int flag) +{ +char *retcode; + if(flag&f_interrupt)return ""; + switch(type){ + case tk_bytevar: + case tk_byte: + retcode="byte "; + break; + case tk_charvar: + case tk_char: + retcode="char "; + break; + case tk_wordvar: + case tk_word: + retcode="word "; + break; + case tk_longvar: + case tk_long: + retcode="long "; + break; + case tk_dwordvar: + case tk_dword: + retcode="dword "; + break; + case tk_doublevar: + case tk_double: + retcode="double "; + break; + case tk_fpust: + retcode="fpust "; + break; + case tk_floatvar: + case tk_float: + retcode="float "; + break; + case tk_qwordvar: + case tk_qword: + retcode="qword "; + break; + case tk_void: + retcode="void "; + break; +/* case tk_intvar: + case tk_int: + retcode="int "; + break;*/ + case tk_structvar: + retcode="struct"; + break; + default: + retcode="int "; + break; + } + return retcode;; +} + +char *GetTypeProc(int flag) +{ +char *retcode; +char *t; + string2[0]=0; + if(flag&f_interrupt)return "interrupt"; + if(flag&f_far)strcat((char *)string2,"far "); + if(flag&f_extern)strcat((char *)string2,"extern "); + if(flag&f_export)strcat((char *)string2,"_export "); + if(flag&f_inline)strcat((char *)string2,"inline "); + if(flag&f_static)strcat((char *)string2,"static "); + if(flag&f_retproc){ + t=""; + switch(((flag&f_retproc)>>8)+tk_overflowflag-1){ + case tk_overflowflag: + t="OVERFLOW "; + break; + case tk_notoverflowflag: + t="NOTOVERFLOW "; + break; + case tk_carryflag: + t="CARRYFLAG "; + break; + case tk_notcarryflag: + t="NOTCARRYFLAG "; + break; + case tk_zeroflag: + t="ZEROFLAG "; + break; + case tk_notzeroflag: + t="NOTZEROFLAG "; + break; + case tk_minusflag: + t="MINUSFLAG "; + break; + case tk_plusflag: + t="PLUSFLAG "; + break; + } + strcat((char *)string2,t); + } + switch(flag&f_typeproc){ + case tp_pascal: + t="pascal "; + break; + case tp_cdecl: + t="cdecl "; + break; + case tp_stdcall: + t="stdcall "; + break; + case tp_fastcall: + t="fastcall "; + break; + } + strcat((char *)string2,t); + return (char *)string2; +} + +char *GetFunParam(unsigned char c,unsigned char c2,unsigned char c3) +{ + switch(c){ + case 'B': + if(c2>=0x30&&c2<=0x37)return begs[c2-0x30]; + return "byte"; + case 'W': + if(c2>=0x30&&c2<=0x37)return regs[0][c2-0x30]; + return "word"; + case 'D': + if(c2>=0x30&&c2<=0x37)return regs[1][c2-0x30]; + return "dword"; + case 'C': return "char"; + case 'I': return "int"; + case 'L': return "long"; + case 'F': return "float"; + case 'A': return "..."; + case 'Q': + if(c2>=0x30&&c2<=0x37){ + sprintf((char *)string2,"%s:%s",regs[1][c2-0x30],regs[1][c3-0x30]); + return (char *)string2; + } + return "qword"; + case 'E': return "double"; + case 'S': + if(c2>=0x30&&c2<=0x37){ + sprintf((char *)string2,"st(%c)",c2); + return (char *)string2; + } + return "fpust"; + case 'T': return "struct"; + case 'U': return "void"; + } + return "";; +} + +char *GetName(char *name,int flag) +{ +char *tn; +char iname[IDLENGTH]; + strcpy(iname,name); + if((tn=strchr(iname,'@'))!=NULL)*tn=0; + if(flag&fs_constructor)sprintf((char *)string3,"%s::%s",iname,iname); + else if(flag&fs_destructor)sprintf((char *)string3,"%s::~%s",iname,iname); + else if(flag&f_classproc)sprintf((char *)string3,"%s::%s",searchteg->name,iname); + else strcpy((char *)string3,iname); + return (char *)string3; +} + +char *GetSizeVar(int type,int adr) +{ +char *reg; +char *sign; + if(type==tp_postvar||type==tp_gvar)return "DS:???"; + if(am32){ + if(ESPloc)reg="ESP"; + else reg="EBP"; + } + else reg="BP"; + if(adr<0)sign=""; + else sign="+"; + sprintf((char *)string2,"%s%s%d",reg,sign,adr); + return (char *)string2; +} + +void GetRangeUsed(char *buf,localinfo *ptr) +{ + if(ptr->count==0)buf[0]=0; + else if(ptr->count==1)sprintf(buf,"%d",ptr->usedfirst); + else sprintf(buf,"%d-%d",ptr->usedfirst,ptr->usedlast); +} + +void mapfun(int line) +{ +treelocalrec *ftlr; +struct localrec *ptr; +int i,fheader; +char buf[32]; + if(hmap==NULL)OpenMapFile(); + if(hmap){ + fprintf(hmap,"\n%s%s%s(",GetTypeProc(itok.flag),GetRetType(itok.rm,itok.flag),GetName(itok.name,itok.flag)); + for(i=0;;i++){ + unsigned char c=string[i]; + if(c==0)break; + if(c>=0x30&&c<=0x37)continue; + if(i)fputc(',',hmap); + unsigned char c2=string[i+1]; + unsigned char c3=string[i+2]; + fputs(GetFunParam(c,c2,c3),hmap); + } + fputc(')',hmap); + fprintf(hmap,"\nlocation: line %d-%d file %s",line,linenumber,startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename); + fprintf(hmap,"\noffset=0x%X(%d)\tsize=0x%X(%d)",itok.number,itok.number,itok.size,itok.size); + } + fheader=0; + for(ftlr=btlr;ftlr!=NULL;ftlr=ftlr->next){ + for(ptr=ftlr->lrec;ptr!=NULL;ptr=ptr->rec.next){ + i=ptr->rec.type; + if(i==tp_postvar||i==tp_gvar||i==tp_localvar||i==tp_paramvar){ + if(!fheader){ + fputs("\nType Address Used Count Size Name",hmap); + fputs("\n----------------------------------------------",hmap); + fheader=TRUE; + } + GetRangeUsed(buf,&ptr->li); + fprintf(hmap,"\n%-8s%-10s%-12s%-4d%-8d",GetRetType(ptr->rec.rectok,0),GetSizeVar(ptr->rec.type,ptr->rec.recnumber),buf,ptr->li.count,ptr->rec.recsize); + if(ptr->rec.npointr)for(i=ptr->rec.npointr;i>0;i--)fputc('*',hmap); + fputs(ptr->rec.recid,hmap); + } + } + } + fputs("\n",hmap); +} + diff --git a/programs/develop/cmm/id.h b/programs/develop/cmm/id.h new file mode 100644 index 0000000000..94e12006bc --- /dev/null +++ b/programs/develop/cmm/id.h @@ -0,0 +1,136 @@ +/* 䠩 ᣥ஢ ணࠬ 'FASTLIST.EXE' */ + +short idofs[53]={ + 0xFFFF,0x0000, //A B + 0x0009,0xFFFF, //C D + 0x0026,0x0037, //E F + 0x0044,0xFFFF, //G H + 0x004C,0xFFFF, //I J + 0xFFFF,0x0052, //K L + 0x005C,0x0069, //M N + 0x0093,0x009F, //O P + 0xFFFF,0x00AB, //Q R + 0x00B5,0xFFFF, //S T + 0xFFFF,0xFFFF, //U V + 0x00BF,0xFFFF, //W X + 0xFFFF,0x00C8, //Y Z + 0x00D4,0x011A, //_ a + 0x0121,0x0130, //b c + 0x014F,0x0175, //d e + 0x018B,0x01A8, //f g + 0xFFFF,0x01B0, //h i + 0xFFFF,0xFFFF, //j k + 0x01CE,0xFFFF, //l m + 0x01E4,0xFFFF, //n o + 0x01EB,0x01F5, //p q + 0x01FE,0x0208, //r s + 0xFFFF,0x0242, //t u + 0x0255,0x025D, //v w + 0xFFFF,0xFFFF, //x y + 0xFFFF}; //z + +unsigned char id[]={ + 0x7A,0x00,0x52,0x45,0x41,0x4B,0, // BREAK + 0xFF,0xFF, // end char 'B' + 0x6A,0x00,0x41,0x52,0x52,0x59,0x46,0x4C,0x41,0x47,0, // CARRYFLAG + 0xA3,0x00,0x41,0x53,0x45,0, // CASE + 0x7C,0x00,0x4F,0x4E,0x54,0x49,0x4E,0x55,0x45,0, // CONTINUE + 0xFF,0xFF, // end char 'C' + 0x47,0x00,0x4C,0x53,0x45,0, // ELSE + 0x4D,0x00,0x58,0x54,0x52,0x41,0x43,0x54,0, // EXTRACT + 0xFF,0xFF, // end char 'E' + 0x7F,0x00,0x4F,0x52,0, // FOR + 0x4C,0x00,0x52,0x4F,0x4D,0, // FROM + 0xFF,0xFF, // end char 'F' + 0x78,0x00,0x4F,0x54,0x4F,0, // GOTO + 0xFF,0xFF, // end char 'G' + 0x45,0x00,0x46,0, // IF + 0xFF,0xFF, // end char 'I' + 0x9A,0x00,0x4F,0x4F,0x50,0x4E,0x5A,0, // LOOPNZ + 0xFF,0xFF, // end char 'L' + 0x70,0x00,0x49,0x4E,0x55,0x53,0x46,0x4C,0x41,0x47,0, // MINUSFLAG + 0xFF,0xFF, // end char 'M' + 0x6B,0x00,0x4F,0x54,0x43,0x41,0x52,0x52,0x59,0x46,0x4C,0x41,0x47,0, // NOTCARRYFLAG + 0x69,0x00,0x4F,0x54,0x4F,0x56,0x45,0x52,0x46,0x4C,0x4F,0x57,0, // NOTOVERFLOW + 0x6D,0x00,0x4F,0x54,0x5A,0x45,0x52,0x4F,0x46,0x4C,0x41,0x47,0, // NOTZEROFLAG + 0xFF,0xFF, // end char 'N' + 0x68,0x00,0x56,0x45,0x52,0x46,0x4C,0x4F,0x57,0, // OVERFLOW + 0xFF,0xFF, // end char 'O' + 0x71,0x00,0x4C,0x55,0x53,0x46,0x4C,0x41,0x47,0, // PLUSFLAG + 0xFF,0xFF, // end char 'P' + 0x72,0x00,0x45,0x54,0x55,0x52,0x4E,0, // RETURN + 0xFF,0xFF, // end char 'R' + 0xA2,0x00,0x57,0x49,0x54,0x43,0x48,0, // SWITCH + 0xFF,0xFF, // end char 'S' + 0x7E,0x00,0x48,0x49,0x4C,0x45,0, // WHILE + 0xFF,0xFF, // end char 'W' + 0x6C,0x00,0x45,0x52,0x4F,0x46,0x4C,0x41,0x47,0, // ZEROFLAG + 0xFF,0xFF, // end char 'Z' + 0x74,0x00,0x5F,0x43,0x4F,0x44,0x45,0x50,0x54,0x52,0x5F,0x5F,0, // __CODEPTR__ + 0x73,0x00,0x5F,0x44,0x41,0x54,0x41,0x50,0x54,0x52,0x5F,0x5F,0, // __DATAPTR__ + 0xA0,0x00,0x5F,0x46,0x49,0x4C,0x45,0x5F,0x5F,0, // __FILE__ + 0xA1,0x00,0x5F,0x4C,0x49,0x4E,0x45,0x5F,0x5F,0, // __LINE__ + 0x75,0x00,0x5F,0x50,0x4F,0x53,0x54,0x50,0x54,0x52,0x5F,0x5F,0, // __POSTPTR__ + 0x98,0x00,0x65,0x78,0x70,0x6F,0x72,0x74,0, // _export + 0xFF,0xFF, // end char '_' + 0x81,0x00,0x73,0x6D,0, // asm + 0xFF,0xFF, // end char 'a' + 0x7B,0x00,0x72,0x65,0x61,0x6B,0, // break + 0x3C,0x00,0x79,0x74,0x65,0, // byte + 0xFF,0xFF, // end char 'b' + 0x83,0x00,0x61,0x73,0x65,0, // case + 0x94,0x00,0x64,0x65,0x63,0x6C,0, // cdecl + 0x3B,0x00,0x68,0x61,0x72,0, // char + 0x7D,0x00,0x6F,0x6E,0x74,0x69,0x6E,0x75,0x65,0, // continue + 0xFF,0xFF, // end char 'c' + 0x84,0x00,0x65,0x66,0x61,0x75,0x6C,0x74,0, // default + 0xAC,0x00,0x65,0x6C,0x65,0x74,0x65,0, // delete + 0x49,0x00,0x6F,0, // do + 0x43,0x00,0x6F,0x75,0x62,0x6C,0x65,0, // double + 0x40,0x00,0x77,0x6F,0x72,0x64,0, // dword + 0xFF,0xFF, // end char 'd' + 0x46,0x00,0x6C,0x73,0x65,0, // else + 0x50,0x00,0x6E,0x75,0x6D,0, // enum + 0x91,0x00,0x78,0x74,0x65,0x72,0x6E,0, // extern + 0xFF,0xFF, // end char 'e' + 0x4F,0x00,0x61,0x72,0, // far + 0x96,0x00,0x61,0x73,0x74,0x63,0x61,0x6C,0x6C,0, // fastcall + 0x41,0x00,0x6C,0x6F,0x61,0x74,0, // float + 0x80,0x00,0x6F,0x72,0, // for + 0xFF,0xFF, // end char 'f' + 0x79,0x00,0x6F,0x74,0x6F,0, // goto + 0xFF,0xFF, // end char 'g' + 0x44,0x00,0x66,0, // if + 0x77,0x00,0x6E,0x6C,0x69,0x6E,0x65,0, // inline + 0x3D,0x00,0x6E,0x74,0, // int + 0x4E,0x00,0x6E,0x74,0x65,0x72,0x72,0x75,0x70,0x74,0, // interrupt + 0xFF,0xFF, // end char 'i' + 0x3F,0x00,0x6F,0x6E,0x67,0, // long + 0x48,0x00,0x6F,0x6F,0x70,0, // loop + 0x9B,0x00,0x6F,0x6F,0x70,0x6E,0x7A,0, // loopnz + 0xFF,0xFF, // end char 'l' + 0xAB,0x00,0x65,0x77,0, // new + 0xFF,0xFF, // end char 'n' + 0x93,0x00,0x61,0x73,0x63,0x61,0x6C,0, // pascal + 0xFF,0xFF, // end char 'p' + 0x42,0x00,0x77,0x6F,0x72,0x64,0, // qword + 0xFF,0xFF, // end char 'q' + 0x4B,0x00,0x65,0x74,0x75,0x72,0x6E,0, // return + 0xFF,0xFF, // end char 'r' + 0x9D,0x00,0x68,0x6F,0x72,0x74,0, // short + 0x9F,0x00,0x69,0x67,0x6E,0x65,0x64,0, // signed + 0x8B,0x00,0x69,0x7A,0x65,0x6F,0x66,0, // sizeof + 0xA6,0x00,0x74,0x61,0x74,0x69,0x63,0, // static + 0x95,0x00,0x74,0x64,0x63,0x61,0x6C,0x6C,0, // stdcall + 0x89,0x00,0x74,0x72,0x75,0x63,0x74,0, // struct + 0x82,0x00,0x77,0x69,0x74,0x63,0x68,0, // switch + 0xFF,0xFF, // end char 's' + 0x97,0x00,0x6E,0x69,0x6F,0x6E,0, // union + 0x9E,0x00,0x6E,0x73,0x69,0x67,0x6E,0x65,0x64,0, // unsigned + 0xFF,0xFF, // end char 'u' + 0x3A,0x00,0x6F,0x69,0x64,0, // void + 0xFF,0xFF, // end char 'v' + 0x4A,0x00,0x68,0x69,0x6C,0x65,0, // while + 0x3E,0x00,0x6F,0x72,0x64,0, // word + 0xFF,0xFF // end char 'w' +}; diff --git a/programs/develop/cmm/le.h b/programs/develop/cmm/le.h new file mode 100644 index 0000000000..c2fa3c7f36 --- /dev/null +++ b/programs/develop/cmm/le.h @@ -0,0 +1,228 @@ +/***************************************************************************** +;* * +;* This structure define format of LE header for OS/2,Windows exe files * +;* ---------------------------------------------------------- * +;* * +;* Author Trigub Serge. B&M&T Corp. * +;* 10 January 1993 * +;* * +;*****************************************************************************/ + +enum CPU_Type +{ + i80286 =0x01, + i80386 =0x02, + i80486 =0x03, + i80586 =0x04, + i860_N10 =0x20, + i860_N11 =0x21, + MIPS_Mark_I =0x40, + MIPS_Mark_II =0x41, + MIPS_Mark_III=0x42 +}; + +struct Module_Type_Flags +{ + unsigned long Module_Is_DLL [1]; + unsigned long Reserved1 [1]; + unsigned long Errors_In_Module [1]; + unsigned long Reserved2 [1]; + unsigned long Code_Load_Application[1]; + unsigned long Application_Type [3]; + + unsigned long Reserved3 [2]; + unsigned long No_External_FIXUP [1]; + unsigned long No_Internal_FIXUP [1]; + unsigned long Protected_Mode_Only [1]; + unsigned long Global_Initialization[1]; + unsigned long Multipledata [1]; + unsigned long Singledata [1]; +}; + +struct LE_Header +{ + unsigned short Signature; // Signature 'LE' for exe header + unsigned char Byte_Order; + unsigned char Word_Order; + unsigned long Exec_Format_Level; + unsigned short CPU_Type; + unsigned short Target_OS; + unsigned long Module_Version; + union{ + unsigned long Type_Flags; + Module_Type_Flags Flags; + }; + unsigned long Number_Of_Memory_Pages; + unsigned long Initial_CS; + unsigned long Initial_EI; + unsigned long Initial_SS; + unsigned long Initial_ESP; + unsigned long Memory_Page_Size; + unsigned long Bytes_On_Last_Page; + unsigned long Fixup_Section_Size; + unsigned long Fixup_Section_Checksum; + unsigned long Loader_Section_Size; + unsigned long Loader_Section_CheckSum; + unsigned long Object_Table_Offset; + unsigned long Object_Table_Entries; + unsigned long Object_Page_Map_Table_Offset; + unsigned long Object_Iterate_Data_Map_Offset; + unsigned long Resource_Table_Offset; + unsigned long Resource_Table_Entries; + unsigned long Resident_Names_Table_Offset; + unsigned long Entry_Table_Offset; + unsigned long Module_Directives_Table_Offset; + unsigned long Module_Directives_Table_Entries; + unsigned long Fixup_Page_Table_Offset; + unsigned long Fixup_Record_Table_Offset; + unsigned long Imported_Module_Names_Table_Offset; + unsigned long Imported_Modules_Count; + unsigned long Imported_Procedure_Name_Table_Offset; + unsigned long Per_page_Checksum_Table_Offset; + unsigned long Data_Pages_Offset; + unsigned long Preload_Page_Count; + unsigned long Nonresident_Names_Table_Offset; + unsigned long Nonresident_Names_Table_Length; + unsigned long Nonresident_Names_Table_Checksum; + unsigned long Automatic_Data_Object; + unsigned long Debug_Information_Offset; + unsigned long Debug_Information_Length; + unsigned long Preload_Instance_Pages_Number; + unsigned long Demand_Instance_Pages_Number; + unsigned long Extra_Heap_Allocation; + unsigned long Unknown[1]; +}; + +struct OBJ_FLAGS +{ + unsigned long I_O_Privilage_Level [1]; + unsigned long Conforming_Segment [1]; + unsigned long BIG_Segment [1]; + unsigned long Alias_16_16 [1]; + unsigned long Reserved [1]; + unsigned long Resident_Long_Locable[1]; + unsigned long Segment_Type [2]; + unsigned long Segment_Invalid [1]; + unsigned long Segment_Preloaded [1]; + unsigned long Segment_Shared [1]; + unsigned long Segment_Discardable [1]; + unsigned long Segment_Resource [1]; + unsigned long Segment_Executable [1]; + unsigned long Segment_Writable [1]; + unsigned long Segment_Readable [1]; +}; + +struct Object_Table +{ + unsigned long Virtual_Segment_Size; + unsigned long Relocation_Base_Address; + union { + unsigned long ObjTableFlags; + OBJ_FLAGS FLAGS; + }; + unsigned long Page_MAP_Index; + unsigned long Page_MAP_Entries; + unsigned long Reserved; +}; + + +enum { + Segment_Type_Normal, + Segment_Zero_Filled, + Segment_Resident, + Segment_Resident_contiguous +}; + +struct PM_FLAGS +{ + unsigned char Page_Type:2; + unsigned char Reserved :6; + unsigned char End_Page :2; +}; + +struct Page_Map_Table +{ + unsigned short High_Page_Number; + unsigned char Low_Page_Number; +// union{ +// PM_FLAGS SFLAGS; + unsigned char FLAGS; +// }; +}; + +enum{//LE_PM_FLG_Page_Type_Enum ENUM { + Legal_Page =0, + Iterated_Page =1, + Invalid_Page =2, + Zero_Filled_Page=3 +}; + +struct Entry_Table +{ + unsigned char Number_of_Entries; + unsigned char Bungle_Flags; + unsigned short Object_Index; +//LE_Entry_First_Entry equ $ +}; + +struct Entry +{ + unsigned char Entry_Flags; + union{ + unsigned short Word_Offset; + unsigned long Dword_Offset; + }; +}; + +struct Entry_Bungle_Flags +{ + unsigned char Bits_Entry :1; + unsigned char Valid_Entry:1; +}; + +struct Fixup_Record_Table +{ + unsigned char Relocation_Address_Type; + unsigned char Relocation_Type; + unsigned short Relocation_Page_Offset; + unsigned char Segment_or_Module_Index; + unsigned short Offset_Or_Ordinal_Value; +}; + +struct Rel_Addr_Type +{ + unsigned char Repeat_Offset :1; + unsigned char Target_OFFSET_Absent:1; + unsigned char Rel_Addr_Type [4]; +}; + +enum// LE_Relocation_Address_Type_ENUM +{ +RA_Low_Byte =0, +RA_16_bits_selector =2, +RA_32_bits_Far_Pointer=3, +RA_16_bits_Offset =5, +RA_48_bits_Far_Pointer=6, +RA_32_bits_Offset =7, +RA_32_bits_EIP_Rel =8 +}; + +struct Reloc_Type +{ + unsigned char Ordinal_Byte :1; + unsigned char Reserv1 :1; + unsigned char ABS_Dword :1; + unsigned char Target_Offset_32:1; + unsigned char Reserv2 :1; + unsigned char ADDITIVE_Type :1; + unsigned char Reloc_Type [2]; +}; + +enum //LE_Relocation_Type_ENUM +{ + Internal_Reference=0, + Imported_Ordinal =1, + Imported_Name =2, + OS_FIXUP =3 +}; + diff --git a/programs/develop/cmm/libobj.cpp b/programs/develop/cmm/libobj.cpp new file mode 100644 index 0000000000..4b01fb1b86 --- /dev/null +++ b/programs/develop/cmm/libobj.cpp @@ -0,0 +1,534 @@ +#include "tok.h" +#include "coff.h" + +char *meserr="Plese, send this obj and sources files to me (sheker@mail.ru)"; +struct LISTINCLFILE{ + char *name; + int typefind; + int type; +}; + +enum{ + s_extern, + s_code, + s_data, + s_bss +}; + +struct LISTNAMESYMBOL{ + int idx; // + int seg; + int adr; + idrec *rec; + int dbg; + char name[IDLENGTH]; +}*listnamesymbol; + +char *curobjname; + +int numobj=0,numname; +LISTINCLFILE *listobj; +unsigned int adr_end; + +void LoadObj(); +void AddPost(unsigned long loc,int type,unsigned int num); +int searchtree2(idrec *fptr,ITOK *itok4,int *tok4,unsigned char *string4); + +int GetSegm(int seg) +{ +OBJECT_ENTRY *obj; + if(seg){ + seg--; + obj=(OBJECT_ENTRY *)(input+(sizeof(COFF_HEADER)+sizeof(OBJECT_ENTRY)*seg)); + seg=obj->vsize; + } + return seg; +} + +int GetOffSec(int seg) +{ +OBJECT_ENTRY *obj; + if(seg){ + seg--; + obj=(OBJECT_ENTRY *)(input+(sizeof(COFF_HEADER)+sizeof(OBJECT_ENTRY)*seg)); + seg=obj->sectionRVA; + } + return seg; +} + +void AddNameObj(char *name,int typefind,int type) +{ +int len; + len=strlen(name); + if(!numobj)listobj=(LISTINCLFILE *)MALLOC(sizeof(LISTINCLFILE)); + else listobj=(LISTINCLFILE *)REALLOC(listobj,sizeof(LISTINCLFILE)*(numobj+1)); + (listobj+numobj)->name=BackString(name); + (listobj+numobj)->typefind=typefind; + (listobj+numobj)->type=type; + numobj++; +} + +void AddObj() +{ +int hold; + for(int i=0;iname; +// puts(curobjname); + hold=loadfile(curobjname,(listobj+i)->typefind); + if(hold==1||hold==-1){ + unableopenfile(curobjname); + continue; + } + if((listobj+i)->type==0)LoadObj(); + free(input); + } +} + +int GetAlighSize(long flag) +{ +int align=0; + int i=(flag&IMAGE_SCN_ALIGN_MASK)>>20; + if(i)align=1<<(i-1); + if(align==1)align=0; + return align; +} + +void ConvertName(char *name) +{ +int i1,i2; +char c; + tok=tk_ID; + i1=i2=0; + c=name[i1]; + if(c=='?'){ + i1++; + c=name[i1]; + if(c=='?'){ + i1=2; + c=name[i1]; + } + } + else if(c=='_'){ + if(strncmp(name,"__imp__",7)==0){ + i1=7; + c=name[i1]; + } + else if(name[1]=='$'){ + i1=2; + c=name[i1]; + } + } + while(c!=0){ + if(c>='a'&&c<='z')tok=tk_id; + name[i2]=c; + i1++; + i2++; + c=name[i1]; + if(c=='@'||c=='$')break; + } + name[i2]=0; +} + +void AddPost(unsigned long loc,int type,unsigned int num) +{ + CheckPosts(); + (postbuf+posts)->num=num; + (postbuf+posts)->type=type; + (postbuf+posts)->loc=loc; + posts++; +} + +void ScanSection(int numobj) +{ +int poutptr,poutptrdata,ppostsize,align; +OBJECT_ENTRY *obj; +long flag; + poutptr=outptr; + poutptrdata=outptrdata; + ppostsize=postsize; + for(int i=0;iflags; + align=GetAlighSize(flag); + obj->vsize=-1; + if((flag&IMAGE_SCN_CNT_CODE)&&(flag&IMAGE_SCN_MEM_EXECUTE)){//ᥪ + obj->vsize=s_code; + obj->sectionRVA=poutptr=Align(poutptr,align); + poutptr+=obj->psize; + if(splitdata==FALSE)poutptrdata=poutptr; + } + else{ + if((flag&IMAGE_SCN_MEM_READ)&&(flag&IMAGE_SCN_MEM_WRITE)){ + if(flag&IMAGE_SCN_CNT_INITIALIZED_DATA){ //ᥪ 樠஢ + obj->vsize=s_data; + obj->sectionRVA=poutptrdata=Align(poutptrdata,align); + poutptrdata+=obj->psize; + if(splitdata==FALSE)poutptr=poutptrdata; + } + else if(flag&IMAGE_SCN_CNT_UNINITIALIZED_DATA){ //ᥪ bss + obj->vsize=s_bss; + obj->sectionRVA=ppostsize=Align(postsize,align); + postsize+=obj->psize; + } + } + } + } +} + +void AddLstName(int numname) +{ +unsigned int minofs; +int i,j,minname; +int oseg; +unsigned int ooutptr,ooutptrdata; + ooutptr=outptr; + ooutptrdata=outptrdata; + for(i=0;idbg==0){ + oseg=(listnamesymbol+i)->seg; + minofs=(listnamesymbol+i)->adr; + minname=i; + for(j=i+1;jseg==oseg){ +checkadr: + if(minofs>=(listnamesymbol+j)->adr&&(listnamesymbol+j)->dbg==0){ + if(minofs==(listnamesymbol+j)->adr){ + (listnamesymbol+minname)->dbg=1; + } + minofs=(listnamesymbol+j)->adr; + minname=j; + oseg=(listnamesymbol+j)->seg; + } + } + } + if(minname!=i)i--; +// printf("seg=%d adr=%d %s\n",oseg,(listnamesymbol+minname)->adr,(listnamesymbol+minname)->name); + if(oseg==s_code){ + if((listnamesymbol+minname)->rec){ + idrec *ptr; + ptr=(listnamesymbol+minname)->rec; + if(ptr->rectok==tk_undefproc||ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)goto dproc; + outptrdata=(listnamesymbol+minname)->adr; + if(splitdata==FALSE)outptr=outptrdata; + AddDataNullLine(3,(listnamesymbol+minname)->name); + } + else{ +dproc: + outptr=(listnamesymbol+minname)->adr;//12.08.04 00:05 +ooutptr; + AddCodeNullLine((listnamesymbol+minname)->name); + } + } + else if(oseg==s_data){ + outptrdata=(listnamesymbol+minname)->adr;//12.08.04 01:19 +ooutptrdata; + if(splitdata==FALSE)outptr=outptrdata; + AddDataNullLine(3,(listnamesymbol+minname)->name); + } + (listnamesymbol+minname)->dbg=1; + } + } + outptr=ooutptr; + outptrdata=ooutptrdata; +} + +int ScanName(COFF_HEADER *head) +{ +int size,i,j,numname,seg,count; +IMAGE_SYMBOL *tsym; +unsigned int ooutptr,ooutptrdata,opostsize; +idrec *rec; + ooutptr=outptr; + ooutptrdata=outptrdata; + opostsize=postsize; + numname=head->COFFsize; + size=numname*sizeof(IMAGE_SYMBOL)+head->pCOFF; + listnamesymbol=(LISTNAMESYMBOL *)MALLOC(sizeof(LISTNAMESYMBOL)*numname); + for(i=0,j=0;ipCOFF+i*sizeof(IMAGE_SYMBOL)); + (listnamesymbol+j)->rec=0; + if(tsym->SectionNumber>=0){ + (listnamesymbol+j)->idx=i; + if(tsym->N.Name.Short==0){ + strcpy((char *)string,(char *)(input+size+tsym->N.Name.Long)); + } + else{ + strncpy((char *)string,(char *)tsym->N.sname,8); + string[8]=0; + } + //८ࠧ + ConvertName((char *)string); + seg=(listnamesymbol+j)->seg=GetSegm(tsym->SectionNumber); +// printf("find name \"%s\" seg=%d type=%d class=%d\n",(char *)string,seg,tsym->Type,tsym->StorageClass); + (listnamesymbol+j)->adr=tsym->Value+GetOffSec(tsym->SectionNumber); + (listnamesymbol+j)->dbg=0; + strcpy((listnamesymbol+j)->name,(char *)string); + if(seg==s_data){ + outptrdata=(listnamesymbol+j)->adr;//12.08.04 01:20 +ooutptrdata; + count=FindOff(string,DS); + } + else if(seg==s_bss){ + postsize=(listnamesymbol+j)->adr;//12.08.04 01:20 +opostsize; + count=FindOff(string,VARPOST); + } + else if(seg==s_code){ + outptr=(listnamesymbol+j)->adr;//11.08.04 23:59 +ooutptr; + count=FindOff(string,CS); +// printf("adr=%08X count=%d\n",outptr,count); + } + displaytokerrors=FALSE; + if(searchtree2(treestart,&itok,&tok,string)){ + rec=(listnamesymbol+j)->rec=itok.rec; + rec->count+=count; + if(tok==tk_undefproc||tok==tk_declare){ + tok=tk_proc; + itok.number=outptr; +// printf("%08X %08X %s\n",(listnamesymbol+j)->adr,ooutptr,itok.name); + updatecall(updatetree(),(unsigned int)itok.number,0); + } + else if(tok!=tk_apiproc&&tsym->SectionNumber!=0)idalreadydefined(); +// if(tok==tk_proc||(tok>=tk_charvar&&tok<=tk_floatvar)) +// printf("tok=%d %s\n",tok,itok.name); + } + else{ + if(seg==s_extern/*&&tsym->Type==32*/){ //譨 ꥪ  ⨯ + strcpy(itok.name,(char *)string); +// printf("undef proc \"%s\"\n",itok.name); + string[0]=0; + itok.flag=(unsigned char)(tok==tk_ID?tp_fastcall:(comfile==file_w32?tp_stdcall:tp_pascal)); + tok=tk_undefproc; + itok.number=secondcallnum; + itok.segm=NOT_DYNAMIC; + itok.rm=tk_void; + itok.post=0; + rec=(listnamesymbol+j)->rec=addtotree(itok.name); + rec->count=count; + secondcallnum++; + } + else{ +// printf("type=%d seg=%d\n",tsym->Type,seg); + if(/*tsym->Type==32*/tsym->StorageClass!=3&&seg==s_code){ + tok=tk_proc; + itok.number=outptr; + itok.segm=NOT_DYNAMIC; + itok.rm=tk_void; + itok.post=0; + strcpy(itok.name,(char *)string); + string[0]=0; + itok.flag=(unsigned char)(tok==tk_ID?tp_fastcall:(comfile==file_w32?tp_stdcall:tp_pascal)); + rec=(listnamesymbol+j)->rec=addtotree(itok.name); + rec->count=count; + } + else{ + (listnamesymbol+j)->rec=NULL; +// printf("undef \"%s\"\n",string); + if(seg==s_extern){ +// puts("323"); + preerror(meserr); +// printf("Type=%d Class=%d seg=%d %s\n",tsym->Type,tsym->StorageClass,seg,string); +// printf("??? %s\n",string); + } + } + } + } +// printf("Type=%d Class=%d %s\n",tsym->Type,tsym->StorageClass,string); + j++; + } + i+=tsym->NumberOfAuxSymbols; + } + if(j!=numname){ + listnamesymbol=(LISTNAMESYMBOL *)REALLOC(listnamesymbol,sizeof(LISTNAMESYMBOL)*j); + } + outptr=ooutptr; + outptrdata=ooutptrdata; + postsize=opostsize; + if(dbg&2)AddLstName(j); + return j; +} + +void LoadObj() +{ +COFF_HEADER *head; +int numobj,align,size,i,j,numrel; +OBJECT_ENTRY *obj; +unsigned char *buf; +IMAGE_RELOCATION *trel; + head=(COFF_HEADER *)input; + if(head->cpu!=0x14C){ + sprintf((char *)string,"file %s is not supported format",curobjname); + preerror((char *)string); + return; + } + if(comfile!=file_w32){ + preerror("include obj file posible only for windows programs"); + return; + } + linenumber=0; + numobj=head->numobj; + ScanSection(numobj); + numname=ScanName(head); + for(i=0;iflags); + size=obj->psize; + adr_end=outptr+size; + numrel=obj->NumberOfRelocations; + trel=(IMAGE_RELOCATION *)(input+obj->PointerToRelocations); + buf=(unsigned char *)(input+obj->pOffset); +// printf("type=%d section=%d\n",(trel+j)->Type,obj->vsize); + switch(obj->vsize){ + case s_code: + if(align)AlignCD(CS,align); + adr_end=Align(outptr+size,4); + for(j=0;jidx==(trel+j)->SymbolTableIndex)break; + } + lns=(LISTNAMESYMBOL *)(listnamesymbol+ii); + idrec *rec=lns->rec; +// printf("type=%d seg=%d tok=%d num=%d %s\n",(trel+j)->Type,lns->seg,rec->rectok,rec->recnumber,lns->name); + switch((trel+j)->Type){ + case IMAGE_REL_I386_DIR32: + *(long *)&buf[(trel+j)->VirtualAddress]+=lns->adr; + switch(lns->seg){ + case s_code: + adr=(trel+j)->VirtualAddress+outptr; + AddPost(adr,FIX_CODE32,0); + break; + case s_data: + adr=(trel+j)->VirtualAddress+outptrdata; + AddPost(adr,FIX_VAR32,0); + break; + case s_bss: + adr=(trel+j)->VirtualAddress+outptr; + AddPost(adr,POST_VAR32,0); + *(long *)&buf[(trel+j)->VirtualAddress]+=postsize; + break; + default: + if(rec!=NULL){ + adr=(trel+j)->VirtualAddress+outptr; + if(rec->rectok==tk_apiproc){ + AddPost(adr,CALL_32I,rec->recnumber); + } + else if(rec->rectok==tk_undefproc){ + AddPost(adr,CALL_32,rec->recnumber); + } + else if(rec->rectok==tk_proc){ + AddPost(adr,FIX_CODE_ADD,adr_end); + AddPost(adr_end,FIX_CODE32,0); + if(dbg&2){ + int ooutptr=outptr; + outptr=adr_end; + AddDataNullLine(4,lns->name); + outptr=ooutptr; + } + *(long *)&output[adr_end]=rec->recnumber; + adr_end+=4; + } + rec->count++; + } + break; + } + break; + case IMAGE_REL_I386_REL32: + adr=(trel+j)->VirtualAddress+outptr; + if(rec!=NULL){ + if(rec->rectok!=tk_proc){ + AddPost(adr,CALL_32,rec->recnumber); + } + else{ + *(long *)&buf[(trel+j)->VirtualAddress]=rec->recnumber-adr-4; + } + } + else{ + *(long *)&buf[(trel+j)->VirtualAddress]=lns->adr-adr-4; + } + if(rec)rec->count++; + break; + default: +// puts("432"); + preerror(meserr); + break; + } + } +/* if(dbg&2){ + sprintf((char *)string,"code from %s",curobjname); + AddCodeNullLine((char *)string); + }*/ + for(j=0;jidx==(trel+j)->SymbolTableIndex)break; + } + lns=(LISTNAMESYMBOL *)(listnamesymbol+ii); + idrec *rec=lns->rec; + switch((trel+j)->Type){ + case IMAGE_REL_I386_DIR32: + *(long *)&buf[(trel+j)->VirtualAddress]+=lns->adr; + switch(lns->seg){ + case s_code: + adr=(trel+j)->VirtualAddress+outptr; + AddPost(adr,FIX_CODE32,0); + break; + case s_data: + adr=(trel+j)->VirtualAddress+outptrdata; + AddPost(adr,FIX_VAR32,0); + break; + case s_bss: + adr=(trel+j)->VirtualAddress+outptr; + AddPost(adr,POST_VAR32,0); + *(long *)&buf[(trel+j)->VirtualAddress]+=postsize; + break; + default: +// puts("472"); + preerror(meserr); +/* if(rec!=NULL){ + adr=(trel+j)->VirtualAddress+outptr; + if(rec->rectok==tk_apiproc){ + AddPost(adr,CALL_32I,rec->recnumber); + } + else if(rec->rectok==tk_undefproc){ + AddPost(adr,CALL_32,rec->recnumber); + } + rec->count++; + }*/ + break; + } + break; + case IMAGE_REL_I386_REL32: +// puts("488"); + preerror(meserr); +/* adr=(trel+j)->VirtualAddress+outptr; + if(rec!=NULL){ + if(rec->rectok!=tk_proc){ + AddPost(adr,CALL_32,rec->recnumber); + } + else{ + *(long *)&buf[(trel+j)->VirtualAddress]=rec->recnumber-adr-4; + } + } + else{ + *(long *)&buf[(trel+j)->VirtualAddress]=lns->adr-adr-4; + } + if(rec)rec->count++;*/ + break; + } + } + for(j=0;j +#include +#include "tok.h" + +static char **_Argv; //!!! simplest way to make your own variable + +unsigned char compilerstr[]="SPHINX C-- 0.239"; +char *rawfilename; /* file name */ +char *rawext; +LISTCOM *listcom; +EWAR wartype={NULL,NULL},errfile={NULL,NULL}; +int numfindpath=0; +char *findpath[16]; +char modelmem=TINY; +char *stubfile=NULL; +char *winstub=NULL; +FILE *hout=NULL; +char *namestartupfile="startup.h--"; + + +char outext[4]="com"; +short extflag=TRUE;// +//int scrsize; +unsigned char gwarning=FALSE; +unsigned char sobj=FALSE; +unsigned char usestub=TRUE; +unsigned char dpmistub=FALSE; +short dllflag=FALSE; +static int numstr; + +char meinfo[]= + "\nEdition of this version by\n" + " Mishel Sheker\n" + " Fido 2:5021/3.40\n" + " E-Mail sheker@mail.ru\n" + " Russia"; + +time_t systime; +struct tm timeptr; +char comsymbios=FALSE; +char fobj=FALSE; // obj +unsigned int startptr = 0x100; // start address +unsigned char wconsole=FALSE; // windows +unsigned char optstr=FALSE; // +unsigned char crif=TRUE; //check reply include file +unsigned char idasm=FALSE; // +unsigned char wbss=2; // +unsigned char use_env=FALSE; // +int numrel=0; // +unsigned char useordinal=FALSE; +unsigned char useDOS4GW=FALSE; +unsigned char clearpost=FALSE; +unsigned char uselea=TRUE; +unsigned char regoverstack=TRUE; +unsigned char shortimport=FALSE; +unsigned char useinline=2; +unsigned char ocoff=FALSE; +unsigned char ESPloc=FALSE; + +int startupfile=-1; +int alignproc=8,aligncycle=8; + +char *usage[]={ +"USAGE: C-- [options] [FILE_NAME.INI] [SOURCE_FILE_NAME]", +"", +" C-- COMPILER OPTIONS", +"", +" OPTIMIZATION", +"/OC optimize for code size /DE enable temporary expansion variable", +"/OS optimize for speed /OST enable optimization string", +"/ON enable optimization number /AP[=n] align start function", +"/UST use startup code for variables /AC[=n] align start cycles", +#ifdef OPTVARCONST +"/ORV replace variable on constant /OIR skip repeated initializing register", +#else +" /OIR skip repeated initializing register", +#endif +"", +" CODE GENERATION", +"/2 80286 code optimizations /SA=#### start code address", +"/3 80386 code optimizations /AL=## set value insert byte", +"/4 80486 code optimizations /WFA fast call API functions", +"/5 pentium code optimizations /IV initial all variables", +"/A enable address alignment /SUV=#### start address variables", +"/AS[=n] def. alignment in structures /LRS load in registers over stack", +"/UL use 'lea' for adding registers /JS join stack calling functions", +"/BA byte access to array",// /ASP addressing local variable via ESP", +"", +" PREPROCESSOR", +"/IP= include file path /IA assembly instructions as identifier", +"/D= defined identifier /CRI- not check include file on repeated", +"/MIF= main input file /IND= import name from dll", +"/SF= other startup file", +"", +" LINKING", +"/AT insert ATEXIT support block /NS disable stub", +"/ARGC insert parse command line /S=##### set stack size", +"/P insert parse command line /WIB=##### set image base address", +"/C insert CTRL ignoring code /WFU add Fix Up table, for Windows", +"/R insert resize memory block /WMB create Windows mono block", +"/ENV insert variable with environ /WS= set name stub file for win32", +"/J0 disable initial jump to main() /WBSS set post data in bss section", +"/J1 initial jump to main() short /WO call API functions on ordinals", +"/J2 initial jump to main() near /CPA clear post area", +"/STUB= set name stub file /WSI short import table, for Windows", +"/DOS4GW file running with DOS4GW /WAF=#### align Windows file (def 512)", +"/STM startup code in main function", +"", +" OUTPUT FILES", +"/TEXE DOS EXE file (model TINY) /D32 EXE file (32bit code for DOS)", +"/EXE DOS EXE file (model SMALL) /W32 EXE for Windows32 GUI", +"/OBJ OBJ output file /W32C EXE for Windows32 console", +"/SOBJ slave OBJ output file /DLL DLL for Windows32", +"/COFF OBJ COFF output file /DBG create debug information", +"/SYM COM file symbiosis /LST create assembly listing", +"/SYS device (SYS) file /B32 32bit binary files", +"/MEOS executable file for MeOS /MAP create function map file", +"/EXT= set file extension", +"", +" MISCELLANEOUS", +"/HELP /H /? help, this info /WORDS list of C-- reserved words", +"/W enable warning /LAI list of assembler instructions", +"/WF= direct warnings to a file /ME display my name and my address", +"/MER=## set maximum number errors /X disable SPHINX C-- header in output", +"/NW=## disable selected warnings /WE=## selected warning will be error", +//" /SCD split code and date", +NULL}; + +char *dir[]={ + "ME", "WORDS", "SYM", "LAI", + + "OBJ", "SOBJ", "J0", "J1", "J2", "C", "R", + "P", "X", "EXE", "S", "SYS", "ARGC", "TEXE", + "ROM", "W32", "D32", "W32C", "AT", "WFA", "SA", + "STM", "SUV", "UST", "MIF", "DLL", "DOS4GW","ENV", + "CPA", "WBSS", "MEOS", "SF", "B32", "WIB", "DBG", + + "OS", "OC", "A", "0", "1", "2", "3", + "4", "5", "6", "7", "8", "9", "W", + "WF", "DE", + "ON", "IP", "STUB", "NS", "AP", "D", "OST", + "CRI", "IA", "SCD", "AL", "WFU", "IV", + "MER", "WMB", "HELP", "H", "?", "AC", "WS", + "IND", "WO", "NW", "LST", "AS", "UL", "LRS", + "WSI", "WAF", "OIR", "COFF", "JS", "BA", "ASP", +#ifdef OPTVARCONST + "ORV", +#endif + "MAP", "WE", "EXT", NULL}; + +enum { + c_me, c_key, c_sym, c_lasm, c_endinfo=c_lasm, + + c_obj, c_sobj, c_j0, c_j1, c_j2, c_ctrlc, c_r, + c_p, c_x, c_exe, c_s, c_sys, c_arg, c_texe, + c_rom, c_w32, c_d32, c_w32c, c_at, c_wfa, c_sa, + c_stm, c_suv, c_ust, c_mif, c_dll, c_d4g, c_env, + c_cpa, c_wbss, c_meos, c_sf, c_b32, c_wib, c_dbg, + c_endstart=c_dbg, + + c_os, c_oc, c_a, c_0, c_1, c_2, c_3, + c_4, c_5, c_6, c_7, c_8, c_9, c_w, + c_wf, c_de, + c_opnum, c_ip, c_stub, c_ns, c_ap, c_define,c_ost, + c_cri, c_ia, c_scd, c_al, c_wfu, c_iv, + c_mer, c_wmb, c_help, c_h, c_hh, c_ac, c_ws, + c_ind, c_wo, c_nw, c_lst, c_as, c_ul, c_lrs, + c_wsi, c_waf, c_oir, c_coff, c_js, c_ba, c_asp, +#ifdef OPTVARCONST + c_orv, +#endif + c_map, c_we, c_ext, c_end}; + +#define NUMEXT 6 // +char extcompile[NUMEXT][4]={"c--","cmm","c","h--","hmm","h"}; + +#ifdef _KOS_ +char __pgmname[256]; +char __cmdline[256]; +#endif + +char *bufstr=NULL; // +int sbufstr=SIZEBUF; // + +void compile(); +void PrintInfo(char **str); +void LoadIni(char *name); +//void CheckNumStr(); +void ListId(int num,unsigned char *list,short *ofs); +void printmemsizes(); +void print8item(char *str); +void doposts(void); +void GetMemExeDat(); +void AddJmpApi(); +void startsymbiosys(char *symfile); +int writeoutput(); +void BadCommandLine(char *str); +void CheckExtenshions(); +void ImportName(char *name); +void WarnUnusedVar();// +void MakeExeHeader(EXE_DOS_HEADER *exeheader); +void CheckPageCode(unsigned int ofs); +int MakePE(); +int MakeObj(); +void CheckUndefClassProc(); +/* +void PrintTegList(structteg *tteg) +{ + if(tteg){ + PrintTegList(tteg->left); + PrintTegList(tteg->right); + puts(tteg->name); + } +} */ + +//unsigned long maxusedmem=0; + +void ErrOpenFile(char *str) +{ + printf("Unable to open file %s.\n",str); +} + +int main(int argc,char *argv[]) +{ +int count; +unsigned char pari=FALSE; + + printf("\nSPHINX C-- Compiler Version %d.%d%s %s\r\n",ver1,ver2,betta,__DATE__); + +// scrsize=24; + if(argc>1){ + _Argv=argv;// This make portable code + bufstr=(char *)MALLOC(SIZEBUF); + output=(unsigned char *)MALLOC((size_t)MAXDATA); + outputdata=output; + postbuf=(postinfo *)MALLOC(MAXPOSTS*sizeof(postinfo)); + strcpy((char *)string,argv[0]); + rawext=strrchr((char *)string,'\\'); + + if(rawext!=NULL){ + rawext[0]=0; + IncludePath((char *)string); + } + rawfilename=getenv("C--"); + if(rawfilename!=NULL)IncludePath(rawfilename); + + rawfilename=rawext=NULL; + LoadIni("c--.ini"); + + for(count=1;count=0)preerror("?endif expected before end of file"); + AddObj(); + docalls(); // + addinitvar(); + CheckUndefClassProc(); + if(undefoffstart!=NULL){ // + UNDEFOFF *curptr=undefoffstart; + for(;;){ + char holdstr[80]; + UNDEFOFF *ocurptr; + linenumber=curptr->pos->line; + sprintf(holdstr,"\'%s\' offset undefined",curptr->name); + currentfileinfo=curptr->pos->file; + preerror(holdstr); + free(curptr->pos); + if(curptr->next==NULL)break; + ocurptr=curptr->next; + free(curptr); + curptr=ocurptr; + } + free(curptr); + } + while(liststring!=NULL){ + STRING_LIST *ins; + ins=(STRING_LIST *)liststring; + nextstr=ins->next; + free(liststring); + liststring=nextstr; + } + free(bufstr); + if(warning==TRUE&&wact[7].usewarn)WarnUnusedVar();// + if(numstrtbl)CreatStrTabRes(); // + if(fobj==FALSE){ + if(comfile==file_w32&&error==0){ + AddJmpApi(); // API + CreatWinStub(); + } + longhold=outptr; + if(comfile==file_rom){ + ooutptr=outptr; + if(modelmem==SMALL){ + *(short *)&output[stackstartaddress]=(short)(((outptrdata+postsize+stacksize)/4+1)*4); + *(short *)&output[dataromstart]=(short)(outptr+4); + *(short *)&output[dataromsize]=(short)(outptrdata/2); +// printf("outptr=%d outptrdate=%d outptrsize=%d\n",outptr,outptrdata,outptrsize); + for(unsigned int i=0;i32)i=64; + else if(i>16)i=32; + else if(i>8)i=16; + else if(i>4)i=8; + else if(i>2)i=4; + romsize=i*1024; + output[2]=(unsigned char)(romsize/512); + } + if(outptr>=romsize)preerror("The size of a code is more than the size of the ROM"); + for(;outptr65535L) + preerror("Data and stack total exceeds 64k"); + } + else if(comfile==file_sys){ + for(int i=0;iname); + *(short *)&output[syscom+i*2]=(unsigned short)itok.number; + } + free(listcom); + } + else longhold+=(long)postsize+(long)(stacksize); + if(am32==0&&longhold>65535L&&!(modelmem==TINY&&(!resizemem)))preerror("Code, data and stack total exceeds 64k"); + if(posts>0)doposts(); // + if(resizemem&&comfile==file_com){ + segments_required=(outptr+postsize+stacksize+15)/16; + *(short *)&output[resizesizeaddress]=(short)segments_required; + *(short *)&output[stackstartaddress]=(short)(segments_required*16); + } + } + deinitregstat(); +#ifdef OPTVARCONST + KillMainLVIC(); +#endif +// puts("List Teg name:"); +// PrintTegList(tegtree); + printf("COMPILING FINISHED. Errors: %d\n",error); + if(error==0){ + if(cpu>=1){ + char m1[12]; + switch(cpu){ + case 5: + strcpy(m1,"Pentium"); + break; + case 6: + strcpy(m1,"MMX"); + break; + case 7: + strcpy(m1,"Pentium II"); + break; + case 8: + strcpy(m1,"Pentium III"); + break; + case 9: + strcpy(m1,"Pentium IV"); + break; + default: sprintf(m1,"80%d86",cpu); + } + printf("CPU required: %s or greater.\n",m1); + } + runfilesize=outptr-startptr; + if(comfile==file_rom)runfilesize=romsize; + else if(modelmem==SMALL&&comfile==file_exe){ + runfilesize+=outptrdata-startptrdata+0x20; + postsize+=postsize%2; + stacksize=(stacksize+15)/16*16; + } + else if((comfile==file_exe||comfile==file_d32)&&modelmem==TINY) + runfilesize+=0x20; + printmemsizes(); + endinptr=outptr; + if(writeoutput()==0)printf("Run File Saved (%ld bytes).\n",runfilesize); + if(comfile==file_w32&&fobj==FALSE)printf("Created file of a format PE for Windows.\nFor alignment section code, added %u zero bytes.\n",filingzerope); +// else if(FILEALIGN&&fobj==FALSE)printf("For alignment file, added %u zero bytes.\n",filingzerope); + } + if(pdbg)DoTDS(); +} + +void printmemsizes() +{ +long stacklong; +unsigned int stackword; +unsigned int postword,codeword; + postword=postsize; + codeword=outptr-startptr; + stackword=stacksize; + if(comfile==file_com||(comfile==file_exe&&modelmem==TINY)){ + if(resizemem==0){ + stacklong=0xFFFE - outptr - postsize; + stackword=stacklong; + } + codeword=codeword-datasize-alignersize; + } + else if(comfile==file_sys)stackword=sysstack; + else if(comfile==file_exe||comfile==file_rom)datasize=outptrdata; + else if(comfile==file_d32)codeword-=datasize; + printf("Code: %u bytes, Data: %u bytes, Post: %u bytes, Stack: %u bytes\n" + ,codeword,datasize,postword,stackword); + for(int i=0;itype){ + case CODE_SIZE: + *(short *)&output[(postbuf+i)->loc]+=codeword; + break; + case CODE_SIZE32: + *(long *)&output[(postbuf+i)->loc]+=codeword; + break; + case DATA_SIZE: + *(short *)&output[(postbuf+i)->loc]+=datasize; + break; + case DATA_SIZE32: + *(long *)&output[(postbuf+i)->loc]+=datasize; + break; + case POST_SIZE: + *(short *)&output[(postbuf+i)->loc]+=postword; + break; + case POST_SIZE32: + *(long *)&output[(postbuf+i)->loc]+=postword; + break; + case STACK_SIZE: + *(short *)&output[(postbuf+i)->loc]+=stackword; + break; + case STACK_SIZE32: + *(long *)&output[(postbuf+i)->loc]+=stackword; + break; + } + } +} + +void PrintInfo(char **str) +{ + numstr=1; + for(int i=0;str[i]!=NULL;i++){ + puts(str[i]); +// CheckNumStr(); + } +} + +/*void CheckNumStr() +{ +#ifndef _UNIX_ + if(((numstr+1)%(scrsize-1))==0&&outfile!=0){ + puts("Press any key..."); + getch(); + } + numstr++; +#endif +} */ + +void strbtrim(char *st) +{ +int i; +char *p,*q; + p=q=st; + while(isspace(*p))p++; // + while(*p)*q++=*p++; // + *q='\0'; + for(i=strlen(st)-1;isspace(st[i])&&i>=0;i--); + st[i+1]='\0'; +} + +unsigned long getnumber(unsigned char *buf) +{ +int temp2; +unsigned long retnum; +unsigned char *oinput; +unsigned int oinptr,oendinptr; + if(!isdigit(buf[0]))return 0; + oinptr=inptr; + oinput=input; + oendinptr=endinptr; + input=buf; + inptr=0; + endinptr=256; + retnum=scannumber(&temp2); + inptr=oinptr; + input=oinput; + endinptr=oendinptr; + return retnum; +} + +int SelectComand(char *pptr,int *count) +{ +int i; +unsigned char neg=FALSE; +char *ptr; +int len; + if((ptr=strchr(pptr,';'))!=NULL)*ptr=0;// + if((ptr=strchr(pptr,'='))!=NULL){ // + *ptr=0; // + ptr++; + strbtrim(ptr); // + } + strbtrim(pptr); // + if(*pptr==0)return c_end+1; // + if((i=strlen(pptr))>1&&pptr[i-1]=='-'){ + neg=TRUE; + pptr[i-1]=0; + } + strupr(pptr); + for(i=0;dir[i]!=NULL;i++){ + if(strcmp(dir[i],pptr)==0){ + if((i<=c_endinfo)&&count==0){ + char buf[80]; + sprintf(buf,"Option '%s' is used only in command line",dir[i]); + preerror(buf); + return i; + } + if(i<=c_endstart&¬doneprestuff!=TRUE){ +errlate: + char buf[80]; + sprintf(buf,"Too late used '#pragma option %s'",dir[i]); + preerror(buf); + return i; + } + switch(i){ + case c_j0: jumptomain=(unsigned char)(neg!=FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)0^neg; break; + case c_j1: jumptomain=(unsigned char)CALL_SHORT; header=(unsigned char)1; break; + case c_j2: jumptomain=(unsigned char)(neg==FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)1^neg; break; + case c_ctrlc: killctrlc=(unsigned char)1^neg; break; + case c_os: optimizespeed=(unsigned char)1^neg; break; + case c_oc: optimizespeed=(unsigned char)0^neg; break; + case c_r: resizemem=(unsigned char)1^neg; break; + case c_p: parsecommandline=(unsigned char)1^neg; break; + case c_a: alignword=(unsigned char)1^neg; break; + case c_sym: + startptr=0x100; + comsymbios=TRUE; + *count=*count+1; + startsymbiosys(_Argv[*count]); + break; + case c_0: chip=0; break; + case c_1: chip=1; break; + case c_2: chip=2; break; + case c_3: chip=3; break; + case c_4: chip=4; break; + case c_5: chip=5; break; + case c_6: chip=6; break; //MMX + case c_7: chip=7; break; //Pro + case c_8: chip=8; break; //PII + case c_9: chip=9; break; //PIII + case c_x: header=(unsigned char)0^neg; break; + case c_exe: + comfile=file_exe; + modelmem=SMALL; + splitdata=TRUE; + GetMemExeDat(); + if(extflag) strcpy(outext,"exe"); + startptr=0; // start address + startptrdata=0; // data start address + dos1=2; + dos2=0; + break; + case c_sys: + comfile=file_sys; + if(extflag) strcpy(outext,"sys"); + startptr=0; // start address + startptrdata=0; // data start address + jumptomain=CALL_NONE; + header=0; + break; + case c_sobj: + sobj=TRUE; + FixUp=TRUE; + jumptomain=CALL_NONE; + case c_obj: + fobj=TRUE; +// if(comfile==file_d32)FixUp=TRUE; + FastCallApi=FALSE; + break; + case c_me: + puts(meinfo); + exit( e_ok ); + case c_key: + int j,jj; + puts("LIST OF RESERVED IDENTIFIERS:"); + numstr=1; + ListId(53,id,idofs); + for(j=0;j4096)alignproc=8; + } + break; + case c_define: + addconsttotree(ptr,TRUE); + break; + case c_ost: + optstr=(unsigned char)TRUE^neg; + break; + case c_cri: + crif=(unsigned char)1^neg; + break; + case c_ia: + idasm=(unsigned char)1^neg; + break; + case c_dbg: + dbg&=0xFE; + char c; + c=(unsigned char)1^neg; + dbg|=c; + if(!neg)InitDbg(); + break; + case c_scd: +/*-----------------13.08.00 23:01------------------- + + --------------------------------------------------*/ + splitdata=(unsigned char)1^neg; + if(modelmem==SMALL)splitdata=TRUE; + break; + case c_al: + if(ptr==NULL)return c_end; + aligner=(unsigned char)getnumber((unsigned char *)ptr); + break; + case c_at: + atex=(unsigned char)1^neg; + break; + case c_wfa: + FastCallApi=(unsigned char)1^neg; + break; + case c_wfu: + FixUpTable=(unsigned char)1^neg; + break; + case c_wib: + if(ptr==NULL)return c_end; + ImageBase=getnumber((unsigned char *)ptr); + break; + case c_iv: + notpost=(unsigned char)1^neg; + break; + case c_mer: + if(ptr==NULL)return c_end; + if((maxerrors=getnumber((unsigned char *)ptr))==0)maxerrors=16; + break; + case c_sa: + if(ptr==NULL)return c_end; + startptrdata=startptr=getnumber((unsigned char *)ptr); + break; + case c_stm: + startuptomain=(unsigned char)1^neg; + break; + case c_suv: + if(ptr==NULL)return c_end; + startStartup=getnumber((unsigned char *)ptr); + break; + case c_wmb: + WinMonoBlock=(unsigned char)1^neg; + break; + case c_ust: + useStartup=(unsigned char)1^neg; + break; + case c_help: + case c_h: + case c_hh: + PrintInfo(usage); + exit(e_ok); + case c_mif: + if(ptr==NULL)return c_end; + if(rawfilename!=NULL){ + free(rawfilename); + rawfilename=NULL; + } + if(rawext!=NULL){ + free(rawext); + rawext=NULL; + } + char *temp; + if((temp=strrchr(ptr,'.'))!=NULL){ + *temp++=0; + rawext=BackString(temp); + CheckExtenshions(); + } + rawfilename=BackString(ptr); + break; + case c_ac: + AlignCycle=(unsigned char)1^neg; + if(ptr!=NULL){ + aligncycle=getnumber((unsigned char *)ptr); + if(aligncycle<1&&aligncycle>4096)aligncycle=8; + } + break; + case c_ws: //dos-stub for windows programs + if(winstub)free(winstub); + winstub=BackString(ptr); + break; + case c_ind: + ImportName(ptr); + break; + case c_wbss: + wbss=(unsigned char)1^neg; + break; + case c_wo: + useordinal=(unsigned char)1^neg; + break; + case c_nw: + if(ptr==NULL)return c_end; + len=getnumber((unsigned char *)ptr); + if(len>0&&len<=WARNCOUNT)wact[len-1].usewarn=(unsigned char)0^neg; + break; + case c_we: + if(ptr==NULL)return c_end; + len=getnumber((unsigned char *)ptr); + if(len>0&&len<=WARNCOUNT){ + if(neg)wact[len-1].fwarn=warningprint; + else wact[len-1].fwarn=preerror3; + } + break; + case c_lst: + SetLST(neg); + break; + case c_d4g: + useDOS4GW=(unsigned char)1^neg; + break; + case c_env: + use_env=(unsigned char)1^neg; + break; + case c_cpa: + clearpost=(unsigned char)1^neg; + break; + case c_ul: + uselea=(unsigned char)1^neg; + break; + case c_as: + if(ptr){ + len=getnumber((unsigned char *)ptr); + if(caselong(len)!=NUMNUM)strpackdef=len; + } + else strpackdef=(neg==FALSE?8:1); + strpackcur=strpackdef; + break; + case c_lrs: + regoverstack=(unsigned char)1^neg; + break; + case c_wsi: + shortimport=(unsigned char)1^neg; + break; + case c_waf: + if(ptr!=NULL){ + FILEALIGN=Align(getnumber((unsigned char *)ptr),16); + } + break; + case c_sf: + if(ptr==NULL)return c_end; + namestartupfile=BackString(ptr); + break; + case c_oir: + optinitreg=(unsigned char)1^neg; + break; + case c_coff: + ocoff=(unsigned char)1^neg; + break; + case c_js: + addstack=(unsigned char)1^neg; + if(addstack==0)RestoreStack(); + break; + case c_ba: + bytesize=(unsigned char)1^neg; + break; + case c_asp: + if(blockproc)goto errlate; + else ESPloc=(unsigned char)1^neg; + break; +#ifdef OPTVARCONST + case c_orv: + replasevar=(unsigned char)1^neg; + if(replasevar&&listvic)ClearLVIC(); + break; + case c_map: + mapfile=(unsigned char)1^neg; + break; +#endif + case c_ext: //***lev*** + strcpy(outext,BackString(ptr)); //***lev*** + extflag=FALSE; // , + break; //***lev*** + } + break; + } + } + return i; +} + +void SetLST(unsigned char neg) +{ + if(((dbg&2)>>1)==neg){ + dbg&=0xFD; + unsigned char c=(unsigned char)((1^neg)<<1); + dbg|=c; + if(neg){ + if((dbg&0xFE)==0)dbgact=TRUE; + AddEndLine(); + } + else{ + InitDbg(); + if(notdoneprestuff!=TRUE)dbgact=FALSE; //startup cod + } + } +} + +void print8item(char *str) +{ +// CheckNumStr(); + for(int j=0;j<8;j++)printf(str,j); + puts(""); +} + + + + +void _loadIni(FILE *inih) +{ + char m1[256]; + for(;;){ + if(fgets(m1,255,inih)==NULL)break; + if(SelectComand(m1,0)==c_end)BadCommandLine(m1); + } + fclose(inih); +} + +void LoadIni(char *name) +{ +FILE *inih; +char m1[256]; + + // load name + //printf("pth: %s\r\n",name); + //if (inih = fopen(name,"rb")) + //{_loadIni(inih);return;} + + //if(strcmp(name,"c--.ini")!=0) + // return; + + //load findpath[0]\c--.ini + /*if (findpath[0]!=0) + { + sprintf(m1,"%s\\%s",findpath[0],name); + printf("pth: %s\r\n",m1); + if (inih = fopen(m1,"rb")) + {_loadIni(inih);return;} + } //http://android-films.net/download4/iz_mashiny_mp4_480x320_android-films.net.torrent + //load PATH[i=0..end]/c--.ini + char* pth = 0;//getenv("PATH"); + if (pth != 0) + { + char* start; + int size; + start = pth; + while(*start) + { + size = 0; + char* endp = strchr(start, DIV_PATH); + size = (endp == 0)? strlen(start): endp-start; + strncpy(m1, start, size); + start += size + 1; + if ((m1[size - 1] != '/') && (m1[size - 1] != '\\')) + m1[size++] = '/'; + + strcpy(m1 + size,"c--.ini"); + printf("pth: %s\r\n",m1); + if (inih = fopen(m1,"rb")) + {_loadIni(inih);return;} + } + } +#ifdef _KOS_ + //for KolibriOS: load program_dir/c--.ini + int p; + strcpy(m1,__pgmname); + p = strlen(m1); + while ((*(m1+p)!='/') && (p != 0)) + p--; + if (p){ + p++; + strcpy(m1+p,"c--.ini"); + printf("pth: %s\r\n",m1); + //if (inih = fopen(m1,"rb")) + //{_loadIni(inih);return;} + } + */ //for KolibriOS: load /rd/0/settings/c--.ini + inih = fopen("/rd/1/settings/c--.ini","rb"); + //for(;;){ + // if(fgets(m1,255,inih)==NULL)break; + // if(SelectComand(m1,0)==c_end)BadCommandLine(m1); + //} + fclose(inih); + //return; +//#endif //_KOS_ +} + +/***************************************************************************** +* .NAME : MALLOC +* .TITLE : . +*****************************************************************************/ +void OutMemory() +{ + preerror("Compiler out of memory"); + exit(e_outofmemory); +} + +void * MALLOC (unsigned long size) +{ +void *mem; + mem=malloc(size); + if(mem==NULL)OutMemory(); + +// if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size; + + return mem; +} + +void *REALLOC(void *block,unsigned long size) +{ +void *mem; + mem=realloc(block,size); + if(mem==NULL)OutMemory(); + +// if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size; + + return mem; +} + +void IncludePath(char *buf) +{ + if(numfindpathtype){ + case POST_VAR: + *(short *)&output[(postbuf+i)->loc]+=(short)addvalue; + break; + case POST_VAR32: + *(long *)&output[(postbuf+i)->loc]+=addvalue+addvalbss; + numrel++; + break; + case FIX_VAR32: + case FIX_CODE32: + *(long *)&output[(postbuf+i)->loc]+=addvalw32; + numrel++; + break; + case FIX_CODE_ADD: + if(am32){ + *(long *)&output[(postbuf+i)->loc]+=addvalw32+(postbuf+i)->num; + (postbuf+i)->type=(unsigned short)FIX_VAR32; + } + else{ + *(short *)&output[(postbuf+i)->loc]+=(short)(addval+(postbuf+i)->num); + (postbuf+i)->type=(unsigned short)FIX_VAR; + } + numrel++; + break; + case DATABLOCK_VAR: + *(short *)&output[(postbuf+i)->loc]+=(short)addval; + if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR; + break; + case DATABLOCK_VAR32: + *(long *)&output[(postbuf+i)->loc]+=addval+addvalw32; + if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR32; + numrel++; + break; + } + } + ooutptr=addvalue; // post debug; +} + +void GetMemExeDat() +{ + if(outputdata==output&&outputdata!=0)outputdata=(unsigned char *)MALLOC((size_t)MAXDATA); +} + +void ListId(int numfirstchar,unsigned char *list,short *ofs) +{ +char buf[40]; + for(int i=0;isign=0x5a4D; // MZ +// if(modelmem==TINY&&comfile==file_exe)pointstart=0x100; +/* else*/ pointstart=EntryPoint(); + count=(unsigned short)(runfilesize%512); + i=(unsigned short)(runfilesize/512); + exeheader->numlastbyte=count; + exeheader->numpage=(unsigned short)(count==0?i:i+1); + exeheader->headsize=2; // size of header in paragraphs (2 paragraphs) + exeheader->initIP=(unsigned short)pointstart; // IP at entry (0x0000) + paragraphsrequired=(outptr+outptrdata+postsize+stacksize+15)/16; + if(modelmem==TINY&&comfile==file_exe){ + exeheader->initSS=0xFFF0; // displacement of SS + exeheader->initSP=0xFFFE; // intial value of SP + exeheader->initCS=0xfff0; // displacement of CS (0x0000) + if(!resizemem){ + exeheader->minmem=0xfff; // min-paragraphs + exeheader->maxmem=0xffff; // max-paragraphs + } + else{ + paragraphsrequired-=0x10; + exeheader->initSP=(unsigned short)(paragraphsrequired*16); // intial value of SP + exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs + exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs + } + } + else if(comfile==file_d32){ + exeheader->initSP=(unsigned short)stacksize; // intial value of SP + exeheader->initSS=(unsigned short)((outptr+postsize+15)/16); // displacement of SS + exeheader->initCS=(unsigned short)((pointstart/65536)*4096); + if(resizemem){ + exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs + exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs + } + else exeheader->maxmem=(unsigned short)0xFFFF; // max-paragraphs + } + else{ + exeheader->initSS=(unsigned short)(outptr/16); // displacement of SS + exeheader->initSP=(unsigned short)(outptrdata+postsize+stacksize); // intial value of SP + exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs + exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs + } + exeheader->ofsreloc=0x1c; // offset of first relocation item (0x0000) +} + +void startsymbiosys(char *symfile) +{ +unsigned int size; +int filehandle; +long filesize; + outptr=startptr; + if((filehandle=open(symfile,O_BINARY|O_RDONLY))==-1){; + ErrOpenFile(symfile); + exit(e_symbioerror); + } + if((filesize=getfilelen(filehandle))!=-1L){ + if(filesize+outptrcount==0&&startupfile!=ptr->file){ + linenumber=ptr->line; + currentfileinfo=ptr->file; + int i=0; + switch(ptr->rectok){ + case tk_proc: + if(ptr->recsegm!=NOT_DYNAMIC||strcmp(ptr->recid,mesmain)==0)break; + i++; + case tk_structvar: + i++; + case tk_charvar: + case tk_bytevar: + case tk_intvar: + case tk_wordvar: + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + case tk_pointer: + case tk_qword: + case tk_double: + if(i<=1&&(ptr->recpost==DYNAMIC_VAR||ptr->recpost==DYNAMIC_POST))break; + warningnotused(ptr->recid,i); + break; + } + } + warnunused(ptr ->left); + warnunused(ptr ->right); + } +} + +void WarnUnusedVar()// +{ + warnunused(treestart); + for(unsigned int i=0;istlist); +} + +void addinitvar() +{ +unsigned int i; + if(numfloatconst){ // float + if(alignword||optimizespeed)AlignCD(DS,chip>5?16:4); + for(i=0;itype==POST_FLOATNUM){ + if(am32)*(unsigned long *)&output[(postbuf+i)->loc]=outptrdata+(postbuf+i)->num; + else *(unsigned short *)&output[(postbuf+i)->loc]=(unsigned short)(outptrdata+(postbuf+i)->num); + if(FixUp)(postbuf+i)->type=FIX_VAR32; + else killpost(i--); + } + } + for(i=0;itype==tk_float)sprintf((char *)string,"const float %f",(floatnum+i)->fnum); + else sprintf((char *)string,"const double %f",(floatnum+i)->dnum); + AddDataNullLine(4,(char *)string); + } + outdwordd((floatnum+i)->num[0]); + if((floatnum+i)->type!=tk_float){ + outdwordd((floatnum+i)->num[1]); + datasize+=4; + } + datasize+=4; + } + free(floatnum); + numfloatconst=0; + floatnum=NULL; + } + for(i=0;i<(unsigned int)numswtable;i++){ // switch + int j; + FSWI *swt=swtables+i; + if(alignword)AlignCD(DS,swt->type); + if(dbg&2)AddDataNullLine((char)swt->type,"switch table address"); + if(am32==FALSE){ // + *(unsigned short *)&output[swt->ptb]=(unsigned short)outptrdata; + } + else *(unsigned long *)&output[swt->ptb]=outptrdata; + unsigned char oam32=am32; + am32=(unsigned char)(swt->type/2-1); + + unsigned long val=swt->defal; + int oline=outptrdata; + for(j=0;jsizetab;j++){ // +// if((swt->info+jj)->type==singlcase) + AddReloc(DS); + if(am32)outdwordd(val); + else outwordd(val); + } + if(swt->mode==2){ + if(dbg&2)AddDataNullLine((char)swt->razr,"switch table value"); + if(oam32==FALSE){ // + *(unsigned short *)&output[swt->ptv]=(unsigned short)outptrdata; + } + else *(unsigned long *)&output[swt->ptv]=outptrdata; + } + int ii=0; // case + for(int jj=0;jjnumcase;jj++){ + j=(swt->info+jj)->value; // + val=(swt->info+jj)->postcase; + if((swt->info+jj)->type==singlcase){ + if(swt->mode==1){ + if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val; + else *(unsigned long *)&outputdata[oline+j*4]=val; + } + else{ + if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val; + else *(unsigned long *)&outputdata[oline+ii*4]=val; + switch(swt->razr){ + case r8: opd(j); break; + case r16: outwordd(j); break; + case r32: outdwordd(j); break; + } + ii++; + } + } + else{ + jj++; + for(;(unsigned int)j<=(swt->info+jj)->value;j++){ + if(swt->mode==1){ + if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val; + else *(unsigned long *)&outputdata[oline+j*4]=val; + } + else{ + if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val; + else *(unsigned long *)&outputdata[oline+ii*4]=val; + switch(swt->razr){ + case r8: opd(j); break; + case r16: outwordd(j); break; + case r32: outdwordd(j); break; + } + ii++; + } + } + } + } + am32=oam32; + free(swt->info); + } + if(numswtable){ + free(swtables); + numswtable=0; + } + + for(i=0;itype==DIN_VAR||(postbuf+i)->type==DIN_VAR32){ + idrec *ptr=(idrec *)(postbuf+i)->num; +// printf("post=%u num=%08X %s\n",ptr->recpost,ptr->recnumber,ptr->recid); + if(ptr->recpost==USED_DIN_VAR)setdindata(ptr,i); + else{ + if((postbuf+i)->type==DIN_VAR){ + *(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber); + } + else{ +// printf("loc=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],ptr->recnumber); + *(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber; + } + } + if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32); + else killpost(i--); + } + } + dopoststrings(); +} + +void setdindata(idrec *ptr,int i) +{ +unsigned char *oldinput; +unsigned int oldinptr,oldendinptr; +unsigned char bcha; +unsigned int oline,ofile; +char *ostartline; + if(alignword){ + if(ptr->rectok==tk_structvar)alignersize+=AlignCD(DS,2); // + else alignersize+=AlignCD(DS,GetVarSize(ptr->rectok)); + } +// printf("loc=%08X out=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],outptrdata,ptr->recnumber); + if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(outptrdata); + else *(unsigned long *)&output[(postbuf+i)->loc]+=outptrdata; + ptr->recpost=0; + ptr->recnumber+=outptrdata; + oline=linenum2; + ofile=currentfileinfo; + oldinput=input; + oldinptr=inptr2; + bcha=cha2; + oldendinptr=endinptr; + input=(unsigned char *)ptr->sbuf; + inptr2=1; + ostartline=startline; + startline=(char*)input; + cha2=input[0]; + linenum2=ptr->line; + currentfileinfo=ptr->file; + endinptr=strlen((char *)input); + endinput=startline+endinptr; + endoffile=0; + tok=ptr->rectok; + if(tok==tk_structvar)datasize+=initstructvar((structteg *)ptr->newid,ptr->recrm); + else{ +long type,ssize; +unsigned char typev; + if(tok>=tk_charvar&&tok<=tk_doublevar){ + type=tok-(tk_charvar-tk_char); + typev=variable; + ssize=typesize(type); + } + else if(tok==tk_pointer){ + typev=pointer; + type=itok.type; + if(am32==FALSE&&((itok.flag&f_far)==0))ssize=2; + else ssize=4; + } + datasize+=initglobalvar(type,ptr->recsize/ssize,ssize,typev); + } + free(input); + linenum2=oline; + currentfileinfo=ofile; + input=oldinput; + inptr2=oldinptr; + cha2=bcha; + endinptr=oldendinptr; + endoffile=0; + startline=ostartline; +} + +FILE *CreateOutPut(char *ext,char *mode) +{ +char buf[256]; +FILE *diskout; + sprintf(buf,"%s.%s",rawfilename,ext); + if((diskout=fopen(buf,mode))==NULL){ + ErrOpenFile(buf); + exit(e_notcreateoutput); + } + return diskout; +} + +int numundefclassproc=0; +idrec **undefclassproc; + +void AddUndefClassProc() +{ + if(numundefclassproc==0)undefclassproc=(idrec **)MALLOC(sizeof(idrec **)); + else undefclassproc=(idrec **)REALLOC(undefclassproc,sizeof(idrec **)*(numundefclassproc+1)); + undefclassproc[numundefclassproc]=itok.rec; + numundefclassproc++; +} + +void CheckUndefClassProc() +{ + for(int i=0;irectok==tk_undefproc){ + currentfileinfo=ptr->file; + linenumber=ptr->line; + thisundefined(ptr->recid); + } + } +} diff --git a/programs/develop/cmm/new_type.cpp b/programs/develop/cmm/new_type.cpp new file mode 100644 index 0000000000..515a8a7b72 --- /dev/null +++ b/programs/develop/cmm/new_type.cpp @@ -0,0 +1,41 @@ +#define _NEW_TYPE_ + +#include "tok.h" + +void convert_type(int *sign,int *rettype,int *pointr,int reg) +{ +int usebracket=FALSE; + if(tok==tk_openbracket&&(tok2>=tk_char&&tok2<=tk_double)){ + nexttok(); + usebracket=TRUE; + } + switch ( tok ){ + case tk_byte: + case tk_word: + case tk_dword: + case tk_float: + case tk_double: + case tk_qword: + *sign=0; + *rettype=tok; + if(usebracket)nexttok(); + else getoperand(reg); + break; + case tk_char: + case tk_int: + case tk_long: + *sign=1; + *rettype=tok; + if(usebracket)nexttok(); + else getoperand(reg); + break; + } + if(usebracket){ + while(tok==tk_mult){ + nexttok(); + *pointr++; + } + if(tok!=tk_closebracket)expected(')'); + else getoperand(reg); + } +} diff --git a/programs/develop/cmm/optreg.cpp b/programs/develop/cmm/optreg.cpp new file mode 100644 index 0000000000..d5603c5cb6 --- /dev/null +++ b/programs/develop/cmm/optreg.cpp @@ -0,0 +1,1164 @@ +#define _REGOPT_ + +#include "tok.h" + +unsigned char optinitreg=TRUE; +int OptNameIDX(char *name,char *nam,int size); +int getnumber(char *buf,unsigned long *num,int *typenum=NULL); +int convertrazr(int *reg,int razr); + +enum{ + t_undef, + t_const, + t_string, + t_id, +}; + +enum{ + razr_8l, + razr_8h, + razr_16, + razr_32 +}; + +REGISTERSTAT *regstat; + +#ifdef OPTVARCONST +void CompareLVIC(BLVIC *bak); +void FreeLVIC(BLVIC *bak); +BLVIC *BakLVIC(); +void CopyLVIC(BLVIC *bak); +#endif + +void KillRegLec(int reg) +{ + KillVar(regs[0][reg]); + KillVar(regs[1][reg]); + if(reg<4){ + KillVar(begs[reg]); + KillVar(begs[reg+4]); + } +} + +void ClearReg(int reg) +{ + if(optinitreg==FALSE)return; + (regstat+reg)->type=t_undef; +REGEQVAR *curv,*nextv; + curv=(regstat+reg)->next; + while(curv){ + nextv=curv->next; + free(curv); + curv=nextv; + } + (regstat+reg)->next=NULL; +// printf("clear reg %d\n",reg); + KillRegLec(reg); +} + +void clearregstat(int regs) +{ + if(optinitreg==FALSE)return; + for(int i=0;i<8;i++){ + if((regs&(1<type=t_undef; +REGEQVAR *curv,*nextv; + curv=(regstat+i)->next; + while(curv){ + nextv=curv->next; + free(curv); + curv=nextv; + } + (regstat+i)->next=NULL; + } + } +} + +void initregstat() +{ + regstat=(REGISTERSTAT *)MALLOC(sizeof(REGISTERSTAT)*8); + for(int i=0;i<8;i++)(regstat+i)->next=NULL; + clearregstat(); +} + +void deinitregstat() +{ + if(regstat){ + clearregstat(); + free(regstat); + } + regstat=NULL; +} + +REGISTERSTAT *BakRegStat() +{ +REGISTERSTAT *bakregstat; +#ifndef OPTVARCONST + if(optinitreg==FALSE)return NULL; + bakregstat=(REGISTERSTAT *)MALLOC(sizeof(REGISTERSTAT)*8); +#else + bakregstat=(REGISTERSTAT *)MALLOC(sizeof(REGISTERSTAT)*8+sizeof(BLVIC *)); + (bakregstat+8)->bakvic=BakLVIC(); +#endif + memcpy(bakregstat,regstat,sizeof(REGISTERSTAT)*8); +REGEQVAR *cur,*news; + for(int i=0;i<8;i++){ + if((bakregstat+i)->next){ + cur=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(cur,(bakregstat+i)->next,sizeof(REGEQVAR)); + (bakregstat+i)->next=cur; + while(cur->next){ + news=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(news,cur->next,sizeof(REGEQVAR)); + cur->next=news->next; + } + } + } + return bakregstat; +} + +void CopyRegStat(REGISTERSTAT *bak) +{ +#ifndef OPTVARCONST + if(optinitreg==FALSE||bak==NULL)return; +#else + if(bak==NULL)return; + CopyLVIC((bak+8)->bakvic); +#endif + memcpy(regstat,bak,sizeof(REGISTERSTAT)*8); +REGEQVAR *cur,*news; + for(int i=0;i<8;i++){ + if((regstat+i)->next){ + cur=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(cur,(regstat+i)->next,sizeof(REGEQVAR)); + (regstat+i)->next=cur; + while(cur->next){ + news=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(news,cur->next,sizeof(REGEQVAR)); + cur->next=news->next; + } + } + } +} + +void ClearRegBak(int reg,REGISTERSTAT *regst) +{ +REGEQVAR *curv,*nextv; + (regst+reg)->type=t_undef; + curv=(regst+reg)->next; + while(curv){ + nextv=curv->next; + free(curv); + curv=nextv; + } + (regst+reg)->next=NULL; +} + +void AddRegVar(int reg, int razr,ITOK *itok4) +{ + if(optinitreg==FALSE||(itok4->flag&f_useidx)!=0)return; +REGEQVAR *cur,*news; + cur=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + cur->razr=convertrazr(®,razr); + cur->next=NULL; + strcpy(cur->name,itok4->name); + if((regstat+reg)->next==NULL)(regstat+reg)->next=cur; + else{ + news=(regstat+reg)->next; + while(news->next)news=news->next; + news->next=cur; + } +} + +int GetRegVar(ITOK *itok4) +{ + if(optinitreg==FALSE||(itok4->flag&f_useidx)!=0)return 0; +int retval=0; + for(int i=0;i<8;i++){ +REGEQVAR *cur; + cur=(regstat+i)->next; + while(cur){ + if(strcmp(itok4->name,cur->name)==0){ + retval|=(1<next; + } + } + return retval; +} + +void FreeStat(REGISTERSTAT *bak) +{ +#ifndef OPTVARCONST + if(optinitreg==FALSE||bak==NULL)return; +#else + if(bak==NULL)return; + FreeLVIC((bak+8)->bakvic); +#endif + for(int i=0;i<8;i++)ClearRegBak(i,bak); + free(bak); +} + +void CompareRegStat(REGISTERSTAT *bak) +{ +#ifndef OPTVARCONST + if(optinitreg==FALSE||bak==NULL)return; +#else + if(bak==NULL)return; + CompareLVIC((bak+8)->bakvic); +#endif + for(int i=0;i<8;i++){ + if((regstat+i)->type==t_undef||(regstat+i)->type!=(bak+i)->type|| + ((regstat+i)->type==t_id&&strcmp((regstat+i)->id,(bak+i)->id)!=0))ClearRegBak(i,bak); + } +} + +int convertrazr(int *reg,int razr) +{ +int nr; + if(razr==r8){ + if(*reg<4)nr=razr_8l; + else{ + nr=razr_8h; + *reg-=4; + } + } + else if(razr==r16)nr=razr_16; + else nr=razr_32; + return nr; +} + +void ConstToReg(unsigned long num,int reg,int razr) +{ +char buf[64]; + if(optinitreg){ + sprintf(buf,"%ld",num); + IDZToReg(buf,reg,razr); + } +} + +void GenRegToReg(int regd,int regs,int razr) +{ + switch(razr){ + case r8: + op(0x88); + op(128+64+regs*8+regd); + break; + case r16: + case r32: + op66(razr); + op(0x89); + op(128+64+regs*8+regd); + break; + } +} + +int CheckIDZReg(char *name,int reg,int razr) +/* + name - ப + */ +{ +int nr; +int retreg=NOINREG; +int i; + if(optinitreg==FALSE||razr>r32)return NOINREG; + nr=convertrazr(®,razr); + for(i=0;i<8;i++){ +//printf("%d type=%d razr=%d %s\n",i,(regstat+i)->type,(regstat+i)->razr,(regstat+i)->id); + if((regstat+i)->type==t_id){ + if((regstat+i)->razr==nr||(razr==r8&&((regstat+i)->razr==razr_8l|| + (regstat+i)->razr==razr_8h))){ + if(strcmp(name,(regstat+i)->id)==0){ + if(i==reg&&nr==(regstat+i)->razr){ + if(/*razr==r8&&*/nr==razr_8h)reg+=4; + waralreadinit(razr==r8?begs[reg]:regs[razr/4][reg]); +// printstatreg(); + return SKIPREG; + } + retreg=i; + } + } + } +REGEQVAR *cur; + cur=(regstat+i)->next; + while(cur){ + if(cur->razr==nr||(razr==r8&&(cur->razr==razr_8l||cur->razr==razr_8h))){ + if(strcmp(name,cur->name)==0){ + if(i==reg&&nr==cur->razr){ + if(nr==razr_8h)reg+=4; + waralreadinit(razr==r8?begs[reg]:regs[razr/4][reg]); + return SKIPREG; + } + retreg=i; + break; + } + } + cur=cur->next; + } + } + if(retreg!=NOINREG){ + if(razr==r8){ + if((regstat+retreg)->razr==razr_8h)retreg+=4; + if(nr==razr_8h)reg+=4; + waralreadinitreg(begs[reg],begs[retreg]); + } + else waralreadinitreg(regs[razr/4][reg],regs[razr/4][retreg]); + } + return retreg; +} + +void IDZToReg(char *name,int reg,int razr) +/* + name - ப + */ +{ +int nr; + if(optinitreg==FALSE||name==NULL||razr>r32)return; + nr=convertrazr(®,razr); + ClearReg(reg); + (regstat+reg)->type=t_id; + (regstat+reg)->razr=nr; + strcpy((regstat+reg)->id,name); + KillRegLec(reg); +} + +int GetRegNumber(int reg,unsigned long *num,int razr) +{ +int nr; + nr=convertrazr(®,razr); + if(optinitreg!=FALSE&&razr<=r32&&(regstat+reg)->type==t_id&& + (regstat+reg)->razr==nr){ + if(isdigit((regstat+reg)->id[0])){ + if(getnumber((regstat+reg)->id,num))return reg; + } + } + return NOINREG; +} + +int GetNumberR(int sreg,unsigned long *num,int razr,unsigned long number) +{ +int nr; +int reg,rreg=NOINREG; +unsigned long dnum=0xffffffff; +unsigned long nnum; + if(optinitreg!=FALSE&&razr<=r32){ + for(reg=0;reg<8;reg++){ + if(reg==sreg)continue; + nr=convertrazr(®,razr); + if((regstat+reg)->type==t_id&&(regstat+reg)->razr==nr){ +// printf("reg=%d %s\n",reg,(regstat+reg)->id); + if(isdigit((regstat+reg)->id[0])){ + if(getnumber((regstat+reg)->id,num)){ + if(*num==number)return reg; + if(*num>number&&(*num-number)' '){ + nam[0]=cha2; + i++; + } + for(j=0;ipinptr)break; + nam[i]=c; + } + inptr2=oinptr2; + inptr=oinptr; + cha=ocha; + linenumber=oline; + tok=otok; + itok=oitok; + if(i==SIZEIDREG)return NULL; + c=nam[0]; + if(c==';'||c==','||c==')'||c=='}')return NULL; + nam[i]=0; + return BackString(nam); +} + +void GetEndLex(int stop1,int stop2,int type) +{ +int i=0; +int oscanlexmode; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + oscanlexmode=scanlexmode; + scanlexmode=DEFLEX; + while(tok2!=stop1&&tok2!=stop2&&tok2!=tk_eof&&itok2.type!=type){ + nexttok(); + while(tok==tk_closebracket&&i){ + i--; + nexttok(); + } + if(tok==tk_openbracket)i++; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + } +// retoldscanmode(oscanlexmode); + scanlexmode=oscanlexmode; +// printf("tok2=%d type2=%d\n",tok2,itok2.type); +} + +void IDXToReg(char *name,int size,int reg) +/* + name - 砫 + size - ࠧ୮ + */ +{ +int nr; +char nam[SIZEIDREG]; + if(optinitreg==FALSE)return; + nr=(am32==0?razr_16:razr_32); + ClearReg(reg); + if(OptNameIDX(name,nam,size)==TRUE){ + (regstat+reg)->type=t_id; + (regstat+reg)->razr=nr; + strcpy((regstat+reg)->id,nam); + } + KillRegLec(reg); +} + +int OptNameIDX(char *name,char *nam,int size) +{ +int i,j; +int maxlen=SIZEIDREG; + j=0; + if(name[j]=='&'){ + size=1; + j++; + } + if(size>1)maxlen-=10; + for(i=0;;i++){ + if(i==maxlen)return FALSE; + char c; + do{ + c=name[j]; + j++; + }while(c<=0x20&&c!=0); + if(c==0||c==';')break; + nam[i]=c; + } + nam[i]=0; + if(size>1)sprintf(nam+i,"*%d",size); + return TRUE; +} + +int CheckIDXReg(char *name,int size,int reg) +/* + name - 砫 + size - ࠧ୮ + */ +{ +int nr; +char nam[SIZEIDREG]; +int retreg=NOINREG; +int i; + if(optinitreg==FALSE)return NOINREG; + nr=(am32==0?razr_16:razr_32); + if(OptNameIDX(name,nam,size)==TRUE){ + for(i=0;i<8;i++){ + if((regstat+i)->type==t_id&&(regstat+i)->razr==nr){ + if(strcmp(nam,(regstat+i)->id)==0){ + if(i==reg){ +// printf("%s %s\n",nam,(regstat+i)->id); + waralreadinit(regs[am32][reg]); + return SKIPREG; + } + retreg=i; + } + } +REGEQVAR *cur; + cur=(regstat+i)->next; + while(cur){ + if(cur->razr==nr&&strcmp(nam,cur->name)==0){ + if(i==reg){ + waralreadinit(regs[am32][reg]); + return SKIPREG; + } + retreg=i; + break; + } + cur=cur->next; + } + } + } + return retreg; +} + +int RegToReg(int regd,int regs,int razr) +{ +int nr,nrs; + if(optinitreg==FALSE)return NOINREG; + nrs=convertrazr(®s,razr); + nr=convertrazr(®d,razr); + if(razr==r8&&nrs!=nr&®s==regd)goto noreg; + if(nrs==nr&&(regstat+regd)->type==(regstat+regs)->type&& + (regstat+regs)->type!=t_undef&&(regstat+regd)->razr==(regstat+regs)->razr){ + if(strcmp((regstat+regd)->id,(regstat+regs)->id)==0)return SKIPREG; + } +noreg: + ClearReg(regd); + memcpy((regstat+regd),(regstat+regs),sizeof(REGISTERSTAT)); +REGEQVAR *cur,*news; + if((regstat+regd)->next){ + cur=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(cur,(regstat+regd)->next,sizeof(REGEQVAR)); + (regstat+regd)->next=cur; + while(cur->next){ + news=(REGEQVAR *)MALLOC(sizeof(REGEQVAR)); + memcpy(news,cur->next,sizeof(REGEQVAR)); + cur->next=news->next; + } + } + (regstat+regd)->razr=nr; + return NOINREG;; +} + +int RegSwapReg(int reg1,int reg2,int razr) +{ +int nr,nrs; +REGISTERSTAT temp; + if(optinitreg==FALSE)return NOINREG; + nrs=convertrazr(®2,razr); + nr=convertrazr(®1,razr); + if((regstat+reg1)->type&&(regstat+reg1)->razr>nr)ClearReg(reg1); + if((regstat+reg2)->type&&(regstat+reg2)->razr>nrs)ClearReg(reg2); + if((regstat+reg1)->razr=razr_16)ClearReg(reg1); + if((regstat+reg2)->razr=razr_16)ClearReg(reg2); + if(razr==r8&&nrs!=nr&®1==reg2)goto noreg; + if((regstat+reg1)->type==(regstat+reg2)->type&& + (regstat+reg2)->type!=r_undef&&(regstat+reg1)->razr==(regstat+reg2)->razr){ + if(strcmp((regstat+reg1)->id,(regstat+reg2)->id)==0)return SKIPREG; + } +noreg: + KillRegLec(reg1); + KillRegLec(reg2); + memcpy(&temp,(regstat+reg1),sizeof(REGISTERSTAT)); + memcpy((regstat+reg1),(regstat+reg2),sizeof(REGISTERSTAT)); + memcpy((regstat+reg2),&temp,sizeof(REGISTERSTAT)); + return NOINREG;; +} + +void KillVar(char *name) +/*-----------------22.04.03 15:51------------------- + ६ ॣ ᫨ , + 樠 ॣ +--------------------------------------------------*/ +{ +char *pstr,*nam; +int len; + if(optinitreg==FALSE)return; + len=strlen(name); + for(int i=0;i<8;i++){ + if((regstat+i)->type==t_id){ + pstr=(regstat+i)->id; + for(;;){ + if((nam=strstr(pstr,name))!=NULL){ + char c; + c=nam[len]; + if(c!='_'&&(!isalpha(c))){ + if(nam!=pstr){ + c=nam[-1]; + if(c=='_'||isalpha(c))goto novar; + } + ClearReg(i); + break; + } + } + else break; +novar: + pstr=nam+1; + } + } +restart: + if((regstat+i)->next){ +REGEQVAR *cur,*prev; + cur=(regstat+i)->next; + if(strcmp(cur->name,name)==0){ + (regstat+i)->next=cur->next; +// printf("kill '%s'\n",name); + free(cur); + goto restart; + } + prev=cur; + cur=cur->next; + while(cur){ + if(strcmp(cur->name,name)==0){ + prev->next=cur->next; + free(cur); + cur=prev->next; + } + else{ + prev=cur; + cur=cur->next; + } + } + } + } +} + +/*-----------------16.06.05 23:45------------------- + ६ ⠭⠬ + --------------------------------------------------*/ +#ifdef OPTVARCONST + +BLVIC *mainvic; +unsigned char replasevar=TRUE; +//void updnum(int tok4,long long *num); + +#define MAXSIZEVIC 64 +int cursizevic=0; +LVIC *listvic=NULL; + +void CreateMainLVIC() +{ + mainvic=(BLVIC *)MALLOC(sizeof(BLVIC)); + listvic=mainvic->listvic=(LVIC *)MALLOC(sizeof(LVIC)*MAXSIZEVIC); + cursizevic=mainvic->sizevic=MAXSIZEVIC; +} + +void KillMainLVIC() +{ + free(listvic); + free(mainvic); + listvic=NULL; +} + +BLVIC *BakLVIC() +{ +BLVIC *bakvic; + if(replasevar==0)return NULL; + bakvic=(BLVIC *)MALLOC(sizeof(BLVIC)); + bakvic->listvic=(LVIC *)MALLOC(sizeof(LVIC)*cursizevic); + bakvic->sizevic=cursizevic; + memcpy(bakvic->listvic,listvic,sizeof(LVIC)*cursizevic); + return bakvic; +} + +void CopyLVIC(BLVIC *bak) +{ + if(bak==NULL)return; + if(cursizevicsizevic){ + listvic=(LVIC *)REALLOC(listvic,sizeof(LVIC)*bak->sizevic); + } + memcpy(listvic,bak->listvic,sizeof(LVIC)*bak->sizevic); + if(cursizevic>bak->sizevic){ + for(int i=bak->sizevic;irec=NULL; + } + else cursizevic=bak->sizevic; +} + +void FreeLVIC(BLVIC *bak) +{ + if(bak==NULL)return; + free(bak->listvic); + free(bak); +} + +void CompareLVIC(BLVIC *bak) +{ +LVIC *bvic; + if(bak==NULL)return; + for(int i=0;isizevic;i++){ + if((bak->listvic+i)->rec != NULL){ + bvic=bak->listvic+i; + int j; + for(j=0;jrec==bvic->rec){ + if((listvic+j)->lnumber!=bvic->lnumber)bvic->rec=NULL; + break; + } + } + if(j==cursizevic)bvic->rec=NULL; + } + } +} + +void ClearLVIC() +{ + memset(listvic,0,cursizevic*sizeof(LVIC)); +/* printf("%s(%d)> Init table LVIC\n", + startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename, + linenumber);*/ +} + +int Const2Var(ITOK *itok4,long long num,int typenum) +{ +int i; +int freevic=-1; + if(replasevar&&itok4->rec&&(itok4->flag&f_useidx)==0){ + if((typenum==tk_word||typenum==tk_dword)&&num<256)typenum=tk_byte; + for(i=0;irec==itok4->rec)break; + if(freevic==-1&&(listvic+i)->rec==NULL)freevic=i; + } + if(i==cursizevic){ + if(freevic==-1){ + cursizevic+=MAXSIZEVIC; + listvic=(LVIC *)REALLOC(listvic,sizeof(LVIC)*cursizevic); + for(freevic=cursizevic-1;freevic>i;freevic--)(listvic+freevic)->rec=NULL; + } + else i=freevic; + } + else if((listvic+i)->contype==typenum&&(listvic+i)->lnumber==num)return FALSE; + (listvic+i)->rec=itok4->rec; + (listvic+i)->contype=typenum; + (listvic+i)->lnumber=num; + switch(itok4->type){ + case tp_localvar: + case tp_paramvar: + (listvic+i)->typevar=tp_localvar; + break; + case tp_postvar: + case tp_gvar: + (listvic+i)->typevar=tp_gvar; + break; + default: + (listvic+i)->typevar=itok4->type; + break; + } +/* printf("%s(%d)> %s var '%s' by num=%u type=%d\n", + startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename, + linenumber, + freevic==-1?"Update":"Add", + itok4->name, + (listvic+i)->number, + typenum);*/ + } + return TRUE; +} + +void Const2VarRec(LVIC *varconst) +{ +int i; +int freevic=-1; + if(replasevar==0)return; + for(i=0;irec==varconst->rec)break; + if(freevic==-1&&(listvic+i)->rec==NULL)freevic=i; + } + if(i==cursizevic){ + if(freevic==-1){ + cursizevic+=MAXSIZEVIC; + listvic=(LVIC *)REALLOC(listvic,sizeof(LVIC)*cursizevic); + for(freevic=cursizevic-1;freevic>i;freevic--)(listvic+freevic)->rec=NULL; + } + else i=freevic; + } + (listvic+i)->rec=varconst->rec; + (listvic+i)->contype=varconst->contype; + (listvic+i)->lnumber=varconst->lnumber; + switch(varconst->rec->type){ + case tp_localvar: + case tp_paramvar: + (listvic+i)->typevar=tp_localvar; + break; + case tp_postvar: + case tp_gvar: + (listvic+i)->typevar=tp_gvar; + break; + default: + (listvic+i)->typevar=varconst->rec->type; + break; + } +} + +void ClearVarByNum(ITOK *itok4) +{ + if(replasevar&&itok4->rec&&(itok4->flag&f_useidx)==0){ + for(int i=0;irec==itok4->rec){ + (listvic+i)->rec=NULL; +/* printf("%s(%d)> Clear by constant var '%s'\n", + startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename, + linenumber, + itok4->name);*/ + break; + } + } + } +} + +int UpdVarConst(ITOK *itok4,long long num,int typenum,int operand) +{ +int retcode=FALSE; +int i; + if(replasevar==0||itok4->rec==NULL||(itok4->flag&f_useidx)!=0)return TRUE; + for(i=0;irec==itok4->rec){ +// printf("%s(%d)> Modif var '%s' by num=%u ",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,itok4->name,(listvic+i)->number); + switch(operand){ + case tk_plusequals: + case tk_plusplus: operand=tk_plus; break; + case tk_minusequals: + case tk_minusminus: operand=tk_minus; break; + case tk_xorequals: operand=tk_xor; break; + case tk_andequals: operand=tk_and; break; + case tk_orequals: operand=tk_or; break; + case tk_multequals: operand=tk_mult; break; + case tk_divequals: operand=tk_div; break; + case tk_rrequals: operand=tk_rr; break; + case tk_llequals: operand=tk_ll; break; + case tk_numsign: + if((listvic+i)->contype==tk_float)(listvic+i)->number|=0x80000000; + else if((listvic+i)->contype==tk_double)(listvic+i)->lnumber|=0x8000000000000000LL; + else (listvic+i)->lnumber=-(listvic+i)->lnumber; + return TRUE;; + case tk_not: + (listvic+i)->lnumber=~(listvic+i)->lnumber; + return TRUE;; + } + switch((listvic+i)->contype){ + case tk_char: + case tk_int: + case tk_long: + retcode=calclongnumber(&(listvic+i)->number,num,operand); + break; + case tk_byte: + case tk_word: + case tk_dword: + retcode=calcdwordnumber((unsigned long *)&(listvic+i)->number,num,operand); + break; + case tk_qword: + retcode=calcqwordnumber((unsigned long long *)&(listvic+i)->lnumber,num,operand); + break; + case tk_float: + retcode=calcfloatnumber(&(listvic+i)->fnumber,*(float *) &num,operand); + break; + case tk_double: + retcode=calcdoublenumber(&(listvic+i)->dnumber,*(double *) &num,operand); + break; + } +/* if(retcode)printf("new num=%u\n",(listvic+i)->number); + else{ + puts("error"); + (listvic+i)->rec=NULL; + } */ + break; + } + } + return TRUE; +} + +void FreeGlobalConst() +{ + if(replasevar==0)return; + for(int i=0;irec!=NULL&&(listvic+i)->typevar!=tp_localvar){ + (listvic+i)->rec=NULL; +/* printf("%s(%d)> Clear global constant var\n", + startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename, + linenumber);*/ + } + } +} + +int CheckRegToConst(int reg,ITOK *itok4,int razr) +{ +unsigned long num; +int typenum; +int nr; + nr=convertrazr(®,razr); + if(replasevar&&optinitreg!=FALSE&&razr<=r32&&(regstat+reg)->type==t_id&& + (regstat+reg)->razr>=nr){ + if(isdigit((regstat+reg)->id[0])){ + if(getnumber((regstat+reg)->id,&num,&typenum)){ + Const2Var(itok4,num,typenum); + return TRUE; + } + } + } + return FALSE; +} + +int CheckUpdRegToConst(int reg,ITOK *itok4,int operand,int razr) +{ +unsigned long num; +int typenum; +int nr; + nr=convertrazr(®,razr); + if(replasevar&&optinitreg!=FALSE&&razr<=r32&&(regstat+reg)->type==t_id&& + (regstat+reg)->razr>=nr){ + if(isdigit((regstat+reg)->id[0])){ + if(getnumber((regstat+reg)->id,&num,&typenum))return UpdVarConst(itok4,num,typenum,operand); + } + } + return FALSE; +} + +int SwapVarConst(ITOK *itok2,ITOK *itok4) +{ +int i; +int fir=-1,sec=-1; +LVIC tempvic; + if(replasevar==0)return TRUE; + if(itok4->rec==NULL||(itok4->flag&f_useidx)!=0)sec=-2; + if(itok2->rec==NULL||(itok2->flag&f_useidx)!=0){ + if(sec==-2)return TRUE; + fir=-2; + } + for(i=0;irec==itok4->rec)sec=i; + else if(fir==-1&&(listvic+i)->rec==itok2->rec)fir=i; + } + if(sec==-2)sec=-1; + if(fir==-2)fir=-1; + if(sec!=-1&&fir!=-1){ + memcpy(&tempvic,listvic+fir,sizeof(LVIC)); + memcpy(listvic+fir,listvic+sec,sizeof(LVIC)); + memcpy(listvic+sec,&tempvic,sizeof(LVIC)); + } + else if(sec==-1&&fir!=-1)(listvic+fir)->rec=itok4->rec; + else if(fir==-1&&sec!=-1)(listvic+sec)->rec=itok2->rec; + return TRUE; +} + +int SwapVarRegConst(int reg,ITOK *itok4,int razr) +{ +int i; +int freevic=-1; +unsigned long num; +int typenum; +int nr; +int numinreg=FALSE; + nr=convertrazr(®,razr); + if(replasevar&&itok4->rec&&(itok4->flag&f_useidx)==0&&optinitreg!=FALSE&&razr<=r32&& + (regstat+reg)->type==t_id&&(regstat+reg)->razr>=nr){ + for(i=0;irec==itok4->rec)break; + if(freevic==-1&&(listvic+i)->rec==NULL)freevic=i; + } + if(isdigit((regstat+reg)->id[0])){ + if(getnumber((regstat+reg)->id,&num,&typenum)){ // ॣ + if(i!=cursizevic)ConstToReg((listvic+i)->lnumber,reg,razr); // ॣ + else{ + if(freevic==-1){ + cursizevic+=MAXSIZEVIC; + listvic=(LVIC *)REALLOC(listvic,sizeof(LVIC)*cursizevic); + for(freevic=cursizevic-1;freevic>i;freevic--)(listvic+freevic)->rec=NULL; + } + else i=freevic; + } + (listvic+i)->rec=itok4->rec; // ६ + (listvic+i)->contype=typenum; + (listvic+i)->lnumber=num; + switch(itok4->type){ + case tp_localvar: + case tp_paramvar: + (listvic+i)->typevar=tp_localvar; + break; + case tp_postvar: + case tp_gvar: + (listvic+i)->typevar=tp_gvar; + break; + default: + (listvic+i)->typevar=itok4->type; + break; + } +/* printf("%s(%d)> %s var '%s' by num=%u type=%d\n", + startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename, + linenumber, + freevic==-1?"Update":"Add", + itok4->name, + (listvic+i)->number, + typenum);*/ + } + } + else{ // ॣ + if(i!=cursizevic){ // ६ + ConstToReg((listvic+i)->lnumber,reg,razr); //⥯ ॣ + (listvic+i)->rec=NULL; // ६ 㦥 + } + } + } + return TRUE; +} + +int CheckConstVar(ITOK *itok4) +{ + if(replasevar==FALSE||itok4->rec==NULL||(itok4->flag&f_useidx)!=0)return FALSE; + if(itok4->rec&&(itok4->flag&f_useidx)==0){ + for(int i=0;irec==itok4->rec){ + itok4->lnumber=(listvic+i)->lnumber; + itok4->rm=(listvic+i)->contype; + itok4->flag=0; + warreplasevar(itok4->name); + return TRUE; + + } + } + } + return FALSE; +} + +int CheckConstVar2(ITOK *itok4,long long *num,int *typenum) +{ +// if(replasevar==FALSE||itok4->rec==NULL||(itok4->flag&f_useidx)!=0)return FALSE; + if(replasevar&&itok4->rec&&(itok4->flag&f_useidx)==0){ + for(int i=0;irec==itok4->rec){ + *num=(listvic+i)->lnumber; + *typenum=(listvic+i)->contype; +// warreplasevar(itok4->name); + return TRUE; + + } + } + } + return FALSE; +} + +/* +void updnum(int tok4,long long *num) +{ + switch(tok4){ + case tk_charvar: + case tk_bytevar: + *num=*num&0xff; + break; + case tk_intvar: + case tk_wordvar: + *num=*num&0xffff; + break; + case tk_longvar: + case tk_dwordvar: + *num=*num&0xffffffff; + break; + + } +} + */ + +void CheckConstVar3(int *tok4,ITOK *itok4,int razr) +{ +long long lnum; +int rm; + if(replasevar==FALSE||itok4->rec==NULL||(itok4->flag&f_useidx)!=0)return; + if(*tok4>=tk_charvar&&*tok4<=tk_doublevar){ + if((optimizespeed||itok4->type==tp_gvar||itok4->type==tp_postvar|| + itok4->number>127||(int)(itok4->number)<-127)&&CheckConstVar(itok4)){ + switch(*tok4){ + case tk_charvar: + case tk_bytevar: + itok4->lnumber=itok4->lnumber&0xff; + break; + case tk_intvar: + case tk_wordvar: + itok4->lnumber=itok4->lnumber&0xffff; + break; + case tk_longvar: + case tk_dwordvar: + itok4->lnumber=itok4->lnumber&0xffffffff; + break; + + } +// updnum(*tok4,&itok4->lnumber); +// printf("tok=%d num=%d %s\n",*tok4,itok.number,itok.name); + *tok4=tk_number; + } + else{ + if(CheckConstVar2(itok4,&lnum,&rm)){ + if(short_ok(lnum,razr==r32?TRUE:FALSE)){ + itok4->lnumber=lnum; + itok4->rm=rm; + *tok4=tk_number; + itok4->flag=0; + warreplasevar(itok4->name); + } + } + } + } +} + +#endif diff --git a/programs/develop/cmm/outle.cpp b/programs/develop/cmm/outle.cpp new file mode 100644 index 0000000000..eb928a7923 --- /dev/null +++ b/programs/develop/cmm/outle.cpp @@ -0,0 +1,197 @@ +#include "tok.h" +#include "le.h" + +#define _OUTLE_ + +unsigned short swapshort(unsigned int var) +{ +unsigned short h,l; + l=var>>8; + h=var<<8; + return l|h; +} + +int MakeBin32() +{ + hout=CreateOutPut(outext,"wb"); + if(fwrite(output,outptr,1,hout)!=1){ + ErrWrite(); + fclose(hout); + hout=NULL; + return(-1); + } + return 0; +} + +unsigned int EntryParamStr() +{ +ITOK btok; +int bb=tk_id; +unsigned char *buf=(unsigned char *)"__bufcomstr"; + btok.number=0; + searchtree(&btok,&bb,buf); + if(bb==tk_id)btok.number=0; + else{ + btok.number+=outptrdata; + if((outptrdata%2)==1)btok.number++; /* alignment of entire post data block manditory */ + } + return btok.number; +} + +int MakeMEOS() +{ +MEOSheader hdr; + hout=CreateOutPut(outext,"wb"); + strcpy((char *)hdr.sign,"MENUET01"); + hdr.vers=1; + hdr.start=EntryPoint(); + hdr.size=outptr; + hdr.alloc_mem=Align(outptr+postsize+stacksize,16); + hdr.esp=hdr.alloc_mem-4; + hdr.I_Param=EntryParamStr(); + hdr.I_Icon=0; + memcpy(output+startptr,&hdr,sizeof(MEOSheader)); + if(fwrite(output,outptr,1,hout)!=1){ + ErrWrite(); + fclose(hout); + hout=NULL; + return(-1); + } + return 0; +} + +int MakeLE() +{ +LE_Header hdr; +Object_Table ot[2]; +Page_Map_Table *pmt; +unsigned int i; +int headerofs; +int headsize=sizeof(LE_Header); +unsigned long *fpto; +int sizeb; + CreatStub(stubfile); + memset(&hdr,0,sizeof(LE_Header)); +#ifdef _WC_ + hdr.Signature='EL'; +#else + hdr.Signature='LE'; +#endif + hdr.CPU_Type=i80386; + hdr.Target_OS=1; + hdr.Type_Flags=0x200; + hdr.Number_Of_Memory_Pages=outptr/0x1000+1; + hdr.Initial_CS=1; + hdr.Initial_EI=EntryPoint(); + hdr.Initial_SS=2; + hdr.Initial_ESP=stacksize; + hdr.Memory_Page_Size=0x1000; + hdr.Bytes_On_Last_Page=outptr%0x1000; + hdr.Object_Table_Offset=sizeof(LE_Header); + hdr.Object_Table_Entries=2; + headerofs=ftell(hout); + if(fwrite(&hdr,sizeof(LE_Header),1,hout)!=1){ +errwrite: + ErrWrite(); + fclose(hout); + hout=NULL; + return(-1); + } + + ot[0].Virtual_Segment_Size=outptr+postsize;//hdr.Initial_ESP; + ot[0].Relocation_Base_Address=0x10000; + ot[0].ObjTableFlags=0x2045; + ot[0].Page_MAP_Index=1; + ot[0].Page_MAP_Entries=hdr.Number_Of_Memory_Pages; + ot[1].Virtual_Segment_Size=hdr.Initial_ESP; + ot[1].Relocation_Base_Address=Align(outptr+postsize,0x10000)+0x10000; + ot[1].ObjTableFlags=0x2043; + ot[1].Page_MAP_Index=2; + ot[0].Reserved=ot[1].Reserved=ot[1].Page_MAP_Entries=0; + if(fwrite(&ot,sizeof(Object_Table)*2,1,hout)!=1)goto errwrite; + hdr.Object_Page_Map_Table_Offset=headsize+=sizeof(Object_Table)*2; + + sizeb=sizeof(Page_Map_Table)*hdr.Number_Of_Memory_Pages; + pmt=(Page_Map_Table *)MALLOC(sizeb); + for(i=0;iHigh_Page_Number=swapshort(((i+1)/256)); + (pmt+i)->Low_Page_Number=(unsigned char)((i+1)%256); + (pmt+i)->FLAGS=0; + } + if(fwrite(pmt,sizeb,1,hout)!=1)goto errwrite; + free(pmt); + hdr.Resource_Table_Offset=hdr.Resident_Names_Table_Offset=headsize+=sizeb; + + i=strlen(rawfilename); + string2[0]=(unsigned char)i; + strcpy((char *)&string2[1],rawfilename); + *(long *)&string2[i+2]=0; + if(fwrite(string2,i+5,1,hout)!=1)goto errwrite; + + hdr.Entry_Table_Offset=headsize+=i+4; + headsize++; + sizeb=sizeof(unsigned long)*(hdr.Number_Of_Memory_Pages+1); + fpto=(unsigned long *)MALLOC(sizeb); + hdr.Fixup_Page_Table_Offset=headsize; + memset(fpto,0,sizeb); +// for(i=0;i<(hdr.Number_Of_Memory_Pages+1);i++){ +// fpto[i]=0; +// } + if(fwrite(fpto,sizeb,1,hout)!=1)goto errwrite; + headsize+=sizeb; + +//Fixup_Record_Table +int sizefixpage=0; + hdr.Fixup_Record_Table_Offset=headsize; + for(i=0;itype==CALL_32I|| + ((postbuf+j)->type>=POST_VAR32&&(postbuf+j)->type<=FIX_CODE32))&& + (postbuf+j)->loc>=startblc&&(postbuf+j)->loc<(startblc+4096)){ + int sizerec; + string2[0]=7; + *(unsigned short *)&string2[2]=(unsigned short)((postbuf+j)->loc-startblc); + string2[4]=1; + unsigned int val=*(unsigned long *)&output[(postbuf+j)->loc]; + if(val<65536){ + string2[1]=0; + *(unsigned short *)&string2[5]=(unsigned short)val; + sizerec=7; + } + else{ + string2[1]=0x10; + *(unsigned long *)&string2[5]=val; + sizerec=9; + } + sizefixpage+=sizerec; + if(fwrite(string2,sizerec,1,hout)!=1)goto errwrite; + } + fpto[i+1]=sizefixpage; + } + } + headsize+=sizefixpage; + +//Imported_Procedure_Name_Table + hdr.Imported_Module_Names_Table_Offset= + hdr.Imported_Procedure_Name_Table_Offset=headsize; + string2[0]=0; + if(fwrite(string2,1,1,hout)!=1)goto errwrite; + headsize++; + + + hdr.Fixup_Section_Size=headsize-hdr.Fixup_Page_Table_Offset;//9+sizefixpage; + hdr.Loader_Section_Size=headsize-sizeof(LE_Header); + hdr.Automatic_Data_Object=2; + hdr.Data_Pages_Offset=Align(headsize+headerofs,16/*1024*/); + ChSize(hdr.Data_Pages_Offset); + + fseek(hout,headerofs,SEEK_SET); + if(fwrite(&hdr,sizeof(LE_Header),1,hout)!=1)goto errwrite; + fseek(hout,headerofs+hdr.Fixup_Page_Table_Offset,SEEK_SET); + if(fwrite(fpto,sizeof(unsigned long)*(hdr.Number_Of_Memory_Pages+1),1,hout)!=1)goto errwrite; + free(fpto); + + fseek(hout,0,SEEK_END); + return 0; +} diff --git a/programs/develop/cmm/outobj.cpp b/programs/develop/cmm/outobj.cpp new file mode 100644 index 0000000000..3c09d7cf3e --- /dev/null +++ b/programs/develop/cmm/outobj.cpp @@ -0,0 +1,385 @@ +#include "tok.h" + +void obj_outrecord(int recordtype,unsigned int recordlength,unsigned char *data); +void outeachPUBDEF(struct idrec *ptr); +void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength, + unsigned char *data); + +#define MAXNUMEXTNAME 1024; + +int *numextname; +int maxnumextname=MAXNUMEXTNAME; +unsigned int lenextstr=0; // ப 譨 +int numextern=0; + +int postseg,stackseg; + +unsigned int findextname(int extnum) +{ + for(unsigned int i=0;ifilename); + string2[0]=(unsigned char)i; + strcpy((char *)&string2[1],startfileinfo->filename); + obj_outrecord(0x80,i+1,&string2[0]);// output the LNAMES + sprintf((char *)&string2[3],"%s %s",compilerstr,__DATE__); + i=strlen((char *)&string2[3]); + *(short *)&string2[0]=0; + string2[2]=(unsigned char)i; + obj_outrecord(0x88,i+3,&string2[0]);// output the LNAMES + for(count=0;counttime; + strcpy((char *)&string2[7],(startfileinfo+count)->filename); + i=strlen((startfileinfo+count)->filename); + *(short *)&string2[0]=0xE940; + string2[6]=(unsigned char)i; + obj_outrecord(0x88,i+7,&string2[0]);// output the LNAMES + } + count=outptr-startptr; //ࠧ + unsigned char *data=output+startptr; //砫 + *(short *)&string2[0]=0xE940; + obj_outrecord(0x88,2,&string2[0]);// ਩ + if(!am32){ + *(short *)&string2[0]=0xEA00; + string2[2]=1; + string2[3]=(unsigned char)(modelmem==SMALL?9:8); + obj_outrecord(0x88,4,&string2[0]); + } + else{ + *(short *)&string2[0]=0xA140; + obj_outrecord(0x88,2,&string2[0]); + } + obj_outrecord(0x96,39,(unsigned char *)"\000\005_TEXT\004CODE\004_BSS\003BSS\006DGROUP\005_DATA\004DATA"); +// output the SEGDEF + if(!am32){ + string2[0]=(unsigned char)0x28; + *(short *)&string2[1]=(short)outptr;//count;// Set the length of the segment of DATA or CODE + string2[3]=0x02; // ᥣ _TEXT + *(short *)&string2[4]=0x0103; // CODE Overlay NONE 1 + obj_outrecord(0x98,6,string2); + i=2; + + if(comfile==file_exe&&modelmem==SMALL){ + string2[0]=(unsigned char)0x48; + *(short *)&string2[1]=outptrdata;// Set the length of the segment DATA + string2[3]=0x07; // ᥣ _DATA + *(short *)&string2[4]=0x0108; // DATA Overlay NONE + obj_outrecord(0x98,6,string2); + i++; + } + + postseg=i; + string2[0]=(unsigned char)0x48; + *(short *)&string2[1]=(short)postsize;// Set the length of the segment BSS + string2[3]=0x04; // ᥣ _BSS + *(short *)&string2[4]=0x0105; // BSS Overlay NONE + obj_outrecord(0x98,6,string2); + i++; + + if(comfile==file_exe&&modelmem==SMALL){ + obj_outrecord(0x96,6,(unsigned char *)"\005STACK"); + string2[0]=0x74; + *(short *)&string2[1]=(short)stacksize;// Set the length of the segment STACK + string2[3]=0x09; // ᥣ STACK + *(short *)&string2[4]=0x0109; // STACK Overlay NONE + obj_outrecord(0x98,6,string2); + stackseg=i; + } + string2[0]=6; // DGROUP + if(comfile==file_exe&&modelmem==SMALL){ + *(short *)&string2[1]=0x2FF; + *(short *)&string2[3]=0x3FF;//postseg*256+255;//0x3FF; + *(short *)&string2[5]=0x4ff;//stackseg*256+255;//0x4FF; + i=7; + } + else{ + *(short *)&string2[1]=0x1FF; +// *(short *)&string2[3]=0x2FF; + *(short *)&string2[3]=0x2ff;//postseg*256+255;//0x3FF; + i=5; + } + obj_outrecord(0x9A,i,string2); + } + else{ + string2[0]=(unsigned char)0xA9; + *(long *)&string2[1]=(long)outptr;//count;// Set the length of the segment of DATA or CODE + string2[5]=0x02; // ᥣ _TEXT + *(short *)&string2[6]=0x0103; // CODE Overlay NONE + obj_outrecord(0x99,8,string2); + i=2; +/* + string2[0]=(unsigned char)0xA9; + *(long *)&string2[1]=0;// Set the length of the segment DATA + string2[5]=0x07; // ᥣ _DATA + *(short *)&string2[6]=0x0108; // DATA Overlay NONE + obj_outrecord(0x99,8,string2); + i++;*/ + + postseg=i; + string2[0]=(unsigned char)0xA9; + *(long *)&string2[1]=(long)postsize;// Set the length of the segment BSS + string2[5]=0x04; // ᥣ _BSS + *(short *)&string2[6]=0x0105; // BSS Overlay NONE + obj_outrecord(0x99,8,string2); + i++; + + obj_outrecord(0x96,11,(unsigned char *)"\005STACK\004FLAT");//9,10 + + if(comfile!=file_w32){ + string2[0]=0x75; + *(long *)&string2[1]=(long)stacksize;// Set the length of the segment STACK + string2[5]=0x09; // ᥣ STACK + *(short *)&string2[6]=0x0109; // STACK Overlay NONE + obj_outrecord(0x99,8,string2); + stackseg=i; + } + string2[0]=10; + + obj_outrecord(0x9A,1,string2); //GRPDEF Group: FLAT + string2[0]=6; // DGROUP + i=1; +// *(short *)&string2[i]=0x2FF; //DATA +// i+=2; + *(short *)&string2[i]=postseg*256+255;//0x3FF; //BSS + i+=2; + if(comfile!=file_w32){ + *(short *)&string2[i]=stackseg*256+255;//0x4FF + i+=2; + } + obj_outrecord(0x9A,i,string2); + } +// 뢮 EXTDEF + while(externnum>maxnumextname)maxnumextname+=MAXNUMEXTNAME; + numextname=(int *)MALLOC(maxnumextname*sizeof(int)); +// output the PUBDEF records for each exteral procedures (all procedures) + outeachPUBDEF(treestart); + if(lenextstr!=0)obj_outrecord(0x8c,lenextstr,&string[0]); +// output the data (LEDATA) in 1K chunks as required! + i=0; + char *bufobj=(char *)MALLOC(512*5); + while(itype>=CALL_EXT&&(postbuf+j)->type<=FIX_CODE32&& + (postbuf+j)->loc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){ + if((postbuf+j)->loc>(i+startptr+sizeblock-(am32==FALSE?2:4))){ + sizeblock=(postbuf+j)->loc-i-startptr;// ࠧ + goto restart; + } + } + } + if((i+sizeblock)>count)sizeblock=count-i; + obj_outLEDATA(1,i+startptr,sizeblock,data+i); + int ofsfix=0; + for(j=0;jloc>=(i+startptr)&&(postbuf+j)->loc<(i+sizeblock+startptr)){ + int hold=(postbuf+j)->loc-i-startptr; + if((postbuf+j)->type>=CALL_32I/*POST_VAR*/&&(postbuf+j)->type<=FIX_CODE32){ + bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256)); + bufobj[ofsfix++]=(unsigned char)(hold%256); + bufobj[ofsfix++]=0x14; + bufobj[ofsfix++]=1; + switch((postbuf+j)->type){ + case POST_VAR: + case POST_VAR32: + bufobj[ofsfix++]=postseg; + break; + case FIX_VAR: + case FIX_VAR32: + bufobj[ofsfix++]=(unsigned char)((comfile==file_exe&&modelmem==SMALL)?2:1); + break; + case FIX_CODE: + case FIX_CODE32: + bufobj[ofsfix++]=1; + break; + } + } + if((postbuf+j)->type>=POST_VAR32&&(postbuf+j)->type<=FIX_CODE32){ + + } + else if((postbuf+j)->type==CALL_EXT){ + int numext=findextname((postbuf+j)->num); + if(numext!=0){ + bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0x84:0xA4)|(hold/256)); + bufobj[ofsfix++]=(unsigned char)(hold%256); + bufobj[ofsfix++]=0x56; + bufobj[ofsfix++]=(unsigned char)numext; + } + } + else if((postbuf+j)->type==EXT_VAR){ + int numext=findextname((postbuf+j)->num); + if(numext!=0){ + bufobj[ofsfix++]=(unsigned char)((am32==FALSE?0xC4:0xE4)|(hold/256)); + bufobj[ofsfix++]=(unsigned char)(hold%256); + bufobj[ofsfix++]=0x16; + bufobj[ofsfix++]=1; + bufobj[ofsfix++]=(unsigned char)numext; + } + } + } + } + if(ofsfix!=0)obj_outrecord(0x9C+am32,ofsfix,(unsigned char *)bufobj); + i+=sizeblock; + } + free(bufobj); + if(comfile==file_exe&&modelmem==SMALL){ + i=0; + while(ioutptrdata)obj_outLEDATA(2,i,outptrdata-i,outputdata+i); + else obj_outLEDATA(2,i,1024,outputdata+i); + i+=1024; + } + } + if(sobj!=FALSE){ +// output end of OBJ notifier + string2[0]=0; + i=1; + } + else{ + count=EntryPoint(); + *(short *)&string2[0]=0xC1; // ⮢ . + *(short *)&string2[2]=0x101; + if(count<65536){ + *(short *)&string2[4]=(short)count; + i=6; + } + else{ + *(long *)&string2[4]=(long)count; + i=8; + } + } + obj_outrecord(i==8?0x8B:0x8A,i,string2); + free(numextname); + runfilesize=ftell(hout); + fclose(hout); + hout=NULL; + return 0; +} + +void obj_outLEDATA(unsigned int segm,unsigned int offset,unsigned int recordlength,unsigned char *data) +{ +int checksum=0; +int i; +unsigned char buf[8]; + buf[3]=(unsigned char)segm; + if(offset>(65536-1024)){ + *(short *)&buf[1]=(short)(recordlength+6); + buf[0]=0xA1; + *(long *)&buf[4]=(long)offset; + i=8; + } + else{ + *(short *)&buf[1]=(short)(recordlength+4); + buf[0]=0xA0; + *(short *)&buf[4]=(short)offset; + i=6; + } + fwrite(buf,i,1,hout); + for(i--;i>=0;i--)checksum+=buf[i]; + for(i=0;(unsigned int)iright); + if(ptr->rectok==tk_apiproc){ + i=0; + for(unsigned int j=0;jnum==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){ + i++; + (postbuf+j)->type=CALL_EXT; + externnum++; + if(externnum>=maxnumextname){ + maxnumextname+=MAXNUMEXTNAME; + numextname=(int *)REALLOC(numextname,maxnumextname*sizeof(int)); + } + } + } + if(i)goto nameext; + goto endp; + } + if(externnum!=0&&ptr->rectok==tk_undefproc&&(ptr->flag&f_extern)!=0){ +nameext: + numextname[numextern++]=ptr->recnumber; + i=strlen(ptr->recid); + if((lenextstr+i+2)>=STRLEN){ + obj_outrecord(0x8c,lenextstr,&string[0]); + lenextstr=0; + } + string[lenextstr++]=(unsigned char)i; + strcpy((char *)&string[lenextstr],ptr->recid); + lenextstr+=i+1; + } + else{ + if((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC){ + string2[0]=(unsigned char)(am32==0?0:1); + string2[1]=0x01; + } + else if((ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)||ptr->rectok==tk_structvar){ + if((ptr->flag&f_extern))goto nameext; + if(am32){ + string2[0]=1; + string2[1]=(unsigned char)(ptr->recpost==0?1:postseg); + } + else if(comfile==file_exe&&modelmem==SMALL){ + string2[0]=1; + string2[1]=(unsigned char)(ptr->recpost==0?2:postseg); + } + else{ + string2[0]=(unsigned char)(ptr->recpost==0?0:1); + string2[1]=(unsigned char)(ptr->recpost==0?1:postseg); + } + } + else goto endp; + for(i=0;ptr->recid[i]!=0;i++)string2[i+3]=ptr->recid[i]; + string2[2]=(unsigned char)i; + if(ptr->recnumber<65536){ + *(short *)&string2[i+3]=(short)ptr->recnumber; + string2[i+5]=0x00; + obj_outrecord(0x90,i+6,&string2[0]); + } + else{ + *(long *)&string2[i+3]=(long)ptr->recnumber; + string2[i+7]=0x00; + obj_outrecord(0x91,i+8,&string2[0]); + } + } +endp: + outeachPUBDEF(ptr->left); + } +} + diff --git a/programs/develop/cmm/outpe.cpp b/programs/develop/cmm/outpe.cpp new file mode 100644 index 0000000000..f1a8e4704d --- /dev/null +++ b/programs/develop/cmm/outpe.cpp @@ -0,0 +1,1105 @@ +#include "tok.h" +#include "coff.h" + +#define _OUTPE_ + +/* ----------------------------------------------------------------------- + PE ଠ + ------------------------------------------------------------------------ */ +#define SIZESTUB 96 +#define STRVERS 0x20 //ᬥ饭 ⥪ ஬ ᨨ + +char stub[]={0x4D,0x5A,0x50,0x00,0x02,0x00,0x00,0x00, + 0x04,0x00,0x0F,0x00,0xFF,0xFF,0x00,0x00, + 0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x1A,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00, + + 0xBA,0x0E,0x00,0x0E,0x1F,0xB4,0x09,0xCD, + 0x21,0xB8,0x01,0x4C,0xCD,0x21,0x46,0x6F, + 0x72,0x20,0x57,0x69,0x6E,0x33,0x32,0x20, + 0x6F,0x6E,0x6C,0x79,0x21,0x0D,0x0A,0x24}; + +#define SIZESTUB2 12 +char stub2[]={0x4D,0x5A,0x53,0x50,0x48,0x49,0x4E,0x58, + 0x20,0x43,0x2D,0x2D}; +unsigned int numdll,numapi; +unsigned char FixUpTable=FALSE; // ᮧ ⠡ Fix UP for Windows +unsigned char WinMonoBlock=TRUE; +int numexport=0; +unsigned long ImageBase=0x400000; +unsigned long vsizeheader=0x1000; //㠫 ࠧ . +unsigned long FILEALIGN=0;//512; // ࠢ ᥪ権 䠩 +int filingzerope; + +struct listexport *lexport=NULL; +static unsigned long sizestub; +static unsigned long numrs=1; + +unsigned long Align(unsigned long size,unsigned long val) +{ + if(val<2)return size; + val--; + return (size+val)&(~val); +} + +/* +#include + +void PrintMem(void *mem) +{ +unsigned char *m,*n; +int i,j; + m=(unsigned char *)mem; + for(i=0;i<192;){ + n=m; + for(j=0;j<16;j++,i++){ + printf("%02X ",*m); + m++; + } + for(j=0;j<16;j++){ + char c=*n; + n++; + if(c<0x20||c>0x7e)c='.'; + putch(c); + } + puts(""); + } +} + +void CheckMem() +{ + if(listdll!=NULL){ // api- +DLLLIST *newdll=listdll; //砫 ᯨ᪠ DLL +APIPROC *listapi=newdll->list; +idrec *rec=listapi->recapi; + PrintMem(rec); + } +} */ + +void AddJmpApi() +{ +// api 楤 +//᪮४஢ ⠡ ६饭 + alignersize+=AlignCD(CS,4); + if(listdll!=NULL){ // api- + DLLLIST *newdll=listdll; //砫 ᯨ᪠ DLL + numdll=numapi=0; + for(APIPROC *listapi=newdll->list;;){ + unsigned short numapiprocdll=0; //᫮ ᯮ㥬 ⥪ 楤 + for(short i=0;inum;i++){ //஢ 楤 + idrec *rec=(listapi+i)->recapi; + unsigned int idnum=rec->recnumber; //䨪 ᯨ᪠ + char useapi=FALSE; //䫠 ᯮ짮 + for(unsigned int j=0;jnum==idnum){ + if((postbuf+j)->type==CALL_32){ //諨 + useapi=API_JMP; //䫠 + unsigned long hold=outptr-((postbuf+j)->loc+4); //ﭨ 맮 + *(long *)&output[(postbuf+j)->loc]=hold; //ࠢ + } + else if((postbuf+j)->type==CALL_32I){ + useapi=API_FAST; //䫠 + numrel++; + } + } + } + if(useapi==API_JMP){ // 楤 뢠 + *(short *)&output[outptr]=0x25ff; // JMP + outptr+=2; + rec->recnumber=outptr; //⥯ . 窠 室 + AddReloc(CS); // ⠡ ६饭 + *(long *)&output[outptr]=0; // 맮 + outptr+=4; + numapi++; //饥 ᫮ ᯮ짮 api-楤 + numapiprocdll++; //᫮ ᯮ짮 楤 ⮩ DLL + } + else if(useapi==API_FAST){ + numapi++; //饥 ᫮ ᯮ짮 api-楤 + numapiprocdll++; //᫮ ᯮ짮 楤 ⮩ DLL + } + rec->recrm=useapi; //⨯ 맮 api; 0 - not used + if(rec->newid!=NULL){ + free(rec->newid); //ᯨ᮪ ࠬ஢ 㦥 + rec->newid=NULL; + } + } + newdll->num=numapiprocdll; //ࠢ ᫮ ॠ쭮 ᯮ 楤 + if(numapiprocdll==0){ // ⮩ ⥪ ᯮ 맮 + free(newdll->list); //㤠 ᯨ᮪ 楤. + } + else numdll++; + if(newdll->next==NULL)break; // ᯨ᪠ + newdll=newdll->next; + listapi=newdll->list; + } + } + outptrdata=outptr; +} + +int MakePE() +{ +unsigned short numobj=1; +char *importblock=NULL; +char *relocblock=NULL; +char *exportblock=NULL; +unsigned long psize,vsize=0,sizereloc=0,sizeReloc=0,sizeImport=0,sizeExport=0, + sizebss=0,sizeRes=0; +unsigned long startsec=0,startsecr=0,startsece=0,startsecres=0; +unsigned int posrel=0,sizeimport=0,startimportname=0,sizeexport=0,sizeres=0, + startexportname=0; +unsigned int sizehead; //ࠧ +unsigned int exportnum=0; // ᥪ樨 ᯮ +unsigned int relocnum=0; // ᥪ樨 ६饭 +unsigned int importnum=0; // ᥪ樨 +unsigned int codenum=0; // ᥪ樨 +unsigned int resnum=0; // ᥪ樨 ᮢ + if(hout==NULL)return -1; + if(WinMonoBlock==FALSE){ + vsize=Align(outptr+(wbss==FALSE?postsize:0),OBJECTALIGN);//㠫 ࠧ ᥪ樨 + psize=Align(outptr,FILEALIGN); //䨧᪨ ࠧ ᥪ樨 + } + else vsize=outptr; +// sizehead=((postsize&&wbss)?2:1)*sizeof(OBJECT_ENTRY); + sizehead=numrs*sizeof(OBJECT_ENTRY); + OBJECT_ENTRY *objentry=(OBJECT_ENTRY *)MALLOC(sizehead);//⠢ ꥪ⮢ + memset(objentry,0,sizehead);// ⠡ ꥪ⮢ +//ᥪ .bss + if(wbss){ // post ६ + numobj++; //㢥稢 ᫮ ꥪ⮢ + codenum=1; // ᥪ樨 + strcpy(objentry->name,".bss"); // ᥪ樨 + objentry->vsize=sizebss=Align(postsize,OBJECTALIGN); + objentry->pOffset=objentry->psize=0; + objentry->flags=0xC0000080; + objentry->sectionRVA=vsizeheader; + } + strcpy((objentry+codenum)->name,"CODE"); // + (objentry+codenum)->vsize=vsize; //ࠧ ᥪ樨 + (objentry+codenum)->psize=psize; //ࠧ ᥪ樨 䠩 + (objentry+codenum)->flags=0xe0000060; //䫠 ᥪ樨 + (objentry+codenum)->sectionRVA=vsizeheader+sizebss;//㠫 ᥪ樨 +//ᥪ + if(numapi!=0){ // 맮 api-楤 ᮧ ᥪ + if(!WinMonoBlock){ //᫨ + importnum=numobj; + numobj++; //㢥稢 ᫮ ꥪ⮢ + } + startsec=vsizeheader+vsize+sizebss; //砫 ᥪ樨 + //ॠ ࠧ ᥪ樨 + startimportname=(numdll+1)*20+(numapi+numdll)*(shortimport==0?8:4); + sizeimport=Align(startimportname,FILEALIGN); //ࠧ ᥪ樨 + importblock=(char *)MALLOC(sizeimport); // + memset(importblock,0,sizeimport); // + DLLLIST *newdll=listdll; //⠡窠 dll 㥬묨 楤ࠬ + unsigned long sn,sn1; + sn1=sn=(numdll+1)*20; + for(int i=0;;i++){ + while(newdll->num==0)if((newdll=newdll->next)==NULL)break;//ய ᯮ㥬 + if(newdll==NULL)break; // 横 ᫨ ᯨ᮪ dll + APIPROC *listapi=newdll->list; //⠡窠 楤 ⥪饩 dll + *(long *)&importblock[i*20+12]=startsec+startimportname; + *(long *)&importblock[i*20]=(shortimport==0?startsec+sn:0); + *(long *)&importblock[i*20+16]=startsec+sn+(shortimport==0?(numdll+numapi)*4:0); + sn+=(newdll->num+1)*4; + unsigned int lenn=strlen(newdll->name)+1; + if((lenn+startimportname+1)>=sizeimport){ + sizeimport+=FILEALIGN; //㢥 ࠧ ᥪ樨 + importblock=(char *)REALLOC(importblock,sizeimport); + memset(importblock+sizeimport-FILEALIGN,0,FILEALIGN); + } + strcpy(&importblock[startimportname],newdll->name); + startimportname+=lenn; + for(int n=0,t=0;nnum;n++,t++){ + while((listapi+t)->recapi->recrm==0)t++; + idrec *rec=(listapi+t)->recapi; + unsigned long newadr; + newadr=ImageBase+startsec+sn1+(shortimport==0?(numdll+numapi)*4:0); + if(rec->recrm==API_JMP)*(long *)&output[rec->recnumber]=newadr; + else{ + for(unsigned int j=0;jnum==(unsigned long)rec->recnumber&&(postbuf+j)->type==CALL_32I){ + *(long *)&output[(postbuf+j)->loc]=newadr; //ࠢ + } + } + } + if(useordinal&&rec->recsib!=-1){ + *(long *)&importblock[sn1]=rec->recsib|0x80000000; + if(shortimport==0)*(long *)&importblock[sn1+(numdll+numapi)*4]=rec->recsib|0x80000000; + } + else{ + if((startimportname%2)==1)importblock[startimportname++]=0; + *(long *)&importblock[sn1]=startsec+startimportname; + if(shortimport==0)*(long *)&importblock[sn1+(numdll+numapi)*4]=startsec+startimportname; + if(rec->recsize!=-1)sprintf((char *)string2,"%s@%u",rec->recid,rec->recsize); + else strcpy((char *)string2,rec->recid); + lenn=strlen((char *)string2)+1; + if((lenn+startimportname+4)>=sizeimport){ + sizeimport+=FILEALIGN; + importblock=(char *)REALLOC(importblock,sizeimport); + memset(importblock+sizeimport-FILEALIGN,0,FILEALIGN); + } + *(short *)&importblock[startimportname]=0; + startimportname+=2; + strcpy(&importblock[startimportname],(char *)string2); + startimportname+=lenn; + } + sn1+=4; + } + if(newdll->next==NULL)break; + newdll=newdll->next; + sn1+=4; + } + importblock[startimportname++]=0; + + if(!WinMonoBlock){ //᫨ + strcpy((objentry+importnum)->name,".idata"); // ᥪ樨 + (objentry+importnum)->vsize=sizeImport=Align(sizeimport,OBJECTALIGN); + (objentry+importnum)->psize=sizeimport; + (objentry+importnum)->flags=0xC0000040; + (objentry+importnum)->sectionRVA=startsec; + } + else sizeImport=sizeimport=Align(startimportname,4); + } +//ᥪ ᯮ + if(numexport!=0){ + if(!WinMonoBlock){ //᫨ + exportnum=numobj; + numobj++; //㢥稢 ᫮ ꥪ⮢ + } + startsece=vsizeheader+vsize+sizeImport+sizebss;//砫 ᥪ樨 + startexportname=sizeof(EXPORT_TABLE)+numexport*10;//ॠ ࠧ ᥪ樨 + sizeexport=Align(startexportname,FILEALIGN); //ࠧ ᥪ樨 + exportblock=(char *)MALLOC(sizeexport); // + memset(exportblock,0,sizeexport); // + *(long *)&exportblock[12]=startsece+startexportname;// 䠩 + *(long *)&exportblock[16]=1; //Ordinal Base + *(long *)&exportblock[20]=numexport; //Num of Functions + *(long *)&exportblock[24]=numexport; //Num of Name Pointer + *(long *)&exportblock[28]=startsece+sizeof(EXPORT_TABLE);//Address Table RVA + *(long *)&exportblock[32]=startsece+sizeof(EXPORT_TABLE)+numexport*4;//Name Pointers RVA + *(long *)&exportblock[36]=startsece+sizeof(EXPORT_TABLE)+numexport*8;//Ordinal Table RVA + char *oname; + strcpy((char *)string2,(char *)rawfilename); + oname=strrchr((char *)string2,'\\'); + if(oname==NULL)oname=(char *)string2; + else oname=oname+1; + sprintf((char *)string,"%s.%s",oname,outext); + unsigned int lenn=strlen((char *)string)+1; + if((lenn+startexportname+1)>=sizeexport){ + sizeexport+=FILEALIGN; //㢥 ࠧ ᥪ樨 + exportblock=(char *)REALLOC(exportblock,sizeexport); + memset(exportblock+sizeexport-FILEALIGN,0,FILEALIGN); + } + strcpy(&exportblock[startexportname],(char *)string); + startexportname+=lenn; + for(int i=0;iaddress+vsizeheader+sizebss; // 㭪権 + *(long *)&exportblock[sizeof(EXPORT_TABLE)+(numexport+i)*4]=startsece+startexportname; // + *(short *)&exportblock[sizeof(EXPORT_TABLE)+numexport*8+i*2]=(short)i; //न + lenn=strlen((lexport+i)->name)+1; + if((lenn+startexportname+1)>=sizeexport){ + sizeexport+=FILEALIGN; //㢥 ࠧ ᥪ樨 + exportblock=(char *)REALLOC(exportblock,sizeexport); + memset(exportblock+sizeexport-FILEALIGN,0,FILEALIGN); + } + strcpy(&exportblock[startexportname],(lexport+i)->name); + startexportname+=lenn; + } + free(lexport);//᢮ 㦥 㦭 + if(!WinMonoBlock){ //᫨ + strcpy((objentry+exportnum)->name,".edata"); // ᥪ樨 + (objentry+exportnum)->vsize=sizeExport=Align(sizeexport,OBJECTALIGN); + (objentry+exportnum)->psize=sizeexport; + (objentry+exportnum)->flags=0x40000040; + (objentry+exportnum)->sectionRVA=startsece; + } + else sizeexport=sizeExport=Align(startexportname,4); + } + + if(numres){ //ᥪ ᮢ + if(WinMonoBlock==FALSE){ //᫨ + resnum=numobj; + numobj++; //㢥 ᫮ ꥪ⮢ + } + startsecres=vsizeheader+vsize+sizeImport+sizebss+sizeExport;//砫 ᥪ樨 + LISTRELOC *resrel; + if(MakeRes(startsecres,&resrel))free(resrel); + if(!WinMonoBlock){ //᫨ + strcpy((objentry+resnum)->name,".rsrc"); // ᥪ樨 + (objentry+resnum)->vsize=sizeRes=Align(curposbuf,OBJECTALIGN); + (objentry+resnum)->psize=sizeres=Align(curposbuf,FILEALIGN); + (objentry+resnum)->flags=0x40000040; + (objentry+resnum)->sectionRVA=startsecres; + } + else sizeres=Align(curposbuf,4); + } + +//ᥪ ⠡ ६饭 + if((FixUpTable==TRUE&&numrel!=0)/*||numexport!=0*/){//ᮧ ᥪ ६饭 + if(WinMonoBlock==FALSE||dllflag==TRUE){ //᫨ DLL + relocnum=numobj; + numobj++; //㢥 ᫮ ꥪ⮢ + } + if(WinMonoBlock&&dllflag)startsecr=vsizeheader+ + Align(sizeimport+sizeexport+outptr+(wbss==FALSE?postsize:0)+sizebss+sizeres,OBJECTALIGN); + else startsecr=vsizeheader+vsize+sizeImport+sizeExport+sizebss+sizeres; //㠫 ᥪ樨 + //䨧᪨ ࠧ ᥪ樨 ⠡ ६饭 + sizereloc=Align(numrel*2+(outptr/4096+1)*10,FILEALIGN); + sizeReloc=Align(sizereloc,OBJECTALIGN);//㠫 ࠧ ⮩ ᥪ樨 + relocblock=(char *)MALLOC(sizereloc); // ᥪ + memset(relocblock,0,sizereloc); // + //塞 ᥪ ६饭 + unsigned int startrsec=0; // 砫 ᥪ樨 ६饭 + unsigned int startblc=0; // ࢮ + posrel=8; + do{ + unsigned char fr=FALSE; //䫠 + for(unsigned int i=0;itype==CALL_32I|| + ((postbuf+i)->type>=POST_VAR32&&(postbuf+i)->type<=FIX_CODE32)) + && + (postbuf+i)->loc>=startblc&&(postbuf+i)->loc<(startblc+4096)){ + *(short *)&relocblock[posrel]=(short)((postbuf+i)->loc%4096|0x3000); + posrel+=2; + fr=TRUE; + } + } + if(fr!=FALSE){ //᫨ 뫨 ६頥 + posrel+=posrel%4; //ࠢ + *(long *)&relocblock[startrsec]=vsizeheader+sizebss+startblc; + *(long *)&relocblock[startrsec+4]=posrel-startrsec; //ࠧ ᪠ + startrsec=posrel; + posrel+=8; + } + startblc+=4096; + }while(startblcname,".reloc"); // ᥪ樨 + (objentry+relocnum)->vsize=sizeReloc; //ࠧ ᥪ樨 + (objentry+relocnum)->psize=sizereloc; //ࠧ ᥪ樨 䠩 + (objentry+relocnum)->flags=0x52000040; //䫠 ᥪ樨 + (objentry+relocnum)->sectionRVA=startsecr; //㠫 ᥪ樨 + } + else sizereloc=Align(posrel,4); + } + if(WinMonoBlock){ + psize=sizeimport+sizeexport+(dllflag==FALSE?sizereloc:0)+sizeres; //ࠧ ⥫ + if(wbss==0){ + for(unsigned int i=0;itype==POST_VAR32) + *(long *)&output[(postbuf+i)->loc]+=psize; + } + } + psize+=outptr; + (objentry+codenum)->vsize=vsize=Align(psize+(wbss==FALSE?postsize:0),OBJECTALIGN);//㠫 ࠧ ᥪ樨 + filingzerope=(objentry+codenum)->psize=Align(psize,FILEALIGN); //䨧᪨ ࠧ ᥪ樨 + filingzerope-=psize; + psize=(objentry+codenum)->psize; + sizeImport=sizeExport=0; + if(dllflag==FALSE)sizeReloc=0; + } + PE_HEADER *peheader=(PE_HEADER *)MALLOC(sizeof(PE_HEADER)); + memset(peheader,0,sizeof(PE_HEADER)); + sizehead=Align(sizeof(PE_HEADER)+sizestub+(numobj+(numres!=0?0:1))*sizeof(OBJECT_ENTRY),FILEALIGN); +#ifdef _WC_ + peheader->sign='EP'; +#else + peheader->sign='PE'; +#endif + peheader->cpu=0x14c;//(chip>=4?(chip>=5?0x14e:0x14D):0x14c); +// peheader->date_time=0; + peheader->DLLflag=dllflag; + peheader->numobj=numobj; + peheader->NTheadsize=0xe0; + peheader->flags=(short)(0x818e|(dllflag==0?0:0x2000)); + peheader->Magic=0x10b; + peheader->LinkVer=(short)((short)ver2*256+ver1); + peheader->sizecode=psize; + peheader->sizeuninitdata=postsize; + { + unsigned int temp; + temp=EntryPoint(); + if(temp==0xffffffff)peheader->EntryRVA=0; + else peheader->EntryRVA=vsizeheader+sizebss+temp; + } + peheader->basecode=vsizeheader+sizebss; + peheader->objAlig=OBJECTALIGN; + peheader->fileAlig=FILEALIGN; + peheader->OSver=1; + peheader->SubSysVer=4; + peheader->ImageBase=ImageBase; + peheader->headsize=sizehead; + peheader->imagesize=vsizeheader+ //ࠧ + vsize+ //ࠧ + sizebss+ //ࠧ post + sizeReloc+ //ࠧ ⠡ ६饭 + sizeImport+//ࠧ ⠡ + sizeRes+ //ࠧ ⠡ ᮢ + sizeExport;//ࠧ ⠡ ᯮ + peheader->SubSys=(short)(2+wconsole); //GUIWIN + peheader->stackRezSize=stacksize*0x10; + peheader->stackComSize=stacksize; + peheader->heapRezSize=0x10000; + peheader->heapComSize=0x1000;//postsize; //???? + peheader->numRVA=0x10; + if(!usestub){ + peheader->basedata=12; + peheader->pCOFF=0x40; + } + (objentry+codenum)->pOffset=sizehead; + if(numapi){ + if(!WinMonoBlock)(objentry+importnum)->pOffset=sizehead+psize; + peheader->importRVA=startsec; + peheader->importSize=startimportname; + } + if(numexport){ + if(!WinMonoBlock)(objentry+exportnum)->pOffset=sizehead+psize+sizeimport; + peheader->exportRVA=startsece; + peheader->exportSize=startexportname; + } + if(numres){ + if(!WinMonoBlock)(objentry+resnum)->pOffset=sizehead+psize+sizeimport+sizeexport; + peheader->resourRVA=startsecres; + peheader->resourSize=curposbuf; + } + if(posrel){ + if(!WinMonoBlock)(objentry+relocnum)->pOffset=sizehead+psize+sizeimport+sizeexport+sizeres; + else if(dllflag)(objentry+relocnum)->pOffset=sizehead+psize; + peheader->fixupRVA=startsecr; + peheader->fixupSize=posrel; + } + if(fwrite(peheader,sizeof(PE_HEADER),1,hout)!=1){ +errwrite: + ErrWrite(); + fclose(hout); + hout=NULL; + return(-1); + } + if(fwrite(objentry,sizeof(OBJECT_ENTRY)*numobj,1,hout)!=1)goto errwrite; + ChSize(sizehead); + runfilesize=sizehead+psize; + outputcodestart=ftell(hout); + if(fwrite(output,outptr,1,hout)!=1)goto errwrite; // + if(!WinMonoBlock){ + filingzerope=psize-outptr; + ChSize(runfilesize); + } + if(numapi){ + if(fwrite(importblock,sizeimport,1,hout)!=1)goto errwrite; + free(importblock); + } + if(numexport){ + if(fwrite(exportblock,sizeexport,1,hout)!=1)goto errwrite; + free(exportblock); + } + if(numres){ + if(fwrite(resbuf,sizeres,1,hout)!=1)goto errwrite; + free(resbuf); + } + if(posrel){ + if(WinMonoBlock&&dllflag)ChSize(runfilesize); + if(fwrite(relocblock,sizereloc,1,hout)!=1)goto errwrite; + free(relocblock); + } + if(WinMonoBlock){ + if(dllflag)runfilesize+=sizereloc; + } + else runfilesize+=sizereloc+sizeimport+sizeexport+sizeres; + ChSize(runfilesize); + free(peheader); + free(objentry); + fclose(hout); + hout=NULL; + ImageBase+=vsizeheader+sizebss; // ࠧ ⨭ + return 0; +} + +void ChSize(long size) +{ +char buf[256]; +long delta,ssave; + memset(buf,0,256); + delta=size-ftell(hout); + while(delta>0){ + ssave=256; + if(delta<256)ssave=delta; + fwrite(buf,ssave,1,hout); + delta-=ssave; + } +} + +int AlignCD(char segm,int val) //ࠢ +{ +unsigned int a; + a=(segm==DS?outptrdata:outptr)%val; + if(a==0)val=0; + else val-=a; + a=0; + while(val!=0){ + segm==DS?opd(aligner):op(0x90); + val--; + a++; + } + return a; +} + +void CreatWinStub() +{ + if(!usestub){ + sizestub=SIZESTUB2; + hout=CreateOutPut(outext,"wb"); + if(fwrite(stub2,SIZESTUB2,1,hout)!=1){ + ErrWrite(); + return; + } + } + else CreatStub(winstub); +// ᫮ ᥪ権 + if(wbss){ + if(postsize)numrs++; + else wbss=FALSE; + } + if(WinMonoBlock==FALSE){ //᫨ + if(numapi)numrs++; // 맮 api-楤 + if(numexport)numrs++; //ᮧ ᥪ + if((FixUpTable==TRUE&&posts)/*||numexport!=0*/)numrs++; //ᮧ ᥪ ६饭 + if(numres)numrs++; // + } + else if(dllflag&&FixUpTable==TRUE&&posts!=0)numrs++; //ᮧ ᥪ ६饭 +//ࠧ 㧮筮 ࠧ + vsizeheader=Align(numrs*sizeof(OBJECT_ENTRY)+sizeof(PE_HEADER)+sizestub,0x1000); +} + +void ImportName(char *name) +{ +FILE *infile; +union{ + PE_HEADER pe; + OBJECT_ENTRY obj; +}; +unsigned long temp; +unsigned long ulexport; //ᥪ ᯮ⮬ +unsigned long numobj; //᫮ ꥪ⮢ +unsigned long posdll; // ᥪ樨 䠩 +unsigned long nameadr; //⠡ ᮢ +unsigned long startname; //砫 +unsigned long ordinallist,ordinalbase; +unsigned int i,j; +DLLLIST *newdll; +APIPROC *listapi; + if((infile=fopen(name,"rb"))==NULL){ + ErrOpenFile(name); + return; + } + fseek(infile,0x3C,SEEK_SET); + if(fread(&temp,4,1,infile)!=1){ +errread: + //fprintf(stderr,"Unable to read from file %s.\n",name); printf("Unable to read from file %s.\n",name); + fclose(infile); + return; + } + fseek(infile,0,SEEK_END); + if((unsigned long)ftell(infile)<=temp){ + //fprintf(stderr,"Bad file %s.\n",name); printf("Bad file %s.\n",name); + fclose(infile); + return; + } + fseek(infile,temp,SEEK_SET); + if(fread(&pe,sizeof(PE_HEADER),1,infile)!=1)goto errread; + if(pe.sign!= +#ifdef _WC_ + 'EP' +#else + 'PE' +#endif + ){ + //fprintf(stderr,"For DLL support only format PE.\n"); printf("For DLL support only format PE.\n"); + fclose(infile); + return; + } + if((ulexport=pe.exportRVA)==0){ + //fprintf(stderr,"No export directory on %s.\n",name); printf("No export directory on %s.\n",name); + fclose(infile); + return; + } + numobj=pe.numobj; + temp=pe.objAlig; + while(numobj!=0){ + if(fread(&obj,sizeof(OBJECT_ENTRY),1,infile)!=1)goto errread; + if((obj.sectionRVA+Align(obj.psize,temp))>ulexport)break; + numobj--; + } + if(numobj==0){ + //fprintf(stderr,"Bad object table in %s.\n",name); printf("Bad object table in %s.\n",name); + fclose(infile); + return; + } + posdll=obj.pOffset+ulexport-obj.sectionRVA; + fseek(infile,posdll+24,SEEK_SET); + if(fread(&numobj,4,1,infile)!=1)goto errread; + fseek(infile,posdll+32,SEEK_SET); + if(fread(&nameadr,4,1,infile)!=1)goto errread; + if(fread(&ordinallist,4,1,infile)!=1)goto errread; + nameadr-=ulexport; + ordinallist-=ulexport; + fseek(infile,posdll+12,SEEK_SET); + if(fread(&startname,4,1,infile)!=1)goto errread; + if(fread(&ordinalbase,4,1,infile)!=1)goto errread; + fseek(infile,posdll+startname-ulexport,SEEK_SET); + j=0; + do{ + if(fread(&string[j],1,1,infile)!=1)goto errread; + }while(string[j++]!=0); // ⥪ + newdll=FindDLL(); + listapi=newdll->list; + + for(i=0;inum==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC)); //ࢠ ᯨ᪥ + else listapi=(APIPROC *)REALLOC(listapi,sizeof(APIPROC)*(newdll->num+1)); + (listapi+newdll->num)->recapi=addtotree(itok.name); + newdll->num++; + } + nameadr+=4; + ordinallist+=2; + } + newdll->list=listapi; + fclose(infile); +} + +void CreatStub(char *name) +{ + sizestub=SIZESTUB; + hout=CreateOutPut(outext,"wb"); + sprintf(&stub[STRVERS],"%s%s",compilerstr,__DATE__); + if(name==NULL){ +stdstub: + if(fwrite(stub,SIZESTUB,1,hout)!=1){ +errwrite: + ErrWrite(); + return; + } + } + else{ +EXE_DOS_HEADER exeheader; // header for EXE format +FILE *stubin; + if((stubin=fopen(name,"rb"))==NULL){ + ErrOpenFile(name); + goto stdstub; + } + if(fread(&exeheader,sizeof(EXE_DOS_HEADER),1,stubin)!=1){ +errread: + ErrReadStub(); + fclose(stubin); + goto stdstub; + } + if(exeheader.sign!=0x5A4D){ +errstub: + //fprintf(stderr,"File %s can not be stub file.\n",name); printf("File %s can not be stub file.\n",name); + fclose(stubin); + goto stdstub; + } + fseek(stubin,0,SEEK_END); + sizestub=ftell(stubin); + unsigned long temp; + if(exeheader.ofsreloc>=0x40){ //஢ઠ 32- 䠩 + fseek(stubin,0x3c,SEEK_SET); + if(fread(&temp,4,1,stubin)!=1)goto errread; + if(temp=maxsizelistname){ + maxsizelistname+=MAXLISTNAME; + ListName=(char *)REALLOC(ListName,maxsizelistname); + } + strcpy(ListName+sizelistName,name); + sizelistName+=size+1; +} + +void CreatSymbolTable(idrec *ptr) +{ +unsigned int i; + if(ptr!=NULL){ + CreatSymbolTable(ptr->right); + if(ptr->rectok==tk_apiproc){ + for(unsigned int j=0;jnum==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){ + goto nameext; + } + } + } + else if((externnum!=0&&ptr->rectok==tk_undefproc&&(ptr->flag&f_extern)!=0)|| + ((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC)|| + ((ptr->rectok>=tk_bits&&ptr->rectok<=tk_doublevar)||ptr->rectok==tk_structvar)){ +nameext: + if(numsymbol+1>=maxnumsymbol){ + maxnumsymbol+=MAXNUMSYMBOL; + isymbol=(IMAGE_SYMBOL *)REALLOC(isymbol,maxnumsymbol*sizeof(IMAGE_SYMBOL)); + memset(isymbol+maxnumsymbol*sizeof(IMAGE_SYMBOL)-MAXSIZESYMBOL,0,MAXSIZESYMBOL); // + } + if(ptr->rectok==tk_apiproc||ptr->rectok==tk_undefproc|| + ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)(isymbol+numsymbol)->Type=32; + i=strlen(ptr->recid); + if(i>8){ + (isymbol+numsymbol)->N.Name.Short=0; + (isymbol+numsymbol)->N.Name.Long=sizelistName+4; + AddName(ptr->recid,i); + } + else strncpy((isymbol+numsymbol)->N.sname,ptr->recid,i); + if(ptr->rectok!=tk_apiproc&&ptr->rectok!=tk_undefproc&&(ptr->flag&f_extern)==0){ + (isymbol+numsymbol)->Value=ptr->recnumber; + if(ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)(isymbol+numsymbol)->SectionNumber=(short)(textnum+1); + else (isymbol+numsymbol)->SectionNumber=(short)((ptr->recpost==0?textnum:bssnum)+1); + } + else{ + (NameId+numextern)->num=ptr->recnumber; + (NameId+numextern)->id=numsymbol; + numextern++; + if(numextern>=maxnumnameid){ + maxnumnameid+=MAXNUMSYMBOL; + NameId=(NAMEID *)REALLOC(NameId,maxnumnameid*sizeof(NAMEID)); + } + } + (isymbol+numsymbol)->StorageClass=2; + numsymbol++; + } + CreatSymbolTable(ptr->left); + } +} + +void FreeCoffBuf() +{ + free(ListName); + free(isymbol); + free(NameId); + free(treloc); + fclose(hout); + hout=NULL; +} + +void IncReloc() +{ + numreloc++; + if(numreloc>=maxnumreloc){ + maxnumreloc+=MAXNUMRELOC; + treloc=(IMAGE_RELOCATION *)REALLOC(treloc,maxnumreloc*sizeof(IMAGE_RELOCATION)); + } +} + +void CreatRelocTable() +{ + for(int j=0;jVirtualAddress=(postbuf+j)->loc-startptr; + if((postbuf+j)->type>=CALL_32I&&(postbuf+j)->type<=FIX_CODE32){ + switch((postbuf+j)->type){ + case POST_VAR: + case POST_VAR32: + (treloc+numreloc)->Type=IMAGE_REL_I386_DIR32; + (treloc+numreloc)->SymbolTableIndex=segbss; + break; + case FIX_VAR: + case FIX_VAR32: + case FIX_CODE: + case FIX_CODE32: + (treloc+numreloc)->Type=IMAGE_REL_I386_DIR32; + (treloc+numreloc)->SymbolTableIndex=segtext; + break; + } + IncReloc(); + } + else{ + for(int i=0;inum==(postbuf+j)->num){ + if((postbuf+j)->type==EXT_VAR)(treloc+numreloc)->Type=IMAGE_REL_I386_DIR32; + else (treloc+numreloc)->Type=IMAGE_REL_I386_REL32; + (treloc+numreloc)->SymbolTableIndex=(NameId+i)->id; + IncReloc(); + break; + } + } + } + + } +} + +int MakeCoff() +{ +COFF_HEADER chead; +unsigned long sizehead,curobj,resnum,numresrel,segres,lastoffset,headernum; +OBJECT_ENTRY *objentry; +int i; +LISTRELOC *resrel=NULL; +char *codesecname; + hout=CreateOutPut("obj","wb"); + chead.cpu=0x14c; + chead.SizeOfOptionalHeader=0; + chead.date_time=0; + chead.Characteristics=0x100; + /*if(header)*/numrs=2; +// ᫮ ᥪ権 + if(wbss){ + if(postsize)numrs++; + else wbss=FALSE; + } + if(numres)numrs++; // + chead.numobj=numrs; + sizehead=numrs*sizeof(OBJECT_ENTRY); + objentry=(OBJECT_ENTRY *)MALLOC(sizehead);//⠢ ꥪ⮢ + memset(objentry,0,sizehead);// ⠡ ꥪ⮢ + curobj=0; + lastoffset=sizehead+sizeof(COFF_HEADER); +// if(header){ + strcpy((objentry+curobj)->name,".version"); + sprintf(&stub[STRVERS],"%s%s",compilerstr,__DATE__); + (objentry+curobj)->psize=strlen(&stub[STRVERS])+1; + (objentry+curobj)->pOffset=lastoffset; + (objentry+curobj)->flags=0x100A00; + headernum=curobj; + lastoffset+=(objentry+curobj)->psize; + curobj++; +// } + codesecname=".text"; + if(splitdata==FALSE)codesecname=".codedat"; + strcpy((objentry+curobj)->name,codesecname); + (objentry+curobj)->psize=outptr; + (objentry+curobj)->pOffset=lastoffset; + (objentry+curobj)->flags=0xE0300060; + lastoffset+=outptr; + textnum=curobj; + curobj++; + if(wbss){ + strcpy((objentry+curobj)->name,".bss"); + (objentry+curobj)->psize=postsize; + (objentry+curobj)->flags=0xC0300080; + bssnum=curobj; + curobj++; + } + if(numres){ + strcpy((objentry+curobj)->name,".rsrc$01"); + numresrel=(objentry+curobj)->NumberOfRelocations=MakeRes(0,&resrel); + (objentry+curobj)->psize=curposbuf; + (objentry+curobj)->flags=0x40000040; + resnum=curobj; + } + sizelistName=0;numsymbol=0; + ListName=(char *)MALLOC(MAXLISTNAME); + isymbol=(IMAGE_SYMBOL *)MALLOC(MAXSIZESYMBOL); + memset(isymbol,0,MAXSIZESYMBOL); // + maxsizelistname=MAXLISTNAME; + maxnumnameid=maxnumsymbol=MAXNUMSYMBOL; + NameId=(NAMEID *)MALLOC(MAXSIZENAMEID); + treloc=(IMAGE_RELOCATION *)MALLOC(sizeof(IMAGE_RELOCATION)*MAXNUMRELOC); + maxnumreloc=MAXNUMRELOC; + numreloc=0; + strcpy(isymbol->N.sname,"@comp.id"); + isymbol->Value=0x141F8E; + isymbol->SectionNumber=-1; + isymbol->StorageClass=3; + strcpy((isymbol+1)->N.sname,".file"); + (isymbol+1)->Value=1; + (isymbol+1)->SectionNumber=-2; + (isymbol+1)->StorageClass=0x67; + i=(strlen(startfileinfo->filename)-1)/sizeof(IMAGE_SYMBOL)+1; + (isymbol+1)->NumberOfAuxSymbols=i; + strcpy((isymbol+2)->N.sname,startfileinfo->filename); + numsymbol=i+2; + segtext=numsymbol; + strcpy((isymbol+numsymbol)->N.sname,codesecname); + (isymbol+numsymbol)->SectionNumber=textnum+1; + (isymbol+numsymbol)->StorageClass=3; + (isymbol+numsymbol)->NumberOfAuxSymbols=1; + numsymbol++; + (isymbol+numsymbol)->N.Name.Short=outptr; + numsymbol++; + if(wbss){ + segbss=numsymbol; + strcpy((isymbol+numsymbol)->N.sname,".bss"); + (isymbol+numsymbol)->SectionNumber=bssnum+1; + (isymbol+numsymbol)->StorageClass=3; + (isymbol+numsymbol)->NumberOfAuxSymbols=1; + numsymbol++; + (isymbol+numsymbol)->N.Name.Short=postsize; + numsymbol++; + strcpy((isymbol+numsymbol)->N.sname,"DGROUP"); + (isymbol+numsymbol)->SectionNumber=bssnum+1; + (isymbol+numsymbol)->StorageClass=3; + } + strcpy((isymbol+numsymbol)->N.sname,"FLAT"); + (isymbol+numsymbol)->SectionNumber=-1; + (isymbol+numsymbol)->StorageClass=3; + numsymbol++; + if(numres){ + segres=numsymbol; + strcpy((isymbol+numsymbol)->N.sname,".rsrc$01"); + (isymbol+numsymbol)->StorageClass=3; + (isymbol+numsymbol)->SectionNumber=resnum+1; + numsymbol++; + } +// if(header){ + strcpy((isymbol+numsymbol)->N.sname,".version"); + (isymbol+numsymbol)->SectionNumber=headernum+1; + (isymbol+numsymbol)->StorageClass=3; + numsymbol++; +// } + CreatSymbolTable(treestart); + CreatRelocTable(); + (isymbol+segtext+1)->N.Name.Long=numreloc; + (objentry+textnum)->NumberOfRelocations=numreloc; + if(numreloc){ + (objentry+textnum)->PointerToRelocations=lastoffset; + lastoffset+=sizeof(IMAGE_RELOCATION)*numreloc; + } + if(numres){ + (objentry+resnum)->pOffset=lastoffset; + lastoffset+=curposbuf; + if(numresrel){ + (objentry+resnum)->PointerToRelocations=lastoffset; + lastoffset+=sizeof(IMAGE_RELOCATION)*numresrel; + } + } + chead.COFFsize=numsymbol; + if(numsymbol){ + chead.pCOFF=lastoffset; + } + if(fwrite(&chead,sizeof(COFF_HEADER),1,hout)!=1){ +errwrite: + ErrWrite(); + free(objentry); + if(resrel)free(resrel); + FreeCoffBuf(); + return(-1); + } + if(fwrite(objentry,sizehead,1,hout)!=1)goto errwrite; +// if(header){ + if(fwrite(&stub[STRVERS],(objentry+headernum)->psize,1,hout)!=1)goto errwrite; +// } + if(fwrite(output,outptr,1,hout)!=1)goto errwrite; // + if(numreloc){ + if(fwrite(treloc,numreloc*sizeof(IMAGE_RELOCATION),1,hout)!=1)goto errwrite; + } + if(numres){ + if(fwrite(resbuf,curposbuf,1,hout)!=1)goto errwrite; + free(resbuf); + if(numresrel){ + IMAGE_RELOCATION *rrel; + rrel=(IMAGE_RELOCATION *)MALLOC(sizeof(IMAGE_RELOCATION)*numresrel); + for(i=0;iVirtualAddress=(resrel+i)->val; + (rrel+i)->Type=IMAGE_REL_I386_DIR32NB; + (rrel+i)->SymbolTableIndex=segres; + } + if(fwrite(rrel,sizeof(IMAGE_RELOCATION)*numresrel,1,hout)!=1)goto errwrite; + free(rrel); + } + } + if(numsymbol){ + if(fwrite(isymbol,numsymbol*sizeof(IMAGE_SYMBOL),1,hout)!=1)goto errwrite; + if(sizelistName){ + sizelistName+=4; + if(fwrite(&sizelistName,4,1,hout)!=1)goto errwrite; + if(fwrite(ListName,sizelistName-4,1,hout)!=1)goto errwrite; + } + else{ + if(fwrite(&sizelistName,4,1,hout)!=1)goto errwrite; + sizelistName+=4; + } + } + runfilesize=lastoffset+sizelistName; + free(objentry); + if(resrel)free(resrel); + FreeCoffBuf(); + return 0; +} diff --git a/programs/develop/cmm/pointer.cpp b/programs/develop/cmm/pointer.cpp new file mode 100644 index 0000000000..089e84c0e9 --- /dev/null +++ b/programs/develop/cmm/pointer.cpp @@ -0,0 +1,277 @@ +#define _POINTER_ + +#include "tok.h" + +void dopointerproc() +{ +unsigned int snum; +int razr=r16; +ITOK wtok; +char *wbuf; +SINFO wstr; + if(am32)razr=r32; + itok.rm=itok.sib; + itok.sib=am32==0?CODE16:CODE32; + if((FixUp) + + &&((itok.rm==rm_d32&&am32)||(itok.rm==rm_d16&&am32==0)))//16.07.04 16:01 + //18.08.04 18:03 itok.rm==rm_d32 was itok.rm==CODE32 + + itok.flag|=f_reloc; + else compressoffset(&itok); + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + unsigned int oaddESP=addESP; + if(wtok.npointr<2){ + itok.flag&=~f_far; +// itok.post=0; + snum=initparamproc(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); + op(0xFF); op(0x10+wtok.rm+((wtok.flag&f_far)!=0?8:0)); + outaddress(&wtok); + } + else{ +int reg=BX; + getpointeradr(&wtok,wbuf,&wstr,wtok.npointr-1,am32==0?r16:r32,reg); + snum=initparamproc(); + op66(razr); + op(0xFF); + op(0xD0+reg); /* CALL reg with stack params */ + } + if((wtok.flag&f_typeproc)==tp_cdecl)CorrectStack(snum); + else addESP=oaddESP; + clearregstat(0); +} + +void dopointer() +{ + if(itok.type==tk_proc){ + if(tok2==tk_openbracket){ + dopointerproc(); + nexttok(); + return; + } + itok.rm=itok.sib; + itok.sib=am32==0?CODE16:CODE32; + compressoffset(&itok); + } +int razr=r16; + if(am32||(itok.flag&f_far))razr=r32; + do_d_wordvar(0,razr); +} + +void getpointeradr(ITOK *gstok,char *&gbuf,SINFO *gstr,int numpointer,int razr, int reg) +{ + if(gstok->flag&f_far){ + CheckAllMassiv(gbuf,4,gstr,gstok); + outseg(gstok,2); + op(0xC4); + op(gstok->rm+8*reg); + outaddress(gstok); + itok.segm=ES; + itok.sib=CODE16; + if(reg==BX)itok.rm=rm_BX; + else if(reg==SI)itok.rm=rm_SI; + else if(reg==DI)itok.rm=rm_DI; + warningreg(segs[0]); + } + else{ + int retreg; + if((gstok->flag&f_useidx)==0&&(retreg=CheckIDZReg(gstok->name,reg,razr))!=NOINREG){ + if(am32==0&&retreg!=BX&&retreg!=SI&&retreg!=DI){ + GenRegToReg(reg,retreg,razr); + IDZToReg(gstok->name,reg,razr); + } + else if(retreg!=SKIPREG)reg=retreg; + if(gbuf){ + free(gbuf); + gbuf=NULL; + } + if(gstr->bufstr){ + free(gstr->bufstr); + gstr->bufstr=NULL; + } + goto nomov; + } + if((gstok->flag&f_useidx))IDZToReg(gstok->name,reg,razr); + CheckAllMassiv(gbuf,razr,gstr,gstok); + outseg(gstok,2); + op(0x8B); + op(reg*8+gstok->rm); + outaddress(gstok); +nomov: + itok.segm=DS; + if(am32==0){ + itok.sib=CODE16; + if(reg==BX)itok.rm=rm_BX; + else if(reg==SI)itok.rm=rm_SI; + else if(reg==DI)itok.rm=rm_DI; + } + else{ + itok.sib=CODE32; + itok.rm=reg; + } + } + itok.post=0; + itok.number=0; + itok.flag=gstok->flag&(!f_reloc); + warningreg(regs[am32][reg]); + while(numpointer){ + outseg(&itok,2); + op(0x8B); + op(itok.rm+reg*8); + outaddress(&itok); + numpointer--; + } +} + +void dovalpointer() +{ +int sign=0,rettype,pointr,razr=r8; +int rrettype; +int numpointer=0; +int hnumber=0; +//int i=0; +int reg=BX; +int npointr=0; + do{ + nexttok(); + numpointer++; + }while(tok==tk_mult); +ITOK wtok; +char *wbuf; +SINFO wstr; +unsigned char ocha; +unsigned int oinptr; +unsigned int olinenum; +int otok2; + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + if(numpointer==itok.npointr){ + switch(itok.type){ + case tk_qword: + case tk_double: + razr+=4; + case tk_dword: + case tk_float: + razr+=2; + case tk_word: + razr++; + break; + case tk_long: + razr+=2; + case tk_int: + razr++; + case tk_char: + sign=1; + break; + } + rrettype=rettype=itok.type; + oinptr=inptr2; + ocha=cha2; + olinenum=linenumber; + otok2=tok2; + nexttok(); + if(tok==tk_assign){ + nexttok(); + convert_type(&sign,(int *)&rettype,&pointr); + while(tok==tk_mult){ + nexttok(); + npointr++; + } + if(npointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + hnumber=MultiAssign(razr,USEALLREG,npointr); + if(reg==hnumber)reg=DI; + goto getfromax; + } + } + linenumber=linenum2=olinenum; + cha2=ocha; + inptr2=oinptr; + tok2=otok2; + itok=wtok; + if(itok.type==tk_proc){ + dopointer(); + return; + } + getpointeradr(&itok,wbuf,&wstr,numpointer-1,razr,reg); + tok=tk_charvar+itok.type-tk_char; + switch(itok.type){ + case tk_long: + case tk_dword: + case tk_int: + case tk_word: + do_d_wordvar(sign,razr); + return; + case tk_char: + case tk_byte: + dobytevar(sign); + return; + case tk_float: + dofloatvar(); + return; + case tk_qword: + doqwordvar(); + return; + case tk_double: +// dodoublevar(); + return; + } +getfromax: + convert_returnvalue(rrettype,rettype); +ITOK otok=itok; + getpointeradr(&wtok,wbuf,&wstr,numpointer-1,razr,reg); + switch(rrettype){ + case tk_char: + case tk_byte: + outseg(&itok,2); + op(0x88); + op(itok.rm+hnumber*8); //[reg]=AL + break; + case tk_int: + case tk_word: + case tk_long: + case tk_dword: + case tk_qword: + op66(razr); + outseg(&itok,2); + op(0x89); + op(itok.rm+hnumber*8); // MOV [rmword],AX + break; + case tk_float: + outseg(&itok,2); //fstp var + op(0xd9); + op(itok.rm+0x18); + fwait3(); + break; + case tk_double: + outseg(&itok,2); //fstpq var + op(0xdd); + op(itok.rm+0x18); + fwait3(); + break; + } + itok=otok; + } + else if(numpointer +#endif + +#pragma option -w-pin + +#include +#include + +#include "tok.h" +#include "port.h" +#include "res.h" + +RES *listres; //⠡ ᮢ +int numres=0; //⥪饥 ᫮ ᮢ +int maxres=0; //ᨬ쭮 ᫮ ᮢ + +unsigned short *sortidx; //ᨢ ஢ ᮢ ᮢ +RES *curtres; //⥪ ⠡ ᮢ + +unsigned char *resbuf; +unsigned int cursizeresbuf; +unsigned int curposbuf=0; +unsigned int iconcount=0; //᫮ +unsigned int cursorcount=0; //᫮ ஢ +unsigned int numidres; //᫮ ᮢ ࠧ id +unsigned int numlangres=0; //᫮ ᮢ 몠 +unsigned int numhlangres=0; //᫮ 㧫 몠 +unsigned short langdef=0; +unsigned short numzerotype=0; + +_STRINGS_ *strinfo=NULL; +int numstrtbl=0; + +struct TUSE{ + unsigned short id; + unsigned short count; + char *tname; // ⨯ +}*tuse=NULL; + +unsigned int numtyperes=0; //᫮ ⨯ ᮢ + +void AddType(unsigned short type,char *tname=NULL) +{ + if(tuse==NULL){ + tuse=(TUSE *)MALLOC(sizeof(TUSE)); + tuse->id=type; + tuse->count=1; + if(type==0)tuse->tname=tname; + numtyperes=1; + return; + } + for(unsigned int i=0;iid){ + if(type==0&&stricmp(tname,(tuse+i)->tname)!=0)continue; + (tuse+i)->count++; + return; + } + } + tuse=(TUSE *)REALLOC(tuse,sizeof(TUSE)*(numtyperes+1)); + (tuse+numtyperes)->id=type; + (tuse+numtyperes)->count=1; + if(type==0)(tuse+numtyperes)->tname=tname; + numtyperes++; +} + +static unsigned int idnum; +static char idname[IDLENGTH]; +static char resname[IDLENGTH]; +static int restok; + +void InitBufRes(); //樠஢ +void CheckResBuf(unsigned int size); //஢ ᫨ 㢥 +void AddWString(unsigned char *name); // ப +void AddNumOrd(unsigned char *name); // न/ப +void r_Accelerators(); +void r_Dialog(); +void r_Icon(); +void r_Bitmap(); +void r_Menu(); +void r_Cursor(); +void r_Accelerators(); +void r_Font(); +void r_Stringtable(); +void r_Rcdata(); +void GetFileName(char *name); +unsigned char *LoadFileBin(char *name); +unsigned short GetFlag(_STRINGS_ *type,int num); +void r_Language(); +void r_Version(); +void NewResourse(); + + +void badformat(char *name) +{ +char buf[80]; + sprintf(buf,"bad format in '%s'",name); + preerror(buf); + while(tok!=tk_endline&&tok!=tk_eof)nexttok(); +} + +void expectedrescommand() +{ + preerror("expected resourse command"); + while(tok!=tk_endline&&tok!=tk_eof)nexttok(); +} + +void equalres() +{ + preerror("two resource with equal 'id'"); +} + +void badico() +{ + preerror("not load binare image"); + while(tok!=tk_endline&&tok!=tk_eof)nexttok(); +} + +extern int CheckResName(char *name); +/* +void SaveFile(char *name) +{ +FILE *inih; + if((inih=fopen(name,"wb"))!=NULL){ + fwrite(resbuf,1,curposbuf,inih); + fclose(inih); + } +} */ + +void input_res() +{ + scanlexmode=RESLEX; + nexttok(); + while(tok!=tk_eof){ + while(tok==tk_semicolon||tok==tk_endline)nexttok(); + while(tok==tk_question){ + directive();//ࠡ⪠ ४⨢ + while(tok==tk_semicolon||tok==tk_endline)nexttok(); + } + if(scanlexmode!=RESLEX||tok==tk_eof)break; + idname[0]=0; + resname[0]=0; + idnum=0; + restok=-1; + switch(tok){ + case tk_number: + idnum=itok.number; + nexttok(); + break; + case tk_id: + case tk_ID: + strcpy(idname,itok.name); + strupr(idname); + nexttok(); + break; + case tk_rescommand: + restok=itok.number; + nexttok(); + break; + default: +// printf("line %u: tok=%u\n",linenumber,tok); + unuseableinput(); break; + } + if(restok==-1){ + if(tok==tk_number)restok=CRT_NEWRESOURCE; + else if(tok!=tk_rescommand){ + if(strlen(itok.name)/*&&tok2==tk_string*/){ + restok=0; + strcpy(resname,itok.name); + nexttok(); + NewResourse(); + continue; + } + expectedrescommand(); + } + else{ + restok=itok.number; + nexttok(); + } + } + switch(restok){ + case rc_accelerators: + r_Accelerators(); + break; + case rc_dialogex: + case rc_dialog: + r_Dialog(); + break; + case rc_icon: + r_Icon(); + break; + case rc_bitmap: + r_Bitmap(); + break; + case rc_menuex: + case rc_menu: + r_Menu(); + break; + case rc_cursor: + r_Cursor(); + break; + case rc_font: + r_Font(); + break; + case rc_stringtable: + r_Stringtable(); + break; + case rc_rcdata: + r_Rcdata(); + break; + case rc_language: + r_Language(); + break; + case rc_versioninfo: + r_Version(); + break; + case CRT_NEWRESOURCE: + restok=itok.number; + nexttok(); + NewResourse(); + break; + default: + expectedrescommand(); + nexttok(); + break; + } + } +} + +void GetResBlock() +{ + if(numres==0){ + maxres=DRESNUM; + listres=(RES *)MALLOC(DRESNUM*sizeof(RES)); + memset(listres,0,DRESNUM*sizeof(RES));// ⠡ + } + else{ + if((numres+1)==maxres){ + listres=(RES *)REALLOC(listres,sizeof(RES)*(maxres+DRESNUM)); + memset(listres+maxres,0,DRESNUM*sizeof(RES));// ⠡ + maxres+=DRESNUM; + } + } + curtres=listres+numres; + curtres->lang=langdef; + numres++; +} + +int OpenBlock() +{ + while(tok==tk_endline)nexttok(); + if(tok==tk_openbrace||(tok==tk_rescommand&&itok.number==rc_begin)){ + nexttok(); + while(tok==tk_endline)nexttok(); + return TRUE; + } + return FALSE; +} + +int CloseBlock() +{ + while(tok==tk_endline)nexttok(); + if(tok==tk_closebrace||(tok==tk_rescommand&&itok.number==rc_end)){ + nexttok(); + while(tok==tk_endline)nexttok(); + return TRUE; + } + return FALSE; +} + +unsigned int GetNumber(int par) +{ +unsigned int num=0; + if(tok==tk_number||(tok==tk_minus&&tok2==tk_number))num=doconstdwordmath(); + else{ + numexpected(par); + nexttok(); + } + return num; +} + +void GetOrdinal(unsigned char **name,int par) +{ +NameOrdinal Temp; + if(tok==tk_number){ + Temp.ordinal[0]=0xffff; + Temp.ordinal[1]=(unsigned short)doconstdwordmath(); + } + else if(tok==tk_string){ + Temp.name=(unsigned char *)BackString((char *)string); + nexttok(); + } + else numexpected(par); + *name=Temp.name; +} + +void GetRectangle(unsigned char *buf,int par) +{ +int i; + for(i=0;i<4;){ + *(unsigned short *)&buf[i*2]=(unsigned short)GetNumber(i+par); + i++; + if(tok==tk_endline)break; + expecting(tk_camma); + } + if(i!=4)preerror("expecting window rectangle (4 signed integers)"); +} + +void AddWString(unsigned char *name) +{ +unsigned int pos; +//unsigned char c; + if(name==NULL){ + CheckResBuf(2); + curposbuf+=2; + } + else{ + pos=(strlen((char *)name)+1)*3; + CheckResBuf(pos); + pos=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,(char *)name,-1,(wchar_t *)&resbuf[curposbuf],pos); + curposbuf+=pos*2; + } +} + +void AddNumOrd(unsigned char *name) +{ +NameOrdinal Temp; + Temp.name=name; + if(Temp.ordinal[0]==0xFFFF){ + CheckResBuf(4); + *(unsigned short *)&resbuf[curposbuf]=Temp.ordinal[0]; + *(unsigned short *)&resbuf[curposbuf+2]=Temp.ordinal[1]; + curposbuf+=4; + } + else AddWString(name); +} + +void InitBufRes() +{ + resbuf=(unsigned char *)MALLOC(SIZERESBUF); + memset(resbuf,0,SIZERESBUF);// ⠡ + curposbuf=0; + cursizeresbuf=SIZERESBUF; +} + +void CheckResBuf(unsigned int size) +{ + while((size+curposbuf)>=cursizeresbuf){ + resbuf=(unsigned char *)REALLOC(resbuf,cursizeresbuf+SIZERESBUF); + memset(resbuf+cursizeresbuf,0,SIZERESBUF);// ⠡ + cursizeresbuf+=SIZERESBUF; + } +} + +void FreeOrdinal(unsigned char *name) +{ +NameOrdinal Temp; + if(name){ + Temp.name=name; + if(Temp.ordinal[0]!=0xFFFF)free(name); + } +} + +unsigned short GetFlag(_STRINGS_ *type,int num) +{ + for(int i=0;iid)==0){ + return (type+i)->val; + } + } + return 0; +} + +void r_Language() +{ +unsigned short langsec; + langdef=(unsigned short)GetNumber(1); + expecting(tk_camma); + langsec=(unsigned short)GetNumber(2)*langdef*256; + langdef|=langsec; + while(tok!=tk_endline&&tok!=tk_eof)nexttok(); +} + +void r_Stringtable() +{ +#define MAXSTRTABINFO 64 +static int maxstrinf=MAXSTRTABINFO; +int num; +int j; + if(strinfo==NULL)strinfo=(_STRINGS_ *)MALLOC(sizeof(_STRINGS_)*MAXSTRTABINFO); + while(tok!=tk_endline&&tok!=tk_eof)nexttok(); + if(!OpenBlock())badformat("STRINGTABLE"); // + do{ + num=GetNumber(1); + for(j=0;jval)preerror("String ID is already used"); + } + (strinfo+numstrtbl)->val=(short)num; + if(tok==tk_camma)nexttok(); + if(tok!=tk_string)badformat("STRINGTABLE"); + (strinfo+numstrtbl)->id=BackString((char *)string); + nexttok(); + numstrtbl++; + if(numstrtbl>=maxstrinf){ + maxstrinf+=MAXSTRTABINFO; + strinfo=(_STRINGS_ *)REALLOC(strinfo,maxstrinf*sizeof(_STRINGS_)); + } + }while(!CloseBlock()&&tok!=tk_eof); +} + +void CreatStrTabRes() +{ +unsigned int i,num,j; +int idnum=0; +int usesec; + for(i=0;i<65536;){ + idnum++; + usesec=FALSE; + for(int ii=0;ii<16;ii++,i++){ + for(j=0;jval){ + if(usesec==FALSE){ + usesec=TRUE; + InitBufRes(); + curposbuf=ii*2; + } + char *name=(strinfo+j)->id; + *(unsigned short *)&resbuf[curposbuf]=(unsigned short)strlen(name); + curposbuf+=2; + AddWString((unsigned char *)name); + free(name); + curposbuf-=4; + break; + } + } + curposbuf+=2; + } + if(usesec){ + GetResBlock(); + curtres->type=CRT_STRING; + AddType(CRT_STRING); + curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; + curtres->id=idnum; + } + } + free(strinfo); +} + +void domenu(unsigned int exts) +{ +unsigned char *name; +unsigned int lastpos; +unsigned long help; + if(OpenBlock()){ + do{ + if(tok!=tk_rescommand)badformat("MENU"); + lastpos=(exts==TRUE?curposbuf+12:curposbuf); + CheckResBuf(18); + restok=itok.number; + nexttok(); + switch(restok){ + case rc_menuitem: + if(tok==tk_string){ + name=(unsigned char *)BackString((char *)string); + nexttok(); + if(tok==tk_camma){ + nexttok(); + if(exts){ + if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf+8]=GetNumber(2); + if(tok==tk_camma){ + nexttok(); + if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf]=GetNumber(3); + if(tok==tk_camma){ + do{ + nexttok(); + if(tok==tk_number)*(unsigned long *)&resbuf[curposbuf+4]|=itok.number; + else *(unsigned long *)&resbuf[curposbuf+4]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); + nexttok(); + }while(tok==tk_or); + } + } + } + else{ + if(tok!=tk_camma)*(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)GetNumber(2); + if(tok==tk_camma){ + do{ + nexttok(); + if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; + else *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); + nexttok(); + }while(tok==tk_or||tok==tk_camma); + } + } + } + curposbuf+=(exts==FALSE?4:14); + AddWString(name); + if(exts){ + CheckResBuf(2); + curposbuf=Align(curposbuf,4); + } + free(name); + } + else if(stricmp(itok.name,"SEPARATOR")==0){ + if(exts){ + *(unsigned long *)&resbuf[curposbuf]=0x800; + curposbuf+=16; + } + else curposbuf+=6; + nexttok(); + } + else badformat("MENU"); + break; + case rc_popup: + help=0; + if(tok!=tk_string)badformat("MENU"); + name=(unsigned char *)BackString((char *)string); + *(unsigned short *)&resbuf[lastpos]=(exts==FALSE?0x10:1); + nexttok(); + if(tok==tk_camma){ + if(exts){ + nexttok(); + if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf+8]=GetNumber(2); + if(tok==tk_camma){ + nexttok(); + if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf]=GetNumber(3); + if(tok==tk_camma){ + do{ + nexttok(); + if(tok==tk_number)*(unsigned long *)&resbuf[curposbuf+4]|=itok.number; + else *(unsigned long *)&resbuf[curposbuf+4]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); + nexttok(); + }while(tok==tk_or); + } + if(tok==tk_camma){ + nexttok(); + help=GetNumber(5); + } + } + } + else{ + do{ + nexttok(); + if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; + else *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); + nexttok(); + }while(tok==tk_or); + } + } + curposbuf+=(exts==FALSE?2:14); + AddWString(name); + if(exts){ + CheckResBuf(6); + curposbuf=Align(curposbuf,4); + *(unsigned long *)&resbuf[curposbuf]=help; + curposbuf+=4; + } + if(name)free(name); + domenu(exts); + break; + default: + badformat("MENU"); + break; + } + }while(!CloseBlock()&&tok!=tk_eof); + resbuf[lastpos]|=0x80; + } + else badformat("MENU"); +} + +void r_Menu() +{ +unsigned int exts=FALSE; + if(restok==rc_menuex)exts=TRUE; + GetResBlock(); + curtres->type=CRT_MENU; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_MENU); + InitBufRes(); + while(tok!=tk_endline)nexttok(); + if(tok==tk_rescommand&&itok.number==rc_language){ + unsigned short olang; + olang=langdef; + nexttok(); + r_Language(); + curtres->lang=langdef; + langdef=olang; + } + if(exts){ + *(unsigned long *)&resbuf[0]=0x00040001; + curposbuf=8; + } + else curposbuf=4; + domenu(exts); + curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; +} + +void r_Rcdata() +{ + GetResBlock(); + curtres->type=CRT_RCDATA; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_RCDATA); +char name[256]; + name[0]=0; + GetFileName(name); + if(name[0]!=0)resbuf=LoadFileBin(name); + else if(tok==tk_string)resbuf=LoadFileBin((char *)string); + else{ + InitBufRes(); + if(!OpenBlock())badformat("RCDATA"); + do{ + if(tok==tk_number||(tok==tk_minus&&tok2==tk_number)){ + CheckResBuf(2); + *(unsigned short *)&resbuf[curposbuf]=(unsigned short)GetNumber(0); + curposbuf+=2; + } + else if(tok==tk_string){ + CheckResBuf(itok.number); + for(int i=0;ires=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; +} + +void GetVersPar(unsigned char *buf) +{ + nexttok(); + *(unsigned short *)&buf[2]=(unsigned short)GetNumber(1); + expecting(tk_camma); + *(unsigned short *)&buf[0]=(unsigned short)GetNumber(2); + expecting(tk_camma); + *(unsigned short *)&buf[6]=(unsigned short)GetNumber(3); + expecting(tk_camma); + *(unsigned short *)&buf[4]=(unsigned short)GetNumber(4); +} + +void GetBlockInfo() +{ +int startpos; + do{ + startpos=curposbuf; + CheckResBuf(6); + curposbuf+=6; + if(stricmp("BLOCK",itok.name)==0){ + nexttok(); + if(tok!=tk_string)stringexpected(); + CheckResBuf((itok.number+1)*2+2); + AddWString((unsigned char *)string); + curposbuf=Align(curposbuf,4); + nexttok(); + if(OpenBlock())GetBlockInfo(); + else badformat("VERSIONINFO"); + } + else if(stricmp("VALUE",itok.name)==0){ + nexttok(); + if(tok!=tk_string)stringexpected(); + CheckResBuf((itok.number+1)*2+2); + AddWString((unsigned char *)string); + curposbuf=Align(curposbuf,4); + nexttok(); + if(tok2==tk_string){ + expecting(tk_camma); + CheckResBuf((itok.number+1)*2+2); + AddWString((unsigned char *)string); + *(unsigned short *)&resbuf[startpos+4]=1; + *(unsigned short *)&resbuf[startpos+2]=(unsigned short)itok.number; + nexttok(); + } + else{ + do{ + nexttok(); + CheckResBuf(4); + *(unsigned short *)&resbuf[curposbuf]=(unsigned short)GetNumber(0); + curposbuf+=2; + *(unsigned short *)&resbuf[startpos+2]+=2; + }while(tok==tk_camma); +// nexttok(); + } + } + else badformat("VERSIONINFO"); + *(unsigned short *)&resbuf[startpos]=(unsigned short)(curposbuf-startpos); + curposbuf=Align(curposbuf,4); + }while(CloseBlock()==FALSE); +} + +void r_Version() +{ + GetResBlock(); + InitBufRes(); + curtres->type=CRT_VERSION; + curtres->id=1; + AddType(CRT_VERSION); + *(unsigned short *)&resbuf[2]=0x34; +// if(idname[0]==0)stringexpected(); + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + curposbuf=6; + AddWString((unsigned char *)"VS_VERSION_INFO"); + curposbuf=Align(curposbuf,4); + *(unsigned long *)&resbuf[curposbuf]=0xfeef04bd; + *(unsigned long *)&resbuf[curposbuf+4]=0x00010000; + curposbuf+=8; + while(!OpenBlock()&&tok!=tk_eof){ + switch(GetFlag((_STRINGS_ *)&typeversion,7)){ + case v_fv: + GetVersPar(resbuf+curposbuf); + break; + case v_pv: + GetVersPar(resbuf+curposbuf+8); + break; + case v_ffm: + nexttok(); + *(unsigned long *)&resbuf[curposbuf+16]=(unsigned long)GetNumber(0); + break; + case v_ff: + nexttok(); + *(unsigned long *)&resbuf[curposbuf+20]=(unsigned long)GetNumber(0); + break; + case v_fo: + nexttok(); + *(unsigned long *)&resbuf[curposbuf+24]=(unsigned long)GetNumber(0); + break; + case v_ft: + nexttok(); + *(unsigned long *)&resbuf[curposbuf+28]=(unsigned long)GetNumber(0); + break; + case v_fs: + nexttok(); + *(unsigned long *)&resbuf[curposbuf+32]=(unsigned long)GetNumber(0); + break; + default: + badformat("VERSIONINFO"); + break; + } + } + curposbuf+=44; + GetBlockInfo(); + *(unsigned short *)&resbuf[0]=(unsigned short)curposbuf; + curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; +} + +void r_Dialog() +{ +unsigned char *name=NULL; +unsigned char *font=NULL; +int sizefont=0,i; +NameOrdinal Menu; +NameOrdinal Class; +unsigned int poscount; // 稪 ⮢ +unsigned int exts=FALSE; +//unsigned short id; + Menu.name=NULL; + Class.name=NULL; + if(restok==rc_dialogex)exts=TRUE; + GetResBlock(); + curtres->type=CRT_DIALOG; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_DIALOG); + InitBufRes(); + if(exts){ + *(unsigned long *)&resbuf[0]=0xFFFF0001; + curposbuf=8; + poscount=16; + *(unsigned long *)&resbuf[12]=0x80880000;//WS_POPUP|WS_BORDER|WS_SYSMENU; //⠭ 㬮砭 + } + else{ + *(unsigned long *)&resbuf[0]=0x80880000;//WS_POPUP|WS_BORDER|WS_SYSMENU; //⠭ 㬮砭 + curposbuf=0; + poscount=8; + } + if(tok2!=tk_camma){ //ய᪠ ࠬ + nexttok(); + if(tok2!=tk_camma){ + nexttok(); + if(tok2!=tk_camma)badformat("DIALOG"); + } + } + GetRectangle(&resbuf[curposbuf+10],1); + //। IDHelp + if(tok!=tk_endline&&exts)/**(unsigned long *)&resbuf[curposbuf]=*/GetNumber(0); + while(!OpenBlock()&&tok!=tk_eof){ + if(tok!=tk_rescommand)expectedrescommand(); + switch(itok.number){ + case rc_style: + nexttok(); + *(unsigned long *)&resbuf[exts==TRUE?12:0]=GetNumber(1); + break; + case rc_caption: + nexttok(); + if(tok!=tk_string)stringexpected(); + name=(unsigned char *)BackString((char *)string); + nexttok(); + break; + case rc_font: + nexttok(); + sizefont=GetNumber(1); + expecting(tk_camma); + if(tok!=tk_string)stringexpected(); + font=(unsigned char *)BackString((char *)string); + nexttok(); + break; + case rc_class: + nexttok(); + GetOrdinal(&Class.name,1); +// if(tok!=tk_string)stringexpected(); +// Class.name=(unsigned char *)BackString((char *)string); +// nexttok(); + break; + case rc_exstyle: + nexttok(); + *(unsigned long *)&resbuf[exts==TRUE?8:4]=GetNumber(1); + break; + case rc_language: + unsigned short olang; + olang=langdef; + nexttok(); + r_Language(); + curtres->lang=langdef; + langdef=olang; + break; + default: + if(exts&&itok.number==rc_menu){ + nexttok(); + GetOrdinal(&Menu.name,1); + } + else badformat("DIALOG"); + break; + } + while(tok==tk_endline)nexttok(); + } +//ନ஢뢠 + curposbuf=exts==TRUE?26:18; + AddNumOrd(Menu.name); + FreeOrdinal(Menu.name); + AddNumOrd(Class.name); + FreeOrdinal(Class.name); + AddWString(name); + if(name)free(name); + if(sizefont){ + resbuf[exts==TRUE?12:0]|=0x40; + *(unsigned short *)&resbuf[curposbuf]=(unsigned short)sizefont; + curposbuf+=2; + if(exts){ + *(unsigned int *)&resbuf[curposbuf]=0x01000000; + curposbuf+=4; + } + AddWString(font); + free(font); + } + while(!CloseBlock()&&tok!=tk_eof){ +// do{ + if(tok!=tk_rescommand)expectedrescommand(); + restok=itok.number; + nexttok(); + curposbuf=Align(curposbuf,4); + CheckResBuf(34); + name=Menu.name=NULL; + i=1; + if(exts)curposbuf+=8; + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?16:18)]=0XFFFF; + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=defdialog[restok].dclass; + *(unsigned long *)&resbuf[curposbuf]=defdialog[restok].style|0x50000000; + switch(restok){ + case rc_control: + GetOrdinal(&Menu.name,1); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(2); + else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(2); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=(unsigned short)itok.number; + else{ + if(tok==tk_string)strncpy(itok.name,(char *)string,IDLENGTH); + i=GetFlag((_STRINGS_ *)&typeclass,6); + if(!i)name=(unsigned char *)BackString((char *)string); + else *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=(unsigned short)i; + } + nextexpecting2(tk_camma); + while(tok==tk_endline)nexttok(); + *(unsigned long *)&resbuf[curposbuf]|=GetNumber(4); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + GetRectangle(&resbuf[curposbuf+(exts==TRUE?4:8)],5); + if(exts&&tok==tk_number)*(unsigned long *)&resbuf[curposbuf-4]=GetNumber(9); + while(tok!=tk_endline&&tok!=tk_eof&&tok!=tk_rescommand)nexttok(); //ய 譨 ࠬ஢ + break; + case rc_auto3state: + case rc_autocheckbox: + case rc_autoradiobutton: + case rc_checkbox: + case rc_ctext: + case rc_defpushbutton: + case rc_groupbox: + case rc_ltext: + case rc_pushbox: + case rc_pushbutton: + case rc_radiobutton: + case rc_rtext: + case rc_state3: + if(tok!=tk_string)stringexpected(); + Menu.name=(unsigned char *)BackString((char *)string); + nexttok(); + if(tok==tk_camma)nexttok(); + while(tok==tk_endline&&tok!=tk_eof)nexttok(); + i++; + case rc_combobox: + case rc_edittext: + case rc_listbox: + case rc_scrollbar: + if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(i); + else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(i); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + GetRectangle(&resbuf[curposbuf+(exts==TRUE?4:8)],i+1); + if(tok!=tk_endline){ + *(unsigned long *)&resbuf[curposbuf]|=(unsigned long)GetNumber(i+5); + if(tok==tk_camma){ + nexttok(); + *(unsigned long *)&resbuf[curposbuf+(exts==TRUE?-4:4)]=(unsigned long)GetNumber(i+6); + } + } + if(exts&&tok==tk_number)*(unsigned long *)&resbuf[curposbuf-4]=GetNumber(i+9); + while(tok!=tk_endline&&tok!=tk_eof&&tok!=tk_rescommand)nexttok(); //ய 譨 ࠬ஢ + break; + case rc_icon: + GetOrdinal(&Menu.name,1); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(2); + else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(2); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?4:8)]=(unsigned short)GetNumber(3); + expecting(tk_camma); + while(tok==tk_endline)nexttok(); + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?6:10)]=(unsigned short)GetNumber(4); + if(tok==tk_camma){ + nexttok(); + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?8:12)]=(unsigned short)GetNumber(5); + if(tok==tk_camma){ + nexttok(); + *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?10:14)]=(unsigned short)GetNumber(6); + if(tok==tk_camma){ + nexttok(); + *(unsigned long *)&resbuf[curposbuf]|=GetNumber(7); + } + } + } + break; + default: + badformat("DIALOG"); + break; + } + while(tok==tk_endline)nexttok(); + *(unsigned short *)&resbuf[poscount]=(unsigned short)(*(unsigned short *)&resbuf[poscount]+1); + curposbuf+=(exts==TRUE?20:22); + if(name){ + curposbuf-=4; + AddWString(name); + free(name); + } + if(Menu.name){ + AddNumOrd(Menu.name); + FreeOrdinal(Menu.name); + } + else curposbuf+=2; + CheckResBuf(6); + curposbuf+=2; +// }while(!CloseBlock()&&tok!=tk_eof); + } + curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; +} + +void GetFileName(char *name) +{ + while(tok!=tk_string&&tok!=tk_endline&&tok!=tk_eof){ + int i; + for(i=0;i<7;i++){ + if(stricmp(itok.name,typemem[i].id)==0)break; + } + if(i==7){ + strcpy(name,itok.name); + i=strlen(itok.name); + name[i++]=cha2; + for(;;){ + cha2=input[inptr2++]; + if(cha2<=0x20)break; + name[i++]=cha2; + } + name[i]=0; + break; + } + nexttok(); + } +} + +unsigned char *LoadFileBin(char *name) +{ +int inico; +unsigned char *bitobr; + if((inico=open(name,O_BINARY|O_RDONLY))==-1){ + badinfile(name); + return NULL; + } + if((curposbuf=getfilelen(inico))==0){ + badinfile(name); + close(inico); + return NULL; + } + bitobr=(unsigned char *)MALLOC(curposbuf); + if((unsigned int)read(inico,bitobr,curposbuf)!=curposbuf){ + errorreadingfile(name); + close(inico); + free(bitobr); + return NULL; + } + close(inico); + nexttok(); + return bitobr; +} + +unsigned char *LoadBitmap() +{ +//㧨 +unsigned char *bitobr=NULL; +char name[80]; + curposbuf=0; + name[0]=0; + GetFileName(name); + if(name[0]!=0)bitobr=LoadFileBin(name); + else if(tok==tk_endline){ // 䠩 + InitBufRes(); + if(!OpenBlock()){ + badico(); + return NULL; + } + do{ + inptr=inptr2; + cha=cha2; + if(tok!=tk_singlquote)badico(); + whitespace(); //ய ᨬ + CheckResBuf(16); + displaytokerrors=1; + do{ + unsigned char hold=0; + for(int i=0;i<2;i++){ + hold*=(unsigned char)16; + if(isdigit(cha))hold+=(unsigned char)(cha-'0'); + else if(isxdigit(cha))hold+=(unsigned char)((cha&0x5f)-'7'); + else expectederror("hexadecimal digit"); + nextchar(); + } + resbuf[curposbuf++]=hold; + whitespace(); //ய ᨬ + }while(cha!='\''&&cha!=26); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + nexttok(); + }while(!CloseBlock()&&tok!=tk_eof); + bitobr=(unsigned char *)REALLOC(resbuf,curposbuf); + } + else if(tok==tk_string)bitobr=LoadFileBin((char *)string); + return bitobr; +} + +void r_Bitmap() +{ +unsigned int size; +unsigned char *bitobr; + if((bitobr=LoadBitmap())==NULL)return; + size=curposbuf-14; + GetResBlock(); //⬠ + curtres->type=CRT_BITMAP; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + curtres->size=size; + curtres->res=(unsigned char *)MALLOC(size); + AddType(CRT_BITMAP); + memcpy(curtres->res,bitobr+14,size); + free(bitobr); +} + +void NewResourse() +{ +unsigned char *bitobr=NULL; +char name[256]; + GetResBlock(); + if(resname[0]==0)curtres->type=restok; + else curtres->tname=BackString(resname); + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(restok,curtres->tname); + name[0]=0; + GetFileName(name); + if(name[0]!=0)bitobr=LoadFileBin(name); + else if(tok==tk_string)bitobr=LoadFileBin((char *)string); + else stringexpected(); + if(bitobr!=NULL){ + curtres->res=bitobr; + curtres->size=curposbuf; + } + nexttok(); +} + +void r_Font() +{ +unsigned char *fontobr; + if((fontobr=LoadBitmap())==NULL)return; + if((unsigned short)curposbuf==*(unsigned short *)&fontobr[2]){ + GetResBlock(); //䮭 + curtres->type=CRT_FONT; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + curtres->size=curposbuf; + curtres->res=fontobr; + AddType(CRT_FONT); + } +} + +void r_Icon() +{ +unsigned char *icoobr; +unsigned long size; +//㧨 + if((icoobr=LoadBitmap())==NULL)return; + GetResBlock(); //㯯 + curtres->type=CRT_GROUP_ICON; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_GROUP_ICON); +unsigned int countico=*(unsigned short *)&icoobr[4]; //᫮ +int sizeicohead=sizeof(_ICOHEAD_)+(sizeof(_RESDIR_)*countico); + curtres->size=sizeicohead; + curtres->res=(unsigned char *)MALLOC(sizeicohead); +unsigned char *icohead=curtres->res; +unsigned int i; + for(i=0;i<6;i++)icohead[i]=icoobr[i]; // +unsigned int ofs=6; +unsigned int ofs2=6; + for(i=0;itype=CRT_ICON; + curtres->id=iconcount; + curtres->size=size=*(unsigned long *)&icohead[ofs+8]; + curtres->res=(unsigned char *)MALLOC(size); + AddType(CRT_ICON); + unsigned int ofs3=*(unsigned int *)&icoobr[ofs2+12]; + for(j=0;(unsigned int)jres[j]=icoobr[j+ofs3]; + ofs+=sizeof(_RESDIR_); + ofs2+=sizeof(_RESDIR_)+2; + } + free(icoobr); +} + +void r_Cursor() +{ +unsigned char *curobr; +unsigned long size; +//㧨 + if((curobr=LoadBitmap())==NULL)return; + GetResBlock(); //㯯 ஢ + curtres->type=CRT_GROUP_CURSOR; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_GROUP_CURSOR); +unsigned int countcur=*(unsigned short *)&curobr[4]; //᫮ ஢ 䠩 +int sizecurhead=sizeof(_ICOHEAD_)+(sizeof(_CURDIR_)*countcur); + curtres->size=sizecurhead; + curtres->res=(unsigned char *)MALLOC(sizecurhead); +unsigned char *curhead=curtres->res; +unsigned int i; + for(i=0;i<6;i++)curhead[i]=curobr[i]; // +unsigned int ofs=6; +unsigned int ofs2=6; + for(i=0;itype=CRT_CURSOR; + curtres->id=cursorcount; + curtres->size=size=*(unsigned long *)&curhead[ofs+8]=*(unsigned long *)&curobr[ofs2+8]+4; + curtres->res=(unsigned char *)MALLOC(size); + AddType(CRT_CURSOR); + unsigned int ofs3=*(unsigned int *)&curobr[ofs2+12]; + *(unsigned short *)&curtres->res[0]=*(unsigned short *)&curobr[ofs2+4]; + *(unsigned short *)&curtres->res[2]=*(unsigned short *)&curobr[ofs2+6]; + size-=4; + for(int j=0;(unsigned int)jres[j+4]=curobr[j+ofs3]; + ofs+=sizeof(_CURDIR_); + ofs2+=sizeof(_CURDIR_)+2; + } + free(curobr); +} + +void r_Accelerators() +{ + GetResBlock(); + curtres->type=CRT_ACCELERATOR; + if(idname[0]==0)curtres->id=idnum; + else curtres->name=BackString(idname); + AddType(CRT_ACCELERATOR); + InitBufRes(); + if(OpenBlock()){ + do{ + CheckResBuf(8); + if(tok==tk_string){ + unsigned char c; + c=string[0]; + if(c=='^'){ + c=string[1]; + if(c<0x40)preerror("Unsolved symbol for Contrl");//error + c-=0x40; + } + *(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)c; + nexttok(); + } + else{ + *(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)GetNumber(1); + } + expecting(tk_camma); + *(unsigned short *)&resbuf[curposbuf+4]=(unsigned short)GetNumber(2); + if(tok==tk_camma){ + nexttok(); + if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; + *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typeacceler,5);//GetAccerFlag(); + nexttok(); + while(tok!=tk_endline){ + if(tok==tk_camma)nexttok(); + if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; + *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typeacceler,5);//GetAccerFlag(); + nexttok(); + } + } + curposbuf+=8; + }while(!CloseBlock()&&tok!=tk_eof); + resbuf[curposbuf-8]|=0x80; + } + else badformat("ACCELERATORS"); + curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); + curtres->size=curposbuf; +} + +void SortRes() +{ +int i,j,k; +int sortpos=0; // ᯨ᪥ ஢ + for(i=0;iid>(tuse+j)->id){ + buf.id=(tuse+i)->id; + buf.count=(tuse+i)->count; + buf.tname=(tuse+i)->tname; + (tuse+i)->id=(tuse+j)->id; + (tuse+i)->count=(tuse+j)->count; + (tuse+i)->tname=(tuse+j)->tname; + (tuse+j)->count=buf.count; + (tuse+j)->id=buf.id; + (tuse+j)->tname=buf.tname; + } + if((tuse+i)->id==(tuse+j)->id){ + if(stricmp((tuse+i)->tname,(tuse+j)->tname)>0){ + buf.count=(tuse+i)->count; + buf.tname=(tuse+i)->tname; + (tuse+i)->count=(tuse+j)->count; + (tuse+i)->tname=(tuse+j)->tname; + (tuse+j)->count=buf.count; + (tuse+j)->tname=buf.tname; + } + } + } + if((tuse+i)->id==0)numzerotype++; + } + + sortidx=(unsigned short *)MALLOC(sizeof(unsigned short)*numres); + for(i=0;iid==(listres+j)->type){ + if((listres+j)->lang){ + numlangres++; + numhlangres++; + } + if((tuse+i)->count==1){ + sortidx[sortpos++]=(unsigned short)j; + break; + } + else{ + if(k==0)sortidx[sortpos++]=(unsigned short)j; + else{ + int m=k; //᫮ ⮢ ⨯ + int n=sortpos-k; + do{ + m--; + if((listres+j)->name==NULL&&(listres+sortidx[m+n])->name==NULL){ + if((listres+j)->id>=(listres+sortidx[m+n])->id){// + if((listres+j)->id==(listres+sortidx[m+n])->id){ //ࠢ + numidres--; + numlangres++; + if((listres+j)->lang==0){ + numlangres++; + numhlangres++; + } + if((listres+j)->lang==(listres+sortidx[m+n])->lang)equalres(); + if((listres+j)->lang>(listres+sortidx[m+n])->lang){ // + sortidx[n+m+1]=(unsigned short)j; // + break; + } + } + else{ + sortidx[n+m+1]=(unsigned short)j; // + break; + } + } + sortidx[n+m+1]=sortidx[n+m]; //ᤢ + } + else if((listres+j)->name==NULL&&(listres+sortidx[m+n])->name!=NULL){ + sortidx[n+m+1]=(unsigned short)j; + break; + } + else if((listres+j)->name!=NULL&&(listres+sortidx[m+n])->name==NULL){ + sortidx[n+m+1]=sortidx[n+m]; + } + else{ + int cmp; + if((cmp=strcmp((listres+j)->name,(listres+sortidx[m+n])->name))>=0){ + if(cmp==0){ + numidres--; + numlangres++; + if((listres+j)->lang==0){ + numlangres++; + numhlangres++; + } +// numhlangres--; + if((listres+j)->lang==(listres+sortidx[m+n])->lang)equalres(); + if((listres+j)->lang>(listres+sortidx[m+n])->lang){ + sortidx[n+m+1]=(unsigned short)j; + break; + } + } + else{ + sortidx[n+m+1]=(unsigned short)j; + break; + } + } + sortidx[n+m+1]=sortidx[n+m]; + } + if(m==0)sortidx[sortpos-k]=(unsigned short)j; + }while(m>0); + sortpos++; + } + } + k++; + } + } + } +/* + for(i=0;itype,(listres+sortidx[i])->id, + (listres+i)->type,(listres+i)->id); + } + */ +} + + +int MakeRes(unsigned long ofsres,LISTRELOC **listrel) +{ +int i,j; +unsigned long nextofs; +unsigned int startlang,ofsback; +unsigned int startofsdata,startdata; +int numrel=0; +RES *curres; +LISTRELOC *listr=NULL; + linenumber=0; + InitBufRes(); + numidres=numres; + SortRes(); +//ᮧ ୥ ஢ + *(unsigned short *)&resbuf[12]=(unsigned short)numzerotype; + *(unsigned short *)&resbuf[14]=(unsigned short)(numtyperes-numzerotype); + curposbuf=16; + nextofs=numtyperes*8+16; +// ࠧ஢ ஢ + startlang=curposbuf+numtyperes*24+numidres*8; + startofsdata=startlang+numhlangres*16+numlangres*8; + startdata=startofsdata+numres*16; + CheckResBuf(startdata-curposbuf); + for(i=0;iid==0){ + *(unsigned long *)&resbuf[curposbuf]=startdata|0x80000000; + curres=listres+sortidx[i]; + int len=strlen(curres->tname); + CheckResBuf(startdata-curposbuf+len*2+4); + *(unsigned short *)&resbuf[startdata]=(unsigned short)len; + unsigned char c; + len=0; + startdata+=2; + for(;;){ + c=curres->tname[len++]; + if(c==0)break; + resbuf[startdata]=c; + startdata+=2; + } + free(curres->tname); + } + else *(unsigned long *)&resbuf[curposbuf]=(tuse+i)->id; + *(unsigned long *)&resbuf[curposbuf+4]=nextofs|0x80000000; + nextofs+=(tuse+i)->count*8+16; + curposbuf+=8; + } +// ࠧ஢ ஢ +/* startlang=curposbuf+numtyperes*16+numidres*8; + startofsdata=startlang+numhlangres*16+numlangres*8; + startdata=startofsdata+numres*16; + CheckResBuf(startdata-curposbuf);*/ +//ᮧ ஢ 몠 + curres=listres+sortidx[0]; + for(j=0;jtype; + while((unsigned int)curres->type==type){ + int k=j; + if(curres->name){ // + if(j<(numres-1)&&type==(unsigned int)(listres+sortidx[j+1])->type&& + (listres+sortidx[j+1])->name!=NULL) + while(strcmp(curres->name,(listres+sortidx[j+1])->name)==0)j++; + *(unsigned short *)&resbuf[ofsback]=(unsigned short)(*(unsigned short *)&resbuf[ofsback]+1); + *(unsigned long *)&resbuf[curposbuf]=startdata|0x80000000; + int len=strlen(curres->name); + CheckResBuf(startdata-curposbuf+len*2+4); + *(unsigned short *)&resbuf[startdata]=(unsigned short)len; + unsigned char c; + len=0; + startdata+=2; + for(;;){ + c=curres->name[len++]; + if(c==0)break; + resbuf[startdata]=c; + startdata+=2; + } +// startdata=Align(startdata,4); + free(curres->name); + } + else{ // id + if(j<(numres-1)&&type==(unsigned int)(listres+sortidx[j+1])->type) + while(curres->id==(listres+sortidx[j+1])->id)j++; + *(unsigned short *)&resbuf[ofsback+2]=(unsigned short)(*(unsigned short *)&resbuf[ofsback+2]+1); + *(unsigned long *)&resbuf[curposbuf]=curres->id; + } + curposbuf+=4; + if(j!=k){ //᪮쪮 ࠧ묨 몠 + *(unsigned long *)&resbuf[curposbuf]=startlang|0x80000000; + *(unsigned long *)&resbuf[startlang+12]=j-k+1; + startlang+=16; + for(;k<=j;k++){ + *(unsigned long *)&resbuf[startlang]=(listres+sortidx[k])->lang; + *(unsigned long *)&resbuf[startlang+4]=startofsdata; + startlang+=8; + startofsdata+=16; + } + } + else{ + if(curres->lang){//㪠 + *(unsigned long *)&resbuf[curposbuf]=startlang|0x80000000; + resbuf[startlang+14]=1; + startlang+=16; + *(unsigned long *)&resbuf[startlang]=curres->lang; + *(unsigned long *)&resbuf[startlang+4]=startofsdata; + startlang+=8; + } + else *(unsigned long *)&resbuf[curposbuf]=startofsdata; + startofsdata+=16; + } + curposbuf+=4; + j++; + if(j==numres)break; + curres=listres+sortidx[j]; + } + } + curposbuf=startlang; +//ᮧ ஢ ᬥ饭 + for(i=0;ival=curposbuf; + numrel++; + curposbuf+=4; + *(unsigned long *)&resbuf[curposbuf]=curres->size; + curposbuf+=12; + CheckResBuf(startdata-curposbuf+curres->size); + memcpy(resbuf+startdata,curres->res,curres->size); + free(curres->res); + startdata+=curres->size; + } + curposbuf=startdata; + nextofs=Align(curposbuf,FILEALIGN); + CheckResBuf(nextofs-curposbuf); +// SaveFile("resorse"); + *listrel=listr; + return numrel; +} diff --git a/programs/develop/cmm/res.h b/programs/develop/cmm/res.h new file mode 100644 index 0000000000..949410ff0f --- /dev/null +++ b/programs/develop/cmm/res.h @@ -0,0 +1,218 @@ +#define CRT_NEWRESOURCE 0x2000 +#define CRT_ERROR 0x7FFF +#define CRT_CURSOR 1 +#define CRT_BITMAP 2 +#define CRT_ICON 3 +#define CRT_MENU 4 +#define CRT_DIALOG 5 +#define CRT_STRING 6 +#define CRT_FONTDIR 7 +#define CRT_FONT 8 +#define CRT_ACCELERATOR 9 +#define CRT_RCDATA 10 +#define CRT_MESSAGETABLE 11 +#define CRT_GROUP_CURSOR 12 +#define CRT_GROUP_ICON 14 +#define CRT_VERSION 16 +#define CRT_DLGINCLUDE 17 +#define CRT_PLUGPLAY 19 +#define CRT_VXD 20 +#define CRT_ANICURSOR 21 +#define CRT_ANIICON 22 +#define CRT_NEWBITMAP (CRT_BITMAP|CRT_NEWRESOURCE) +#define CRT_NEWMENU (CRT_MENU|CRT_NEWRESOURCE) +#define CRT_NEWDIALOG (CRT_DIALOG|CRT_NEWRESOURCE) + +#define TOTALTYPERES 22 +#define NUMMENUPOPUP 8 + +struct RES{ + int type; //⨯ + char *tname; // ⨯ + int id; // id + char *name; // + unsigned short lang; // + unsigned char *res; //㪠⥫ ⠡ + unsigned int size; //ࠧ ⠡ +}; + +#define DRESNUM 100 +#define SIZERESBUF 2048 + +struct _STRINGS_{ + char *id; + short val; +}; + +_STRINGS_ typemem[7]={ + "MOVEABLE", 0x0010, + "FIXED", ~0x0010, + "PURE", 0x0020, + "IMPURE", ~0x0020, + "PRELOAD", 0x0040, + "LOADONCALL", ~0x0040, + "DISCARDABLE",0x1000 +}; + +_STRINGS_ typeclass[6]={ + "BUTTON", 0x80, + "EDIT", 0x81, + "STATIC", 0x82, + "LISTBOX", 0x83, + "SCROLLBAR",0x84, + "COMBOBOX", 0x85 +}; + +_STRINGS_ typemenu[NUMMENUPOPUP]={ + "GREYED", 0x0001, + "INACTIVE", 0x0002, + "BITMAP", 0x0004, + "OWNERDRAW", 0x0100, + "CHECKED", 0x0008, + "MENUBARBREAK",0x0020, + "MENUBREAK", 0x0040, + "HELP", 0x4000 +}; + +_STRINGS_ typeacceler[5]={ + "VIRTKEY", 0x01, + "NOINVERT", 0x02, + "SHIFT", 0x04, + "CONTROL", 0x08, + "ALT", 0x10 +}; + +enum {v_fv=1,v_pv,v_ffm,v_ff,v_fo,v_ft,v_fs}; + +_STRINGS_ typeversion[7]={ + "FILEVERSION",v_fv, + "PRODUCTVERSION",v_pv, + "FILEFLAGSMASK",v_ffm, + "FILEFLAGS",v_ff, + "FILEOS",v_fo, + "FILETYPE",v_ft, + "FILESUBTYPE",v_fs +}; + +enum{ +rc_accelerators,rc_auto3state, rc_autocheckbox,rc_autoradiobutton,rc_bitmap, +rc_caption, rc_characteristics,rc_checkbox, rc_class, rc_combobox, +rc_control, rc_ctext, rc_cursor, rc_defpushbutton, rc_dialog, +rc_dialogex, rc_edittext, rc_exstyle, rc_font, rc_groupbox, +rc_icon, rc_listbox, rc_ltext, rc_menu, rc_menuex, +rc_menuitem, rc_messagetable, rc_popup, rc_pushbox, rc_pushbutton, +rc_radiobutton, rc_rcdata, rc_rtext, rc_scrollbar, rc_state3, +rc_stringtable, rc_style, rc_version, rc_versioninfo, rc_begin, +rc_end, rc_language +}; + +struct{ + unsigned short dclass; + unsigned long style; +}defdialog[rc_state3+1]={ + 0,0, + 0x80,6,//BS_AUTO3STATE + 0X80,3|0x00010000,//BS_AUTOCHECKBOX|WS_TABSTOP, + 0X80,9,//BS_AUTORADIOBUTTON, + 0,0, + 0,0, + 0,0, + 0X80,0x00010002,//BS_CHECKBOX|WS_TABSTOP, + 0,0, + 0X85,0x00010000,//0,WS_TABSTOP + 0,0x40000000|0x10000000,//WS_CHILD|WS_VISIBLE, + 0X82,1,//ES_CENTER, + 0,0, + 0X80,1|0x00010000,//BS_DEFPUSHBUTTON|WS_TABSTOP, + 0,0, + 0,0, + 0X81,0x00800000|0x00010000,//ES_LEFT|WS_BORDER|WS_TABSTOP, + 0,0, + 0,0, + 0X80,7|0x00010000,//BS_GROUPBOX, + 0X82,3,//SS_ICON, + 0X83,0x00800000|1,//WS_BORDER|LBS_NOTIFY, + 0X82,0x00020000,//ES_LEFT|WS_GROUP, + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + 0X80,0x00010000,// ??? BS_PUSHBOX, + 0X80,0x00010000,//BS_PUSHBUTTON|WS_TABSTOP, + 0X80,4,//BS_RADIOBUTTON, + 0,0, + 0X82,2|0x00020000,//ES_RIGHT|WS_GROUP, + 0X84,0, + 0X80,5//BS_3STATE +}; + + +union NameOrdinal +{ + unsigned char *name; + unsigned short ordinal[2]; +}; + + +struct _DBH_ // +{ + unsigned long lStyle; + unsigned long lExtendedStyle; + unsigned short NumberOfItems; + unsigned short x; + unsigned short y; + unsigned short cx; + unsigned short cy; + NameOrdinal MenuName; + NameOrdinal ClassName; + char *Caption; + unsigned short FontSize; + char *FontName; +}; + +struct _CD_ //஫ +{ + unsigned long lStyle; + unsigned long lExtendedStyle; + unsigned short x; + unsigned short y; + unsigned short cx; + unsigned short cy; + unsigned short Id; + NameOrdinal ClassId; + NameOrdinal Text; + unsigned short Extra; +}; + +struct _ICOHEAD_ +{ + unsigned short res1; + unsigned short type; + unsigned short count; +// unsigned short res2; +}; + +struct _RESDIR_ +{ + unsigned char width; + unsigned char heigth; + unsigned char color; + unsigned char res1; + unsigned short planes; + unsigned short bitcount; + unsigned long binres; + unsigned short nameord; +// unsigned short res2; +}; + +struct _CURDIR_ +{ + unsigned short width; + unsigned short heigth; + unsigned short planes; + unsigned short bitcount; + unsigned long binres; + unsigned short nameord; +// unsigned short res2; +}; diff --git a/programs/develop/cmm/resname.h b/programs/develop/cmm/resname.h new file mode 100644 index 0000000000..ebde790c20 --- /dev/null +++ b/programs/develop/cmm/resname.h @@ -0,0 +1,75 @@ +/* 䠩 ᣥ஢ ணࠬ 'FASTLIST.EXE' */ + +short ofsres[26]={ + 0x0000,0x003B, //a b + 0x004C,0x009B, //c d + 0x00BE,0x00D8, //e f + 0x00E0,0xFFFF, //g h + 0x00EC,0xFFFF, //i j + 0xFFFF,0x00F4, //k l + 0x0110,0xFFFF, //m n + 0xFFFF,0x0138, //o p + 0xFFFF,0x0156, //q r + 0x0174,0xFFFF, //s t + 0xFFFF,0x019D, //u v + 0xFFFF,0xFFFF, //w x + 0xFFFF,0xFFFF}; //y z + +unsigned char resMnem[]={ + 0x00,0x00,0x63,0x63,0x65,0x6C,0x65,0x72,0x61,0x74,0x6F,0x72,0x73,0, // accelerators + 0x01,0x00,0x75,0x74,0x6F,0x33,0x73,0x74,0x61,0x74,0x65,0, // auto3state + 0x02,0x00,0x75,0x74,0x6F,0x63,0x68,0x65,0x63,0x6B,0x62,0x6F,0x78,0, // autocheckbox + 0x03,0x00,0x75,0x74,0x6F,0x72,0x61,0x64,0x69,0x6F,0x62,0x75,0x74,0x74,0x6F,0x6E,0, // autoradiobutton + 0xFF,0xFF, // end char 'a' + 0x27,0x00,0x65,0x67,0x69,0x6E,0, // begin + 0x04,0x00,0x69,0x74,0x6D,0x61,0x70,0, // bitmap + 0xFF,0xFF, // end char 'b' + 0x05,0x00,0x61,0x70,0x74,0x69,0x6F,0x6E,0, // caption + 0x06,0x00,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x69,0x73,0x74,0x69,0x63,0x73,0, // characteristics + 0x07,0x00,0x68,0x65,0x63,0x6B,0x62,0x6F,0x78,0, // checkbox + 0x08,0x00,0x6C,0x61,0x73,0x73,0, // class + 0x09,0x00,0x6F,0x6D,0x62,0x6F,0x62,0x6F,0x78,0, // combobox + 0x0A,0x00,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0, // control + 0x0B,0x00,0x74,0x65,0x78,0x74,0, // ctext + 0x0C,0x00,0x75,0x72,0x73,0x6F,0x72,0, // cursor + 0xFF,0xFF, // end char 'c' + 0x0D,0x00,0x65,0x66,0x70,0x75,0x73,0x68,0x62,0x75,0x74,0x74,0x6F,0x6E,0, // defpushbutton + 0x0E,0x00,0x69,0x61,0x6C,0x6F,0x67,0, // dialog + 0x0F,0x00,0x69,0x61,0x6C,0x6F,0x67,0x65,0x78,0, // dialogex + 0xFF,0xFF, // end char 'd' + 0x10,0x00,0x64,0x69,0x74,0x74,0x65,0x78,0x74,0, // edittext + 0x28,0x00,0x6E,0x64,0, // end + 0x11,0x00,0x78,0x73,0x74,0x79,0x6C,0x65,0, // exstyle + 0xFF,0xFF, // end char 'e' + 0x12,0x00,0x6F,0x6E,0x74,0, // font + 0xFF,0xFF, // end char 'f' + 0x13,0x00,0x72,0x6F,0x75,0x70,0x62,0x6F,0x78,0, // groupbox + 0xFF,0xFF, // end char 'g' + 0x14,0x00,0x63,0x6F,0x6E,0, // icon + 0xFF,0xFF, // end char 'i' + 0x29,0x00,0x61,0x6E,0x67,0x75,0x61,0x67,0x65,0, // language + 0x15,0x00,0x69,0x73,0x74,0x62,0x6F,0x78,0, // listbox + 0x16,0x00,0x74,0x65,0x78,0x74,0, // ltext + 0xFF,0xFF, // end char 'l' + 0x17,0x00,0x65,0x6E,0x75,0, // menu + 0x18,0x00,0x65,0x6E,0x75,0x65,0x78,0, // menuex + 0x19,0x00,0x65,0x6E,0x75,0x69,0x74,0x65,0x6D,0, // menuitem + 0x1A,0x00,0x65,0x73,0x73,0x61,0x67,0x65,0x74,0x61,0x62,0x6C,0x65,0, // messagetable + 0xFF,0xFF, // end char 'm' + 0x1B,0x00,0x6F,0x70,0x75,0x70,0, // popup + 0x1C,0x00,0x75,0x73,0x68,0x62,0x6F,0x78,0, // pushbox + 0x1D,0x00,0x75,0x73,0x68,0x62,0x75,0x74,0x74,0x6F,0x6E,0, // pushbutton + 0xFF,0xFF, // end char 'p' + 0x1E,0x00,0x61,0x64,0x69,0x6F,0x62,0x75,0x74,0x74,0x6F,0x6E,0, // radiobutton + 0x1F,0x00,0x63,0x64,0x61,0x74,0x61,0, // rcdata + 0x20,0x00,0x74,0x65,0x78,0x74,0, // rtext + 0xFF,0xFF, // end char 'r' + 0x21,0x00,0x63,0x72,0x6F,0x6C,0x6C,0x62,0x61,0x72,0, // scrollbar + 0x22,0x00,0x74,0x61,0x74,0x65,0x33,0, // state3 + 0x23,0x00,0x74,0x72,0x69,0x6E,0x67,0x74,0x61,0x62,0x6C,0x65,0, // stringtable + 0x24,0x00,0x74,0x79,0x6C,0x65,0, // style + 0xFF,0xFF, // end char 's' + 0x25,0x00,0x65,0x72,0x73,0x69,0x6F,0x6E,0, // version + 0x26,0x00,0x65,0x72,0x73,0x69,0x6F,0x6E,0x69,0x6E,0x66,0x6F,0, // versioninfo + 0xFF,0xFF // end char 'v' +}; diff --git a/programs/develop/cmm/static.lds b/programs/develop/cmm/static.lds new file mode 100644 index 0000000000..5362f4a8c2 --- /dev/null +++ b/programs/develop/cmm/static.lds @@ -0,0 +1,113 @@ +/*OUTPUT_FORMAT("binary")*/ + +ENTRY(__start) +SECTIONS +{ + .text 0x000000: + { + LONG(0x554e454D); + LONG(0x32305445); + LONG(1); + LONG(__start); + LONG(___iend); + LONG(___memsize); + LONG(___stacktop); + LONG(___cmdline); + LONG(___pgmname); /* full path */ + LONG(0); /*FIXME tls data */ + + *(.init) + *(.text) + *(SORT(.text$*)) + *(.text.*) + *(.glue_7t) + *(.glue_7) + ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); + ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); + *(.fini) + /* ??? Why is .gcc_exc here? */ + *(.gcc_exc) + PROVIDE (etext = .); + *(.gcc_except_table) + } + + .rdata ALIGN(16) : + { + *(.rdata) + *(SORT(.rdata$*)) + ___RUNTIME_PSEUDO_RELOC_LIST__ = .; + __RUNTIME_PSEUDO_RELOC_LIST__ = .; + *(.rdata_runtime_pseudo_reloc) + ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + } + .CRT ALIGN(16) : + { + ___crt_xc_start__ = . ; + *(SORT(.CRT$XC*)) /* C initialization */ + ___crt_xc_end__ = . ; + ___crt_xi_start__ = . ; + *(SORT(.CRT$XI*)) /* C++ initialization */ + ___crt_xi_end__ = . ; + ___crt_xl_start__ = . ; + *(SORT(.CRT$XL*)) /* TLS callbacks */ + /* ___crt_xl_end__ is defined in the TLS Directory support code */ + ___crt_xp_start__ = . ; + *(SORT(.CRT$XP*)) /* Pre-termination */ + ___crt_xp_end__ = . ; + ___crt_xt_start__ = . ; + *(SORT(.CRT$XT*)) /* Termination */ + ___crt_xt_end__ = . ; + } + + .data ALIGN(16) : + { + __data_start__ = . ; + *(.data) + *(.data2) + *(SORT(.data$*)) + *(.jcr) + __CRT_MT = .; + LONG(0); + __data_end__ = . ; + *(.data_cygwin_nocopy) + } + + .eh_frame ALIGN(16) : + { + *(.eh_frame) + ___iend = . ; + } + + bss ALIGN(16): + { + *(.bss) + *(COMMON) + . = ALIGN(16); + ___menuet__app_path_area = .; + . = . + 1024 + 16; + ___stacktop = .; + ___memsize = . ; + } + + /DISCARD/ : + { + *(.debug$S) + *(.debug$T) + *(.debug$F) + *(.drectve) + *(.note.GNU-stack) + *(.comment) + *(.debug_abbrev) + *(.debug_info) + *(.debug_line) + *(.debug_frame) + *(.debug_loc) + *(.debug_pubnames) + *(.debug_aranges) + *(.debug_ranges) + } + +} diff --git a/programs/develop/cmm/struct.h b/programs/develop/cmm/struct.h new file mode 100644 index 0000000000..fa7dfedfbb --- /dev/null +++ b/programs/develop/cmm/struct.h @@ -0,0 +1,546 @@ +#include +#include + +typedef struct _BIT_{ + unsigned int siz:8; + unsigned int ofs:24; +}BIT; + +struct _PROCINFO_ +{ + char *buf; // ⥪ 楤 + void *classteg; // ⥣, । 楤 + unsigned int warn:1; + unsigned int speed:1; + unsigned int lst:1; + unsigned int typestring:2; + unsigned int inlinest:1; + unsigned int code32:1; + unsigned int align:1; + unsigned int acycle:1; + unsigned int idasm:1; + unsigned int opnum:1; + unsigned int de:1; + unsigned int ostring:1; + unsigned int uselea:1; + unsigned int regoverstack:1; + unsigned int sizeacycle; + char chip; +}; + +struct idrec +{ + union{ + struct idrec *left; + struct localrec *next; + }; + struct idrec *right; //। ᫥ + char recid[IDLENGTH]; // + unsigned int flag; + char *newid; // 묨, ⥣, 楤 ࠬ + int rectok; //⨯ + int recrm; // ᫮ + int recsegm; + int recpost; + int recsize; + int recsib; + int line; // + int file; //䠩 + int count; //稪 ᯮ짮 + unsigned short type; + unsigned short npointr; + union{ + char *sbuf; //㪠⥫ 室 ⥪ + _PROCINFO_ *pinfo; + }; + union{ + long recnumber; + long long reclnumber; + double recdnumber; + float recfnumber; + }; +}; + +struct localinfo +{ + int usedfirst; + int usedlast; + int start; + int end; + int level; + int count; +}; + +struct localrec +{ +/* struct localrec *next; + int localtok; + unsigned short type; + unsigned short npointr; + union{ + unsigned int localnumber; + idrec *rec; + }; + int locsize; + char localid[IDLENGTH]; + unsigned char fuse; //䫠 ᯮ짮 + unsigned char flag; //䫠 static*/ + idrec rec; + localinfo li; + unsigned char fuse; //䫠 ᯮ짮 +}; + +#define INITBPPAR 1 //樠 BP ᫥ ࠬ஢ +#define INITBPLOC 2 //樠 BP ᫥ +#define INITBPENTER 4 +#define INITBPADDESP 8 + +struct HEADLOC +{ + int type; //⨯ + unsigned int ofs; // 祭 + unsigned int num; //稭 祭 +}; + +struct treelocalrec +{ + treelocalrec *next; + localrec *lrec; + int initbp; + int level; + unsigned int addesp; + int endline; +}; + +typedef struct _ITOK_ +{ + int rm; + int segm; + int post; + int sib; + union{ + long number; + long long lnumber; + double dnumber; + float fnumber; + }; + union{ + int size; + BIT bit; + }; + unsigned short type; + unsigned short npointr; +union{ + idrec *rec; + localrec *locrec; + }; + char name[IDLENGTH]; + unsigned int flag; +}ITOK; + +struct elementteg +{ + union{ + void *nteg; // ⥣ + idrec *rec; + }; + int tok; + union{ + unsigned int numel; //᫮ ⮢ ⮣ ⨯ + BIT bit; + }; + unsigned int ofs; //ᬥ饭 砫 + char name[IDLENGTH]; +}; + +struct structteg +{ + struct structteg *left; //᫥騩 ⥣ + struct structteg *right; //᫥騩 ⥣ + unsigned int size; //ࠧ ⥣ + unsigned int numoper; //᫮ ࠭ + struct elementteg *baza; // ᠭ ⮢ ⥣ + unsigned int flag; + char name[IDLENGTH]; +}; + +struct listexport +{ + long address; + char name[IDLENGTH]; +}; + +typedef struct _IOFS_ +{ + unsigned int ofs; + unsigned int line; // + unsigned int file; //䠩 + unsigned char dataseg; +}IOFS; + +typedef struct _UNDEFOFF_ +{ + struct _UNDEFOFF_ *next; + IOFS *pos; // ᠬ 㤠 뫪 + int num; //᫮ 뫮 + char name[IDLENGTH]; +}UNDEFOFF; + +typedef struct _LISTCOM_ +{ + char name[IDLENGTH]; +}LISTCOM; + +typedef struct _SINFO_ +{ + char *bufstr; + int size; +}SINFO; + +// ᯨ᪠ api-楤 +typedef struct _APIPROC_ +{ + struct idrec *recapi; +}APIPROC; + +// +typedef struct _DLLLIST_ +{ + struct _DLLLIST_ *next; //᫥ DLL + struct _APIPROC_ *list; //ᯨ᮪ 楤 + unsigned short num; //᫮ 楤 + char name[IDLENGTH]; // DLL +}DLLLIST; + +typedef struct _PE_HEADER_ +{ + long sign; //ᨣ - ᥣ 'PE' + short cpu; // ⨯ CPU - ᥣ 0x14C + short numobj; //᫮ 室 ⠡ ꥪ⮢ + long date_time; // 䨪樨 ஬ + long pCOFF; + long COFFsize; + short NTheadsize; //ࠧ PE MAGIC - ᥣ 0xE0 + short flags; + short Magic; //祭 ࠬ + short LinkVer; // + long sizecode; + long sizeinitdata; + long sizeuninitdata; + long EntryRVA; // ⭮ IMAGE BASE ஬ । ࠢ + long basecode; //RVA ᥪ, ᮤন ணࠬ + long basedata; //RVA ᥪ,ᮤঠ + long ImageBase; //㠫 砫 㧪 ணࠬ + long objAlig; //ࠢ ணࠬ ᥪ権 + long fileAlig; //ࠢ ᥪ権 䠩 + long OSver; // ᨨ ⥬ ணࠬ + long userver; + long SubSysVer; + long rez; + long imagesize; //ࠧ 㦠 ࠧ ࠢ + long headsize; //ࠧ stub+PE+objtabl + long checksum; + short SubSys; //樮 ᪠ + short DLLflag; + long stackRezSize; + long stackComSize; + long heapRezSize; + long heapComSize; + long loaderFlag; + long numRVA; //ᥣ 10 + long exportRVA; + long exportSize; + long importRVA; + long importSize; + long resourRVA; + long resourSize; + long exceptRVA; + long exceptSize; + long securRVA; + long securSize; + long fixupRVA; + long fixupSize; + long debugRVA; + long debugSize; + long descripRVA; + long descripSize; + long machinRVA; + long machinSize; + long tlsRVA; + long tlsSize; + long loadConfRVA; + long loadConfSize; + long rez2[2]; + long iatRVA; + long iatSize; + long rez3[6]; +}PE_HEADER; + +typedef struct _OBJECT_ENTRY_ +{ + char name[8]; + long vsize; + long sectionRVA; + long psize; + long pOffset; + unsigned long PointerToRelocations; + unsigned long PointerToLinenumbers; + unsigned short NumberOfRelocations; + unsigned short NumberOfLinenumbers; + long flags; +}OBJECT_ENTRY; + +typedef struct _EXPORT_TABLE_ +{ + unsigned long Flags; + unsigned long Time; + unsigned short Version[2]; + unsigned long NameRVA; + unsigned long OriginalBase; + unsigned long NumFunc; + unsigned long NumName; + unsigned long AddressRVA; + unsigned long NamePRVA; + unsigned long OrdinalRVA; +}EXPORT_TABLE; + +struct ftime { + unsigned ft_tsec:5; /* ᥪ㭤 */ + unsigned ft_min:6; /* */ + unsigned ft_hour:5; /* */ + unsigned ft_day:5; /* */ + unsigned ft_month:4; /* */ + unsigned ft_year:7; /* -1980 */ +}; + + +typedef struct _STRING_LIST_ +{ + void *next; //᫥ + unsigned int len; // ப + unsigned int ofs; // 室 䠩 + unsigned char type; //⨯ ନ + unsigned char plase; // ᥩ ப - post or data +}STRING_LIST; + +struct FILEINFO +{ + char *filename; + int numdline; + idrec *stlist; + union{ + struct ftime time; + unsigned short lineidx[2]; + }; +}; + +struct EWAR{ + FILE *file; + char *name; +}; + +typedef struct _ICOMP_ +{ + unsigned int type; + unsigned int loc; + unsigned int use_cxz; +}ICOMP; + +typedef struct _RETLIST_ +{ + unsigned int line; + unsigned int loc; + unsigned int type; +// int use; +}RETLIST; + +enum{ + singlcase,startmulti,endmulti}; + +typedef struct _ISW_ +{ + unsigned char type; + unsigned int postcase; + unsigned long value; +}ISW; + +struct postinfo +{ + unsigned int loc; + unsigned int num; + unsigned short type; + unsigned short line; + unsigned short file; + +}; + +typedef struct _EXE_DOS_HEADER_ +{ + unsigned short sign; + unsigned short numlastbyte; + unsigned short numpage; + unsigned short numreloc; + unsigned short headsize; + unsigned short minmem; + unsigned short maxmem; + unsigned short initSS; + unsigned short initSP; + unsigned short checksum; + unsigned short initIP; + unsigned short initCS; + unsigned short ofsreloc; + unsigned short overlay; + unsigned long fullsize; +}EXE_DOS_HEADER; + +typedef struct _FSWI_ +{ + ISW *info; + int sizetab; //᫮ ⮢ + int type; //ࠧ來 + int numcase; //᫮ ᯮ㥬 ⮢ + int defal; //祭 㬮砭. + int ptb; // 㪠⥫ ⠡ + int ptv; // ⠢ 稭 + int mode; //⨯ switch + int razr; //ࠧ來 稭 +}FSWI; + +struct paraminfo +{ + unsigned int ofspar; + unsigned char type[8]; +}; + +struct MEOSheader +{ + unsigned char sign[8]; + unsigned long vers; + unsigned long start; + unsigned long size; + unsigned long alloc_mem; + unsigned long esp; + unsigned long I_Param; + unsigned long I_Icon; +}; + +#ifdef OPTVARCONST + +struct LVIC{ + idrec *rec; +// int blocks; + int typevar; + int contype; //⨯ ᮤন + union{ + long number; + long long lnumber; + double dnumber; + float fnumber; + }; +}; + +struct BLVIC +{ + int sizevic; + LVIC *listvic; +}; + +#endif + +#define SIZEIDREG 256 +#define NOINREG 8 +#define SKIPREG 9 + +struct REGEQVAR +{ + REGEQVAR *next; + char name[IDLENGTH]; + unsigned char razr; +}; + +struct REGISTERSTAT +{ + union{ + REGEQVAR *next; +#ifdef OPTVARCONST + BLVIC *bakvic; +#endif + }; + union{ + char id[SIZEIDREG]; + void *stringpar; + unsigned long number; + }; + unsigned char type; + unsigned char razr; +}; + +struct SAVEREG +{ + unsigned int size; //ࠧ ॣ஢ + unsigned char all; // ॣ + unsigned char reg[8]; // ॣ஢ +}; + +struct SAVEPAR +{ + unsigned char ooptimizespeed; + unsigned char owarning; + unsigned char odbg; + unsigned char odosstring; + unsigned char ouseinline; + unsigned char oam32; // ० 32 ⭮ 樨 + unsigned char oalignword; + unsigned char oAlignCycle; //ࠢ 砫 横 + unsigned char oidasm; //ᥬ 樨 䨪ࠬ + int ooptnumber; + int odivexpand; + unsigned char ooptstr; //⨬ ப ⠭ + unsigned char ochip; + int oaligncycle; + unsigned char ouselea; + unsigned char oregoverstack; +}; + +struct COM_MOD +{ + COM_MOD *next; + unsigned char *input; /* dynamic input buffer */ + unsigned int endinptr; /* end index of input array */ + unsigned int inptr; /* index in input buffer */ + unsigned int inptr2; /* index in input buffer */ + unsigned int linenumber; + unsigned int currentfileinfo; + int numparamdef; //᫮ ࠬ஢ ⥪饬 define + char *declareparamdef; //ᯨ᮪  ࠬ஢ define + char *paramdef; //ᯨ᮪ ࠬ஢ + int freze; //䫠 饭 㤠 +}; + +struct LISTRELOC { + unsigned int val; +}; + +struct LISTFLOAT +{ + union{ + float fnum; + double dnum; + unsigned long num[2]; + }; + int type; + unsigned int ofs; +}; + +struct LILV +{ + unsigned int ofs; + int size; + localrec *rec; +}; + +struct WARNACT +{ + void (*fwarn)(char *str,unsigned int line,unsigned int file); + unsigned char usewarn; +}; diff --git a/programs/develop/cmm/switch.cpp b/programs/develop/cmm/switch.cpp new file mode 100644 index 0000000000..0b8cc6b7f4 --- /dev/null +++ b/programs/develop/cmm/switch.cpp @@ -0,0 +1,829 @@ +#define _SWITCH_ + +#include "tok.h" + +extern int lastcommand; //᫥ + +#define MAXCASE 1024 + +FSWI *swtables; //⠡ ଠ権 switch +int numswtable=0; //᫮ ⮩ ⠡ +char mesSWITCH[]="SWITCH"; +char mesCASE[]="CASE"; +int numexpandcase; +int numberbreak=0; + +void CheckJmpSW(int line,int endsw,int startsw,int shortjmp,char *mes) +{ +int size=startsw-endsw; + if(shortjmp==FALSE){ + if((unsigned int)size<128)warningjmp(mes,line); + if(am32==FALSE)*(unsigned short *)&output[endsw-2]=(unsigned short)size; + else *(unsigned long *)&output[endsw-4]=(unsigned long)size; + } + else{ + if((unsigned int)size>127)jumperror(line,mes); + output[endsw-1]=(unsigned char) size; + } +} + +void CmpRegNum(int tokr,unsigned long value,int reg) +{ + if(tokr!=r8){ + op66(tokr); //CMP EAX,val + if(value==0){ + op(0x85); + op(0xC0+reg*9); //test AX,AX + } + else{ + if(short_ok(value,tokr==r32?TRUE:FALSE)){ + op(0x83); + op(0xF8+reg); + op(value); + } + else{ + if(reg==0)op(0x3D); + else{ + op(0x81); + op(0xF8+reg); + } + tokr==r32?outdword(value):outword(value); + } + } + } + else{ //CMP AL,val + if(value==0){ + op(0x84); + op(0xC0+reg*9); + } + else{ + if(reg==0)op(0x3c); + else{ + op(0x80); + op(0xF8+reg); + } + op(value); + } + } +} + +int ScanSwitch(int *numcase,ISW *caseinf,COM_MOD *startmod) +{ +unsigned char dcha; +int dtok,line,oinptr,i,otok2; +//new +unsigned char *oinput; +int oendinptr; + +ITOK otok; +int retcode=TRUE; + dtok=tok; + otok=itok; + otok2=tok2; + line=linenum2; + dcha=cha2; + oinptr=inptr=inptr2; + cha=cha2; +//new + oinput=input; + oendinptr=endinptr; + if(startmod!=cur_mod){ + COM_MOD *pmod=cur_mod; + while(pmod->next!=startmod){ + pmod=pmod->next; + } + input=pmod->input; + inptr=pmod->inptr; + endinptr=pmod->endinptr; + cha=input[inptr]; + inptr++; + } + + if(SkipParam()){ + FastTok(0); + if(tok!=tk_openbrace){ + SwTok(tk_openbrace); + retcode=FALSE; + } + else{ + for(i=1;i!=0;){ + FastTok(1); + if(tok==tk_question)CheckDir(); + switch(tok){ + case tk_eof: + unexpectedeof(); + retcode=FALSE; + i=0; + break; + case tk_openbrace: i++; break; + case tk_closebrace: i--; break; + case tk_id: + case tk_case: + case tk_CASE: + if(i==1){ + if(stricmp(itok.name,"case")==0){ + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + (caseinf+*numcase)->postcase=(itok.name[0]=='c'?FALSE:TRUE); + nexttok(); + if(tok==tk_number||(tok==tk_minus&&tok2==tk_number)){ + if(*numcase==MAXCASE){ + preerror("Many to use "); + retcode=FALSE; + } + else{ + unsigned long val=doconstlongmath(); + for(int j=0;j<*numcase;j++){ + if(val==(caseinf+j)->value){ + preerror("Duplicate 'case'"); + retcode=FALSE; + break; + } + } + (caseinf+*numcase)->value=val; + if(tok==tk_multipoint){ + (caseinf+*numcase)->type=startmulti; + nexttok(); + val=doconstlongmath(); + numexpandcase+=val-(caseinf+*numcase)->value-1; + if(val<(caseinf+*numcase)->value){ + preerror("The first value 'case' should be smaller"); + retcode=FALSE; + } + *numcase=*numcase+1; + (caseinf+*numcase)->type=endmulti; + (caseinf+*numcase)->value=val; + (caseinf+*numcase)->postcase=(caseinf+*numcase-1)->postcase; + } + else (caseinf+*numcase)->type=singlcase; + *numcase=*numcase+1; + } + } + else{ + numexpected(); + retcode=FALSE; + } + inptr=inptr2; + cha=cha2; + } + } + break; + } + } + } + } + if(retcode){ //᫨ 訡 + tok=dtok; + itok=otok; + linenum2=line; + cha2=dcha; + inptr2=oinptr; + tok2=otok2; + } + else{ + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + } +//new + input=oinput; + endinptr=oendinptr; + + return retcode; +} + +void doswitch() +{ +ISW *caseinf; +int numcase=0,reg=AX,mode=0; +unsigned int endsw,defaul=0,tokr,endsw2=0; +int shortjmp=(tok==tk_switch?FALSE:TRUE); +int sline=linenumber; +REGISTERSTAT *bakregstat,*changeregstat; +char *ofsstr=NULL; +//new +COM_MOD *startmod=cur_mod; +unsigned char oinline=useinline; +#ifdef OPTVARCONST +ITOK otok; +int swvar=FALSE; +unsigned long numbervar; +int numrm; +int nonum; +#endif + useinline=0; + caseinf=(ISW *)MALLOC(sizeof(ISW)*MAXCASE); // case + numexpandcase=0; + uptdbr(/*TRUE*/); + getoperand(); +char signflag=0; + expecting(tk_openbracket); + switch(tok){ + case tk_intvar: + signflag=1; + goto dint; + case tk_int: + signflag=1; + case tk_word: + getoperand(); + case tk_wordvar: + case tk_reg: +dint: + tokr=r16; + break; + case tk_charvar: + signflag=1; + goto dchar; + case tk_char: + signflag=1; + case tk_byte: + getoperand(); + case tk_bytevar: + case tk_beg: +dchar: + tokr=r8; + break; + case tk_long: + signflag=1; + case tk_dword: + getoperand(); + goto dlong; + case tk_qword: + getoperand(); + goto qword; + case tk_floatvar: + case tk_longvar: signflag=1; + case tk_dwordvar: + case tk_reg32: +dlong: + tokr=r32; + break; + case tk_doublevar: signflag=1; + case tk_qwordvar: +qword: + tokr=r64; + break; + case tk_openbracket: + nexttok(); + if(tok>=tk_char&&tok<=tk_double){ + tokr=typesize(tok); + switch(tok){ + case tk_double: + case tk_float: + case tk_char: + case tk_int: + case tk_long: + signflag=1; + } + } + nexttok(); + expectingoperand(tk_closebracket); + break; + default: + tokr=(am32+1)*2; + break; + } +#ifdef OPTVARCONST + if(tok>=tk_charvar&&tok<=tk_dwordvar&&tok2==tk_closebracket){ + otok=itok; + swvar=TRUE; + } +#endif + if(ScanSwitch(&numcase,caseinf,startmod)){ +int i; +unsigned int sizetab; //ࠧ ⠡ +unsigned long min=0xffffffff,max=0; +unsigned int size0=0,size1; +int reg0=0,svop=0; +long smin=0x7fffffff,smax=-0x7fffffff; +unsigned int size2=0; +unsigned oaddESP=addESP; + if(numcase>2){ + if(!optimizespeed){ + if((am32==FALSE&&tokr==r32)||(am32&&tokr==r16))size0=numcase; + else if(tokr==r8)size0=numcase*2; + if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket) + reg0=itok.number; //। ॣ ⮤ 0 + } + for(i=0;ivalue>max)max=(caseinf+i)->value; + if((caseinf+i)->valuevalue; + if((long) (caseinf+i)->value>smax)smax=(caseinf+i)->value; + if((long) (caseinf+i)->valuevalue; + if((!optimizespeed)&&tokr!=r8){ + if((caseinf+i)->value==0)size0+=2; + else if((caseinf+i)->value<128)size0+=3; + else{ + size0+=(reg0==0?3:4); + if(am32)size0+=2; + } + } + if(i!=0){ + if((caseinf+i)->postcase==0)size0+=(am32==FALSE?(chip<3?5:4):6); + else size0+=2; + } + } + if((unsigned int)(smax-smin)<(max-min)){ + max=smax-smin; + svop=8; + min=-smin; + } + else{ + smin=min; + max-=min; + } + sizetab=max+1; //ࠧ ⠡ ⮤ 1 + if(sizetab<0x1000000&&(!(am32==FALSE&&tokr==r32))){ + if(optimizespeed){ + if((unsigned int)(sizetab/numcase)<(unsigned int)(am32==FALSE?3:4)){ + mode=1; + if(am32==FALSE)reg=BX; + /* ᫨ ⭮襭 ᫠ ⮢ ⠡ case + 3 16-⭮ ० 4 32-⭮, ⮤ 1 */ + } + } + else{ //᫨ ࠧ ⨬樨 ࠧ + if(shortjmp)size0+=2; + else size0+=(am32==FALSE?(chip<3?5:4):6); + size1=sizetab*(am32==FALSE?2:4); + size1+=(max<128?3:am32==FALSE?4:6)+(shortjmp==FALSE?(chip<3?5:4):2); + if(max>127&®0==AX)size1--; + if(min!=0){ + if(min==1)size1++; + else if(min==2&&(!optimizespeed))size1+=2; + else if(min<128)size1+=3; + else{ + size1+=(am32==FALSE?4:6); + if(reg0==AX)size1--; + } + } + size1+=(am32==FALSE?6:9); + if(am32){ + if(tokr!=r32)size1+=3; + if(shortjmp)size1-=2; + } + else{ + if(reg0!=BX)size1+=2; + } + //롮 ⮤ 訬 ࠧ஬ + if(size1<=size0){ + mode=1; + size0=size1; + if(am32==FALSE)reg=BX; + + } + } + } + } + if(numcase>9&&(!optimizespeed)){ +// ⮤ 2 + size2=numcase+numexpandcase; + switch(tokr){ + case r8: + if(am32)size2=size2*5; + else size2=size2*3+8; + break; + case r16: + if(am32)size2=size2*6+1; + else size2=size2*4+8; + break; + case r32: + if(am32)size2=size2*8; + else size2=size2*6+9; + break; + } + size2+=29; + //롮 ⮤ 訬 ࠧ஬ + if(size2<=size0)mode=2; + } +// printf("Num CASE %d Metod 0 size=%d. Metod 1 size=%d. Metod 2 size=%d\n",numcase,size0,size1,size2); + if(mode==2){ + reg=AX; + reg0=idxregs[1]; + if((!am32)||(am32&&(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket)))){ + if(tokr==r8)doalmath(signflag,&ofsstr); + else do_e_axmath(signflag,tokr,&ofsstr); + } + else{ + reg=itok.number; + if(reg==reg0)reg0=idxregs[0]; + nexttok(); + } + ClearReg(reg); + ClearReg(reg0); + warningreg(regs[am32][reg0]); + } + else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket){ + if(reg==AX){ + reg=itok.number; + if(mode&&am32)getintoreg_32(reg,r32,0,&ofsstr); + else nexttok(); + ClearReg(AX); + } + else{ + getintoreg_32(BX,r16,0,&ofsstr); + ClearReg(BX); + warningreg("BX"); + } + } + else{ + if(tokr==r8)doalmath(signflag,&ofsstr); + else do_e_axmath(signflag,tokr,&ofsstr); + if(reg!=AX){ + ClearReg(BX); + if(tokr==r8)outword(0xB4); //mov ah,0 + if(optimizespeed)outword(0xC389); //mov bx,ax + else op(0x93); //xchg ax,bx + } + else{ + ClearReg(AX); + if(mode&&am32&&tokr!=r32){ + op(0x0F); + op(tokr==r8?0xB6:0xB7); + op(0xC0); + } + } + } + nextexpecting2(tk_openbrace); //஢ ᪮ + if(numcase){ + if(mode==1){ // ⮤ + if(min!=0){ + if(min==1)op(0x48+reg-svop); //dec reg + else if(min==2&&(!optimizespeed)){ + op(0x48+reg-svop); //dec reg + op(0x48+reg-svop); //dec reg + } + else if(min<128){ + op(0x83); + op(0xE8+reg-svop*5); + op(min); + } + else{ + if(reg==AX)op(0x2D-svop*5); + else{ + op(0x81); + op(0xE8+reg-svop*5); + } + if(am32)outdword(min); + else outword(min); + } + if(am32)warningreg(regs[1][reg]); + } + if(max<128){ + op(0x83); //cmp reg,max + op(0xF8+reg); + op(max); + } + else{ + if(reg==AX)op(0x3D); + else{ + op(0x81); + op(0xF8+reg); + } + if(am32)outdword(max); + else outword(max); + } + if(shortjmp==FALSE){ + if(chip<3){ + outword(0x376); //jbe 3 + op(0xE9); //jmp to default + } + else outword(0x870F); //ja default + outword(0); + if(am32)outword(0); + } + else{ + op(0x77); + op(0); + } + endsw=outptr; // switch default + if(am32){ + outword(0x24FF); + op(0x85+reg*8); + } + else outdword(0xA7FFDB01); //add bx,bx jmp [bx+table] + AddReloc(CS); + size1=outptr; + outword(0); + if(am32)outword(0); + } + else if(mode==0){ + svop=numcase; + for(;numcase>0;){ //⢫ + numcase--; + CmpRegNum(tokr,(caseinf+numcase)->value,reg); + if((caseinf+numcase)->type==singlcase){ + if(numcase){ + if((caseinf+numcase)->postcase==FALSE){ + if(chip<3){ + outword(0x375); //jnz 3 + op(0xE9); //jmp to default + } + else outword(0x840F); //jz default + outword(0); + if(am32)outword(0); + } + else outword(0x74); + (caseinf+numcase)->postcase=outptr; + } + else{ + if(shortjmp==FALSE){ + if(chip<3){ + outword(0x374); //jnz 3 + op(0xE9); //jmp to default + } + else outword(0x850F); //jz default + outword(0); + if(am32)outword(0); + } + else outword(0x75); + endsw=outptr; // switch default + } + } + else{ //case 1...5 + numcase--; + max=(caseinf+numcase)->value; + if(numcase!=0){ + if((caseinf+numcase+1)->postcase==FALSE){ + if(max==0){ + if(chip>2){ + outdword(0x860F); + if(am32)outword(0); + } + else{ + outword(am32==FALSE?0x0377:0x577); + jumploc0(); + } + } + else{ + outword(0x77); + endsw=outptr; + CmpRegNum(tokr,max,reg); + if(chip>2){ + outdword(0x830F); + if(am32)outword(0); + } + else{ + outword(am32==FALSE?0x0372:0x572); + jumploc0(); + } + output[endsw-1]=(unsigned char)(outptr-endsw); + } + } + else{ + if(max==0)outword(0x76); + else{ + outword(0x77); + endsw=outptr; + CmpRegNum(tokr,max,reg); + outword(0x73); + output[endsw-1]=(unsigned char)(outptr-endsw); + } + } + (caseinf+numcase)->postcase=outptr; + } + else{ + if(shortjmp==FALSE){ + if((optimizespeed&&chip>2)||(chip>2&&max==0)){ + outdword(0x870F); + if(am32)outword(0); + if(max!=0){ + endsw2=outptr; + CmpRegNum(tokr,max,reg); + outdword(0x820F); + if(am32)outword(0); + } + } + else{ + if(max==0) outword(am32==FALSE?0x0376:0x576); + else{ + outword(0x77); + endsw=outptr-1; + CmpRegNum(tokr,max,reg); + outword(am32==FALSE?0x0373:0x573); + output[endsw]=(unsigned char)(outptr-endsw-1); + } + jumploc0(); + } + } + else{ + outword(0x77); + if(max!=0){ + endsw2=outptr; + CmpRegNum(tokr,max,reg); + outword(0x72); + } + } + endsw=outptr; // switch default + } + } + } + } + else if(mode==2){ + if(!am32){ + outdword(0x071E0651); //push cx,es,ds pop es + op(0xB9); //mov CX,numcase + outword(numcase+numexpandcase); + op(0xBF); //mov DI,tableval + AddReloc(CS); + size2=outptr; + outword(0); + op(0xF2); //repnz + switch(tokr){ + case r8: op(0xAE); break; + case r32: op(0x66); + case r16: op(0xAF); break; + } + outword(0x7407); //pop es ,jz + op(shortjmp==FALSE?4:3); + op(0x59); //pop cx + if(shortjmp==FALSE)jumploc0(); + else outword(0xEB); + endsw=outptr; // switch default + op(0xBF); //mov DI,numcase + outword(numcase+numexpandcase); + outdword(0x014FCF29); //sub di,cx dec di add di,di + op(0xFF); + outword(0xC781); //add di,tableadr + AddReloc(CS); + size1=outptr; + outword(0); + op(0x59); //pop cx + outword(0x25FF); //jmp [di] + } + else{ + op(0x31); + op(0xC0+reg0*9); //xor reg0,reg0 + switch(tokr){ //cmp [reg0*size+tableadr],reg + case r8: op(0x38); op(0x4+reg*8); op(5+reg0*8); break; + case r32: op(0x39); op(0x4+reg*8); op(0x85+reg0*8); break; + case r16: op(0x66); op(0x39); op(0x4+reg*8); op(0x45+reg0*8); break; + } + AddReloc(CS); + size2=outptr; + outdword(0); + outword(0x0775); //jne + outword(0x24FF); //jmp [reg0*4+tableadr] + op(0x85+reg0*8); + AddReloc(CS); + size1=outptr; + outdword(0); + op(0x40+reg0); //inc reg0 + if((numcase+numexpandcase)>127){ //cmp reg0,numcase + op(0x81); + op(0xF8+reg0); + outdword(numcase+numexpandcase); + } + else{ + op(0x83); + op(0xF8+reg0); + op(numcase+numexpandcase); + } + op(0x72); + if((numcase+numexpandcase)>127)op(tokr==r16?0xE6:0xE7); + else op(tokr==r16?0xE9:0xEA); + if(shortjmp==FALSE)jumploc0(); + else outword(0xEB); + endsw=outptr; // switch default + } + } + } + numcase=0; + useinline=oinline; + bakregstat=BakRegStat(); + changeregstat=BakRegStat(); + lastcommand=tk_switch; + do{ + if(tok==tk_case||tok==tk_CASE||tok==tk_default){ //᫨ case - 稭 + RestoreStack(); + CompareRegStat(changeregstat); + switch(lastcommand){ + case tk_goto: + case tk_GOTO: + case tk_break: + case tk_BREAK: + case tk_return: + case tk_RETURN: + case tk_switch: + CopyRegStat(bakregstat); +#ifdef OPTVARCONST + nonum=FALSE; +#endif + addESP=oaddESP; + break; + default: + CopyRegStat(changeregstat); +#ifdef OPTVARCONST + nonum=TRUE; +#endif + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + break; + } + if(tok==tk_default){ //⮦ default + if(mode==0&&svop){ + if(numcase==0)jumploc0(); //default ᠬ + CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH); + if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH); + } + if(defaul)preerror("Duplicate 'default'"); + defaul=outptr; + nexttok(); + expecting(tk_colon); //஢ : ⥭ ᫥ tok + continue; + } + if(mode==0){ + if(numcase==0&&defaul){ //default ᠬ + if(am32==FALSE)*(unsigned short *)&output[defaul-2]=(unsigned short)(outptr-defaul); + else *(unsigned long *)&output[defaul-4]=(unsigned long)(outptr-defaul); + } + else if(numcase)CheckJmpSW(linenumber,(caseinf+numcase)->postcase,outptr,tok==tk_case?FALSE:TRUE,mesCASE); + } + else (caseinf+numcase)->postcase=outptr; + lastcommand=tok; //new 12.12.07 14:27 + nexttok(); +#ifdef OPTVARCONST + numrm=itok.rm; + numbervar=doconstlongmath(); + (caseinf+numcase)->value=numbervar-(mode==1?smin:0); +#else + (caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0); +#endif + numcase++; + if(tok==tk_multipoint){ + nexttok(); + (caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0); + numcase++; + } +#ifdef OPTVARCONST + else if(swvar&&nonum==FALSE)Const2Var(&otok,numbervar,numrm); +#endif + expecting(tk_colon); //஢ : ⥭ ᫥ tok + if(tok==tk_closebrace)numcase--; + continue;//goto checkcase; + } + startblock(); + docommand(); + endblock(); + }while(tok!=tk_closebrace); + RestoreStack(); + if(numberbreak==0){ + switch(lastcommand){ + case tk_break: + posts--; + outptr-=(am32==FALSE?3:5); + break; + case tk_BREAK: + posts--; + outptr-=2; + break; + } + } + if(defaul&&outptroutptr)defaul=outptr; + CheckJmpSW(sline,endsw,defaul,shortjmp,mesSWITCH); + caseinf=(ISW *)REALLOC(caseinf,sizeof(ISW)*numcase); + if(!numswtable)swtables=(FSWI *)MALLOC(sizeof(FSWI)); + else swtables=(FSWI *)REALLOC(swtables,sizeof(FSWI)*(numswtable+1)); + FSWI *swt=swtables+numswtable; + swt->info=caseinf; + swt->sizetab=(mode==2?numcase:sizetab)+numexpandcase; + swt->type=(am32==FALSE?2:4); + swt->numcase=numcase; + swt->defal=defaul; + swt->ptb=size1; + swt->ptv=size2; + swt->mode=mode; + swt->razr=tokr; + numswtable++; + } + } + else free(caseinf); + SetBreakLabel(); + SetContinueLabel(); + } + nexttok(); + lastcommand=tk_switch; + retproc=FALSE; +} diff --git a/programs/develop/cmm/table.h b/programs/develop/cmm/table.h new file mode 100644 index 0000000000..949fc5bd3f --- /dev/null +++ b/programs/develop/cmm/table.h @@ -0,0 +1,32 @@ +/* some defines for extracting instruction bit fields from bytes */ +#define MOD(a) (((a)>>6)&3) +#define REG(a) (((a)>>3)&7) +#define RM(a) ((a)&7) +#define SCALE(a) (((a)>>6)&3) +#define INDEX(a) (((a)>>3)&7) +#define BASE(a) ((a)&7) + +typedef union{ + struct{ + unsigned short ofs; + unsigned short seg; + }w; + unsigned long dword; +}WORD32; + +/* prototypes */ +void ua_str(char *); +unsigned char getbyte(void); +int modrm(); +int sib(); +void uprintf(char *, ...); +void uputchar(char ); +int bytes(char ); +void outhex(char , int , int , int , int ); +void reg_name(int , char ); +void do_sib(int ); +void do_modrm(char ); +void floating_point(int ); +void percent(char , char ); +void undata(unsigned ofs,unsigned long len,unsigned int type); + diff --git a/programs/develop/cmm/tok.h b/programs/develop/cmm/tok.h new file mode 100644 index 0000000000..2beb2e594b --- /dev/null +++ b/programs/develop/cmm/tok.h @@ -0,0 +1,793 @@ +//void PrintMem(void *mem); +//void CheckMem(); + +#include "port.h" + +#include +#include +#include +#include +#include + + +//#define DEBUGMODE + +#define OPTVARCONST // + +#define MAXNUMPATH 16 +#define DATATYPES 9 // number of data types +#define MAXDATA 65500 /* output run file buffer 65500 bytes */ + +#define DYNAMIC_USED 0 +#define DYNAMIC 1 +#define NOT_DYNAMIC 2 /* flag value specifing a non-dynamic proc */ +#define DYNAMIC_SET 3 + +#define FILENAMESIZE 80 +#define SHORTMAX 127 // largest 8 bit signed value +#define SHORTMIN -128 // smallest 8 bit signed value +#define IDLENGTH 65 /* length of significance of IDS + NULL, therefore 32 */ +#define STRLEN 2048 /* length of string token holder */ +#define MAXPOSTS 2048 +#define SIZEBUF 16384 +#define ID2S 6*DATATYPES +#define MAXSYSCOM 25 +#define NUMNUM 32 +#define NUMNUM64 64 +#define OBJECTALIGN 4096 // +#define WARNCOUNT 15 // + +#define ver1 0 +#define ver2 239 + +#define BETTA + +#ifdef BETTA +#define betta " b26" +#else +#define betta "" +#endif + +#include "const.h" +#include "struct.h" + +#ifdef _UNIX_ + #ifndef stricmp + #define stricmp strcasecmp + #endif +#endif + +#ifdef _UNIX_ + #ifndef O_BINARY + #define O_BINARY 0 + #endif +#endif + +extern unsigned char FixUpTable; // Fix UP for Windows +extern unsigned char WinMonoBlock; +extern unsigned int currentfileinfo; + +#if !defined (_MAIN_) +extern char fobj; // obj +extern char *rawfilename; +extern struct tm timeptr; +extern char outext[]; +extern unsigned char compilerstr[]; /* compiler ID string */ +extern LISTCOM *listcom; +extern unsigned char gwarning; +extern EWAR wartype,errfile; +extern int numfindpath; +extern char *findpath[]; +extern char bufpath[]; +extern unsigned int startptr; +extern unsigned char wconsole;// windows +extern unsigned long ImageBase; +extern int numexport; +extern struct listexport *lexport; +extern unsigned char optstr; // +extern unsigned char crif; //check reply include file +extern unsigned char idasm; // +extern char modelmem; +extern char *stubfile; +extern char comsymbios; +extern unsigned char sobj; +extern short dllflag; +extern char *bufstr; // +extern int sbufstr; // +extern unsigned char wbss; // +extern int numrel; // +extern unsigned char usestub; +extern char *winstub; +extern unsigned char dpmistub; +extern unsigned char useordinal; +extern int startupfile; +extern int alignproc,aligncycle; +extern FILE *hout; +extern unsigned char useDOS4GW; +extern unsigned char use_env; // +extern unsigned char clearpost; +extern unsigned char uselea; +extern unsigned char regoverstack; +extern unsigned char shortimport; +extern char *namestartupfile; +extern unsigned char useinline; +extern unsigned char ocoff; +extern unsigned char ESPloc; + +#endif + +extern unsigned char string[STRLEN],string2[STRLEN+20]; + +#if !defined (_TOKC_) +extern unsigned int outptrsize; // +extern unsigned char string3[STRLEN]; +extern char *BackTextBlock; // +extern int SizeBackBuf; +extern unsigned char cha; +extern unsigned int inptr; +extern unsigned char AlignProc; +extern unsigned int secondcallnum; //# of different second calls and labels +extern unsigned char header; +extern unsigned char killctrlc; +extern unsigned char optimizespeed; +extern unsigned char alignword; +extern unsigned int outptr,outptrdata; +extern unsigned char comfile; +extern unsigned char chip; +extern unsigned char dos1,dos2; +extern unsigned int stacksize; +extern int error; +extern unsigned char *output,*outputdata; +extern unsigned char notdoneprestuff; +extern unsigned long postsize; +extern unsigned int posts; +extern postinfo *postbuf; +extern int maxposts; +extern unsigned char cpu; +extern long runfilesize; +extern unsigned char *input; /* dynamic input buffer */ +extern unsigned int endinptr; /* end index of input array */ +extern unsigned int localsize,paramsize; +extern char endoffile; +extern unsigned int current_proc_type; /* current procedure type */ +extern unsigned char aligner; +extern unsigned int alignersize; +extern unsigned int datasize; +extern unsigned char warning; +extern unsigned int startStartup; +extern unsigned char useStartup; +extern unsigned int endStartup; +extern unsigned char notpost; +extern unsigned char am32; // 32 +extern unsigned int externnum; +extern unsigned char FastCallApi; // API +extern unsigned char FixUp; // +extern void *liststring; // +extern struct FILEINFO *startfileinfo; +extern unsigned int totalmodule; +extern int retproc; +extern unsigned char splitdata; // +extern unsigned char AlignCycle; // +extern char param[]; // +extern unsigned char dynamic_flag; // +extern unsigned char setzeroflag; // zero flag +extern unsigned char insertmode; +extern unsigned int numblocks; // +extern unsigned char notunreach; +extern idrec *staticlist; +extern unsigned int procedure_start; /* address of start of procedure */ +extern int lastcommand; // +extern unsigned int initBP; +extern unsigned char fstatic; +//extern int sizestack; // +extern unsigned char addstack; +extern unsigned long addESP; // +extern unsigned char blockproc; // +extern treelocalrec *tlr; // +extern treelocalrec *btlr; // +extern int returntype; /* return type, (void, byte, word, ...) */ +#endif +extern int tok,tok2; + +#if !defined (_TOKR_) +extern char useasm; +extern short ofsmnem[]; +extern unsigned char asmMnem[]; +extern char asmparam; +#endif + +#if !defined (_TOKA_) +extern unsigned char id[]; +extern short idofs[]; +extern char id2[ID2S][9]; +extern char regs[2][8][4]; +extern char begs[8][3]; +extern char segs[8][3]; +extern struct idrec *treestart; +extern unsigned int linenum2; +extern unsigned int inptr2; +extern unsigned char cha2; +extern char displaytokerrors; +extern char *bufrm; +extern UNDEFOFF *undefoffstart; +extern DLLLIST *listdll; +extern char skipfind; +extern struct structteg *tegtree; // +extern struct structteg *ltegtree; // +//extern struct idrec *lstructlist; // +extern struct idrec *definestart; +extern SINFO strinf; +extern char *startline, *endinput; +extern ITOK structadr; +extern int scanlexmode; +extern COM_MOD *cur_mod; +extern unsigned char bytesize; +#endif + +#if !defined (_TOKE_) +extern int maxerrors; +extern char mesmain[]; +extern int endifcount; +extern int sysstack; +extern int sysnumcom; +extern int syscom; +extern unsigned char fargc; +extern unsigned char jumptomain; +extern unsigned int startptrdata; +extern unsigned char parsecommandline; +extern unsigned int romsize; +extern unsigned char resizemem; +extern unsigned int resizesizeaddress; +extern unsigned int stackstartaddress; +extern int dataromstart,dataromsize; +extern unsigned char startuptomain; +extern unsigned char dosstring; +extern unsigned int numdomain; // main +extern char *domain; // main +extern unsigned char usedirectiv; // +extern unsigned char atex; +extern unsigned int postnumflag; // +extern unsigned char sdp_mode; // +extern int calcnumber; +extern int strpackdef; +extern int strpackcur; +#ifdef DEBUGMODE +extern int debug; +#endif +extern int dirmode; + +#endif + +extern ITOK itok,itok2,ptok; + +#if !defined (_TOKB_) +extern int divexpand; +extern int optnumber; +extern char *badadr; +extern LISTFLOAT *floatnum; // float +extern unsigned int numfloatconst; +extern unsigned int ofsfloatlist; +#endif +extern unsigned int linenumber; + +#if !defined (_DEBUG_) +extern unsigned int ooutptr; +extern unsigned int outputcodestart; +extern unsigned char dbg,dbgact; +extern unsigned int pdbg; // number of post entrys +#endif + +#if !defined (_OUTPE_) +extern unsigned long ImageBase; +extern unsigned long vsizeheader; // . +extern int filingzerope; +extern unsigned long FILEALIGN; // +#endif + +#if !defined (_ERRORS_) +extern WARNACT wact[]; +extern unsigned char mapfile; +#endif + +#if !defined (_DISASM_) +extern unsigned char seg_size; /* default size is 16 */ +extern unsigned long instruction_offset; +#endif + +#if !defined (_SWITCH_) +extern FSWI *swtables; +extern int numswtable; +#endif + +#if !defined (_CLASS_) +extern structteg *searchteg; +extern int destructor; +#endif + +#if !defined (_RES_) +extern unsigned char *resbuf; +extern unsigned int curposbuf; +extern int numres; // +extern int numstrtbl; +#endif + +extern unsigned char idxregs[5]; + +// start of procedure pre-definitions +/*-----------------19.09.98 17:18------------------- + main.cpp +--------------------------------------------------*/ +void *MALLOC(unsigned long size); +void *REALLOC(void *block,unsigned long size); +void IncludePath(char *buf); +int SelectComand(char *pptr,int *count); +void strbtrim(char *st); +unsigned long Align(unsigned long size,unsigned long val); +int AlignCD(char segm,int val); // +void ErrOpenFile(char *str); +unsigned int EntryPoint(); +long CopyFile(FILE *in,FILE *out); +unsigned long getnumber(unsigned char *buf); +void addinitvar(); +FILE *CreateOutPut(char *ext,char *mode); +void SetLST(unsigned char neg); +void AddUndefClassProc(); +int MakeCoff(); +void setdindata(idrec *ptr,int i); + +/*-----------------08.03.98 20:10------------------- + toka.c +--------------------------------------------------*/ +void CheckAllMassiv(char *&buf,int sizeel,SINFO *strc,ITOK *ctok=&itok,int reg1=idxregs[0],int reg2=idxregs[1]); +void docalls(); //attempt to declare undefs from library and dynamic proc's +int FindOff(unsigned char *name,int base); +void nextchar(); // toke +void nexttok(); +void whitespace(); // +int searchtree(ITOK *itk4,int *tk4,unsigned char *strin4); +void AddUndefOff(int segm,char *ostring); +void InitStruct(); // +unsigned long LocalStruct(int flag,int *localline); // +struct structteg * FindTeg(int Global,char *name=itok.name); // +void dostruct(); +int FastSearch(unsigned char *list,short *ofs,int type,char *str); +void FindDirectiv(); +unsigned long long scannumber(int *rm); +void FastTok(int mode,int *tok4=&tok,ITOK *itok4=&itok); +unsigned int initstructvar(structteg *tteg,int numel); +unsigned int ScanTok3(); +int GetVarSize(int var); +void compressoffset(ITOK *thetok); +void AddDynamicList(idrec *ptr); +int CheckUseAsUndef(unsigned char *name); +int CheckMassiv(char *&buf,int sizeel,int treg,int *idx=0,int *base=0,long *num=0); +void AutoDestructor(); +void dodelete(); +void donew(); +void RunNew(int size); +int CallDestructor(structteg *searcht); +int FindUseName(char *name); // +void DateToStr(char *buf); +int CalcRm16(int base,int idx); +int CheckDef(); +void SetNewStr(char *name); +struct structteg *CreatTeg(int Global,int useunion=FALSE,int noname=FALSE); +void InitStruct2(unsigned int flag,structteg *tteg); +unsigned long LocalStruct2(int flag,int *localline,int binptr,char bcha,structteg *tteg); +void retoldscanmode(int mode); +void ExpandRm(int rm,int sib,int *zoom,int *base,int *idx); +void BackMod(); + +/*-----------------08.03.98 21:45------------------- + tokb.h +--------------------------------------------------*/ +void AddReloc(int segm=itok.segm); +int doalmath(int sign,char **ofsstr); +int do_e_axmath(int sign,int razr,char **ofsstr); +void getintoal(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr); /* AH may also be changed */ +void getinto_e_ax(int sign,int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int useAX=FALSE); +int doeaxfloatmath(int itreturn=tk_reg32,int reg=AX,int addop=0); +int dobytevar(int sign,int terminater=tk_semicolon); // byte, char +int do_d_wordvar(int sign,int razr,int terminater=tk_semicolon); /* signed or unsigned 16 bit memory variable */ +int doreg_32(int reg,int razr,int terminater=tk_semicolon); +void doseg(int seg); +int caselong(unsigned long val); +int dobeg(int beg,int terminater=tk_semicolon); +void dobegmath(int beg); /* math done is on all begs except AL */ +void doregmath_32(int reg,int razr,int sign,char **ofsstr,int i=0); /* math done is on all regs except AX */ +int getintobeg(int beg,char **ofsstr); +int getintoreg_32(int reg,int razr,int sign,char **ofsstr,int useloop=TRUE); /* get into word reg (except AX) with enum */ +void outaddress(ITOK *outtok); +void FloatToNumer(int addop=0); +int dofloatvar(int addop=0,int retrez=tk_floatvar,int terminater=tk_semicolon); +void fwait3(); +void AddFloatConst(long long fnumber,int type=tk_float); +void setwordpost(ITOK *); /* for post word num setting */ +void setwordext(long *id); +void RegMulNum(int reg,unsigned long num,int razr,int sign,int *expand,int flag); +int OnlyNumber(int sign); +void PopSeg(int seg); +void PushSeg(int seg); +void MovRegNum(int razr,int relocf,unsigned long number,int reg); +int CheckMinusNum(); +int getintoreg(int reg,int razr,int sign,char **ofsstr); +void dobits(); +void bits2reg(int reg,int razr); +void getoperand(int reg=BX); +int optnumadd(unsigned long num,int reg,int razr,int vop); +int MultiAssign(int razr,int usereg,int npointr=0); +void CheckInitBP(); +void RestoreBP(); +void fistp_stack(int addop=0); +void fld_stack(int size); +void fildq_stack(); +void cpointr(int reg,int numpointr); +int doqwordvar(int terminater=tk_semicolon); //64 bit memory variable +void doreg64(int reg,int terminater=tk_semicolon); +void doregmath64(int reg); +void getintoreg64(int reg); +void float2stack(int num); +void dofloatstack(int num); + +/*-----------------08.03.98 20:59------------------- + tokc.c +--------------------------------------------------*/ +localrec * addlocalvar(char *str,int tok,unsigned int num,int addmain=FALSE); +int addpoststring(int segm=CS,int len=itok.number, int term=itok.flag); /* add a string to the post queue */ +void define_locallabel(); +unsigned int dofrom(); +unsigned int doextract(); +int doparams(); /* do stack procedure parameter pushing */ +int swapparam(); +long updatetree(); +void addacall(unsigned int idnum,unsigned char callkind); +idrec * addtotree(char *keystring); +void compilefile(char *filename,int firstflag); +void convert_returnvalue(int expectedreturn,int actualreturn); +int doid (char uppercase,int expectedreturn); +void insert_dynamic(int insert=FALSE); +int macros(int expectedreturn); +void op(int byte); +void opd(int byte); // +void op66(int ctoc); +int op67(int ctok); +void outqwordd (unsigned long long); +void outqword (unsigned long long); +void outdwordd (unsigned long); +void outdword (unsigned long); +void outwordd (unsigned int); +void outword (unsigned int); +void outseg(ITOK *outtok,unsigned int locadd); +int procdo(int expectedreturn); +int updatecall(unsigned int which,unsigned int where,unsigned int top); +void AddBackBuf(int,char); +void CharToBackBuf(char c); +void missingpar(char *name=""); +int CheckCodeSize(); +void CheckPosts(); +int doanyundefproc(int jumpsend=FALSE); +int doanyproc(int jumpsend=FALSE); +void killpost(unsigned int poz); +char *BackString(char *str); +DLLLIST *FindDLL(); +long initglobalvar(int type,long elements,long ssize,char typev); +int typesize(int vartype); +void dopoststrings(); +char *dynamic_var(); +void uptdbr(/*int usesw=FALSE*/); +void docommand(); /* do a single command */ +//int CheckStopBlock(); +void MakeBreak(unsigned char typeb); +void SetBreakLabel(); +void SetContinueLabel(); +void CheckDir(); +int SkipParam(); +long GetBitMask(int ofs,int size); +void AddPostData(unsigned int loop); +//void NotPostUnion(); +unsigned int initparamproc(); +void CorrectStack(unsigned int num); +int testInitVar(int checkaldef=TRUE); +void declareparamreg(); +void declareparamstack(); /* declare procedure parameters */ +void declareparams(); /* declare procedure parameters */ +void declarelocals(int mode,int finline=FALSE); /* declare locals */ +void doblock2(); +void doblock(); +void setreturn(); +int CidOrID(); +void dynamic_proc(); +void setproc(int defflag); +void define_procedure(); +void doregparams(); +int CheckDeclareProc(); +int loadfile(char *filename,int firstflag); +void RestoreStack(); +void IsUses(idrec *rec); +int SkipBlock(); +void declareanonim(); +void declareunion(); +void startblock(); +void endblock(); +void LLabel(); +void AddApiToPost(unsigned int num); + +/*-----------------08.03.98 20:06------------------- + toke.c +--------------------------------------------------*/ +void jumperror(unsigned int line,char *type); +void beep(); /* beep for any internal errors */ +void codeexpected(); +void datatype_expected(int type=0); +unsigned long doconstdwordmath(); +signed long doconstlongmath(); +long doconstfloatmath(); +void dwordvalexpected(); +void idalreadydefined(); +void illegalfloat(); +void internalerror (char *str);// serious internal compiler error message +void maxoutputerror(); +void maxwordpostserror(); +void nextseminext(); +void numexpected(int type=0); +void operatorexpected(); +void seminext(); +void shortjumptoolarge(); +void stringexpected(); +void swaperror(); +void SwTok(int want); +void unabletoopen(char *str); +void unexpectedeof(); +void unknowncompop(); +void valueexpected(); +void varexpected(int type); +void wordvalexpected(); +int includeit(int type); +int includeproc(); +int CheckMacros(); +void tobigpost(); +void expected (char ch); +int expecting(int want); +void outprocedure(unsigned char *array,unsigned int length); +void preerror(char *str);//error on currentline with line number and file name +void thisundefined(char *str,int next=TRUE); +void addconsttotree(char *keystring,long long constvalue,int type=tk_dword); +void directive(); +void doenum(); +void doprestuff(); //do initial code things, like resize mem, jump to main... +void searchvar(char *name,int err=1); +void expectingoperand(int want); +void InitDefineConst(); +unsigned long long doconstqwordmath(); +long long doconstdoublemath(); +int calclongnumber(long *retnum,long number,int operand); +int calcqwordnumber(unsigned long long *retnum,unsigned long long number,int operand); +int calcdwordnumber(unsigned long *retnum,unsigned long number,int operand); +int calcfloatnumber(float *retnum,float number,int operand); +int calcdoublenumber(double *retnum,double number,int operand); + +/*-----------------08.03.98 22:24------------------- + tokr.c +--------------------------------------------------*/ +void doasm(int next=FALSE); +int short_ok(long thenumber,int reg32=FALSE); +void callloc(long loc); /* produce CALL # */ +void callloc0(); +void cbw(void); +int GOTO(); +void expecting2(int want); +unsigned char gotol(int faradd); +void jumploc(long loc); /* produce JUMP # */ +void jumploc0(); +void movsb(void); +void movsd(void); +void movsw(void); +void popes(); /* produce POP ES */ +void pushds(); /* produce PUSH DS */ +void pushss(); +void ret(); /* produce RET */ +void retf(); /* produce RETF */ +void stosb(void); +void stosd(void); +void stosw(void); +void fwait(); +void xorAHAH(void); /* produce XOR AH,AH */ +void xorAXAX(void); /* produce XOR AX,AX */ +void xorEAXEAX(void); /* produce XOR EAX,EAX */ +void nextexpecting2(int want); +void tobedefined(int callkind,int expectedreturn); +void cwdq(int razr); +void Leave(); +void CheckIP(); +int iTest(int mode=0); +void ZeroReg(int reg, int razr); +int Push(ITOK *wtok=NULL); + +/*-----------------08.08.00 22:50------------------- + errors.cpp + --------------------------------------------------*/ +void warningstring(); +void warningexpand(); +void warningjmp(char *str2,int line=linenumber,int file=currentfileinfo); +void warningreg(char *str2); +void preerror3(char *str,unsigned int line,unsigned int file=currentfileinfo);// error message at a different than current line +void unableopenfile(char *name); +void tegnotfound(); +void errstruct(); +void warningdefined(char *); +void extraparam(char *name=""); +void warningretsign(); +void ErrWrite(); +void ErrReadStub(); +void warningnotused(char *name,int type); +void regBXDISIBPexpected(); +void reg32expected(int type=0); +void InvOperComp(); +void warningusenotintvar(char *name); +void warningdestroyflags(); +void warningunreach(); +void unuseableinput(); +void redeclare(char *name); +void undefclass(char *name); +void badinfile(char *name); +void errorreadingfile(char *name); +void expectederror(char *str); +void unknowntype(); +void unknownstruct (char *name,char *sname); +void unknowntagstruct (char *name); +void warninline(); +void ZeroMassiv(); +void bytevalexpected(int type); +void FindStopTok(); +//void not_union_static(); +extern void edpip(int num=0); +void waralreadinit(char *reg); +void waralreadinitreg(char *reg,char *reg2); +void OnlyComFile(); +void warnsize(); +void destrdestreg(); +void qwordvalexpected(); +void fpustdestroed(); +void unknownobj(char *name); +void FindEndLex(); +void fpu0expected(); +void unknownpragma(char *name); +void warpragmapackpop(); +void SkipBlock2(); +void warreplasevar(char *name); +void warcompneqconst(); +void warcompeqconst(); +void warpointerstruct(); +void warESP(); +void waralreadinitvar(char *name,unsigned int num); +void warningprint(char *str,unsigned int line,unsigned int file); +void notexternfun(); + +void AddDataLine(char ssize/*,char typev*/); +void mapfun(int); + +/*-----------------24.01.01 01:42------------------- + disasm.cpp + --------------------------------------------------*/ +void undata(unsigned ofs,unsigned long len,unsigned int type); +void unassemble(unsigned long ofs); + +/*-----------------25.01.01 23:02------------------- + debug.cpp + --------------------------------------------------*/ +void AddLine(int SkipLine=FALSE); +void DoTDS(); +void InitDbg(); +void KillLastLine(); +void AddDataNullLine(char ssize/* new!!! */,char *name=NULL); +void AddCodeNullLine(char *name=NULL); +void AddEndLine(); +#ifdef DEBUGMODE +void printdebuginfo(); +#endif +//void AddMainLine(); + +/*-----------------12.04.01 22:46------------------- + outpe + --------------------------------------------------*/ +void CreatStub(char *name); +void CreatWinStub(); +void ChSize(long size); + +/*-----------------12.04.01 22:57------------------- + outle + --------------------------------------------------*/ +int MakeLE(); +int MakeMEOS(); +int MakeBin32(); + +/*-----------------08.12.01 23:43------------------- + pointer + --------------------------------------------------*/ +void dopointer(); +void dovalpointer(); +void getpointeradr(ITOK *gstok,char *&gbuf,SINFO *gstr,int numpointer,int razr,int reg=BX); +void dopointerproc(); + +/*-----------------09.12.01 00:28------------------- + new_type + --------------------------------------------------*/ +void convert_type(int *sign,int *rettype,int *pointr,int reg=BX); + +/*-----------------23.12.01 02:39------------------- + class + --------------------------------------------------*/ +void doclassproc(unsigned int); +void AddThis(); + +/*-----------------27.01.02 23:39------------------- + res + --------------------------------------------------*/ +void input_res(); +int MakeRes(unsigned long ofsres,LISTRELOC **listrel); +void CreatStrTabRes(); + +/*-----------------14.04.03 21:31------------------- + optreg +--------------------------------------------------*/ +void initregstat(); +void deinitregstat(); +void IDXToReg(char *name,int size,int reg); +int CheckIDXReg(char *name,int size,int reg); +void IDZToReg(char *name,int reg,int razr); +int CheckIDZReg(char *name,int reg,int razr); +void clearregstat(int regs=0); +void ConstToReg(unsigned long num,int reg,int razr); +void ClearReg(int reg); +int RegSwapReg(int reg1,int reg2,int razr); +char *GetLecsem(int stop1,int stop2=tk_eof,int type=-1); +REGISTERSTAT *BakRegStat(); +void CopyRegStat(REGISTERSTAT *bak); +void KillVar(char *name); +void CompareRegStat(REGISTERSTAT *bak); +int RegToReg(int regd,int regs,int razr); +void GenRegToReg(int regd,int reds,int razr); +void GetEndLex(int stop1,int stop2=tk_eof,int type=-1); +int GetRegNumber(int reg,unsigned long *num,int razr); +int GetNumberR(int reg,unsigned long *num,int razr,unsigned long number); +void FreeStat(REGISTERSTAT *bak); +void AddRegVar(int reg, int razr,ITOK *itok4); +int GetRegVar(ITOK *itok4); +#ifdef OPTVARCONST +void CreateMainLVIC(); +void KillMainLVIC(); +void ClearLVIC(); +int Const2Var(ITOK *itok4,long long num,int typenum); +void ClearVarByNum(ITOK *itok4); +int UpdVarConst(ITOK *itok4,long long num,int typenum,int operand); +void FreeGlobalConst(); +int CheckRegToConst(int reg,ITOK *itok4,int razr); +int CheckUpdRegToConst(int reg,ITOK *itok4,int operand,int razr); +int SwapVarConst(ITOK *itok2,ITOK *itok4); +int SwapVarRegConst(int reg,ITOK *itok4,int razr); +int CheckConstVar(ITOK *itok4); +//int CheckConstVar2(ITOK *itok4,long long *num,int *typenum); +void CheckConstVar3(int *tok4,ITOK *itok4,int razr); +void Const2VarRec(LVIC *varconst); +#endif + +#ifndef _REGOPT_ +extern unsigned char optinitreg; +#ifdef OPTVARCONST +extern unsigned char replasevar; +extern LVIC *listvic; +#endif +#endif + +/*----------------------- +libobj + -------------------------*/ +void AddNameObj(char *name,int typefind,int type); +void AddObj(); + +#ifdef __NEWLEX__ +void inittokn(); +void doblockstart(char *); + +#endif +/* end of TOK.H */ diff --git a/programs/develop/cmm/toka.cpp b/programs/develop/cmm/toka.cpp new file mode 100644 index 0000000000..271c84e2fe --- /dev/null +++ b/programs/develop/cmm/toka.cpp @@ -0,0 +1,6448 @@ + +#define _TOKA_ + +#include "tok.h" + +#pragma option -w-pin + +#ifdef _WIN32_ +#include +#endif + +#include +#include + +#include "dirlist.h" +#include "id.h" +#include "resname.h" + +struct idrec *treestart=NULL; +struct idrec *definestart=NULL; +UNDEFOFF *undefoffstart=NULL; +DLLLIST *listdll=NULL; +struct structteg *tegtree=NULL; // ᮪ ⥣ +struct structteg *ltegtree=NULL; // ᮪ ⥣ +//struct idrec *lstructlist=NULL; //ᯨ᮪ +SINFO strinf={NULL}; +static int notdef=TRUE; +static char precha; +int scanalltoks=TRUE; + + +static volatile idrec **DynamicList=NULL; +static int sizeDL; //ࠧ ᯨ᪠ +static volatile int countDP; //᫮ ᪨ 楤 ᯨ᪥ +static int findofset=FALSE; +#define STEPDL 128; //蠣 㢥祭 ࠧ ᯨ᪠ +ITOK structadr; + + +char id2[ID2S][9]={ + "ESCHAR","ESBYTE","ESINT","ESWORD","ESLONG","ESDWORD","ESFLOAT","ESQWORD","ESDOUBLE", + "CSCHAR","CSBYTE","CSINT","CSWORD","CSLONG","CSDWORD","CSFLOAT","CSQWORD","CSDOUBLE", + "SSCHAR","SSBYTE","SSINT","SSWORD","SSLONG","SSDWORD","SSFLOAT","SSQWORD","SSDOUBLE", + "DSCHAR","DSBYTE","DSINT","DSWORD","DSLONG","DSDWORD","DSFLOAT","DSQWORD","DSDOUBLE", + "FSCHAR","FSBYTE","FSINT","FSWORD","FSLONG","FSDWORD","FSFLOAT","FSQWORD","FSDOUBLE", + "GSCHAR","GSBYTE","GSINT","GSWORD","GSLONG","GSDWORD","GSFLOAT","GSQWORD","GSDOUBLE",}; + +char regs[2][8][4]={"AX","CX","DX","BX","SP","BP","SI","DI", + "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI"}; +char begs[8][3]={"AL","CL","DL","BL","AH","CH","DH","BH"}; +char segs[6][3]={"ES","CS","SS","DS","FS","GS"}; + +char mon[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug", + "Sep","Oct","Nov","Dec"}; + +unsigned char cha2; +char skipfind=FALSE; /* ய ᪠ 쭮 ॢ । + ६ */ +static unsigned char savestring3=FALSE; //ࠧ string3 +static int posstr3; //㪠⥫ 樨 string3 + +unsigned int inptr2; +unsigned int linenum2=0; //᫨ , ⪠ +char displaytokerrors; /* flag to display errors, 0 for tok2 scan */ +char *bufrm=NULL; +char *startline=NULL; +char *endinput=NULL; +unsigned char skiplocals=FALSE; +int scanlexmode=STDLEX; +unsigned char bytesize=TRUE; + +COM_MOD *cur_mod=NULL; + +void docals(struct idrec *ptr); +void dostructvar2(int *tok4,ITOK *itok4,struct structteg *tteg,unsigned char *string4); //ࠧ ६ +void dosizeof(ITOK *itok4); // 祭 sizeof +void ofsstr(int *tok4,ITOK *itok4); +int searchlocals(ITOK *itok4,int *tok4,unsigned char *string4); +unsigned char convert_char(); +void tokscan (int *tok4,ITOK *itok4,unsigned char *string4); +int calcnum(int *ctok,ITOK *cstok,char *cstring,long *retval); +int GetDirective(char *str); +int CheckAsmName(char *name); +void tag_massiv(int *tok4,ITOK *itok4,unsigned char *string4); +int CheckResName(char *name); +void GetTypeVar(int *tok4); +int RegToRM(int number,int tok4); +elementteg *FindClassEl(structteg *searcht,unsigned char *string4,int *addofs, + structteg *subteg); +int AskUseDestr(structteg *searcht); +int SaveStruct(int size,idrec *newrec); +int CheckDefPar(char *name); +int searchtree2(idrec *fptr,ITOK *itok4,int *tok4,unsigned char *string4); + +extern void blockerror(); +extern void block16_32error(); +extern void notstructname(); +extern void badtoken(); +extern void opb(unsigned long num,unsigned int ofs,unsigned int size); +extern void CorrectOfsBit(int bitofs); +extern int skipstring(int pos,unsigned char term); +extern int skipcomment(int pos); + + +void retoldscanmode(int mode) +{ + if(mode==STDLEX&&cha2==13&&tok!=tk_endline){ + cha2=cha; + } + scanlexmode=mode; +} + +void CheckConvertString(char *string4) +{ + if(cha=='o'){ + OemToChar(string4,string4); + nextchar(); + } + else if(cha=='w'){ + CharToOem(string4,string4); + nextchar(); + } +} + +void DateToStr(char *buf) +{ +// GetDateFormat(LOCALE_SYSTEM_DEFAULT,DATE_SHORTDATE|LOCALE_NOUSEROVERRIDE,NULL,NULL,buf,80); + sprintf(buf,"%2d %s %d",timeptr.tm_mday,mon[timeptr.tm_mon],timeptr.tm_year+1900); +} + +void compressoffset(ITOK *thetok) +{ + if(thetok->sib==CODE16){ + if(thetok->rm!=rm_d16){ + thetok->rm&=7; + if(thetok->number==0){ + if(thetok->rm==rm_BP)thetok->rm|=rm_mod01; + } + else if((int)thetok->number<128&&(int)thetok->number>=-128)thetok->rm|=rm_mod01; + else thetok->rm|=rm_mod10; + } + } + else{ + if(thetok->rm!=rm_d32&&thetok->rm!=rm_sib){ + thetok->rm&=7; + if(thetok->number==0){ + if(thetok->rm==5)thetok->rm|=rm_mod01; + if(thetok->rm==4&&(thetok->sib&7)==5)thetok->rm|=rm_mod01; + } + else if(thetok->number<128&&thetok->number>=-128)thetok->rm|=rm_mod01; + else thetok->rm|=rm_mod10; + } + } +} + +int CalcRm16(int base,int idx) +{ +int rm; + rm=0; + switch(base+idx){ + case 2: rm++; + case 4: rm++; + case 6: rm++; + case 5: rm++; + case 12: rm++; + case 11: rm++; + case 10: rm++; + } + return rm; +} + +void SRBackBuf(int mode) //save/restore BackTextBlock +{ +static int size=0; +static char *buf; + if(mode==0){ + if(SizeBackBuf){ + size=SizeBackBuf; + SizeBackBuf=0; + buf=BackTextBlock; + } + } + else{ + SizeBackBuf=size; + size=0; + BackTextBlock=buf; + } +} + +void ExpandRm(int rm,int sib,int *zoom,int *base,int *idx) +{ +int rm0; +int reg1=-1,reg2=-1; +int z=0; + rm0=rm&0x7; + if(sib==CODE16||sib==(CODE16+1)){ + switch(rm0){ + case 0: + reg1=BX; + reg2=SI; + break; + case 1: + reg1=BX; + reg2=DI; + break; + case 2: + reg1=BP; + reg2=SI; + break; + case 3: + reg1=BP; + reg2=DI; + break; + case 4: + reg2=SI; + break; + case 5: + reg2=DI; + break; + case 6: + if((rm&0xC0)!=0)reg1=BP; + break; + case 7: + reg1=BX; + break; + } + } + else{ + if(rm0==4){ + reg1=sib&7; + reg2=(sib>>3)&7; + if(reg1==5&&(rm&0xc0)==0)reg1=-1; + if(reg2==4)reg2=-1; + else z=sib>>6; + } + else{ + reg1=rm0; + if(reg1==5&&(rm&0xc0)==0)reg1=-1; + } + } + *base=reg1; + *idx=reg2; + *zoom=z; +} + +int CheckZoom(int size) +{ +int zoom=0; + switch(size){ + case 8: zoom++; + case 4: zoom++; + case 2: zoom++; + } + return zoom; +} + +void calcrm(ITOK *itok4,int ttok)//ࠡ⪠ ࠦ [] +{ +int idx,base,razr=0,zoom,rm=0; +long numrm=0,cnum,ocnum; +int nextscan; +ITOK cstok,dstok; +int ctok,sopenb; +unsigned char *pstring; +unsigned int flag; +unsigned int sizevar=1; +unsigned int prevtok=tk_number,operand=tk_plus; +int dsword,dsword2; + nextchar(); + whitespace();//ய ᨬ + if(!displaytokerrors){ + for(int i=1;i!=0;){ + FastTok(0,&ctok,&cstok); + switch(ctok){ + case tk_closeblock: i--; break; + case tk_openblock: i++; break; + case tk_eof: i=0; break; + } + } + return; + } + + dsword2=dsword=itok4->post&POINTER; + itok4->post&=NOTPOINTER; + memcpy(&dstok,itok4,sizeof(ITOK)); + ExpandRm(dstok.rm,dstok.sib,&zoom,&base,&idx); + if((dstok.sib==CODE16||dstok.sib==(CODE16+1))&&dstok.rm!=rm_d16)razr=r16; + if(am32&&dstok.rm!=rm_d32){ + rm=dstok.rm&0xC0; + razr=r32; + } +// printf("in idx=%d base=%d zoom=%d\n",idx,base,zoom); + pstring=(unsigned char *)MALLOC(STRLEN); + sopenb=inptr; + char bcha=cha; + SRBackBuf(0); + flag=f_useidx;//0;//cstok.flag; + if(bytesize==FALSE){ + sizevar=GetVarSize(ttok); + if(dsword)sizevar=1; + if(am32)zoom=CheckZoom(sizevar); + } + if(cha=='&'){ + nextchar(); + whitespace();//ய ᨬ + sizevar=1; + zoom=0; + } + for(;;){ + nextscan=TRUE; + if(cha=='#'&&dsword)dsword=1; + tokscan(&ctok,&cstok,pstring); + whitespace();//ய ᨬ + if(dsword==1)strcpy(dstok.name,cstok.name); +// printf("tok=%d num=%d %s\n",ctok,cstok.number,cstok.name); +loopsw: + switch(ctok){ + case tk_reg: + if(razr==0)razr=r16; + else if(razr==r32||sizevar!=1||operand!=tk_plus)goto runblock; //16.12.04 22:39 + if(cstok.number==BP||cstok.number==BX){ + if(base==-1)base=cstok.number; + else goto runblock; + } + else if(cstok.number==SI||cstok.number==DI){ + if(idx==-1)idx=cstok.number; + else goto runblock; + } + else goto runblock; + prevtok=tk_reg; + break; + case tk_minus: + if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock; + prevtok=tk_number; + ocnum=cstok.number; + goto enumb; + case tk_number: + if(operand==tk_mult&&prevtok==tk_reg32){ + if(zoom==0){ + prevtok=tk_number; + if(razr==0)razr=r32; + else if(razr==r16)goto runblock; + zoom=CheckZoom(cstok.number); + if(zoom)break; + } + else goto runblock; + } + prevtok=tk_number; + ocnum=cstok.number; + if(zoom==0&&razr!=r16&&(idx==-1||base==-1)){ + if((zoom=CheckZoom(cstok.number))!=0){ + if(cha=='*'){ + nextchar(); + tokscan(&ctok,&cstok,pstring); + if(ctok==tk_reg32){ + if(idx!=-1)base=idx; + idx=cstok.number; + prevtok=tk_reg32; + if(razr==0)razr=r32; + break; + } + if(ctok==tk_number){ + calclongnumber(&ocnum,cstok.number,tk_mult); + numrm+=ocnum; + zoom=0; + break; + } + goto runblock; + } + zoom=0; + } + } + if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock; +enumb: + flag^=cstok.flag; + whitespace();//ய ᨬ + ocnum=cnum; + numrm+=cnum; + if(cstok.type==tp_opperand||cstok.type==tp_stopper)nextscan=FALSE; + else{ + operand=tk_plus; + goto loopsw; + } + break; + case tk_reg32: +// printf("prevtok=%d operand=%d ocnum=%d idx=%d base=%d zoom=%d\n",prevtok,operand,ocnum,idx,base,zoom); + if(razr==0)razr=r32; + if(razr==r16||(operand!=tk_plus&&operand!=tk_mult)||(idx!=-1&&base!=-1))goto runblock; + if(sizevar!=1){ + if(idx!=-1)goto runblock; + idx=cstok.number; + } + else if(operand==tk_mult){ + if(prevtok!=tk_number)goto runblock; + zoom=CheckZoom(ocnum); + numrm-=ocnum; + if(idx!=-1)base=idx; + idx=cstok.number; + } + else if(cha=='*'){ + if(idx!=-1)base=idx; + idx=cstok.number; + } + else if(base==-1)base=cstok.number; + else if(idx==-1)idx=cstok.number; +// else goto runblock; + prevtok=tk_reg32; + break; + case tk_postnumber: + if(dsword==0||sizevar!=1)goto runblock; + if((cstok.post&USED_DIN_VAR)==USED_DIN_VAR){ //᪠ ६ + if(dstok.rec!=NULL)goto runblock; + dstok.rec=cstok.rec; + } + if(operand==tk_minus)numrm-=cstok.number; + else numrm+=cstok.number; + dstok.post|=cstok.post; + prevtok=tk_number; + break; + case tk_undefofs: + if(dsword==0||sizevar!=1)goto runblock; + if(operand==tk_minus)numrm-=cstok.number; + else numrm+=cstok.number; + dstok.post|=UNDEF_OFSET; + strcpy(dstok.name,cstok.name); + flag^=cstok.flag; + prevtok=tk_number; + break; + case tk_rmnumber: +/* if(strinf.bufstr!=NULL){ + free(strinf.bufstr); + strinf.bufstr=NULL; + goto runblock; + }*/ + if(dsword==0||sizevar!=1)goto runblock; + if(operand==tk_minus)numrm-=cstok.number; + else numrm+=cstok.number; + dstok.post|=cstok.post; + if(dstok.sib==CODE16){ + if(cstok.rm!=rm_d16){ + switch(cstok.rm&7){ + case 0: + if(base!=-1||idx!=-1)goto runblock; + base=BX; idx=SI; break; + case 1: + if(base!=-1||idx!=-1)goto runblock; + base=BX; idx=DI; break; + case 2: + if(base!=-1||idx!=-1)goto runblock; + base=BP; idx=SI; break; + case 3: + if(base!=-1||idx!=-1)goto runblock; + base=BP; idx=DI; break; + case 4: + if(idx!=-1)goto runblock; + idx=SI; break; + case 5: + if(idx!=-1)goto runblock; + idx=DI; break; + case 6: + if(idx!=-1)goto runblock; + base=BP; break; + case 7: + if(idx!=-1)goto runblock; + base=BX; break; + } + } + razr=r16; + } + else{ + if(cstok.rm!=rm_d32){ + rm=cstok.rm&0xC0; + cstok.rm&=7; + if(base==-1)base=cstok.rm; + else if(idx==-1){ + idx=base; + base=cstok.rm; + } + else goto runblock; + if(base==4){ + base=cstok.sib&7; + idx=(cstok.sib>>3)&7; + if(base==5&&rm==0)base=-1; + if(idx==4)idx=-1; + } + } + else dstok.flag|=cstok.flag&f_reloc; + razr=r32; + } + break; +//-----------------28.07.98 13:59------------------- +// var[i] +//-------------------------------------------------- + default: +runblock: + if(dsword2){ + CharToBackBuf('&'); + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + } + AddBackBuf(sopenb,bcha); + if(bufrm){ + if(strcmp(bufrm,"&this;")==0){ + free(bufrm); + CharToBackBuf(0); + sprintf((char *)string3,"&%s*%d+this;",BackTextBlock,GetVarSize(ttok)); + bufrm=BackString((char *)string3); +// puts((char *)string3); + goto con1; + } + else free(bufrm); + } + CharToBackBuf(';'); + CharToBackBuf(0); + bufrm=(char *)REALLOC(BackTextBlock,SizeBackBuf+1); +con1: + if(cha!=']')blockerror(); + tokscan(&ctok,&cstok,pstring); + if(itok4->sib>=CODE16)itok4->sib++; + SRBackBuf(1); +// if(itok4->post&POINTER)itok4->post=0;//&=NOTPOINTER; + free(pstring); + itok4->flag|=flag; + return; +//-----------------28.07.98 13:59------------------- +// end +//-------------------------------------------------- + } + if(dsword==1)dsword=0; + if(nextscan){ + tokscan(&ctok,&cstok,pstring); + whitespace();//ய ᨬ + } + while(ctok==tk_minus){ + if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock; + whitespace();//ய ᨬ + numrm+=cnum; + flag^=cstok.flag; + if(cstok.type!=tp_opperand&&cstok.type!=tp_stopper){ + operand=tk_plus; + goto loopsw; + } + } + operand=ctok; +// printf("operand tok=%d flag=%08X %s\n",ctok,cstok.flag,cstok.name); + if(ctok==tk_closeblock||ctok==tokens||ctok==tk_eof)break; + if(ctok!=tk_plus&&ctok!=tk_mult)goto runblock; +// flag|=cstok.flag; + } +// printf("out idx=%d base=%d zoom=%d\n",idx,base,zoom); + SRBackBuf(1); + if(ctok!=tk_closeblock)expected(']'); + numrm*=sizevar; + dstok.number+=numrm; + if(razr==r16){ + if(idx==-1&&base==-1)cstok.rm=6; + else{ + cstok.rm=CalcRm16(base,idx)|rm_mod10; + dstok.sib=CODE16; + } + } + else if(razr==0){ + if(dstok.number<65536&&dstok.number>-65535)cstok.rm=6; + else{ + cstok.rm=5; + dstok.sib=0; + } + if(am32)cstok.rm=5; + } + else{ +// printf("razr=%d sib=%08X %s\n",razr,dstok.sib,dstok.name); + if(dstok.sib>CODE32)dstok.sib-=CODE32; + else dstok.sib=0; + if(idx!=-1){ + cstok.rm=4; + if(idx==4)preerror("ESP cannot be the index register"); + if(base!=-1)dstok.sib=(zoom<<6)+(idx<<3)+base; + else{ + dstok.sib=(zoom<<6)+(idx<<3)+5; + rm=(base==5?rm_mod10:0); + } + } + else{ + if(base==4){ + dstok.sib=(4<<3)+4; + cstok.rm=4; + } + else if(base==-1){ + cstok.rm=rm_d32; + } + else cstok.rm=base; + } + if(base!=-1||rm!=0)cstok.rm|=rm_mod10; //४ MOD 㤥 , ᥩ ᨬ + } + dstok.rm=cstok.rm; + dstok.flag|=flag; + memcpy(itok4,&dstok,sizeof(ITOK)); + free(pstring); +} + +int calcnum(int *ctok,ITOK *cstok,char *cstring,long *retval) +{ +long value; +unsigned int flag; + if(*ctok==tk_minus){ + tokscan(ctok,cstok,(unsigned char *)cstring); + if(*ctok!=tk_number)return(0); + cstok->number=-cstok->number; + } + else if(*ctok!=tk_number)return(0); + value=cstok->number; + flag=cstok->flag; + for(;;){ +int otok; + tokscan(ctok,cstok,(unsigned char *)cstring); + otok=*ctok; + if(otok==tk_closeblock)break; + tokscan(ctok,cstok,(unsigned char *)cstring); + if(*ctok!=tk_number){ + if(*ctok==tk_reg32&&(otok==tk_mult||otok==tk_minus)){ + *ctok=(unsigned int)cstok->number; + *retval=value; + cstok->flag=flag; + return 0; + } + break; + } + if(calclongnumber(&value,cstok->number,otok)==FALSE){ + if(displaytokerrors)blockerror(); + break; + } +/* switch(otok){ + case tk_minus: value-=cstok->number; break; + case tk_plus: value+=cstok->number; break; + case tk_xor: value^=cstok->number; break; + case tk_and: value&=cstok->number; break; + case tk_or: value|=cstok->number; break; + case tk_mod: value%=cstok->number; break; + case tk_div: value/=cstok->number; break; + case tk_mult: value*=cstok->number; break; + case tk_rr: value>>=cstok->number; break; + case tk_ll: value<<=cstok->number; break; + case tk_xorminus: value^=-cstok->number; break; + case tk_andminus: value&=-cstok->number; break; + case tk_orminus: value|=-cstok->number; break; + case tk_modminus: value%=-cstok->number; break; + case tk_divminus: value/=-cstok->number; break; + case tk_multminus: value*=-cstok->number; break; + case tk_rrminus: value>>=-cstok->number; break; + case tk_llminus: value<<=-cstok->number; break; + default: if(displaytokerrors)blockerror(); goto end; + }*/ + flag^=cstok->flag; + } +//end: + cstok->flag=flag; + *retval=value; + return -1; +} + +void CheckReg(int idx,int base,int *reg1,int *reg2,int razr) +{ + if(razr==r32){ + unsigned char lreg[8]; + int i; + for(i=0;i<8;i++){ + if(i==ESP||i==EBP)lreg[i]=1; + else{ + if((idx!=-1&&idx==i)||(base!=-1&&base==i))lreg[i]=1; + else lreg[i]=0; + } +// printf("%c",lreg[i]+'0'); + } + if(lreg[*reg1]==0)lreg[*reg1]=1; + else{ + for(i=8;i!=0;i--){ + if(lreg[i]==0){ + lreg[i]=1; + *reg1=i; + break; + } + } + } +// printf("\nreg1=%d",*reg1); + if(lreg[*reg2]!=0){ + for(i=8;i!=0;i--){ + if(lreg[i]==0){ + *reg2=i; + break; + } + } + } +// printf(" reg2=%d\n",*reg2); + } + else{ + if(base!=-1){ + if(base==*reg1)*reg1=SI; + else if(base==*reg2)*reg2=DI; + if(*reg1==*reg2){ + if(*reg1==SI)*reg2=DI; + else *reg2=SI; + } + } + if(idx!=-1){ + if(idx==SI)*reg1=DI; + else *reg1=SI; + *reg2=CX; + } + } +} + +void CheckAllMassiv(char *&buf,int sizeel,SINFO *strc,ITOK *ctok,int reg1,int reg2) +{ +int zoom0,idx0,base0,newreg; +int zoom1=0,zoom2=0; +char pv=FALSE; +int razr=r32; +//printf("sib=%X\n",ctok->sib); + switch(ctok->sib){ + case CODE16+2: + case CODE32+2: ctok->sib--; + case CODE16+1: + case CODE32+1: ctok->sib--; + } + if(ctok->sib==CODE16){ + razr=r16; + if(am32)block16_32error(); + } + if(buf==NULL&&strc->bufstr==NULL)return; + ExpandRm(ctok->rm,ctok->sib,&zoom0,&base0,&idx0); + if(base0==-1&&idx0!=-1&&zoom0==0){ + base0=idx0; + idx0=-1; + } + CheckReg(idx0,base0,®1,®2,razr); +// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0); + if(buf!=NULL){ + if(*buf=='&'){ + sizeel=1; + pv=TRUE; + ctok->flag&=~f_reloc; + } + if((newreg=CheckIDXReg(buf,sizeel,reg1))!=NOINREG){ + if(newreg!=SKIPREG){ + if(razr==r16){ + if(newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt; + if(base0!=-1&&(newreg==BX||newreg==BP))goto noopt; + if(idx0!=-1&&(newreg==DI||newreg==SI))goto noopt; + } + waralreadinitreg(regs[am32][reg1],regs[am32][newreg]); + reg1=newreg; + } + free(buf); + buf=NULL; + } + else{ + if(razr==r32){ + if((zoom1=CheckZoom(sizeel))){ + sizeel=1; + if((newreg=CheckIDXReg(buf,sizeel,reg1))!=NOINREG){ + if(newreg!=SKIPREG){ + waralreadinitreg(regs[1][reg1],regs[1][newreg]); + reg2=reg1; + reg1=newreg; + } + free(buf); + buf=NULL; + goto cont1; + } + } + } +noopt: + if(razr==r32&&idx0==-1&&base0==-1&&zoom1==0){ +ITOK wtok; + wtok=*ctok; + newreg=CheckMassiv(buf,sizeel,reg1,&idx0,&base0,&wtok.number); + *ctok=wtok; +// newreg=CheckMassiv(buf,sizeel,reg1); + } + else newreg=CheckMassiv(buf,sizeel,reg1); + if(newreg!=-1){ + reg2=reg1; + reg1=newreg; + } + } + } + else{ + reg2=reg1; + reg1=-1; + } +cont1: +// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0); + if(strc->bufstr!=NULL){ + sizeel=strc->size; + if((newreg=CheckIDXReg(strc->bufstr,sizeel,reg2))!=NOINREG){ + if(newreg!=SKIPREG){ + if(razr==r16){ + if(newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt2; + if(base0!=-1&&(newreg==BX||newreg==BP))goto noopt2; + if(idx0!=-1&&(newreg==DI||newreg==SI))goto noopt2; + } + waralreadinitreg(regs[am32][reg2],regs[am32][newreg]); + reg2=newreg; + } + free(strc->bufstr); + strc->bufstr=NULL; + } + else{ + if(razr==r32&&zoom1==0){ + if((zoom2=CheckZoom(sizeel))){ + sizeel=1; + if((newreg=CheckIDXReg(strc->bufstr,sizeel,reg2))!=NOINREG){ + if(newreg!=SKIPREG){ + waralreadinitreg(regs[2][reg1],regs[2][newreg]); + reg2=newreg; + } + free(strc->bufstr); + strc->bufstr=NULL; + goto cont2; + } + } + } +noopt2: + if((newreg=CheckMassiv(strc->bufstr,sizeel,reg2))!=-1)reg2=newreg; + } +cont2: + if(reg1==-1){ + reg1=reg2; + zoom1=zoom2; + reg2=-1; + zoom2=0; + } + } + else reg2=-1; +// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0); + if(base0==-1){ + if(reg1!=-1&&zoom1==0){ + base0=reg1; + reg1=reg2; + zoom1=zoom2; + reg2=-1; + zoom2=0; + } + else if(reg2!=-1&&zoom2==0){ + base0=reg2; + reg2=-1; + } + } + if(idx0==-1){ + if(zoom1){ + zoom0=zoom1; + zoom1=0;//zoom2; + idx0=reg1; + reg1=reg2; + reg2=-1; + } + else{ + if(reg1!=-1){ + idx0=reg1; + reg1=reg2; + zoom1=zoom2; + reg2=-1; + zoom2=0; + } + } + } +// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0); + if(reg2!=-1){ + if(zoom1==0&&zoom2==0){ + op(3); + op(0xC0+reg1*8+reg2); //add reg1,reg2 + } + else{ + if(zoom1==0){ + op(0x8d); //lea reg1,[reg1+reg2*zoom2] + op(reg1*8+4); + op((zoom2<<6)+(reg2<<3)+reg1); + } + else{ + op(0x8d); //lea reg1,[reg2+reg1*zoom1] + op(reg1*8+4); + op((zoom1<<6)+(reg1<<3)+reg2); + zoom1=0; + } + } + ClearReg(reg1); + } + if(reg1!=-1){ + if(base0!=-1){ + if(zoom1==0){ + op(3); + op(0xC0+reg1*8+base0); //add reg1,base0 + } + else{ + op(0x8d); //lea reg1,[base0+reg1*zoom1] + op(reg1*8+4); + op((zoom1<<6)+(reg1<<3)+base0); + } + } + else if(zoom1){ + op(0xC1); + op(0xE0+reg1); //shl reg2,zoom2 + op(zoom1); + } + base0=reg1; + } + if(razr==r32){ + ctok->sib=CODE32; + if(idx0!=-1){ + ctok->rm=4; + if(base0!=-1){ + ctok->sib=(zoom0<<6)+(idx0<<3)+base0; + ctok->rm|=rm_mod10; + } + else ctok->sib=(zoom0<<6)+(idx0<<3)+5; + } + else{ + ctok->rm=base0; + if(pv==FALSE)ctok->rm|=rm_mod10; + } + } + else{ + if(base0==SI||base0==DI){ + if(idx0==BX||idx0==BP||idx0==-1){ + newreg=idx0; + idx0=base0; + base0=newreg; + } + else{ + op(3); + op(0xC0+base0*8+idx0); //add base0,idx0 + idx0=base0; + base0=-1; + } + } + if(idx0==BX||idx0==BP){ + if(base0==-1){ + newreg=idx0; + idx0=base0; + base0=newreg; + } + else{ + op(3); + op(0xC0+base0*8+idx0); //add base0,idx0 + idx0=base0; + base0=-1; + } + } + ctok->rm=CalcRm16(base0,idx0)|rm_mod10; + } + if(ctok->post==0&&(ctok->flag&f_reloc)==0)compressoffset(ctok); +} + +int CheckMassiv(char *&buf,int sizeel,int treg,int *idx,int *base,long *num) +{ +ITOK oitok; +SINFO ostr; +unsigned char *oldinput; +unsigned int oldinptr,oldendinptr; +unsigned char bcha; +int otok; +char *ostring; +char *ofsst; +int retcode=-1; + +//07.09.04 22:45 +COM_MOD *ocurmod=cur_mod; + cur_mod=NULL; +///////////////// + ostring=BackString((char *)string); + ofsst=BackString(buf); + free(buf); + buf=NULL; + oldinput=input; // ६ + oldinptr=inptr2; + bcha=cha2; + oldendinptr=endinptr; + otok=tok; + oitok=itok; + ostr=strinf; + strinf.bufstr=NULL; + + if(idx&&*idx==-1&&*base==-1){ + char *tbuf; + int i; + int idx0,base0; + long numr; + int operand; + int startptr,skipvar; + int firsttok; + i=0; + idx0=base0=-1; + numr=0; + if(*ofsst=='&')i++; + tbuf=BackString(ofsst+i); +// puts(tbuf); + input=(unsigned char *)tbuf; + inptr2=1; + cha2=input[0]; + endinptr=strlen((char *)input); + operand=tk_plus; + startptr=0; + firsttok=tk_eof; + do{ + skipvar=FALSE; + getoperand(); + if(operand==tk_plus){ + if(tok==tk_reg32){ + if(itok.number!=treg){ + skipvar=TRUE; + if(idx0==-1)idx0=itok.number; + else if(base0==-1)base0=itok.number; + else skipvar=FALSE; + } + else if(firsttok==tk_eof)firsttok=tk_reg32; + } + else if(tok==tk_number){ + numr+=itok.number; + skipvar=TRUE; + } + else if(firsttok==tk_eof)firsttok=tok; + } + if(operand==tk_minus&&tok==tk_number){ + numr-=itok.number; + skipvar=TRUE; + } + if(skipvar){ + for(;startptr%s\n",(startfileinfo+currentfileinfo)->filename,linenumber,tbuf); + if(tok==tk_semicolon/*&&(idx0!=-1||base0!=-1)*/){ + *idx=idx0; + *base=base0; + *num+=numr; + free(ofsst); + ofsst=tbuf; +// printf("idx0=%d base0=%d num=%d\n",idx0,base0,numr); + } + else free(tbuf); + } + + input=(unsigned char *)ofsst; + inptr2=1; + cha2=input[0]; + if(cha2=='&'){ + inptr2=2; + cha2=input[1]; + } + endinptr=strlen((char *)input); + getoperand(); + if(am32&&sizeel==1&&tok==tk_reg32&&itok2.type==tp_stopper)retcode=itok.number; + else{ + warningreg(regs[am32][treg]); + if((chip==7||chip==8)&&am32==FALSE&&((sizeel>1&&sizeel<6)||sizeel==8||sizeel==9)){ + // 饭 ⭮ ॣ + op(0x31); + op(0xC0+treg*9); + } + ofsst=NULL; + if(treg==AX)do_e_axmath(0,(am32+1)*2,&ofsst); + else getintoreg(treg,(am32+1)*2,0,&ofsst); + IDXToReg((char *)input,sizeel,treg); + } + strinf=ostr; + tok=otok; + itok=oitok; + endoffile=0; + free(input); + input=oldinput; + inptr2=oldinptr; + cur_mod=ocurmod; //07.09.04 22:45 + cha2=bcha; + endinptr=oldendinptr; + otok=0; + strcpy((char *)string,ostring); + free(ostring); + if(sizeel>1)RegMulNum(treg,sizeel,(am32+1)*2,0,&otok,0); + return retcode; +} + +void nextchar() +{ + if(inptrinput[cur_mod->inptr]; +// printf("cha=%02X\n",cha); + } + } + else{ + if(cur_mod){ + if(displaytokerrors){ + inptr=cur_mod->inptr; + input=cur_mod->input; +// printf("last cha=%02X\n",input[inptr]); + + if(cur_mod->numparamdef)clearregstat(); + + endinptr=cur_mod->endinptr; + linenumber=cur_mod->linenumber; + currentfileinfo=cur_mod->currentfileinfo; + COM_MOD *temp=cur_mod; + cur_mod=cur_mod->next; + if(temp->freze==FALSE){ + if(temp->paramdef)free(temp->paramdef); +// if(debug)printf("Free curmod %08X new cur_mod %08X\n",temp,cur_mod); + free(temp); + } +// else if(debug)printf("Freze curmod %08X\n",temp); + nextchar(); +// printf("%c\n",cha); + if(!cur_mod)notdef=TRUE; + } + else{ + cha=cur_mod->input[cur_mod->inptr2]; + cur_mod->inptr2++; + } + } + else{ + cha=26; + endoffile++; + if(endoffile>2)unexpectedeof(); + } + } +} + +void ScanTok2() +{ + inptr2=inptr; + linenum2=linenumber; + cha2=cha; + displaytokerrors=0; + tokscan(&tok2,&itok2,string2); +} + +unsigned int ScanTok3() +{ +unsigned int oinptr,oline,otok,rtok; +unsigned char ocha; +ITOK oitok; + ocha=cha; + oinptr=inptr; + oline=linenumber; + otok=tok; + oitok=itok; + do{ + FastTok(1); + if(tok==tk_id||tok==tk_ID){ + char disp=displaytokerrors; + displaytokerrors=0; + strcpy((char *)string3,itok.name); + searchtree(&itok,&tok,string3); //NEW 09.06.06 20:29 +// searchtree2(definestart,&itok,&tok,string3); + displaytokerrors=disp; + } + }while(tok==tk_endline); + rtok=tok; + tok=otok; + cha=ocha; + itok=oitok; + inptr=oinptr; + linenumber=oline; + return rtok; +} + +//extern idrec *crec; + +void nexttok() +{ +#ifdef DEBUGMODE +if(debug)puts("start nexttok"); +#endif + inptr=inptr2; + linenumber=linenum2; + cha=cha2; + displaytokerrors=1; + tokscan(&tok,&itok,string); //ࠧ +// printf("input=%08X inptr=%08X tok=%d %s\n",input,inptr,tok,itok.name); + if(tok==tk_dblcolon&&numblocks){ + skiplocals=TRUE; + tokscan(&tok,&itok,string); //ࠧ + } + ScanTok2(); + if(tok2==tk_dblcolon&&numblocks){ + skiplocals=TRUE; + tokscan(&tok2,&itok2,string2); + } + if(tok2==tk_tilda){ + if(ScanTok3()==tk_number){ + tok2=tk_number; +// puts("tok2=tk_tilda tok3=tk_number"); + } + } + linenumber=linenum2; + // new !!! 02.04.02 20:22 + if(tok==tk_int&&idasm==TRUE&&tok2==tk_number){ + tok=tk_idasm; + itok.rm=a_int; + } + // new !!! 02.04.02 20:22 + +#ifdef DEBUGMODE + if(debug)printdebuginfo(); +#endif + if(tok2==tk_number){ + if(tok==tk_not){ + nexttok(); + if(itok.rm!=tk_float&&itok.rm!=tk_double){ + if(scanlexmode==RESLEX){ + if(itok.number)itok.number=0; + else itok.number=1; + } + else itok.lnumber^=-1; + } + else illegalfloat(); + return; + } + if(tok==tk_tilda){ +// puts("tok=tk_tilda tok2=tk_number"); + nexttok(); + if(itok.rm!=tk_float&&itok.rm!=tk_double)itok.lnumber=~itok.lnumber; + else illegalfloat(); + return; + } + } + if(idasm==TRUE&&tok==tk_loop&&tok2!=tk_openbracket){ + tok=tk_idasm; + itok.rm=a_loop; + return; + } + if(tok==tk_dollar){ + if(itok2.type==tp_opperand||itok2.type==tp_stopper||tok2==tk_dollar){ + tok=tk_number; + itok.number=outptr; + if(FixUp)itok.flag|=f_reloc; //new!!! + return; + } + + int qq; //09.07.08 13:27 new + if((qq=CheckAsmName(itok2.name))!=-1){ + tok=tk_idasm; + itok.rm=qq; + strcpy(itok.name,itok2.name); + ScanTok2(); + } + + } + if(tok>=tk_charvar&&tok<=tk_doublevar){ +localrec *ptr; + ptr=itok.locrec; + switch(itok.type){ + case tp_paramvar: +// case tp_ppointer: +// case tp_pfpointer: + if(ptr->fuse==NOTINITVAR&&tok2==tk_assign&&(!asmparam))warningnotused(itok.name,4); + goto llq; + case tp_localvar: +// case tp_lpointer: +// case tp_lfpointer: + if(ptr->fuse==NOTINITVAR&&tok2!=tk_assign){ + if(asmparam)ptr->fuse|=INITVAR; + else warningusenotintvar(itok.name); + } +llq: + ptr->fuse|=(unsigned char)(tok2==tk_assign?INITVAR:USEDVAR); + break; + } +#ifdef OPTVARCONST + if(calcnumber&&CheckConstVar(&itok))tok=tk_number; +#endif + } +#ifdef OPTVARCONST + if(tok2>=tk_charvar&&tok2<=tk_doublevar){ + if(calcnumber&&CheckConstVar(&itok2))tok2=tk_number; + } +#endif + if(usedirectiv==FALSE&&calcnumber==FALSE)while(tok==tk_question)directive(); +//16.08.04 00:23 + if(tok==tk_at&&tok2==tk_macro){ + nexttok(); + } +#ifdef OPTVARCONST + displaytokerrors=1; +#endif + +// if(crec)printf("num=%08X\n",crec->recnumber); + +} + +void whitespace() //ய ᨬ +{ + while(isspace(cha)||cha==255||cha==0){ + if(cha==13){ + linenumber++; + if((dbg&2)&&displaytokerrors&¬def)startline=(char*)(input+inptr+1); + if(scanlexmode==RESLEX||scanlexmode==DEFLEX||scanlexmode==ASMLEX)break; + } + nextchar(); + } +} + +unsigned char convert_char() +//Returns the value of the current character. Parses \n and \x00 etc. +//cha equals the last character used. +{ +int hold=0; +int i; +unsigned char c; + if(cha!='\\'){ + if(cha==13){ + linenumber++; + if((dbg&2)&&displaytokerrors&¬def)startline=(char*)(input+inptr+1); + } + return(cha); + } + nextchar(); // move past '\\' + switch(cha){ + case 'a': return('\a'); // what is \a anyway? + case 'b': return('\b'); + case 'f': return('\f'); + case 'l': return(10); + case 'n': return(13); +// case 'p': return(''); + case 'r': return(13); + case 't': return('\t'); + case 'v': return('\v'); + case 'x': + for(i=0;i<2;i++){ + c=cha; + nextchar(); + hold*=16; + if(isdigit(cha))hold+=cha-'0'; + else if(isxdigit(cha))hold+=(cha&0x5f)-'7'; + else{ +// expectederror("hexadecimal digit"); + if(savestring3)posstr3--; + inptr--; + cha=c; + break; + } + } + return (unsigned char)hold; + default: + if(isdigit(cha)){ + hold=cha-'0'; + for(i=0;i<2;i++){ + c=cha; + nextchar(); + if(isdigit(cha))hold=hold*10+(cha-'0'); + else{ +// expectederror("decimal digit"); + if(savestring3)posstr3--; + inptr--; + cha=c; + break; + } + } + return (unsigned char)hold; + } + return cha; + } +} + +void convert_string(unsigned char *str) +{ +int k,j,i; +unsigned char c; +unsigned char hold; + for(k=0,j=0;;k++,j++){ + c=str[k]; + if(c=='\\'){ + c=str[++k]; + switch(c){ + case 'a': hold='\a'; break; // what is \a anyway? + case 'b': hold='\b'; break; + case 'f': hold='\f'; break; + case 'l': hold=10; break; + case 'n': str[j++]=13; hold=10; break; + case 'r': hold=13; break; + case 't': hold='\t'; break; + case 'v': hold='\v'; break; + case 'x': + hold=0; + for(i=0;i<2;i++){ + c=str[++k]; + hold*=(unsigned char)16; + if(isdigit(c))hold+=(unsigned char)(c-'0'); + else if(isxdigit(c))hold+=(unsigned char)((c&0x5f)-'7'); + else{ + k--; + break; + } + } + break; + default: + hold=c; + if(isdigit(c)){ + hold-='0'; + for(i=0;i<2;i++){ + c=str[++k]; + if(isdigit(c))hold=(unsigned char)(hold*10+(c-'0')); + else{ + k--; + break; + } + } + } + } + str[j]=hold; + } + else str[j]=c; + if(c==0)break; + } +} + +int CheckChar2() +{ + if(isalnum(cha)||cha=='_'||cha>=0x80)return TRUE; + return FALSE; +} + +void GetTokString(int *tok4,ITOK *itok4,unsigned char *string4,int useunicode) +{ +int strptr=0; + if(displaytokerrors){ + savestring3=TRUE; + posstr3=0; + } +nextstr: + nextchar(); //ப ⠭ + while(cha!='\"'&&!endoffile&&strptr=(STRLEN-1)&&displaytokerrors)preerror("Maximum String Length Exceeded"); + string4[strptr]=0; + *tok4=tk_string; +// itok4->number=strptr; + itok4->rm=1; // ਣ ப + if(cha!='\"')expected('\"'); + while(cha!='\"'&&!endoffile)nextchar(); //scan until closing '\"' + nextchar(); + if(dosstring)itok4->flag=dos_term; + CheckConvertString((char *)string4); + switch(cha){ + case 'z': + itok4->flag=zero_term; + nextchar(); + break; + case 'n': + itok4->flag=no_term; + nextchar(); + break; + case '$': + itok4->flag=dos_term; + nextchar(); + break; + } + CheckConvertString((char *)string4); + +// 10.08.04 22:20 + whitespace(); //ய ᨬ + if(cha=='\"'){ + if(displaytokerrors)savestring3=TRUE; + goto nextstr; + } + + if(useunicode&&displaytokerrors){ + char *bak; + bak=BackString((char *)string4); + strptr=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,bak,-1,(wchar_t *)string4,STRLEN)-1; +// printf("size string=%d\n",strptr); +// if(itok4->flag==no_term)strptr--; + strptr*=2; +// string4[strptr-2]=string4[strptr-1]=0; + itok4->flag|=s_unicod; + free(bak); + } + itok4->number=strptr; +} + +void tokscan(int *tok4,ITOK *itok4,unsigned char *string4) +// 䨪஢, ४⨢ ... +{ +int useme; +unsigned int strptr=0; +char uppercase=1,next=1; +//⠭ 㬮砭 +#ifdef DEBUGMODE +if(debug)printf("start tokscan input=%08X inptr=%08X %c%s\n",input,inptr,cha,input+inptr); +#endif + if(am32==FALSE){ + itok4->rm=rm_d16; + itok4->sib=CODE16; + } + else{ + itok4->rm=rm_d32; + itok4->sib=CODE32; + } + itok4->segm=DS; + itok4->lnumber=0; + itok4->post=0; + itok4->flag=0; + itok4->size=0; + itok4->rec=NULL; + itok4->type=tp_ucnovn; + itok4->npointr=0; + itok4->name[0]=0; + whitespace(); //ய ᨬ +// if(displaytokerrors)printf("%c ",cha); + if(isalpha(cha)||(cha=='_')||(cha>=0x80)){ //䨪 + do{ + string4[strptr++]=cha; + if(islower(cha))uppercase=0; + nextchar(); + }while((strptr=IDLENGTH){ // 32 + if(displaytokerrors)preerror("Maximum length for an identifier exceeded"); + while(CheckChar2()==TRUE)nextchar(); // ᫮ + strptr=IDLENGTH-1; //१ 32 + } + if(cha=='~'&&strptrname,(char *)string4); +// if(displaytokerrors)printf("%s (%u) >%s\n",(startfileinfo+currentfileinfo)->filename,linenumber,itok4->name); +#ifdef DEBUGMODE + if (debug)printf("ID: '%s' cur_mod=%08X prev cur_mod=%08X\n",itok4->name,cur_mod,cur_mod==NULL?0:cur_mod->next); +#endif + if(scanlexmode==RESLEX){ + if(stricmp((char *)string4,"not")==0)*tok4=tk_not; + else if(stricmp((char *)string4,"or")==0)*tok4=tk_or; + else if(stricmp((char *)string4,"xor")==0)*tok4=tk_xor; + else if(stricmp((char *)string4,"and")==0)*tok4=tk_and; + else{ + if(uppercase)*tok4=tk_ID; + else *tok4=tk_id; + searchtree(itok4,tok4,string4); + if(*tok4==tk_id||*tok4==tk_ID){ + if((useme=CheckResName(itok4->name))!=-1){ + *tok4=tk_rescommand; + itok4->number=useme; + } + } + } + return; + } + if(uppercase){ //孨 ॣ + if(strptr==1&&string4[0]=='L'&&cha=='"'){ + itok4->name[0]=0; + GetTokString(tok4,itok4,string4,TRUE); + return; + } + *tok4=tk_ID; + if(string4[1]=='S'&&strptr>=5&&strptr<=8){ + for(useme=0;usemesegm=useme/DATATYPES; + itok4->number=0; + itok4->post=POINTER; + goto yesid; + } + } + } + } + else *tok4=tk_id; + if(strptr==2){ // 2 ᨬ check for AX, CX, DX, ... + if((string4[0]&0x5f)=='S'&&(string4[1]&0x5f)=='T'){ + if(cha=='('){ + nextchar(); + if(cha>='0'&&cha<='7'){ + itok4->number=cha-'0'; + nextchar(); + if(cha!=')')expected(')'); + nextchar(); + *tok4=tk_fpust; + } + } + else{ + itok4->number=0; + *tok4=tk_fpust; + } + return; + } + if(asmparam||*tok4==tk_ID){ + for(useme=0;useme<8;useme++){ + int i; + if(asmparam)i=stricmp((char *)string4,regs[0][useme]); + else i=strcmp((char *)string4,regs[0][useme]); + if(i==0){ + *tok4=tk_reg; + itok4->number=useme; +extreg: + if(cha=='.'){ + tag_massiv(tok4,itok4,string4); + goto yesid; + } + return; + } + if(asmparam)i=stricmp((char *)string4,begs[useme]); + else i=strcmp((char *)string4,begs[useme]); + if(i==0){ + *tok4=tk_beg; + itok4->number=useme; + return; + } + } + if(string4[1]=='S'||(asmparam&&string4[1]=='s')){ + for(useme=0;useme<6;useme++){ // check for CS, SS, ... + if(string4[0]==segs[useme][0]||(asmparam&&(string4[0]&0x5F)==segs[useme][0])){ + if(cha==':'){ + int oinptr=inptr; + unsigned char ocha=cha; + int oline=linenumber; + nextchar(); +/* switch(cha&(asmparam==FALSE?0xFF:0x5F)){ + case 'E': + case 'B': + case 'S': + case 'D':*/ + tokscan(tok4,itok4,string4); + if(*tok4>=tk_bits&&*tok4<=tk_doublevar){ + itok4->segm=useme; + goto yesid; + } +// } + inptr=oinptr; + cha=ocha; + linenumber=oline; + } + *tok4=tk_seg; + itok4->number=useme; + return; + } + } + } + } + } + if(strptr==3&&(string4[0]=='E'||(asmparam&&string4[0]=='e'))){// check for EAX, ECX, EDX, ... + for(useme=0;useme<8;useme++){ + int i; + if(asmparam)i=stricmp((char *)&string4[1],regs[0][useme]); + else i=strcmp((char *)&string4[1],regs[0][useme]); + if(i==0){ + *tok4=tk_reg32; + itok4->number=useme; +extreg32: + if(cha=='.'){ + tag_massiv(tok4,itok4,string4); + goto yesid; + } + if(cha==':'){ + int oinptr=inptr; + unsigned char ocha=cha; + int oline=linenumber; + nextchar(); + tokscan(tok4,itok4,string4); + if(*tok4==tk_reg32||*tok4==tk_reg){ + itok4->number|=useme*256; + *tok4=tk_reg64; + goto yesid; + } + inptr=oinptr; + cha=ocha; + linenumber=oline; + } + return; + } + } + } + if(asmparam){ + if((string4[1]&0x5f)=='R'){ + if(string4[2]>='0'&&string4[2]<='7'){ + itok4->number=string4[2]-'0'; + switch((string4[0]&0x5f)){ + case 'C': *tok4=tk_controlreg; return;// check for CR0, CR1, ... + case 'D': *tok4=tk_debugreg; return;//check for DR0, DR1, ... + case 'T': *tok4=tk_testreg; return;//check for TR0, TR1, ... + default: itok4->number=0; break; + } + } + } + else if((*(short *)&string[0]&0x5f5f)==0x4d4d){ + if(string4[2]>='0'&&string4[2]<='7'){ + itok4->number=string4[2]-'0'; + *tok4=tk_mmxreg; + return; + } + } + else if((*(short *)&string[1]&0x5f5f)==0x4d4d&&(string4[0]&0x5f)=='X'){ + if(string4[3]>='0'&&string4[3]<='7'){ + itok4->number=string4[3]-'0'; + *tok4=tk_xmmreg; + return; + } + } + } + if(useasm==FALSE){ + if((useme=FastSearch(id,idofs,2,(char *)string4))!=-1)*tok4=useme; + else if(idasm==TRUE&&(useme=CheckAsmName((char *)string4))!=-1){ + *tok4=tk_idasm; + itok4->rm=useme; + return; + } + } + if(*tok4==tk_id||*tok4==tk_ID){ + if(cur_mod&&cur_mod->numparamdef&&(displaytokerrors||scanalltoks)){//18.03.05 15:12 +/* if(debug&&cur_mod){ + printf("Find %s in %d entries curmod=%08X\n",itok4->name,cur_mod->numparamdef,cur_mod); + COM_MOD *nmod; + nmod=cur_mod; + while(nmod){ + printf("\tinput=%08X inptr=%08X\n",nmod->input,nmod->inptr); + nmod=nmod->next; + } + }*/ + if(CheckDefPar(itok4->name)){ + tokscan(tok4,itok4,string4); + if(displaytokerrors==0){ + inptr=cur_mod->inptr; + input=cur_mod->input; + endinptr=cur_mod->endinptr; + linenumber=cur_mod->linenumber; + currentfileinfo=cur_mod->currentfileinfo; + COM_MOD *temp=cur_mod; + cur_mod=cur_mod->next; + free(temp); + nextchar(); + } +#ifdef DEBUGMODE + if(debug)printf("1601 tok=%d input=%08X inptr=%08X disp=%d %s %c%40s\n\t%s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr,""/*input*/); +#endif + return; + } + } + if(searchlocals(itok4,tok4,string4)==FALSE){// । ⮪ + //᫨ 祣 ॢ ६ + searchtree(itok4,tok4,string4); + if(*tok4==tk_endline){ + if(scanlexmode!=DEFLEX){ + tokscan(tok4,itok4,string4); +#ifdef DEBUGMODE + if(debug)printf("1610 tok=%d input=%08X inptr=%08X disp=%d %s %c%40s\n\t%s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr,""/*input*/); +#endif + return; + } + *tok4=tk_macro; + } + if(*tok4==tk_number||*tok4==tk_idasm)return; + if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||*tok4==tk_pointer){ + if(itok4->rm==rm_d16||itok4->rm==rm_d32){ + if(am32==FALSE){ + itok4->rm=rm_d16; + itok4->sib=CODE16; + } + else{ + itok4->rm=rm_d32; + itok4->sib=CODE32; + } + } + if(itok4->post==DYNAMIC_POST){ //८ࠧ + if(alignword&&*tok4!=tk_charvar&&*tok4!=tk_bytevar){ //஢ + switch(*tok4){ + case tk_intvar: + case tk_wordvar: + if(postsize%2==1)postsize++; + break; + default: + if(postsize%4!=0)postsize+=4-(postsize%4); + break; + } + } + idrec *ptr=itok4->rec; + itok4->post=ptr->recpost=1; + itok4->number=ptr->recnumber=postsize; + if(am32==FALSE&&(postsize+itok4->size)>0xFFFFL)tobigpost(); + postsize+=itok4->size; + } + else if(itok4->post==DYNAMIC_VAR){ + idrec *ptr=itok4->rec; + itok4->post=ptr->recpost=USED_DIN_VAR; + } + } + } + if(tok==tk_reg)goto extreg; + if(tok==tk_reg32)goto extreg32; + } + switch(*tok4){ + int len; + case tk_dataptr: *tok4=tk_number; itok4->number=outptrdata; + if(FixUp)itok.flag|=f_reloc; //new!!! + break; + case tk_codeptr: *tok4=tk_number; itok4->number=outptr; + if(FixUp)itok.flag|=f_reloc; //new!!! + break; + case tk_postptr: *tok4=tk_number; itok4->number=postsize; break; + case tk_line: *tok4=tk_number; itok4->number=linenumber; break; + case tk_file: + *tok4=tk_string; + strcpy((char *)string4,(startfileinfo+currentfileinfo)->filename); + itok4->number=strlen((char *)string4); + break; + case tk_structvar: + struct idrec *ptrs; + ptrs=itok4->rec; +// puts(itok4->name); + dostructvar2(tok4,itok4,(structteg *)ptrs->newid,string4); + break; + case tk_sizeof: + dosizeof(itok4); + if(itok4->post)*tok4=tk_postnumber; + else *tok4=tk_number; + break; + case tk_signed: + case tk_unsigned: + case tk_int: + case tk_long: + case tk_short: + if(itok4->type!=tp_modif){ + GetTypeVar(tok4); + itok4->type=tp_modif; + } + break; + case tk_ID: +// printf("%s %s %d %c\n",itok.name,string4,strptr,cha); + if(strlen(itok4->name)==1&&itok4->name[0]=='L'&&cha=='"'){ + itok4->name[0]=0; + GetTokString(tok4,itok4,string4,TRUE); + return; + } + case tk_id: + if(findofset==FALSE){ + struct structteg *tteg; +// if(displaytokerrors)printf("find teg %s cha=%02X\n",itok4->name,cha); + if(((tteg=FindTeg(FALSE,itok4->name))!=NULL|| + (tteg=FindTeg(TRUE,itok4->name))!=NULL)&&(cha=='.'||precha=='.')){ +// if(displaytokerrors)puts("finding"); + dostructvar2(tok4,itok4,tteg,string4); +// printf("tok=%d\n",*tok4); + if(displaytokerrors&&(*tok4==tk_proc||*tok4==tk_declare|| + *tok4==tk_undefproc)&&(itok4->flag&f_static)==0)unknownobj(itok4->name); + } + } + break; + + } + if(*tok4==tk_string&&displaytokerrors){ + strcpy((char *)string3,(char *)string4); + if(itok4->rm==2){ + convert_string(string4); + itok4->rm--; + } + if(dosstring)itok.flag=dos_term; + } +yesid: + if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||*tok4==tk_pointer){ + whitespace();//ய ᨬ + if(cha=='[')calcrm(itok4,*tok4);//ࠡ⪠ ࠦ [] + } + if(itok4->rm!=rm_d16&&*tok4!=tk_proc&&*tok4!=tk_undefproc&& + *tok4!=tk_apiproc&&*tok4!=tk_declare&&(!(*tok4==tk_pointer&&itok4->type==tk_proc))) + if(itok4->post==0&&(itok4->flag&f_reloc)==0){ // cannot compress if POST var + compressoffset(itok4); + } + next=0; + } + else if(isdigit(cha)){//᫠ + inptr--; + itok4->lnumber=scannumber(&itok4->rm); + *tok4=tk_number; + next=0; + } + else switch(cha){ + case '\"': + GetTokString(tok4,itok4,string4,FALSE); + next=0; + break; + case '\'': //ᨬ쭠 ⠭ 1 ᨬ + nextchar(); + next=0; + if(scanlexmode==RESLEX){ + *tok4=tk_singlquote; + break; + } + *tok4=tk_number; + itok4->number=0; + while(cha!='\''&&!endoffile){ // special character + itok4->lnumber=itok4->lnumber*256+convert_char(); + nextchar(); + } + if(cha!='\''){ + if(displaytokerrors)expected('\''); + } + else nextchar(); + next=0; + break; + case '-': + nextchar(); + switch(cha){ + case '=': *tok4=tk_minusequals; break; // ࠢ + case '-': *tok4=tk_minusminus; break; //- + default: *tok4=tk_minus; next = 0; itok4->type=tp_opperand; break;// + } + break; + case '+': + nextchar(); + switch(cha){ + case '=': *tok4=tk_plusequals; break; // ࠢ + case '+': *tok4=tk_plusplus; break; //- + default: whitespace(); // spaces allowed between + if(cha=='-')*tok4=tk_minus; // optimization of + - + else{ + *tok4=tk_plus; // + next=0; + } + itok4->type=tp_opperand; + break; + } + break; + case '*': + nextchar(); + switch(cha){ + case '=': *tok4=tk_multequals; break; + case '-': *tok4=tk_multminus; break; //㬭 + default: + *tok4=tk_mult; //㬭 + next=0; + } + itok4->type=tp_opperand; + break; + case '/': nextchar(); + switch(cha){ + case '*': nextchar(); //ᮬ਩ + useme=1; + while(!endoffile&&useme>0){ + whitespace(); + if(cha=='*'){ + nextchar(); + if(cha=='/'){ + nextchar(); + if(cha=='/')nextchar(); + else useme--; + } + continue; + } + else if(cha=='/'){ + nextchar(); + if(cha=='*')useme++; + else if(cha=='/'){ + nextchar(); + continue; + } + else continue; + } + nextchar(); + } + if(endoffile){ + *tok4=tk_eof; + if(useme>0&&displaytokerrors)unexpectedeof(); + } + else tokscan(tok4,itok4,string4); + break; + case '/': + do{ + nextchar(); + }while(!endoffile&&cha!=13); //ப + if(endoffile)*tok4=tk_eof; + else{ + if(scanlexmode==DEFLEX)*tok4=tk_endline; + else{ + whitespace(); + if(cha==13)nextchar(); + tokscan(tok4,itok4,string4); + } + } + break; + case '=': *tok4=tk_divequals; nextchar(); return; + default: + whitespace(); + if(cha=='-'){ + *tok4=tk_divminus; // + nextchar(); + } + else *tok4=tk_div; + itok4->type=tp_opperand; + break; + } + next=0; + break; + case '%': + nextchar(); + whitespace(); + if(cha=='-')*tok4=tk_modminus; //⮪ + else{ + *tok4=tk_mod; + next=0; + } + itok4->type=tp_opperand; + break; + case '|': + nextchar(); + switch(cha){ + case '=': *tok4=tk_orequals; break; //OR= + case '|': *tok4=tk_oror; break; //OR-OR + default: + whitespace(); + if(cha=='-')*tok4=tk_orminus; //OR- + else{ + *tok4=tk_or; + if(cha==13)nextchar(); //OR + next=0; + } + itok4->type=tp_opperand; + break; + } + break; + case '&': + nextchar(); + switch(cha){ + case '=': *tok4=tk_andequals; break; //AND= + case '&': *tok4=tk_andand; break; + default: + whitespace(); + if(cha=='-')*tok4=tk_andminus; + else{ + *tok4=tk_and; + next=0; + } + itok4->type=tp_opperand; + break; + } + break; + case '!': + nextchar(); + if(cha=='='){ + *tok4=tk_notequal; //!= + itok4->type=tp_compare; + } + else{ + *tok4=tk_not; + next=0; + } + break; + case '^': + nextchar(); + if(cha=='=')*tok4=tk_xorequals; //XOR= + else{ + whitespace(); + if(cha=='-')*tok4=tk_xorminus; + else{ + *tok4=tk_xor; + next=0; + } + itok4->type=tp_opperand; + } + break; + case '=': + nextchar(); + if(cha=='='){ + *tok4=tk_equalto; //== + itok4->type=tp_compare; + } + else{ + *tok4=tk_assign; //᢮ + next=0; + } + break; + case '>': + nextchar(); + switch(cha){ + case '>': + nextchar(); + if(cha=='=')*tok4=tk_rrequals; //ᤢ ࠢ ᢮ + else{ + whitespace(); + if(cha=='-')*tok4 = tk_rrminus; + else{ + *tok4=tk_rr; //ᤢ ࠢ + next=0; + } + itok4->type=tp_opperand; + } + break; + case '<': *tok4=tk_swap; break; // + case '=': *tok4=tk_greaterequal; itok4->type=tp_compare; break; // ࠢ + default: *tok4=tk_greater; next=0; itok4->type=tp_compare; break; // + } + break; + case '<': + nextchar(); + switch(cha){ + case '<': + nextchar(); + if(cha=='=')*tok4=tk_llequals; //ᤢ ᢮ + else{ + whitespace(); + if(cha=='-')*tok4=tk_llminus; + else{ + *tok4=tk_ll; //ᤢ + next=0; + } + itok4->type=tp_opperand; + } + break; + case '>': *tok4=tk_notequal; itok4->type=tp_compare; break; //!= + case '=': *tok4=tk_lessequal; itok4->type=tp_compare; break; // ࠢ + default: *tok4=tk_less; next=0; itok4->type=tp_compare; break;// + } + break; + case '#': + next=0; + nextchar(); + findofset=TRUE; + tokscan(tok4,itok4,string4); + findofset=FALSE; + if((useme=GetDirective((char *)string4))!=-1){ + itok4->number=useme; + *tok4=tk_question; + break; + } + if(*tok4==tk_dblcolon){ + skiplocals=TRUE; + tokscan(tok4,itok4,string4); + } +/* char buf[16]; + strncpy(buf,(char *)(input+inptr),15); + buf[15]=0;*/ +// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d flag=%08X %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->flag,itok4->name/*,buf*/); +// printf("skiplocals=%d skipfind=%d searchteg=%08X\n",skiplocals,skipfind,searchteg); + switch(*tok4){ + case tk_structvar: +// printf("%08X %s\n",itok4->sib,itok4->name); + if((itok4->sib&1)==0){ + ofsstr(tok4,itok4); +// if(displaytokerrors)printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d flag=%08X %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->flag,itok4->name/*,buf*/); + break; + } + itok4->rm=(am32==0?rm_d16:rm_d32); + case tk_struct: + *tok4=tk_number; + if(bufrm){ + *tok4=tk_rmnumber; + if(itok4->type==tp_classvar)itok4->flag|=f_useidx; + } + break; + case tk_apiproc: //!!!16.12.06 23:06 + itok4->rm=tk_undefofs; + *tok4=tk_apioffset; + if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25 + strcpy((char *)string4,itok4->name); +// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->name/*,buf*/); + break; + case tk_proc: + case tk_interruptproc: + if(cha=='.')goto structofs; +procofs: + if(itok4->segm!=NOT_DYNAMIC){ + if(displaytokerrors){ + idrec *ptr=itok4->rec; + itok4->segm=ptr->recsegm=DYNAMIC_USED; + } + itok4->rm=*tok4=tk_undefofs; //ᬥ饭 ⭮ ⪨ + itok4->number=0; +// if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25 + } + else{ + *tok4=tk_number; + itok4->segm=CS;//(splitdata==FALSE)?DS:CS; +// if(FixUp)itok4->flag|=f_reloc; + } + if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25 + strcpy((char *)string4,itok4->name); +// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->name/*,buf*/); + break; + case tk_id: + case tk_ID: +structofs: + struct structteg *tteg; + if(((tteg=FindTeg(FALSE,itok4->name))!=NULL|| + (tteg=FindTeg(TRUE,itok4->name))!=NULL)/*&&cha=='.'*/){ + dostructvar2(tok4,itok4,tteg,string4); +// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->name/*,buf*/); + + if(*tok4==tk_proc)goto procofs;//04.10.04 14:25 + + if(*tok4==tk_declare)goto undefofs; //24.09.04 00:33 +// printf("tok=%d segm=%d %s\n",*tok4,itok4->segm,itok4->name); + if(strinf.bufstr){ + *tok4=tk_rmnumber; + if(itok4->type==tp_classvar)itok4->flag|=f_useidx; + } + else{ + if(FixUp&&*tok4==tk_proc)itok4->flag|=f_reloc; //new!!! + else itok4->flag&=~f_reloc; +// else itok4->flag&=!f_reloc; 16.08.04 18:51 + +//30.09.04 20:22 + if(itok4->post){ + *tok4=tk_postnumber; + itok4->rm=tk_undefofs; + } + else +///// + + *tok4=tk_number; + } + } + else{ +undefofs: + itok4->rm=*tok4=tk_undefofs; //ᬥ饭 ⭮ ⪨ + itok4->number=0; + if(FixUp)itok4->flag|=f_reloc; //new!!! + } + case tk_number: + case tk_rmnumber: + break; + case tk_reg: + case tk_reg32: + itok4->rm=RegToRM(itok4->number,*tok4)/*|rm_mod10*/; + *tok4=(am32==0?tk_wordvar:tk_dwordvar);//tk_rmnumber; + itok4->number=0; + break; + default: + if(cha=='.')goto structofs; + if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||tok==tk_pointer){ +#ifdef OPTVARCONST + if(displaytokerrors)ClearVarByNum(itok4); +#endif + switch(itok4->type){ + case tp_localvar: + case tp_paramvar: +localrec *ptr; + ptr=itok4->locrec; + ptr->fuse|=(unsigned char)(INITVAR|USEDVAR); + break; + case tk_proc: + itok4->rm=itok4->sib; + itok4->sib=am32==0?CODE16:CODE32; + break; + } + itok4->size=GetVarSize(*tok4); + if((itok4->sib==CODE16&&itok4->rm==rm_d16)|| + (itok4->sib==CODE32&&itok4->rm==rm_d32)){ + if(itok4->post==0){ + *tok4=tk_number; + itok4->segm=DS; + if(FixUp)itok4->flag|=f_reloc; + itok4->rm=am32==FALSE?tk_word:tk_dword; + } + else{ + *tok4=tk_postnumber; + itok4->rm=tk_undefofs; + } + } + else{ + *tok4=tk_rmnumber; + if(itok4->type==tp_classvar)itok4->flag|=f_useidx; + } + } + else{ + itok4->rm=*tok4=tk_undefofs; //ᬥ饭 ⭮ ⪨ + itok4->number=0; + strcpy((char *)string4,itok4->name); + } + break; + } + itok4->type=tp_ofs; +// if(displaytokerrors)printf("name=%s tok=%d post=%d flag=%08X rm=%d\n",itok4->name,*tok4,itok4->post,itok4->flag,itok4->rm); + break; + case '(': + if(*(unsigned short *)&(input[inptr])== +#ifdef _WC_ + ')E' +#else + 'E)' +#endif + || + (*(unsigned short *)&(input[inptr])== +#ifdef _WC_ + ')e' +#else + 'e)' +#endif + )){ + for(useme=0;useme<8;useme++){ + int i; + if(asmparam)i=strnicmp((char *)input+inptr+2,regs[0][useme],2); + else i=strncmp((char *)input+inptr+2,regs[0][useme],2); + if(i==0){ + inptr+=4; + nextchar(); + itok4->number=useme; + if(am32){ + *tok4=tk_reg32; + goto extreg32; + } + *tok4=tk_reg; + goto extreg; + } + } + } + *tok4=tk_openbracket; + break; + case ':': + nextchar(); + if(cha!=':'){ + next=0; + *tok4=tk_colon; + } + else *tok4=tk_dblcolon; + break; + case ';': itok4->type=tp_stopper; *tok4=tk_semicolon; break; + case ')': itok4->type=tp_stopper; *tok4=tk_closebracket; break; + case '{': *tok4=tk_openbrace; break; + case '}': itok4->type=tp_stopper; *tok4=tk_closebrace; break; + case '[': *tok4=tk_openblock; break; + case ']': itok4->type=tp_stopper; *tok4=tk_closeblock; break; + case ',': itok4->type=tp_stopper; *tok4=tk_camma; break; + case '.': + next=0; + nextchar(); + if(cha!='.'){ + *tok4=tk_period; + break; + } + nextchar(); + if(cha!='.'){ + badtoken(); + nextchar(); + tokscan(tok4,itok4,string4); + break; + } + nextchar(); + *tok4=tk_multipoint; + break; + case '@': *tok4=tk_at; break; + case '$': *tok4=tk_dollar; break; + case '?': + nextchar(); + tokscan(tok4,itok4,string4); + *tok4=tk_question; + itok4->number=GetDirective((char *)string4); + return; + case '~': *tok4=tk_tilda; break; + case 26: *tok4=tk_eof; return; + case 13: *tok4=tk_endline; break; + case '\\': + nextchar(); + if(cha==13){ + tokscan(tok4,itok4,string4); + if(*tok4==tk_endline)tokscan(tok4,itok4,string4); + return; + } + default: + badtoken(); + nextchar(); + tokscan(tok4,itok4,string4); + return; + } + if(next)nextchar(); +#ifdef DEBUGMODE + if(debug)printf("2172 tok=%d input=%08X inptr=%08X disp=%d %s %X %s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr); +#endif +} + + +void NewMod(int numipar) +{ +COM_MOD *newm; +int oline; +int numpar=0,ns,i,size,nsize; +char *buf=NULL; + newm=(COM_MOD *)MALLOC(sizeof(COM_MOD)); + newm->numparamdef=numipar; + newm->freze=FALSE; + size=0; + whitespace(); + if(cha=='('){ + nextchar(); + whitespace(); + if(cha!=')'){ + inptr--; + oline=linenumber; + for(i=inptr,ns=1;ns>0;i++){ // ࠬ஢ + switch(input[i]){ + case '(': ns++; break; + case ')': ns--; break; + case ',': + if(ns==1){ + numpar++; + nsize=i-inptr; + if(!buf)buf=(char *)MALLOC(nsize+1); + else buf=(char *)REALLOC(buf,size+nsize+1); + strncpy(buf+size,(char *)(input+inptr),nsize); + buf[size+nsize]=0; + strbtrim(buf+size); +// puts(buf+size); + size+=strlen(buf+size)+1; + inptr+=nsize+1; + } + break; + case '/': + i=skipcomment(i); + break; + case '"': + case 0x27: + i=skipstring(i,input[i]); + break; + } + if((unsigned int)i>=endinptr){ + unexpectedeof(); + break; + } + } + linenumber=oline; + numpar++; + nsize=i-inptr; + if(!buf)buf=(char *)MALLOC(nsize); + else buf=(char *)REALLOC(buf,size+nsize); + strncpy(buf+size,(char *)(input+inptr),nsize-1); + buf[size+nsize-1]=0; + strbtrim(buf+size); +// puts(buf+size); + inptr=i; + } + if(numipar>numpar)missingpar(itok.name); + else if(numiparnumparamdef=numpar; + } + else inptr--; + newm->input=input; + newm->inptr2=newm->inptr=inptr; + newm->endinptr=endinptr; + newm->linenumber=linenumber; + newm->currentfileinfo=currentfileinfo; + newm->paramdef=buf; + newm->next=cur_mod; + cur_mod=newm; +// if(debug)printf("New curmod %08X numpar=%d input=%08X prev curmod=%08X\n",cur_mod,numipar,input,cur_mod->next); + nextchar(); +/* char *temp=buf; + for(i=0;iinptr; + inptr2=cur_mod->inptr2; + input=cur_mod->input; + endinptr=cur_mod->endinptr; + linenumber=cur_mod->linenumber; + currentfileinfo=cur_mod->currentfileinfo; + cur_mod=cur_mod->next; + cha2=input[inptr2]; + } +} + +char *FindDefPar(char *name,COM_MOD *cmod) +{ +char *temp; +int i,numpar,nsize=0; + numpar=cmod->numparamdef; + temp=cmod->declareparamdef; +// if(debug)printf("check for %s\n",name); + for(i=0;iparamdef; + for(;i>0;i--){ + temp+=strlen(temp)+1; + } + return temp; + } + temp+=nsize; + } + return NULL; +} + +int CheckDefPar(char *name) +{ +char *temp,*nname; +COM_MOD *fmod; + fmod=cur_mod; + nname=name; + while((temp=FindDefPar(nname,fmod))!=NULL){ + nname=temp; + if(fmod->next==NULL)break; + fmod=fmod->next; + } + if(fmod==cur_mod&&temp==NULL)return FALSE; + SetNewStr(nname); + return TRUE; +} + +void SetNewStr(char *name) +{ +COM_MOD *fmod; + fmod=(COM_MOD *)MALLOC(sizeof(COM_MOD)); + fmod->next=cur_mod; + fmod->numparamdef=0; + fmod->paramdef=NULL; + fmod->freze=FALSE; + fmod->input=input; + fmod->inptr2=fmod->inptr=inptr-1; + fmod->endinptr=endinptr; + fmod->linenumber=linenumber; + fmod->currentfileinfo=currentfileinfo; + cur_mod=fmod; +// if(debug)printf("new curmod %08X prev cur_mod=%08X old input %08X %s\n",cur_mod,cur_mod->next,input,name); + input=(unsigned char*)(name); + inptr=1; + cha=input[0]; + endinptr=strlen(name)+1; +} + +int searchtree2(idrec *fptr,ITOK *itok4,int *tok4,unsigned char *string4) +// ॢ ६ +{ +struct idrec *ptr; +int cmpresult; + for(ptr=fptr;ptr!=NULL;){ + if((cmpresult=strcmp(ptr->recid,(char *)string4))==0){ + if(scanlexmode==RESLEX&&ptr->rectok!=tk_number&&ptr->rectok!=tk_string)break; + itok4->lnumber=ptr->reclnumber; + itok4->rm=ptr->recrm; + *tok4=ptr->rectok; + itok4->post=ptr->recpost; + itok4->segm=ptr->recsegm; + itok4->flag|=ptr->flag; + itok4->size=ptr->recsize; + itok4->sib=ptr->recsib; + itok4->rec=ptr; + itok4->type=ptr->type; + itok4->npointr=ptr->npointr; +// if(debug)printf("Find: tok=%d\n",*tok4); + if(displaytokerrors){ + ptr->count++; +// printf("%s notdoneprestuff=%d tok=%d segm=%d\n",itok4->name,notdoneprestuff,*tok4,itok4->segm); + if(notdoneprestuff==2&&*tok4==tk_proc&&itok4->segm==DYNAMIC)AddDynamicList(ptr); + } + if(*tok4==tk_macro){ +// printf("tok=%d %s %s\n",*tok4,itok4->name,input); + if(dirmode==dm_if)return TRUE; + if(scanlexmode==DEFLEX||scanlexmode==DEFLEX2)*tok4=tk_id; + else if(displaytokerrors){ + NewMod(itok4->size); + notdef=FALSE; + cur_mod->declareparamdef=ptr->newid; + input=(unsigned char*)(ptr->sbuf); + inptr=1; + cha=input[0]; + endinptr=strlen((char *)input); +// if(debug)printf("New cur_mod tok=%d numpar=%d %s %s\n",*tok4,cur_mod->numparamdef,itok4->name,input); +// debug=TRUE; + clearregstat(); + *tok4=tk_endline; + return TRUE; + } + } + else if(ptr->newid){ + switch(*tok4){ + case tk_string: + memcpy((char *)string4,ptr->newid,itok4->number); + if(displaytokerrors&&itok4->rm==1&&ptr->sbuf)strcpy((char *)string3,ptr->sbuf); + break; + case tk_structvar: + itok4->segm=0; + if(ptr->recpost==DYNAMIC_POST){ + ptr->recpost=itok4->post=1; + if(alignword){ //஢ + if(postsize%2==1)postsize++; + } + itok4->number=ptr->recnumber=postsize; + if(am32==FALSE&&(ptr->recsize+postsize)>0xFFFFL)tobigpost(); + postsize+=ptr->recsize; + } + else if(ptr->recpost==DYNAMIC_VAR)itok4->post=ptr->recpost=USED_DIN_VAR; + return TRUE; + case tk_proc: + case tk_apiproc: + case tk_declare: + case tk_undefproc: + strcpy((char *)string4,ptr->newid); + break; + default: + if(scanlexmode==DEFLEX2){ + *tok4=tk_id; + return TRUE; + } + strcpy((char *)string4,ptr->newid); + if(strcmp((char *)string4,ptr->recid)!=0){ // see if ID has changed +// searchtree2(fptr,itok4,tok4,string4); // search again + searchtree(itok4,tok4,string4); // search again + switch(*tok4){ + case tk_proc: + case tk_apiproc: + case tk_declare: + case tk_undefproc: + strcpy(itok4->name,ptr->recid); // 㦭 undefine + break; + default: + strncpy(itok4->name,(char *)string4,IDLENGTH-1); // 㦭 undefine + break; + } + return TRUE; + } + break; + } + } + else string4[0]=0; + strcpy(itok4->name,ptr->recid); // 㦭 undefine + if(displaytokerrors)ptr->count++; + break; + } + else if(cmpresult<0)ptr=ptr->left; + else ptr=ptr->right; + } + if(ptr==NULL)return FALSE; + else return TRUE; +} + +int searchtree(ITOK *itok4,int *tok4,unsigned char *string4) +{ +int retval=FALSE; + if(skipfind==FALSE){ + if(staticlist)retval=searchtree2(staticlist,itok4,tok4,string4); + if(!retval)retval=searchtree2(treestart,itok4,tok4,string4); + if(!retval){ + if((retval=searchtree2(definestart,itok4,tok4,string4))==TRUE){ + if(scanlexmode==DEFLEX2)*tok4=tk_id; + } + } + } + return retval; +} + +void AddDynamicList(idrec *ptr) +{ +// printf("Add dinamic list %s %08X seg=%d tok=%d\n",ptr->recid,ptr,ptr->recsegm,ptr->rectok); + if(DynamicList==NULL){ + sizeDL=STEPDL; + DynamicList=(volatile idrec **)MALLOC(sizeof(idrec **)*sizeDL); + countDP=0; + } + else if(sizeDL==(countDP+1)){ + sizeDL+=STEPDL; + DynamicList=(volatile idrec **)REALLOC(DynamicList,sizeof(idrec **)*sizeDL); + } + for(int i=0;irecid); + tok=ptr->rectok; + if(sdp_mode==FALSE&&(ptr->flag&f_export)!=0&&tok==tk_proc){ + if(lexport==NULL){ + lexport=(struct listexport *)MALLOC(sizeof(struct listexport)); + lexport->address=ptr->recnumber; + strcpy(lexport->name,ptr->recid); + numexport=1; + } + else{ + int cmpname,i; + for(i=0;irecid,(lexport+i)->name))<=0)break; + } + if(cmpname!=0){ + lexport=(struct listexport *)REALLOC(lexport,sizeof(struct listexport)*(numexport+1)); + if(cmpname<0){ + for(int j=numexport;j>i;j--){ + memcpy(&(lexport+j)->address,&(lexport+j-1)->address,sizeof(struct listexport)); + } + } + numexport++; + (lexport+i)->address=ptr->recnumber; + strcpy((lexport+i)->name,ptr->recid); + } + } + } + if(!(ptr->flag&f_extern)){ + if(tok==tk_undefproc){ + strcpy(itok.name,ptr->recid); + if(sdp_mode){ + int boutptr=outptr; + int i; + if((ptr->flag&f_typeproc)==tp_fastcall){ + if((i=includeit(1))!=-1){ + if(updatecall((unsigned int)ptr->recnumber,boutptr,0)>0){ + ptr->rectok=tk_proc; + ptr->recnumber=boutptr; // record location placed + ptr->recrm=i; + ptr->count++; + } + } + } + else{ + if((i=includeproc())!=-1){ + if(updatecall((unsigned int)ptr->recnumber,boutptr,0)>0){ + ptr->rectok=tk_proc; + ptr->recnumber=boutptr; // record location placed + ptr->recrm=i; + ptr->count++; + } + } + } + } + else{ + if(updatecall((unsigned int)ptr->recnumber,outptr,0)>0){ + ptr->recnumber=outptr; // record location placed + linenumber=ptr->line; + currentfileinfo=ptr->file; + if((ptr->flag&f_typeproc)==tp_fastcall){ + if(includeit(1)==-1)thisundefined(itok.name); + } + else{ + if(includeproc()==-1)thisundefined(itok.name); + } + ptr->rectok=tk_proc; + ptr->count++; + } + } + } + else if(tok==tk_proc){ +// printf("%08X %s\n",ptr->recpost,ptr->recid); + itok.segm=ptr->recsegm; + if(itok.segm==DYNAMIC_USED){ +// printf("%08X %s\n",ptr->recpost,ptr->recid); +// if(updatecall((unsigned int)ptr->recnumber,outptr,0)>0){ + itok.number=ptr->recnumber; + itok.flag=ptr->flag; + itok.post=ptr->recpost; + strcpy(itok.name,ptr->recid); + if(ptr->newid==NULL)string[0]=0; + else strcpy((char *)string,(char *)ptr->newid); + itok.rm=ptr->recrm; + itok.size=ptr->recsize; + itok.rec=ptr; + insert_dynamic(); +// } + } + } +// else printf("tok=%d %s\n",tok,ptr->recid); + } + docals(ptr ->left); + docals(ptr ->right); + } +} + +void docalls2() +{ +// puts("start docalls2"); + docals(treestart); + for(unsigned int i=0;istlist); +// puts("end docalls2"); +} + +void docalls() /* attempt to declare undefs from library and dynamic proc's */ +{ +int numdinproc; +// puts("start docalls"); + notdoneprestuff=2; + docalls2(); + while(DynamicList!=NULL){ + idrec *ptr; + numdinproc=0; +// printf("%d dinamic proc\n",countDP); + for(int i=0;irectok; + itok.segm=ptr->recsegm; +// printf("%d %08X seg=%d tok=%d %s\n",i+1,ptr,itok.segm,ptr->rectok,ptr->recid); + if(itok.segm==DYNAMIC_USED){ + itok.number=ptr->recnumber; + itok.flag=ptr->flag; + strcpy(itok.name,ptr->recid); + if(ptr->newid==NULL)string[0]=0; + else strcpy((char *)string,(char *)ptr->newid); + itok.rm=ptr->recrm; + itok.size=ptr->recsize; + itok.rec=ptr; + insert_dynamic(); + numdinproc++; + } + } + docalls2(); + if(numdinproc==0)break; + } + free(DynamicList); + DynamicList=NULL; + countDP=0; +// puts("end docalls"); +} + +void CreatParamDestr(idrec *ptrs) +{ + if(am32==FALSE){ + structadr.rm=rm_d16; + structadr.sib=CODE16; + } + else{ + structadr.rm=rm_d32; + structadr.sib=CODE32; + } + structadr.segm=DS; + structadr.number=ptrs->recnumber; + structadr.flag=0; + structadr.size=0; //addofs + structadr.rec=NULL; + structadr.type=tp_ucnovn; + structadr.npointr=0; + structadr.post=ptrs->recpost; + if(ptrs->recsegm==USEDSTR)structadr.sib++; + if(structadr.post==LOCAL){ + if(ESPloc&&am32){ + structadr.rm=rm_mod10|rm_sib; + structadr.sib=0x24; + structadr.number+=addESP; + } + else{ + structadr.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + structadr.segm=SS; + compressoffset(&structadr); + } +} + +void CallDestr(idrec *ptr) +{ +int oinptr2; +char ocha2; +int oldendinptr=endinptr; +unsigned char odbg; +int otok,otok2; +unsigned char *oinput; +ITOK oitok; //18.08.04 19:07 + oinptr2=inptr2; + ocha2=cha2; + odbg=dbg; + dbg=0; + otok=tok; + otok2=tok2; + oitok=itok; //18.08.04 19:07 + oinput=input; + string[0]=0; + if(ptr->newid)strcpy((char *)string,ptr->newid); + itok.type=ptr->type; + itok.npointr=ptr->npointr; + itok.rm=ptr->recrm; + itok.flag=ptr->flag; + itok.rec=ptr; + strcpy(itok.name,ptr->recid); + itok.number=ptr->recnumber; + tok=ptr->rectok; + itok.post=ptr->recpost; + itok.segm=ptr->recsegm; + itok.sib=ptr->recsib; + ptr->count++; + if(itok.segm==DYNAMIC)AddDynamicList(ptr); + tok2=tk_openbracket; + input=(unsigned char*)"();"; + inptr2=1; + cha2='('; + endinptr=3; + docommand(); + tok=otok; + input=oinput; + inptr2=oinptr2; + cha2=ocha2; + tok2=otok2; + endinptr=oldendinptr; + dbg=odbg; + itok=oitok;//18.08.04 19:07 +} + +elementteg *FindOneDestr(structteg *searcht) +{ +elementteg *bazael=searcht->baza,*retrez=NULL; +idrec *ptrs; +int i; +/// new! + for(i=0;inumoper;i++){ + ptrs=(bazael+i)->rec; + if((bazael+i)->tok==tk_proc&&(ptrs->flag&fs_destructor)!=0)return(bazael+i); + } + for(i=0;inumoper;i++){ + ptrs=(bazael+i)->rec; + if((bazael+i)->tok==tk_baseclass + ||(bazael+i)->tok==tk_struct //new 20.06.05 21:32 + ){ + if((retrez=FindOneDestr((structteg *)ptrs))!=NULL)break; + } + } + return retrez; +} + +void Destructor(idrec *ptrs) +{ +char name[IDLENGTH]; +struct elementteg *bazael; +int addofs; +structteg *tteg; + tteg=(structteg *)ptrs->newid; + sprintf(name,"%s~",tteg->name); + if((bazael=FindClassEl(tteg,(unsigned char *)name,&addofs,NULL))==NULL){ + if((bazael=FindOneDestr(tteg))==NULL)preerror("destructor not defined"); + } + if(ptrs->recsize)CreatParamDestr(ptrs); + else structadr.sib=THIS_ZEROSIZE; + CallDestr(bazael->rec); +} + +void RunNew(int size) +{ +char buf[128]; +int oinptr2; +char ocha2; +int oldendinptr=endinptr; +unsigned char odbg; +int otok,otok2; +unsigned char *oinput; +oinptr2=inptr2; +ocha2=cha2; +odbg=dbg; + sprintf(buf,"__new(%u);}",size); + dbg=0; + otok=tok; + otok2=tok2; + oinput=input; + input=(unsigned char*)buf; + inptr2=1; + cha2='_'; + tok=tk_openbrace; + endinptr=strlen(buf); + doblock(); + tok=otok; + tok2=otok2; + input=oinput; + inptr2=oinptr2; + cha2=ocha2; + endinptr=oldendinptr; + dbg=odbg; +} + +void donew() +{ +structteg *tteg; +elementteg *bazael; +int addofs=0; +struct idrec *ptr; + nexttok(); + if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){ + tegnotfound(); +er: + while(tok2!=tk_semicolon&&tok!=tk_eof)nexttok(); + return; + } +// printf("flag=%08X\n",tteg->flag); + if((tteg->flag&fs_constructor)==0){ + RunNew(tteg->size); + goto er; + } + bazael=FindClassEl(tteg,(unsigned char *)tteg->name,&addofs,NULL); + structadr.sib=THIS_NEW; + structadr.number=tteg->size; + ptr=bazael->rec; + string[0]=0; + if(ptr->newid!=NULL)strcpy((char *)string,ptr->newid); + itok.type=ptr->type; + itok.npointr=ptr->npointr; + itok.rm=ptr->recrm; + itok.flag=ptr->flag; + itok.rec=ptr; + strcpy(itok.name,ptr->recid); + itok.number=ptr->recnumber; + tok=ptr->rectok; + itok.post=ptr->recpost; + itok.segm=ptr->recsegm; + itok.sib=ptr->recsib; + ptr->count++; + if(itok.segm==DYNAMIC)AddDynamicList(ptr); +// docommand(); + if(dbg)AddLine(); + int oflag=current_proc_type; + current_proc_type&=~f_static; + if(tok==tk_proc)doanyproc(); + else doanyundefproc(); + current_proc_type=oflag; +} + +void dodelete() +{ +int addofs=0; +int oinptr,oinptr2; +char ocha2; +int oldendinptr=endinptr; +unsigned char odbg; +unsigned char *oinput; +structteg *tteg=NULL; +elementteg *bazael; +char buf[128]; + getoperand(); + if(tok==tk_structvar){ + oinptr=tok2; +// if((itok.flag&fs_useconstr)!=0){ + if((itok.flag&fs_destructor)!=0){ + Destructor(itok.rec); + } + else if(itok.rec->newid&&AskUseDestr((structteg *)itok.rec->newid))Destructor(itok.rec); +// } + if(oinptr!=tk_semicolon)nexttok(); + } + else{ + ITOK wtok; + char *wbuf; + wbuf=bufrm; + bufrm=NULL; + wtok=itok; + SINFO wstr; + wstr=strinf; + strinf.bufstr=NULL; + getinto_e_ax(0,tok,&wtok,wbuf,&wstr,(am32+1)*2); + bufrm=NULL; + strinf.bufstr=NULL; + if(tok2!=tk_semicolon){ + nexttok(); + if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){ + tegnotfound(); + while(tok!=tk_semicolon&&tok!=tk_eof)nexttok(); + return; + } + } + oinptr2=inptr2; + ocha2=cha2; + odbg=dbg; + dbg=0; + oinput=input; + int oflag=current_proc_type; + current_proc_type&=~f_static; + if(tteg){ + structadr.number=0; + if((tteg->flag&fs_destructor)!=0){ + op(0x50); + addESP+=am32==FALSE?2:4; + sprintf(buf,"%s~",tteg->name); + bazael=FindClassEl(tteg,(unsigned char *)buf,&addofs,NULL); + + structadr.sib=THIS_REG; + structadr.rm=AX; + structadr.size=addofs; // ???? 19.08.04 12:54 ᯮ + CallDestr(bazael->rec); + addESP-=am32==FALSE?2:4; + op(0x58); + } + else if(AskUseDestr(tteg)){ + bazael=FindOneDestr(tteg); + op(0x50); + addESP+=am32==FALSE?2:4; + structadr.sib=THIS_REG; + structadr.rm=AX; + structadr.size=0;//addofs; + CallDestr(bazael->rec); + addESP-=am32==FALSE?2:4; + op(0x58); + } + } + input=(unsigned char*)"__delete((E)AX);}"; + inptr2=1; + cha2='_'; + endinptr=strlen((char *)input); + tok=tk_openbrace; + doblock(); + input=oinput; + inptr2=oinptr2; + cha2=ocha2; + endinptr=oldendinptr; + dbg=odbg; + current_proc_type=oflag; + } + nextseminext(); +} + +int AskUseDestr(structteg *searcht) +{ +elementteg *bazael=searcht->baza; + if((searcht->flag&fs_destructor)!=0)return TRUE; + for(int i=0;inumoper;i++){ +// printf("tok=%d\n",(bazael+i)->tok); + if((bazael+i)->tok==tk_baseclass + ||(bazael+i)->tok==tk_struct //new 20.06.05 21:33 + ){ + if(AskUseDestr((structteg *)(bazael+i)->rec))return TRUE; + } + } + return FALSE; +} + +void AutoDestructor() +{ +struct localrec *ptrs; +int calldestruct=FALSE; +int zerosize=FALSE; +treelocalrec *ftlr; + for(ftlr=tlr;ftlr!=NULL;ftlr=ftlr->next){ + for(ptrs=ftlr->lrec;ptrs!=NULL;ptrs=ptrs->rec.next){ + if(ptrs->rec.rectok==tk_structvar){ + if((ptrs->rec.flag&fs_destructor)!=0||AskUseDestr((structteg *)ptrs->rec.newid)){ + if(!calldestruct){ + calldestruct=TRUE; + if(ptrs->rec.recsize==0||returntype==tk_void)zerosize=TRUE; + else{ + op66(r32); + op(0x50); + addESP+=4; + } + } + Destructor(&ptrs->rec); + } + } + } + } + if(calldestruct&&zerosize==FALSE){ + op66(r32); + op(0x58); + addESP-=4; + } +} + +elementteg *FindClassEl(structteg *searcht,unsigned char *string4,int *addofs, + structteg *subteg) +{ +struct elementteg *bazael=searcht->baza; +int numclass=0; +void **listclass; +//11.08.04 22:54 +char name[IDLENGTH]; + strcpy(name,searcht->name); + + for(unsigned int i=0;inumoper;i++){ + if((bazael+i)->tok==tk_baseclass){ + if(!numclass)listclass=(void **)MALLOC(sizeof(void **)); + else listclass=(void **)REALLOC(listclass,sizeof(void **)*(numclass+1)); + listclass[numclass]=(void *)(bazael+i)->nteg; + numclass++; + continue; + } + if(strcmp((bazael+i)->name,(char *)string4)==0){ + if(subteg&&subteg!=searcht)continue; + if(numclass)free(listclass); +//11.08.04 22:54 + strcpy((char *)string4,name); + + return (bazael+i); + } + } + if(numclass){ +structteg *ssubteg=subteg; + for(int i=numclass-1;i>=0;i--){ + structteg *s=(structteg *)listclass[i]; + if(subteg==searcht)ssubteg=s; + if((bazael=FindClassEl(s,string4,addofs,ssubteg))!=NULL){ + i--; + while(i>=0){ + s=(structteg *)listclass[i]; + *addofs+=s->size; + i--; + } + free(listclass); + return bazael; + } + } + free(listclass); + } + return NULL; +} + +int CallDestructor(structteg *searcht) +{ +elementteg *bazael=searcht->baza; +idrec *ptrs; + for(int i=0;inumoper;i++){ + ptrs=(bazael+i)->rec; + if((searcht->flag&fs_destructor)==0){ + if((bazael+i)->tok==tk_baseclass){ + if(CallDestructor((structteg *)ptrs))return TRUE; + } + } + else if((bazael+i)->tok==tk_proc&&(ptrs->flag&fs_destructor)!=0){ + structadr.sib=THIS_PARAM; + structadr.number=0;//addofs; + CallDestr(ptrs); + return TRUE; + } + } + return FALSE; +} + +void CopyTok(int *tok4,ITOK *itok4,idrec *ptr) +{ + itok4->number=ptr->recnumber; + itok4->rm=ptr->recrm; + *tok4=ptr->rectok; + itok4->post=ptr->recpost; + itok4->segm=ptr->recsegm; + itok4->flag=ptr->flag; + itok4->size=ptr->recsize; + itok4->sib=ptr->recsib; + itok4->rec=ptr; + itok4->type=ptr->type; + itok4->npointr=ptr->npointr; +} + +int searchlocals(ITOK *itok4,int *tok4,unsigned char *string4) +// ६ 易 ᯨ᪠ +{ + if(skiplocals){ + skiplocals=FALSE; + return FALSE; + } + if(skipfind==LOCAL)return FALSE; +treelocalrec *ftlr; +struct localrec *ptr; + for(ftlr=tlr;ftlr!=NULL;ftlr=ftlr->next){ + for(ptr=ftlr->lrec;ptr!=NULL;ptr=ptr->rec.next){ +// puts(ptr->rec.recid); + if(strcmp(ptr->rec.recid,(char *)string4)==0){ + itok4->number=ptr->rec.recnumber; + *tok4=ptr->rec.rectok; + itok4->locrec=ptr; + if(displaytokerrors){ + if(mapfile){ + if(ptr->li.count==0)ptr->li.usedfirst=linenumber; + else ptr->li.usedlast=linenumber; + ptr->li.count++; + } + if(*tok4==tk_structvar)ptr->rec.count++; + } +// printf("type=%d num=%08X %s\n",ptr->rec.type,ptr->rec.recnumber,ptr->rec.recid); + if(ptr->rec.type==tp_postvar){ + itok4->segm=DS; + itok4->flag=ptr->rec.flag; + itok4->size=ptr->rec.recsize; + itok4->rm=(am32==FALSE?rm_d16:rm_d32); + itok4->npointr=ptr->rec.npointr; + itok4->type=tp_localvar; + itok4->post=1; + if(*tok4==tk_structvar){ + itok4->rec=&ptr->rec; + itok4->post=ptr->rec.recpost; +// itok4->segm=0; + } + return TRUE; + } + if(ptr->rec.type==tp_gvar){ + itok4->number=0; + itok4->rm=(am32==FALSE?rm_d16:rm_d32); + itok4->segm=DS; + itok4->size=ptr->rec.recsize; + itok4->npointr=ptr->rec.npointr; + itok4->type=ptr->rec.recsib; //????01.09.05 15:58 + itok4->post=USED_DIN_VAR; + if(ptr->rec.recpost==DYNAMIC_VAR)ptr->rec.recpost=USED_DIN_VAR; + itok4->rec=&ptr->rec; + ptr->fuse=USEDVAR; + if(*tok4==tk_structvar){ + itok4->number=ptr->rec.recnumber; + itok4->flag|=ptr->rec.flag; + } + return TRUE; + } + itok4->type=ptr->rec.type; + if(ptr->rec.type==tp_paramvar||ptr->rec.type==tp_localvar){ + if(ESPloc&&am32){ + itok4->rm=rm_mod10|rm_sib; + itok4->sib=0x24; + if(ptr->rec.type==tp_paramvar)itok4->number+=localsize+addESP; + else itok4->number+=-4+addESP; + } + else itok4->rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + itok4->segm=SS; + itok4->npointr=ptr->rec.npointr; + if(ptr->rec.npointr){ + itok4->type=(unsigned short)*tok4-tk_charvar+tk_char; + *tok4=tk_pointer; + } + if(*tok4==tk_structvar){ + itok4->rec=&ptr->rec; + itok4->post=ptr->rec.recpost; + itok4->segm=0; + } + } + else if(!(ptr->rec.rectok==tk_locallabel||ptr->rec.rectok==tk_number)){ + internalerror("Bad *tok4 value in searchlocals"); + } + itok4->size=ptr->rec.recsize; + itok4->flag=ptr->rec.flag; + return TRUE; + } + } + } + if(searchteg){ +struct elementteg *bazael; +int addofs=0; +structteg *subteg=NULL; + if(cha==':'&&cha2==':'){ + nextchar(); + nextchar(); + if((subteg=FindTeg(TRUE,itok4->name))==NULL&&displaytokerrors)undefclass(itok4->name); + tokscan(tok4,itok4,string4); + whitespace(); + } + if(destructor){ + destructor=FALSE; + strcat((char *)string4,"~"); + } + if((bazael=FindClassEl(searchteg,string4,&addofs,subteg))!=NULL){ + *tok4=bazael->tok; + itok4->type=tp_classvar; +// printf("tok=%d bazael->rec=%08X %s\n",*tok4,bazael->rec,itok4->name); + if(*tok4==tk_proc||*tok4==tk_pointer){ + idrec *ptr=bazael->rec; + if(strchr(itok4->name,'@')==NULL){ + strcat(itok4->name,"@"); + strcat(itok4->name,(char *)string4); + } +// } +// printf("tok=%d %s %s\n",*tok4,ptr->recid,ptr->newid); + if(*tok4==tk_proc&&ptr->newid!=NULL)strcpy((char *)string4,ptr->newid); + CopyTok(tok4,itok4,bazael->rec); + structadr.sib=THIS_PARAM; + structadr.number=0;//addofs; + if(displaytokerrors){ + ptr->count++; + if(*tok4==tk_proc){ + if(itok4->segm==DYNAMIC)AddDynamicList(ptr); + } + } + if(*tok4==tk_pointer)goto locvar; + } + else if(*tok4==tk_struct){ + *tok4=tk_structvar; +// printf("teg=%08X\n",bazael->nteg); + dostructvar2(tok4,itok4,(structteg *)bazael->nteg,string4); + if(*tok4==tk_structvar){ + itok4->rec=(idrec *)bazael->nteg; + itok4->number+=(itok4->post==0?0:itok4->rm*((structteg *)bazael->nteg)->size); + itok4->size=(itok4->post==0?bazael->numel:1)*((structteg *)bazael->nteg)->size; + + itok4->number+=bazael->ofs+addofs; + if(displaytokerrors){ + if(strinf.bufstr!=NULL)free(strinf.bufstr); + strinf.bufstr=(char *)MALLOC(7); + strcpy(strinf.bufstr,"&this;"); + strinf.size=1; + } +// itok4->flag|=f_useidx; +// if(itok4->sib>=CODE16)itok4->sib++; + return TRUE; + + } + else if(*tok4==tk_proc){ + structadr.sib=THIS_PARAM; + structadr.number+=bazael->ofs+addofs; + + if(itok4->sib>=CODE16)itok4->sib++; + return TRUE; + } + + goto locvar;; + } + else{ + if(bazael->rec){ //static var + CopyTok(tok4,itok4,bazael->rec); + return TRUE; + } + +locvar: + itok4->number+=bazael->ofs+addofs; + if(displaytokerrors){ + if(bufrm!=NULL)free(bufrm); + bufrm=(char *)MALLOC(7); + strcpy(bufrm,"&this;"); + } +// itok4->flag|=f_useidx; + if(itok4->sib>=CODE16)itok4->sib++; +// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,string4); + } + return TRUE; + } + } + return FALSE; +} + +void dostructvar2(int *tok4,ITOK *itok4,struct structteg *tteg,unsigned char *string4) //ࠧ ६ +{ +struct elementteg *bazael; +int numel=0; +int usenumstruct=FALSE; +int sopenb; +long cnum; +ITOK cstok; +char *cstring; +char c=0; +int i; +structteg *subteg=NULL; + structadr=*itok4; +// bazael=tteg->baza; + whitespace();//ய ᨬ + cstring=(char *)MALLOC(STRLEN); + if(cha=='['){ //[ + usenumstruct=TRUE; + nextchar(); + sopenb=inptr; + unsigned char bcha=cha; + tokscan(&i,&cstok,(unsigned char *)cstring); + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(i==tk_number){ //᫮ + ITOK dstok; + memcpy(&dstok,itok4,sizeof(ITOK)); + calcnum(&i,&cstok,cstring,&cnum); + memcpy(itok4,&dstok,sizeof(ITOK)); + if(i!=tk_closeblock)goto notnum; + numel=cnum; + } + else{ +notnum: +//new!!! + if(displaytokerrors){ + if(itok4->segm==USEDSTR)preerror("only once possible use variable an index structure"); + +// if(itok4->segm==USEDSTR&&displaytokerrors)preerror("only once possible use variable an index structure"); + itok4->segm=USEDSTR; + SRBackBuf(0); + AddBackBuf(sopenb,bcha); + CharToBackBuf(';'); + CharToBackBuf(0); + if(cha!=']')blockerror(); + if(strinf.bufstr!=NULL)free(strinf.bufstr);//internalerror("Previous block was not used"); + strinf.bufstr=(char *)REALLOC(BackTextBlock,SizeBackBuf+1); + SRBackBuf(1); + nextchar(); +//new!!! + } + else{ + do{ + tokscan(&i,&cstok,(unsigned char *)cstring); + if(i==tk_eof)break; + }while(i!=tk_closeblock); + } + + c=1; + strinf.size=tteg->size; + } + itok4->flag|=f_useidx; + whitespace();//ய ᨬ + } + if(cha=='.'){ + int fdestr=FALSE; + nextchar(); + if(cha=='~'){ + nextchar(); + fdestr=TRUE; + } + skipfind=LOCAL; + do{ + tokscan(&i,&cstok,(unsigned char *)cstring); +// puts(cstok.name); + if(cha=='.')searchtree2(definestart,&cstok,&i,(unsigned char *)cstring); + }while(i==tk_endline); + whitespace(); + if(cha==':'){ + nextchar(); + if(cha!=':')expectederror("::"); + nextchar(); + if((subteg=FindTeg(TRUE,cstok.name))==NULL&&displaytokerrors)undefclass(cstok.name); + tokscan(&i,&cstok,(unsigned char *)cstring); + whitespace(); + } + skipfind=FALSE; + int addofs=0; + if(fdestr)strcat(cstok.name,"~"); + if((bazael=FindClassEl(tteg,(unsigned char *)cstok.name,&addofs,subteg))==NULL){ + if(displaytokerrors)unknownstruct(cstok.name,tteg->name); + *tok4=tk_number; + free(cstring); + return; + } + free(cstring); + *tok4=bazael->tok; + itok4->size=bazael->numel*GetVarSize(*tok4); + cnum=(c==0?tteg->size*numel:0); + if((itok4->flag&f_extern)!=0)itok4->number+=((bazael->ofs+cnum)<<16); + else itok4->number+=bazael->ofs+cnum; + if(*tok4==tk_struct){ + *tok4=tk_structvar; + itok4->size=bazael->numel*((structteg *)bazael->nteg)->size; + dostructvar2(tok4,itok4,(structteg *)bazael->nteg,string4); + return; + } + if((itok4->flag&f_extern)!=0)itok4->number+=addofs<<16; + else itok4->number+=addofs; +// printf("tok=%d %s\n",*tok4,bufrm); + if(*tok4==tk_proc||*tok4==tk_pointer){ + idrec *ptr;//=NULL; + if(*tok4==tk_proc){ + if(am32==FALSE){ + structadr.rm=rm_d16; + structadr.sib=CODE16; + } + else{ + structadr.rm=rm_d32; + structadr.sib=CODE32; + } + structadr.segm=DS; + structadr.number=itok4->number; +// structadr.number=0; + structadr.flag=0; + structadr.size=addofs; + structadr.type=tp_ucnovn; + structadr.npointr=0; + structadr.post=itok4->post; + structadr.rec=(structadr.post==USED_DIN_VAR?itok4->rec:NULL); + if(itok4->segm==USEDSTR)structadr.sib++; + if(structadr.post==LOCAL){ + if(ESPloc&&am32){ + structadr.rm=rm_mod10|rm_sib; + structadr.sib=0x24; //??? + structadr.number+=addESP; + } + else{ + structadr.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + structadr.segm=SS; + compressoffset(&structadr); + if(tteg->size==0)structadr.sib=THIS_ZEROSIZE; //14.11.05 13:51 + } +/* if(strcmp(bazael->name,tteg->name)==0&&itok4->rec){ //맮 + ptr=itok4->rec; +// printf("constructor %08X\n",ptr); + }*/ + } +// if(ptr)printf("new address constructor %08X\n",bazael->rec); + ptr=bazael->rec; + itok4->type=ptr->type; + itok4->npointr=ptr->npointr; + itok4->rm=ptr->recrm; + itok4->flag=ptr->flag; + itok4->rec=ptr; + strcpy(itok4->name,ptr->recid); + if(*tok4==tk_pointer){ +// puts("Check this code"); + string4[0]=0; + if(ptr->newid!=NULL)strcpy((char *)string4,ptr->newid); + *tok4=ptr->rectok; +//!!! + if(itok4->type==tk_proc&&cha!='('){ + itok4->type=(am32==FALSE?tk_wordvar:tk_dwordvar); + goto notbit; + } + + if(itok4->type!=tk_proc)goto notbit; +// printf("post=%08X %s\n",itok4->post,itok4->name); + if(itok4->post==LOCAL){ + if(ESPloc&&am32){ + itok4->rm=rm_mod10|rm_sib; + itok4->sib=0x24; + itok4->number+=addESP; + } + else{ + itok4->sib=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); //???rm + } + itok4->segm=SS; + itok4->post=FALSE; + } + else{ + itok4->sib=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + itok4->segm=DS; + } +// itok4->post=0; + itok4->flag|=f_useidx; + return; + } + itok4->number=ptr->recnumber; + *tok4=ptr->rectok; + itok4->post=ptr->recpost; + itok4->segm=ptr->recsegm; + itok4->sib=ptr->recsib; + itok4->size=ptr->recsize; //11.08.04 00:24 +//11.09.04 00:28 + if(strchr(itok4->name,'@')==NULL){ + strcat(itok4->name,"@"); + strcat(itok4->name,(char *)string4); + } + string4[0]=0; + if(ptr->newid!=NULL)strcpy((char *)string4,ptr->newid); +//////////////////// + +// printf("tok=%d num=%d %s\n",*tok4,itok4->number,itok4->name); + if(displaytokerrors){ + ptr->count++; + if(*tok4==tk_proc&&itok4->segm==DYNAMIC)AddDynamicList(ptr); + if(*tok4!=tk_proc&&*tok4!=tk_undefproc&&*tok4!=tk_declare)thisundefined(ptr->recid,FALSE); + } + return; + } +// if((itok4->flag&f_extern)!=0)itok4->number+=addofs; +// else itok4->number+=addofs; + if(*tok4==tk_bits){ + itok4->flag|=f_useidx; + itok4->number+=bazael->bit.ofs/8; + if((bazael->bit.ofs%8)==0){ + switch(bazael->bit.siz){ + case 8: + *tok4=tk_bytevar; + goto notbit; + case 16: + *tok4=tk_wordvar; + goto notbit; + case 32: + *tok4=tk_dwordvar; + goto notbit; + } + } + itok4->bit.siz=bazael->bit.siz; + itok4->bit.ofs=bazael->bit.ofs%8; + } + else if(bazael->rec){ //static var + CopyTok(tok4,itok4,bazael->rec); + return; + } +notbit: + itok4->sib=cstok.sib; + if(itok4->post==LOCAL){ + if(ESPloc&&am32){ + itok4->rm=rm_mod10|rm_sib; +// printf("sib=%x tok=%d name=%s\n",itok4->sib,*tok4,itok4->name); + itok4->sib=0x24; + itok4->number+=addESP; + } + else{ + itok4->rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + if(itok4->segm==USEDSTR&&itok4->sib>=CODE16)itok4->sib++; + } + itok4->segm=SS; + itok4->post=FALSE; + itok4->flag=f_useidx; + } + else{ + itok4->rm=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + if(itok4->segm==USEDSTR&&itok4->sib>=CODE16)itok4->sib++; + itok4->segm=DS; + itok4->flag=FixUp|f_useidx; + } + return; + } +// itok4->size=(numel==0?bazael->numel:1)*((structteg *)bazael->nteg)->size; +// itok4->rec=(idrec *)tteg; + itok4->rm=numel; + itok4->post=usenumstruct; + free(cstring); +} + +void dosizeof(ITOK *itok4) // 祭 sizeof +{ +struct structteg *tteg; +int i,brase=FALSE; +ITOK cstok; + whitespace();//ய ᨬ + itok4->number=0; + if(cha=='('){ + nextchar(); + brase=TRUE; + } +// if((cha!='(')&&(displaytokerrors))expected('('); +// nextchar(); + cstok.name[0]=0; +// if(displaytokerrors)puts("start sizeof"); + tokscan(&i,&cstok,string2); +// if(displaytokerrors)printf("tok=%d findoffset=%d %s\n",i,findofset,cstok.name); + if(i==tk_dblcolon&&numblocks){ + skiplocals=TRUE; + tokscan(&i,&cstok,string2); + } + if(strcmp(cstok.name,"__CODESIZE")==0){ + itok4->post=CODE_SIZE+am32; + } + else if(strcmp(cstok.name,"__DATASIZE")==0){ + itok4->post=DATA_SIZE+am32; + } + else if(strcmp(cstok.name,"__POSTSIZE")==0){ + itok4->post=POST_SIZE+am32; + } + else if(strcmp(cstok.name,"__STACKSIZE")==0){ + itok4->post=STACK_SIZE+am32; + } + else{ + switch(i){ + case tk_char: + case tk_byte: + case tk_beg: + itok4->number=1; + break; + case tk_int: + case tk_word: + case tk_reg: + case tk_seg: + itok4->number=2; + break; + case tk_float: + case tk_reg32: + case tk_long: + case tk_dword: + itok4->number=4; + break; + case tk_double: + case tk_qword: + itok4->number=8; + break; + case tk_string: + itok4->number=cstok.number; + if(/*itok4->*/cstok.flag!=no_term)itok4->number++; + break; + case tk_bits: + itok4->number=cstok.bit.siz; + break; + case tk_proc: + case tk_charvar: + case tk_bytevar: + case tk_intvar: + case tk_wordvar: + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + case tk_structvar: + case tk_qwordvar: + case tk_doublevar: + case tk_interruptproc: + if(cstok.size==0)if(displaytokerrors)preerror("unknown size"); + itok4->number=cstok.size; + break; + default: + if((tteg=FindTeg(FALSE,cstok.name))!=NULL||(tteg=FindTeg(TRUE,cstok.name))!=NULL){ + if(cha=='.'){ + dostructvar2(&i,itok4,tteg,string2); + itok4->number=itok4->size; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + } + else itok4->number=tteg->size; + itok4->flag=0; + break; + } + if(strcmp("file",(char *)string2)==0){ + displaytokerrors=1; + tokscan(&i,&cstok,string2); + if(i==tk_string){ + struct stat statbuf; + if(stat((char *)string3,&statbuf)!=0)unableopenfile((char *)string3); + else itok4->number=statbuf.st_size; + } + else stringexpected(); + } + else if(displaytokerrors)preerror("illegal use of sizeof"); + break; + } + } + whitespace();//ய ᨬ + if(brase){ + if(cha!=')'&&displaytokerrors)expected(')'); + nextchar(); + } +} + +void ofsstr(int *tok4,ITOK *itok4) +{ +struct structteg *tteg; +int newreg=(idxregs[4]==255?idxregs[0]:idxregs[4]); //14.06.06 20:06 +int poststr; +int flagstr; + if(itok4->type==tp_classvar){ + tteg=(structteg *)itok4->rec; + poststr=0; + flagstr=f_useidx; + } + else{ +struct idrec *ptrs; + ptrs=itok4->rec; + tteg=(structteg *)ptrs->newid; + poststr=ptrs->recpost; + flagstr=ptrs->flag; + } + if(tteg==NULL){ + if(displaytokerrors){ + unknowntagstruct(itok4->name); + } + return; + } + if(strinf.bufstr==NULL&&itok4->post==TRUE)itok4->number+=(tteg->size*(itok4->rm)); + itok4->size=tteg->size; + itok4->sib=(am32==FALSE?CODE16:CODE32); + char ocha=cha; + int binptr=inptr; + if(poststr==LOCAL){ + itok4->rm=rm_mod10; + if(strinf.bufstr==NULL){ + if(ESPloc&&am32){ + itok4->rm|=rm_sib; + itok4->sib=0x24; + } + else{ + itok4->rm|=(am32==FALSE?rm_BP:rm_EBP); + } + } + else{ + if(displaytokerrors){ + if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,idxregs[0]))!=NOINREG){ + if(newreg==SKIPREG){ + newreg=idxregs[0]; + } + else{ + if(am32==FALSE&&newreg!=DI)goto noopt1; + waralreadinitreg(regs[am32][idxregs[0]],regs[am32][newreg]); + } + free(strinf.bufstr); + strinf.bufstr=NULL; + goto cont1; + } + newreg=idxregs[0]; +noopt1: + CheckMassiv(strinf.bufstr,strinf.size,idxregs[0]); +cont1: ; + } + if(am32==FALSE)itok4->rm|=CalcRm16(BP,newreg); + else{ + itok4->sib=(newreg<<3)+(ESPloc?ESP:EBP); + itok4->rm=4|rm_mod10; + } + } + itok4->segm=SS; + if(ESPloc&&am32)itok4->number+=addESP; +// else itok4->number-=localsize; + *tok4=tk_rmnumber; + if(itok4->type==tp_classvar)itok4->flag|=f_useidx; + itok4->post=FALSE; + compressoffset(itok4); + } + else{ + itok4->post=poststr; + if(strinf.bufstr==NULL){ + itok4->rm=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + if(itok4->post!=0)*tok4=tk_postnumber; + else *tok4=tk_number; + } + else{ + if(displaytokerrors){ + if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,idxregs[0]))!=NOINREG){ + if(newreg==SKIPREG){ + newreg=idxregs[0]; + } + else{ + if(am32==FALSE&&newreg!=DI&&newreg!=BX)goto noopt2; + waralreadinitreg(regs[am32][idxregs[0]],regs[am32][newreg]); + } + free(strinf.bufstr); + strinf.bufstr=NULL; + goto cont2; + } + newreg=(idxregs[4]==255?idxregs[0]:idxregs[4]); //14.06.06 20:06 +noopt2: + CheckMassiv(strinf.bufstr,strinf.size,(idxregs[4]==255?idxregs[0]:idxregs[4])); +cont2: ; + } + itok4->rm=RegToRM(newreg,(am32==FALSE?tk_reg:tk_reg32))|rm_mod10; + *tok4=tk_rmnumber; + } + itok4->segm=DS; + } + if(itok4->post==0&&(itok4->flag&f_reloc)==0){ // cannot compress if POST var + compressoffset(itok4); + } +// compressoffset(itok4); + itok4->flag|=flagstr; + inptr=binptr; + cha=ocha; +} + +void AddUndefOff(int segm,char *ostring) //䨪஢ 饭  +/*segm - ᥣ 㤠 饭 + 0 - ᥣ + 1 - ᥣ + 2 - ᥣ , ᥭ ⠡ ६饭 + 3 - ᥣ , ᥭ ⠡ ६饭 +*/ +{ +UNDEFOFF *curptr; + if(undefoffstart==NULL){ //᫨ 뫮 ⮪ + undefoffstart=(UNDEFOFF *)MALLOC(sizeof(UNDEFOFF)); + memset(undefoffstart,0,sizeof(UNDEFOFF)); + strcpy(undefoffstart->name,ostring); + } + for(curptr=undefoffstart;;curptr=curptr->next){ + if(strcmp(curptr->name,ostring)==0){ //࠭ 㦥 頫 + //⠡ 饭 undef + if(curptr->pos==NULL)curptr->pos=(IOFS *)MALLOC(sizeof(IOFS)*(curptr->num+1)); + else curptr->pos=(IOFS *)REALLOC(curptr->pos,sizeof(IOFS)*(curptr->num+1)); + (curptr->pos+curptr->num)->ofs=segm==0?outptr:outptrdata; + (curptr->pos+curptr->num)->dataseg=(unsigned char)segm; + (curptr->pos+curptr->num)->line=linenumber; + (curptr->pos+curptr->num)->file=currentfileinfo; + curptr->num++; + return; + } + if(curptr->next==NULL)break; // ᯨ᪠ + } + curptr=curptr->next=(UNDEFOFF *)MALLOC(sizeof(UNDEFOFF)); // undef + memset(curptr,0,sizeof(UNDEFOFF)); + strcpy(curptr->name,ostring); + curptr->num=1; + curptr->pos=(IOFS *)MALLOC(sizeof(IOFS)); + curptr->pos->ofs=segm==0?outptr:outptrdata; + curptr->pos->dataseg=(unsigned char)segm; + curptr->pos->line=linenumber; + curptr->pos->file=currentfileinfo; +} + +int CheckUseAsUndef(unsigned char *name) +{ +UNDEFOFF *curptr; +int count=0; + if(undefoffstart==NULL)return 0; // 뫮 饭 undef + for(curptr=undefoffstart;;curptr=curptr->next){ + if(strcmp(curptr->name,(char *)name)==0){ //諨 + count=curptr->num; + break; + } + if(curptr->next==NULL)break; + } + return count; +} + +int FindOff(unsigned char *name,int base) // 뫮 ⥪饥 +{ +/*-----------------13.08.00 23:48------------------- + ᬮ 楤 ࠧ + --------------------------------------------------*/ +UNDEFOFF *curptr,*prev; +unsigned char segm; +unsigned int ofs,valofs; +int count=0; + if(undefoffstart==NULL)return 0; // 뫮 饭 undef + for(curptr=undefoffstart;;curptr=curptr->next){ + if(strcmp(curptr->name,(char *)name)==0){ //諨 + for(int i=0;inum;i++){ + ofs=(curptr->pos+i)->ofs; + segm=(curptr->pos+i)->dataseg; + if(base==DS&&dynamic_flag){ //뫮 饭 ᪨ . ६ + CheckPosts(); + (postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32); + (postbuf+posts)->num=(int)itok.rec; + (postbuf+posts)->loc=ofs; + } + else{ + if((segm&1)==0||modelmem==TINY){ // ᥣ + if(base!=VARPOST){ +// if(am32==FALSE)valofs=*(unsigned short *)&output[ofs]; +// else valofs=*(unsigned long *)&output[ofs]; +// valofs+=(base==CS?outptr:outptrdata); + valofs=(base==CS?outptr:outptrdata); + } + else valofs=postsize; + if(am32==FALSE)*(unsigned short *)&output[ofs]+=(unsigned short)valofs; + else *(unsigned long *)&output[ofs]+=valofs; + } + else{ + if(am32==FALSE)*(unsigned short *)&outputdata[ofs]+=(unsigned short)(base==CS?outptr:outptrdata); + else *(unsigned long *)&outputdata[ofs]+=(unsigned long)(base==CS?outptr:outptrdata); + } + if((FixUp!=FALSE&&(segm&2)==0)/*||base==VARPOST*/){ + CheckPosts(); + (postbuf+posts)->type=(unsigned char) +// (base==VARPOST?(am32==FALSE?POST_VAR:POST_VAR32): + ((segm&1)==0?(am32==FALSE?FIX_VAR:FIX_VAR32): + (am32==FALSE?FIX_CODE:FIX_CODE32) +// ) + ); + (postbuf+posts)->loc=ofs; + posts++; + } + if(base==VARPOST){ + unsigned int i; + for(i=0;iloc)break; + } + if(i==posts){ + CheckPosts(); + posts++; + (postbuf+i)->loc=ofs; + } + (postbuf+i)->type=(unsigned char)(am32==FALSE?POST_VAR:POST_VAR32); + } + } + } + free(curptr->pos); + if(undefoffstart->next==NULL)undefoffstart=NULL; + else if(undefoffstart==curptr)undefoffstart=curptr->next; + else{ + for(prev=undefoffstart;prev->next!=curptr;prev=prev->next); + prev->next=curptr->next; + } + count=curptr->num; + free(curptr); + break; + } + if(curptr->next==NULL)break; + } + return count; +} + +int FindUseName(char *name) // 뫮 ⥪饥 +{ +UNDEFOFF *curptr; + if(undefoffstart){ + for(curptr=undefoffstart;;curptr=curptr->next){ + if(strcmp(curptr->name,(char *)name)==0){ //諨 + return curptr->num; + } + if(curptr->next==NULL)break; + } + } + return 0; +} + +int GetDirective(char *str) +{ + int i; + i=FastSearch(dirlist,ofsdir,1,str); +// printf("i=%d %s\n",i,str); + if(i!=-1&&i0){ +short offs=-1; +unsigned char c; + c=str[0]; + switch(type){ + case 0: + if(c>='A'&&c<='Z')offs=ofs[c-'A']; + break; + case 1: + if(c=='D')offs=ofs[0]; + else if(c>='a'&&c<='z')offs=ofs[c-0x60]; + break; + case 2: + if(c=='_')offs=ofs[26]; + else if(c>='a'&&c<='z')offs=ofs[c-'a'+27]; + else offs=ofs[c-'A']; + break; + case 3: + if(c>='a'&&c<='z')offs=ofs[c-0x61]; + break; + } +// if(type==0)printf("%s\n",str); + if(offs!=-1){ + for(unsigned char *ii=(unsigned char *)(list+offs);;ii++){ + short types; + if((types=*(short *)&*ii)==-1)break; + ii+=2; + unsigned char c=*ii; + int i; + i=1; + while(c==str[i]){ + if(c==0)return types; + ii++; + i++; + c=*ii; + } + if(c>str[i])break; + while(*ii!=0)ii++; + } + } + } + return -1; +} + +/*-----------------05.01.00 22:56------------------- + ࠬ + --------------------------------------------------*/ + +int GetVarSize(int var) +{ + switch(var){ + case tk_reg: + case tk_intvar: + case tk_seg: + case tk_wordvar: return 2; + case tk_bits: + case tk_charvar: + case tk_beg: + case tk_bytevar: return 1; + case tk_pointer: + if(am32==0)return 2; + case tk_longvar: + case tk_dwordvar: + case tk_reg32: + case tk_floatvar: return 4; + case tk_doublevar: + case tk_qwordvar: return 8; + default: + if(am32)return 4; + } + return 2; +} + +unsigned long getsizebit(int size) +{ +unsigned long num; + nexttok(); + if(tok!=tk_number)numexpected(); + num=doconstdwordmath(); + if(num>(unsigned int)(size*8))preerror("Bit field to large"); + return num; +} + +int GetFirstDestr(structteg *searcht) +{ +elementteg *bazael=searcht->baza; +idrec *ptrs; + if((searcht->flag&fs_destructor)!=0)return TRUE; + for(int i=0;inumoper;i++){ + ptrs=(bazael+i)->rec; + if((bazael+i)->tok==tk_baseclass){ + if(GetFirstDestr((structteg *)ptrs))return TRUE; + } + } + return FALSE; +} + +void AddTegToTree(structteg *newteg,int Global) +{ +struct structteg *tteg; +int i; + tteg=(Global==TRUE?tegtree:ltegtree); + if(tteg==NULL)(Global==TRUE?tegtree:ltegtree)=newteg; + else{ + while(((i=strcmp(tteg->name,newteg->name))<0&&tteg->left!=NULL)||(i>0&&tteg->right!=NULL)) + tteg=(i<0?tteg->left:tteg->right); + (i<0?tteg->left:tteg->right)=newteg; + } +} + +int IsClass(structteg *searcht) +{ +elementteg *bazael=searcht->baza; + if((searcht->flag&fs_destructor)!=0)return TRUE; + for(int i=0;inumoper;i++){ + if((bazael+i)->tok==tk_baseclass)return TRUE; +// if(IsClass((structteg *)(bazael+i)->rec))return TRUE; + else if((bazael+i)->tok==tk_proc){ + if((bazael+i)->rec&&((bazael+i)->rec->flag&f_classproc))return TRUE; + } + } + return FALSE; +} + +struct structteg *CreatTeg(int Global,int useunion,int noname) //ᮧ ⥣ +{ +struct structteg *newteg,*tteg; +struct elementteg *bazael; +int ssize=0,numel=0,localtok,size,numt,nameid=FALSE,tsize; +int bitofs=0,bitsize=0,i,type; +int isdestr=FALSE,isbase=0; +int unionsize=0; + newteg=(struct structteg *)MALLOC(sizeof(struct structteg)); + newteg->left=newteg->right=NULL; + newteg->baza=NULL; + newteg->flag=useunion; + newteg->name[0]=0; + if(tok==tk_ID||tok==tk_id){ + strcpy(newteg->name,itok.name); + AddTegToTree(newteg,Global); + nexttok(); + nameid=TRUE; + } + if(tok==tk_colon){ + nexttok(); + do{ + if((tteg=FindTeg(TRUE))==NULL)undefclass(itok.name); + else{ + size=tteg->size; + if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)); + else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1)); + for(i=0;iname,itok.name)==0){ + sprintf((char *)string,"Dublicate base class '%s'",itok.name); + preerror((char *)string); + } + } + strcpy((bazael+numel)->name,itok.name); + (bazael+numel)->tok=tk_baseclass; + (bazael+numel)->ofs=ssize; + (bazael+numel)->numel=1; + ssize+=size; + (bazael+numel)->nteg=tteg; + numel++; + isbase++; + } + nexttok(); + if(tok==tk_openbrace)break; + expecting(tk_camma); + }while(tok!=tk_eof); + if(useunion)preerror("union cannot have a base type"); + } + expecting(tk_openbrace); + while(tok!=tk_closebrace&&tok!=tk_eof){ + int oflag,orm,npointr; + int utestInitVar=FALSE; + orm=tokens; + npointr=oflag=0; + type=variable; + if(tok==tk_tilda){ + newteg->flag|=fs_destructor; + oflag|=fs_destructor; +// oflag=newteg->flag; + nexttok(); + isdestr=TRUE; + } +//13.09.04 00:08 + if(tok==tk_static){ + oflag|=f_static; + nexttok(); + } +///////////// + switch(tok){ + case tk_int: orm=tok; localtok=tk_intvar; size=2; break; + case tk_word: orm=tok; localtok=tk_wordvar; size=2; break; + case tk_char: orm=tok; localtok=tk_charvar; size=1; break; + case tk_byte: orm=tok; localtok=tk_bytevar; size=1; break; + case tk_long: orm=tok; localtok=tk_longvar; size=4; break; + case tk_dword: orm=tok; localtok=tk_dwordvar; size=4; break; + case tk_float: orm=tok; localtok=tk_floatvar; size=4; break; + case tk_qword: orm=tok; localtok=tk_qwordvar; size=8; break; + case tk_double: orm=tok; localtok=tk_doublevar; size=8; break; + case tk_union: + nexttok(); + i=FALSE; + if(bitofs&&(!useunion)){ + ssize+=(bitofs+7)/8; + bitofs=0; + } + if(tok==tk_openbrace)i=TRUE; + if((tteg=CreatTeg(Global,TRUE,i))!=NULL){ + if(tok==tk_semicolon){ + if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)*tteg->numoper); + else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+tteg->numoper)); + for(i=0;inumoper;i++)(tteg->baza+i)->ofs+=ssize; + memcpy((elementteg *)(bazael+numel),tteg->baza,sizeof(struct elementteg)*tteg->numoper); + tsize=tteg->size; + if(useunion==FALSE)ssize+=tsize; + else if(unionsize<(unsigned int)(tsize))unionsize=tsize; + numel+=tteg->numoper; + free(tteg->baza); + free(tteg); + size=0; + nexttok(); + break; + } + else{ + tsize=size=tteg->size; + localtok=tk_struct; + goto dproc2; + } + } + else declareunion(); + break; + case tk_struct: + nexttok(); + case tk_id: + case tk_ID: + if(bitofs&&(!useunion)){ + ssize+=(bitofs+7)/8; + bitofs=0; + } + i=0; + if(tok==tk_openbrace||tok2==tk_openbrace){ + if(tok==tk_openbrace)i=TRUE; + if((tteg=CreatTeg(Global,FALSE,i))!=NULL){ + if(tok!=tk_semicolon){ + tsize=size=tteg->size; + localtok=tk_struct; +// printf("tok=%d %s\n",tok,itok.name); + goto dproc2; + } + else{ + if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)*tteg->numoper); + else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+tteg->numoper)); + for(i=0;inumoper;i++)(tteg->baza+i)->ofs+=ssize; + memcpy((elementteg *)(bazael+numel),tteg->baza,sizeof(struct elementteg)*tteg->numoper); + tsize=tteg->size; + if(useunion==FALSE)ssize+=tsize; + else if(unionsize<(unsigned int)(tsize))unionsize=tsize; + numel+=tteg->numoper; + free(tteg->baza); + free(tteg); + size=0; + nexttok(); + break; + } + } + datatype_expected(); + } + if(strcmp(itok.name,newteg->name)==0&&tok2==tk_openbracket){ + if(oflag==0){ + newteg->flag|=fs_constructor; + oflag|=fs_constructor; + orm=am32==FALSE?tk_word:tk_dword; + } + else if(oflag==fs_destructor){ + strcat(itok.name,"~"); + orm=tk_void; + } + goto dproc2; + } + if((tteg=FindTeg(FALSE))!=NULL||(tteg=FindTeg(TRUE))!=NULL){ + if(tok2==tk_mult){ + while(tok2==tk_mult)nexttok(); + if(am32){ + localtok=tk_dwordvar; + size=4; + orm=tk_dword; + } + else{ + localtok=tk_wordvar; + size=2; + orm=tk_word; + } + warpointerstruct(); + } + else{ + size=tteg->size; + localtok=tk_struct; + } + goto locvar; + // break; + } + default: + skipfind=LOCAL; // 쭮 쭮 ᯨ᪥ + utestInitVar=TRUE; + if((i=testInitVar())==FALSE||i==2){ //। 楤 ࠡ뢠 + skipfind=FALSE; //ࠧ + FindEndLex(); + datatype_expected(); + nexttok(); + size=0; + break; + } + oflag|=itok.flag; + npointr=itok.npointr; + if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); + orm=itok.rm; + if(tok2==tk_openbracket&&strcmp(itok.name,newteg->name)==0){ + newteg->flag|=fs_constructor; + oflag|=fs_constructor; + if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword; + } +/* if(tok==tk_openbracket){ + if(itok.npointr)orm=am32==FALSE?tk_word:tk_dword; + npointr=0; + nexttok(); + while(tok==tk_mult){ //㪠⥫ 楤 + npointr++; + nexttok(); + } + type=pointer; + }*/ + goto dproc2; + } + if(size!=0){ +locvar: + do{ + tsize=size; + skipfind=LOCAL; // 쭮 쭮 ᯨ᪥ + nexttok(); + if(tok==tk_colon){ + numt=getsizebit(size); + if(numt==0)numt=size*8-bitofs%(size*8); //(am32==0?16:32)-bitofs%(am32==0?16:32); + bitofs+=numt; + continue; + } +dproc2: + if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)); + else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1)); + if(tok!=tk_ID&&tok!=tk_id){ + utestInitVar=TRUE; + if(testInitVar()==FALSE){ //। 楤 ࠡ뢠 + idalreadydefined(); + } + else{ + oflag|=itok.flag; + npointr=itok.npointr; + if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); + if(itok.rm!=tokens)orm=itok.rm; + if(tok==tk_openbracket){ + if(itok.npointr)orm=am32==FALSE?tk_word:tk_dword; + npointr=0; + nexttok(); + while(tok==tk_mult){ //㪠⥫ 楤 + npointr++; + nexttok(); + } + type=pointer; + } + for(i=0;iname,itok.name)==0)idalreadydefined(); + } + strcpy((bazael+numel)->name,itok.name); + if(tok2==tk_openbracket&&strcmp(itok.name,newteg->name)==0){ + newteg->flag|=fs_constructor; + oflag|=fs_constructor; + if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword; + } + nexttok(); + if(tok==tk_openbracket||type==pointer)goto dproc; + if(npointr){ + idrec *nrec; + nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec)); + strcpy(nrec->recid,(bazael+numel)->name);//᪮ + nrec->newid=NULL; + nrec->npointr=(unsigned short)npointr; + nrec->flag=oflag; + nrec->line=linenumber; + nrec->file=currentfileinfo; + nrec->rectok=(bazael+numel)->tok=tk_pointer; + nrec->type=(unsigned short)orm; + tsize=2; + if(am32||(oflag&f_far))tsize=4; + goto endelteg; + } + else unuseableinput(); + } + } + else{ + for(i=0;iname,itok.name)==0){ + idalreadydefined(); + FindEndLex(); + break; + } + } + strcpy((bazael+numel)->name,itok.name/*(char *)string*/); + if(tok2==tk_openbracket&&utestInitVar==FALSE){ + if(tok==tk_id)oflag|=(comfile==file_w32?tp_stdcall:tp_pascal); //⨯ 㬮砭 + else oflag=tp_fastcall; + } +// printf("tok=%d %s\n",tok,itok.name); + nexttok(); + if(tok==tk_colon){ + numt=getsizebit(size); + if(numt==0)preerror("Bit fields must contain at least one bit"); + (bazael+numel)->ofs=ssize; + (bazael+numel)->tok=tk_bits; + (bazael+numel)->bit.siz=numt; + (bazael+numel)->bit.ofs=bitofs; + if(useunion==FALSE)bitofs+=numt; + else if(numt>bitsize)bitsize=numt; +// printf("n=%d size=%d %s\n",numel,numt,(bazael+numel)->name); + } + else if(tok==tk_openbracket){ +dproc: + idrec *nrec; + param[0]=0; + if(type==pointer)expecting(tk_closebracket); + else{ + if(npointr){ + orm=am32==FALSE?tk_word:tk_dword; + npointr=0; + } + } + skipfind=FALSE; //ࠧ + expecting(tk_openbracket); + if((oflag&f_typeproc)==tp_fastcall)declareparamreg(); + else declareparamstack(); + skipfind=LOCAL; + nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec)); + strcpy(nrec->recid,(bazael+numel)->name);//᪮ + nrec->newid=NULL; +// printf("name=%s param=%s\n",nrec->recid,param); + if(param[0]!=0)nrec->newid=BackString((char *)param); + if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword;//tk_void; + nrec->npointr=(unsigned short)npointr; + nrec->recrm=orm; + nrec->flag=oflag; + nrec->line=linenumber; + nrec->file=currentfileinfo; + nrec->count=0; + nrec->recpost=0;//itok.post; + nrec->recsize=0;//itok.size; + nrec->recsib=(am32==TRUE?CODE32:CODE16);//itok.sib; + nrec->sbuf=NULL; + if(npointr){ + nrec->rectok=(bazael+numel)->tok=tk_pointer; + nrec->type=tk_proc; + nrec->recsib=am32==FALSE?rm_d16:rm_d32; + tsize=2; + if(am32||(oflag&f_far))tsize=4; + if(bitofs&&(!useunion)){ + ssize+=(bitofs+7)/8; + bitofs=0; + } + tsize=Align(tsize,strpackcur); //new 16.03.05 14:21 + nrec->recnumber=(bazael+numel)->ofs=ssize; + if(useunion==FALSE)ssize+=tsize; + else if(unionsize<(unsigned int)(tsize))unionsize=tsize; + } + else{ + (bazael+numel)->tok=tk_proc; + nrec->rectok=tk_declare; + nrec->type=tp_ucnovn; + nrec->recsegm=NOT_DYNAMIC; + (bazael+numel)->ofs=0; + nrec->recnumber=secondcallnum++; + nrec->flag|=f_classproc; + } + (bazael+numel)->numel=1; + nexttok(); + if(tok==tk_openbracket)IsUses(nrec); +// printf("name=%s post=%08X\n",nrec->recid,nrec->recpost); + } + else{ + (bazael+numel)->rec=NULL; + (bazael+numel)->tok=localtok; +endelteg: + if(bitofs&&(!useunion)){ + ssize+=(bitofs+7)/8; + bitofs=0; + } + (bazael+numel)->ofs=ssize; + numt=1; + if(tok==tk_openblock){//[ + skipfind=FALSE; + nexttok(); + numt=doconstlongmath(); + expecting(tk_closeblock); + skipfind=LOCAL; + } + (bazael+numel)->numel=numt; +// printf("%d: unionsize=%d elemsize=%d\n",numel,unionsize,tsize*numt); + if((oflag&f_static)){ + idrec *nrec; + nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec)); + strcpy(nrec->recid,(bazael+numel)->name);//᪮ + nrec->line=linenumber; + nrec->file=currentfileinfo; + nrec->count=0; + nrec->sbuf=NULL; + nrec->recsize=tsize*numt; + nrec->recsegm=DS; + if(localtok==tk_struct){ + nrec->recsib=0; + nrec->newid=(char *)tteg; + (bazael+numel)->tok=nrec->rectok=tk_structvar; + nrec->flag=/*flag|*/tteg->flag; + if(FixUp)nrec->flag|=f_reloc; + nrec->recrm=numt; + } + else{ + nrec->newid=NULL; + nrec->npointr=(unsigned short)npointr; + nrec->recrm=(am32==FALSE?rm_d16:rm_d32); + if(FixUp)oflag|=f_reloc; + nrec->flag=oflag; + nrec->recsib=(am32==TRUE?CODE32:CODE16);//itok.sib; + nrec->rectok=localtok; + nrec->type=tp_ucnovn; + } + if(tok==tk_assign){ + skipfind=FALSE; //ࠧ + nrec->recpost=0; + if(localtok==tk_struct){ + if(alignword)alignersize+=AlignCD(DS,2); //஢ + nrec->recnumber=outptrdata; // 砫 + i=initstructvar(tteg,numt); + if(numt==0){ + numt=i/tteg->size; + if((i%tteg->size)!=0){ + numt++; + i=tteg->size-(i%tteg->size); + for(;i!=0;i--)opd(0); + i=numt*tteg->size; + } + nrec->recrm=numel; + nrec->recsize=i; + } + datasize+=i; + } + else{ + if(alignword)alignersize+=AlignCD(DS,tsize); + nrec->recnumber=outptrdata; + initglobalvar(orm,numt,tsize,variable); + datasize+=tsize*numt; + } + } + else{ + nrec->recpost=1; + if(localtok==tk_struct){ + if(numt==0){ + ZeroMassiv(); + break; + } + } + if(alignword){ //஢ + if(postsize%2==1)postsize++; + if(tsize==4&&postsize%4!=0)postsize+=2; + } + nrec->recnumber=postsize; + AddPostData(numt*tteg->size); + } + } + else{ + tsize=Align(tsize*numt,strpackcur); //new 16.03.05 14:21 + if(useunion==FALSE)ssize+=tsize; + else if(unionsize<(unsigned int)tsize)unionsize=tsize; + if(localtok==tk_struct)(bazael+numel)->nteg=tteg; + } + } + if(useunion)bitofs=0; + numel++; + } + newteg->size=ssize+unionsize; + }while(tok==tk_camma); + skipfind=FALSE; //ࠧ + seminext(); + } + };//while(tok!=tk_closebrace&&tok!=tk_eof); + if(bitofs&&useunion==FALSE)ssize+=(bitofs+7)/8; + else if(bitsize&&((unsigned int)((bitsize+7)/8)>unionsize))unionsize=(bitsize+7)/8; +// printf("bitofs=%d size=%d\n",bitofs,ssize); + if(isdestr==FALSE&&isbase>1){ + char *buf=(char *)MALLOC(16); + strcpy(buf,"(){"); + int j; + for(i=0,j=0;integ))j++; + } + if(j>1){ + strcat(buf,"};"); +int oflag,oinptr2; +char ocha2; +int oldendinptr=endinptr; +char *oinput; +idrec *nrec; + oinptr2=inptr2; + ocha2=cha2; + oinput=(char*)input; + string[0]=0; + newteg->flag|=fs_destructor; + strcpy(itok.name,newteg->name); + if(CidOrID()==tk_ID)oflag=tp_fastcall; + else oflag=(comfile==file_w32?tp_stdcall:tp_pascal); + bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1)); + strcpy((bazael+numel)->name,itok.name); + strcat((bazael+numel)->name,"~"); + itok.rec=nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec)); + strcpy(nrec->recid,itok.name);//᪮ + nrec->newid=NULL; + itok.npointr=nrec->npointr=0; + itok.rm=nrec->recrm=tk_void; + itok.flag=nrec->flag=fs_destructor|oflag|f_classproc; + nrec->line=linenumber; + nrec->file=currentfileinfo; + nrec->count=0; + itok.post=nrec->recpost=0; + itok.size=nrec->recsize=0; + itok.sib=nrec->recsib=(am32==TRUE?CODE32:CODE16); + nrec->sbuf=NULL; + (bazael+numel)->tok=tk_proc; + tok=nrec->rectok=tk_declare; + itok.type=nrec->type=tp_ucnovn; + itok.segm=nrec->recsegm=NOT_DYNAMIC; + (bazael+numel)->ofs=0; + itok.number=nrec->recnumber=secondcallnum++; + (bazael+numel)->numel=1; + numel++; + input=(unsigned char*)buf; + inptr2=1; + cha2='('; + endinptr=strlen(buf); + searchteg=newteg; + dynamic_proc(); + searchteg=NULL; + input=(unsigned char*)oinput; + inptr2=oinptr2; + cha2=ocha2; + endinptr=oldendinptr; + } + free(buf); + } + newteg->size=ssize+unionsize; + newteg->numoper=numel; + newteg->baza=bazael; + nexttok(); + if(noname==FALSE&&nameid==FALSE){ + if(tok==tk_ID||tok==tk_id){ + strcpy(newteg->name,itok.name); + AddTegToTree(newteg,Global); + } + else{ + notstructname(); + if(newteg->baza)free(newteg->baza); + free(newteg); + newteg=NULL; + } + } + return newteg; +} + +struct structteg * FindTeg(int Global,char *name) // ⥣ +{ +struct structteg *tteg; +int i; +char *tn; + if((tn=strchr(name,'@'))!=NULL)*tn=0; + tteg=(Global==TRUE?tegtree:ltegtree); + while(tteg&&(i=strcmp(tteg->name,name))!=0)tteg=(i<0?tteg->left:tteg->right); + return tteg; +} + +unsigned int SaveVal(unsigned long long val,int type) +{ +unsigned int loop=0; + switch(type){ + case tk_bytevar: + case tk_charvar: + opd(val); + break; + case tk_wordvar: + case tk_intvar: + outwordd(val); + loop++; + break; + case tk_dwordvar: + case tk_longvar: + case tk_floatvar: + outdwordd(val); + loop+=3; + break; + case tk_qwordvar: + case tk_doublevar: + outqwordd(val); + loop+=7; + break; + case tk_pointer: + if(am32){ + outdwordd(val); + loop+=3; + } + else{ + outwordd(val); + loop++; + } + break; + case tk_proc: + loop--; + break; + default: internalerror("Bad type variable"); + } + return loop; +} + +void FillTeg(unsigned long long val,unsigned int numel,struct structteg *tteg) +/*-----------------03.10.99 00:20------------------- + 묨 稭 + --------------------------------------------------*/ +{ +struct elementteg *elem=tteg->baza; +int bitofs=0; +unsigned int startstruct; + if(dbg&2)AddDataLine(1/*,variable*/); + for(unsigned int j=0;jnumoper;c++){ + if((elem+c)->ofs)outptrdata=startstruct+(elem+c)->ofs; + if(splitdata==FALSE)outptr=outptrdata; + int type=(elem+c)->tok; + if(type==tk_bits){ + opb(val,(elem+c)->bit.ofs,(elem+c)->bit.siz); + bitofs=(elem+c)->bit.ofs+(elem+c)->bit.siz; + } + else{ + if(bitofs){ + CorrectOfsBit(bitofs); + bitofs=0; + } + for(unsigned int i=0;i<(elem+c)->numel;i++){ + if(type==tk_struct||type==tk_baseclass){ + FillTeg(val,(elem+c)->numel,(struct structteg *)(elem+c)->nteg); + break; + } + SaveVal(val,type); + } + } + } + } + if(bitofs)CorrectOfsBit(bitofs); +} + +unsigned int Fill2Teg(unsigned int numel,struct structteg *tteg) +/*-----------------03.10.99 00:20------------------- + 稭 + --------------------------------------------------*/ +{ +unsigned long long hold; +struct elementteg *elem=tteg->baza; +unsigned int tnumel=0; // ⨯ +unsigned int ttype=0; // +unsigned int nums=0; // +unsigned int loop=0; // ࠧ +int type=tokens; +int bitofs=0; +unsigned int startstruct=outptrdata; + scanalltoks=FALSE; + for(;;){ + hold=0; + if(tnumel==(elem+ttype)->numel||type==tk_bits){ + tnumel=0; + ttype++; + if(ttype==tteg->numoper){ + ttype=0; + nums++; + startstruct=outptrdata; + if(nums==numel){ + scanalltoks=TRUE; + return loop; + } + } + loop=(elem+ttype)->ofs; + outptrdata=startstruct+loop; + if(splitdata==FALSE)outptr=outptrdata; + loop+=tteg->size*nums; + } + tnumel++; + type=(elem+ttype)->tok; +// puts((elem+ttype)->name); + if(type==tk_struct||type==tk_baseclass){ + tnumel=(elem+ttype)->numel; + loop+=Fill2Teg((elem+ttype)->numel,(struct structteg *)(elem+ttype)->nteg); + if(tok==tk_closebrace)break; + continue; + } + if(type==tk_proc)continue; + if((elem+ttype)->rec&&((elem+ttype)->rec->flag&f_static))continue; + if(dbg&2)AddDataLine((char)GetVarSize(type)/*,variable*/); +loopsw: + int htok=tok; +// printf("tok=%d\n",tok); + switch(tok){ + case tk_camma: + hold=0; + goto strl3; + case tk_postnumber: + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + itok.flag=0; +// goto strl1; + case tk_undefofs: +// AddUndefOff(1,itok.name); +//strl1: + tok=tk_number; + if(htok==tk_undefofs)AddUndefOff(3,itok.name); + hold+=doconstdwordmath(); + if(tok==tk_plus&&tok2==tk_postnumber&&htok!=tk_undefofs){ + nexttok(); + goto loopsw; + } + goto strl2; + case tk_minus: + case tk_number: + if(type==tk_bytevar||type==tk_wordvar||type==tk_dwordvar||type==tk_bits||type==tk_pointer){ + hold=doconstdwordmath(); + } + else if(type==tk_charvar||type==tk_intvar||type==tk_longvar){ + hold=doconstlongmath(); + } + else if(type==tk_floatvar)hold=doconstfloatmath(); + else if(type==tk_doublevar)hold=doconstdoublemath(); + else if(type==tk_qwordvar)hold=doconstqwordmath(); +// printf("tok=%d num=%08X\n",tok,hold); +strl2: + if((postnumflag&f_reloc)!=0)AddReloc(); +strl3: + if(type==tk_bits){ + opb(hold,(elem+ttype)->bit.ofs,(elem+ttype)->bit.siz); + bitofs=(elem+ttype)->bit.ofs+(elem+ttype)->bit.siz; + } + else{ + if(bitofs){ + CorrectOfsBit(bitofs); + loop+=(bitofs+7)/8; + bitofs=0; + } + loop+=SaveVal(hold,type); + } + break; + case tk_string: + if(type==tk_bytevar||type==tk_charvar){ + unsigned int i; + if((unsigned int)itok.number<(elem+ttype)->numel)i=itok.number; + else i=(elem+ttype)->numel; + tnumel=0; + for(;tnumelnumel){ + switch(itok.flag&3){ + case zero_term: + if(itok.flag&s_unicod)opd(0); + opd(0); + tnumel++; + break; + case dos_term: + if(itok.flag&s_unicod)opd(0); + opd('$'); + tnumel++; + break; + } + while(tnumel<(elem+ttype)->numel){ + opd(aligner); + tnumel++; + } + } + loop+=tnumel-1; + nexttok(); + break; + } + if(am32==FALSE){ + outwordd(addpoststring()); + if(type==tk_longvar||type==tk_dwordvar){ + loop+=2; + outword(0); + } + loop++; + } + else{ + if(type==tk_intvar||type==tk_wordvar)dwordvalexpected(); + outdwordd(addpoststring()); + loop+=3; + } + nexttok(); + break; + default: + numexpected(); + nexttok(); + break; + } + loop++; + if(tok==tk_closebrace)break; +// printf("tok=%d\n",tok); + expecting(tk_camma); + } + scanalltoks=TRUE; + if(bitofs){ + CorrectOfsBit(bitofs); + loop+=(bitofs+7)/8; + } + return loop; +} + +unsigned int initstructvar(structteg *tteg,int numel) +{ +unsigned int loop=0; + nexttok(); + switch(tok){ // 稭 + case tk_minus: + case tk_number: + if(numel==0)ZeroMassiv(); + FillTeg(doconstqwordmath(),numel,tteg); + loop=numel*tteg->size; + break; + case tk_from: // 䠩 묨 + nexttok(); + loop=dofrom(); + for(;loopsize*numel;loop++)opd(aligner); + nexttok(); + break; + case tk_extract: // ࠣ 䠩 묨 + nexttok(); + loop=doextract(); + for(;loopsize*numel;loop++)opd(aligner); + break; + case tk_openbrace: //ᨢ + nexttok(); + loop=Fill2Teg(numel,tteg); + for(;loopsize*numel;loop++)opd(aligner); + if(tok!=tk_closebrace){ + preerror("extra parameter at initialization of structure"); + while(tok!=tk_closebrace&&tok!=tk_eof)nexttok(); + } + nexttok(); + break; + default: +// printf("tok=%d\n",tok); + numexpected(); nexttok(); break; + } + return loop; +} + +void InitStruct2(unsigned int flag,structteg *tteg) //樠஢ +{ +struct idrec *newrec=NULL,*ptr; +int numel,count; +char done=0,dynamic; +unsigned int loop; + while(tok!=tk_eof&&done==0){ + loop=0; +// printf("3 tok=%d %s\n",tok,itok.name); + switch(tok){ + case tk_id: + case tk_ID: //樠஢ +//뤥 + newrec=(struct idrec *)MALLOC(sizeof(struct idrec)); + +// if(strcmp(itok.name,"ccchrg")==0)printf("rec=%08X teg=%08X size=%X %s\n",newrec,tteg,sizeof(idrec),itok.name); + + ptr=((flag&f_static)==0?treestart:staticlist); //砫 ॢ + if(ptr==NULL)((flag&f_static)==0?treestart:staticlist)=newrec;//砫 ॢ + else{ // ப ॢ + while(((numel=strcmp(ptr->recid,itok.name))<0&&ptr->left!=NULL)||(numel>0&&ptr->right!=NULL)){ + ptr=(numel<0?ptr->left:ptr->right); + } + (numel<0?ptr->left:ptr->right)=newrec; //ப + } + newrec->recsib=0; + strcpy(newrec->recid,itok.name);//᪮ + newrec->newid=(char *)tteg; + newrec->left=NULL; + newrec->right=NULL; + newrec->rectok=tk_structvar; + newrec->flag=flag|tteg->flag; + newrec->line=linenumber; + newrec->file=currentfileinfo; + newrec->type=tp_gvar; + if(FixUp)newrec->flag|=f_reloc; + numel=1; + nexttok(); + if(tok==tk_openblock){//[ + nexttok(); + if(tok!=tk_closeblock)numel=doconstlongmath(); //᫮ ⮢ + else numel=0; + expecting(tk_closeblock);//] + } + newrec->recrm=numel; + newrec->recsize=numel*tteg->size; + dynamic=FALSE; + if(tok==tk_assign||notpost==TRUE){//= + if(useStartup==TRUE&&tok!=tk_assign&&numel!=0){ + if(SaveStruct(numel*tteg->size,newrec)==TRUE)break; + } + if(alignword&&(!dynamic_flag))alignersize+=AlignCD(DS,2); //஢ +// NotPostUnion(); + itok.rec=newrec; + if((count=FindOff((unsigned char *)newrec->recid,DS))==0){ + if(dynamic_flag)dynamic=DYNAMIC_VAR; + } + else if(dynamic_flag)dynamic=USED_DIN_VAR; + newrec->recnumber=(dynamic==0?outptrdata:0); // 砫 + newrec->recpost=dynamic; + if(notpost==TRUE&&tok!=tk_assign){ + if(numel==0)ZeroMassiv(); + for(;loopsize*numel;loop++)opd(aligner); + datasize+=loop; + break; + } + if(dynamic)newrec->sbuf=dynamic_var(); + else{ + loop=initstructvar(tteg,numel); + if(numel==0){ + numel=loop/tteg->size; + if((loop%tteg->size)!=0){ + numel++; + int i=tteg->size-(loop%tteg->size); + for(;i!=0;i--)opd(0); + loop=numel*tteg->size; + } + newrec->recrm=numel; + newrec->recsize=loop; + } + datasize+=loop; + } + } + else{ + if(numel==0){ + ZeroMassiv(); + break; + } + if(CheckUseAsUndef((unsigned char *)newrec->recid)==0&&dynamic_flag)dynamic=TRUE; + switch(tok){ //樠஢ + default: expected(';'); + case tk_semicolon: done=1;// ; + case tk_camma: //, post global type +// long longpostsize; + if(useStartup==TRUE){ + if(SaveStruct(numel*tteg->size,newrec)==TRUE){ + nexttok(); + break; + } + } + newrec->recpost=dynamic+1; + loop=numel*tteg->size; + if((flag&f_extern)==0&&dynamic==0){ + if(alignword){ //஢ + if(postsize%2==1)postsize++; + } + newrec->recnumber=postsize; + } + else newrec->recnumber=externnum++; + count=FindOff((unsigned char *)newrec->recid,VARPOST); + if((flag&f_extern)==0&&dynamic==0) + /*-----------------10.09.02 23:21------------------- + 맮 ᫥ FindOff + --------------------------------------------------*/ + AddPostData(loop); + nexttok(); + break; + } + } + newrec->count=count; + break; + case tk_proc: + case tk_qwordvar: + case tk_doublevar: + case tk_floatvar: + case tk_dwordvar: + case tk_longvar: + case tk_charvar: + case tk_intvar: + case tk_bytevar: + case tk_wordvar: idalreadydefined(); nexttok(); break; + default: + if(newrec)expected(';'); + else errstruct(); + FindStopTok(); + case tk_semicolon: done=1; + case tk_camma: nexttok(); break; + } + } + dopoststrings(); +} + +void InitStruct() //樠஢ +{ +struct structteg *tteg; +unsigned int flag; +//if(debug)puts("start init struct"); + flag=itok.flag; + if(fstatic){ + flag|=f_static; + fstatic=FALSE; + } + if(tok==tk_struct)nexttok(); + else if(tok2!=tk_id&&tok2!=tk_ID){ + if(tok2==tk_dblcolon){ + itok.flag=f_classproc; + itok.rm=am32==FALSE?tk_word:tk_dword;//tk_void; + itok.npointr=0; + doclassproc(0/*comfile==file_w32?tk_stdcall:tk_pascal 18.10.05 10:52*/); + return; + } + notstructname(); + } + tteg=FindTeg(TRUE); + if(tteg==NULL){ + if(tok==tk_openbrace||tok2==tk_openbrace||tok==tk_colon||tok2==tk_colon) + tteg=CreatTeg(TRUE); // ᮧ ⥣ + else{ + while(tok!=tk_semicolon&&tok!=tk_eof)nexttok(); + tegnotfound(); + return; + } + } + else{ + if(tok2==tk_openbrace)idalreadydefined(); + nexttok(); + } + InitStruct2(flag,tteg); +} + +unsigned long LocalStruct2(int flag,int *localline,int binptr,char bcha,structteg *tteg) //樠஢ +{ +int numel,first=FALSE; +struct localrec *newrec; +unsigned long size=0; + skipfind=TRUE; // ᪠ 쭮 ॢ + do{ + if(first!=FALSE){ + binptr=inptr2; + bcha=cha2; + nexttok(); + } + first=TRUE; + if(tok!=tk_ID&&tok!=tk_id)idalreadydefined(); + else{ //樠஢ + numel=1; + newrec=addlocalvar((char *)string,tk_structvar,localsize); + newrec->rec.newid=(char *)tteg; + newrec->rec.flag=tteg->flag; + newrec->rec.type=tp_localvar; + nexttok(); + if(tok==tk_openblock){//[ + skipfind=FALSE; + nexttok(); + numel=doconstlongmath(); //᫮ ⮢ + skipfind=TRUE; + expecting(tk_closeblock);//] + } + newrec->rec.recrm=numel; + size=numel*tteg->size; + newrec->rec.recsize=size; + if(flag&f_static){ +// if(bcha==0)not_union_static(); + if(tok==tk_assign){ +// newrec->rec.rectok=tk_structvar; + newrec->rec.recnumber=0; + newrec->rec.recpost=DYNAMIC_VAR; +// newrec->rec.recsize=tteg->size; +// newrec->rec.recrm=numel; + newrec->rec.line=linenumber; + newrec->rec.file=currentfileinfo; + newrec->rec.npointr=0; + newrec->rec.sbuf=dynamic_var(); + newrec->rec.recsib=newrec->rec.type=tp_gvar; + } + else{ + newrec->rec.recpost=TRUE; + if(alignword){ //஢ + if(postsize%2==1)postsize++; + } + newrec->rec.recnumber=postsize; + AddPostData(size); + } + size=0; + } + else{ + size=Align(size,(am32==FALSE?2:4)); + newrec->rec.recpost=LOCAL; + newrec->rec.recnumber=-localsize-size; +// localsize+=size; + if(tok==tk_assign){ + if(*localline==0)*localline=linenumber; + AddBackBuf(binptr,bcha); + } + } + } + localsize+=size; + }while(tok==tk_camma); + skipfind=FALSE; // ᪠ 쭮 ॢ +// localsize+=size; + itok.name[0]=0; + seminext(); + return size; +} + +unsigned long LocalStruct(int flag,int *localline) //樠஢ +{ +struct structteg *tteg; +int binptr; +char bcha; +structteg *osearchteg; + osearchteg=searchteg; + searchteg=NULL; + skipfind=TRUE; // ᪠ 쭮 ॢ + if(tok==tk_struct)nexttok(); + binptr=inptr2; + bcha=cha2; + if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){ + skipfind=FALSE; + if(tok==tk_openbrace||tok2==tk_openbrace){ + tteg=CreatTeg(FALSE); // ᮧ ⥣ + } + else{ + while(tok!=tk_semicolon&&tok!=tk_eof)nexttok(); + tegnotfound(); + searchteg=osearchteg; + return 0; + } + } + else{ + searchteg=osearchteg; + if(tok2==tk_openbrace){ + idalreadydefined(); + SkipBlock2(); + return 0; + } + nexttok(); + if(tok!=tk_id&&tok!=tk_ID){ + notstructname(); + FindStopTok(); + return 0; + } + } + searchteg=osearchteg; + return LocalStruct2(flag,localline,binptr,bcha,tteg); +} + +void dostruct() +{ +struct structteg *tteg; +int numel; +int usenumstr; +SINFO rstr; +char *ofsst=NULL; +int oneloop=FALSE; +unsigned long hnum; +unsigned int num,sized=0,sign=FALSE; +unsigned long adr; +int localstr=FALSE; +int poststr; +int flagstr; +struct idrec *ptrs; + if(tok2==tk_assign){ + switch(ScanTok3()){ + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + ptrs=itok.rec; + if(ptrs->recpost==LOCAL){ + if(ESPloc&&am32){ + itok.rm=rm_mod10|rm_sib; + itok.sib=0x24; + itok.number+=addESP; + } + else{ + itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + itok.segm=SS; + itok.post=0; + compressoffset(&itok); + } + else{ + itok.segm=DS; + itok.rm=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + itok.post=ptrs->recpost; + } + itok.sib=(am32==FALSE?CODE16:CODE32); + itok.flag=ptrs->flag; + switch(itok.size){ + case 1: + tok=tk_bytevar; + dobytevar(0); + break; + case 2: + case 3: + tok=tk_wordvar; + do_d_wordvar(0,r16); + break; + case 4: + case 5: + case 6: + case 7: + tok=tk_dwordvar; + do_d_wordvar(0,r32); + break; + default: + tok=tk_qwordvar; + doqwordvar(); + break; + } + return; + } + } + adr=itok.number; + numel=itok.rm; //᫮ + usenumstr=itok.post; //뫮 㪠 + if(itok.type==tp_classvar){ + tteg=(structteg *)itok.rec; + poststr=0; + flagstr=f_useidx; + } + else{ + ptrs=itok.rec; + tteg=(structteg *)ptrs->newid; + if(ptrs->recpost==LOCAL)localstr=TRUE; + poststr=ptrs->recpost; + flagstr=ptrs->flag; + } + rstr=strinf; + strinf.bufstr=NULL; + num=itok.size; +// if(bufrm)printf("num=%d %s\n",adr,bufrm); + nexttok(); + if(tok==tk_assign){ + getoperand(); +int starts=0; //ᬥ饭 + if(tok==tk_int||tok==tk_word){ + sized=2; + getoperand(); + } + else if(tok==tk_long||tok==tk_dword){ + sized=4; + getoperand(); + } + else if(tok==tk_char||tok==tk_byte){ + sized=1; + getoperand(); + } + switch(tok){ + case tk_charvar: + case tk_bytevar: + case tk_intvar: + case tk_wordvar: + case tk_longvar: + case tk_dwordvar: + int razr,retreg; + ITOK wtok; + char *wbuf; + wbuf=bufrm; + bufrm=NULL; + wtok=itok; + SINFO wstr; + wstr=strinf; + strinf.bufstr=NULL; + if((retreg=CheckIDZReg(itok.name,AX,razr=GetVarSize(tok)))!=NOINREG){ + GenRegToReg(AX,retreg,razr); + IDZToReg(itok.name,AX,razr); + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + if(sized){ + switch(razr){ + case r8: tok=tk_beg; break; + case r16: tok=tk_reg; break; + case r32: tok=tk_reg32; break; + } + itok.number=0; + goto convr; + } + break; + } + IDZToReg(itok.name,AX,razr); + if(sized==0){ + switch(tok){ + case tk_charvar: + case tk_bytevar: + getintoal(tok,&wtok,wbuf,&wstr); + sized=1; + break; + case tk_intvar: + sign=TRUE; + case tk_wordvar: + getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,r16); + sized=2; + break; + case tk_longvar: + sign=TRUE; + case tk_dwordvar: + getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,r32); + sized=4; + break; + } + } + else{ +convr: + switch(sized){ + case 1: + getintoal(tok,&wtok,wbuf,&wstr); + break; + case 2: + getinto_e_ax(0,tok,&wtok,wbuf,&wstr,r16); + break; + case 4: + getinto_e_ax(0,tok,&wtok,wbuf,&wstr,r32); + break; + } + } + if(usenumstr!=FALSE){ +// num/=ptrs->recrm; //㪠 - + num=tteg->size; + if(strinf.bufstr==NULL)starts=num*numel; + } + num/=sized; + goto fillstr; + case tk_minus: + nexttok(); + if(tok!=tk_number){ + errstruct(); + break; + } + itok.number=-itok.number; + case tk_number: + if(sized==0){ + sized=4; + if(itok.number<65536)sized=2; + if(itok.number<256)sized=1; + } + if(usenumstr!=FALSE){ +// num/=ptrs->recrm; //㪠 - + num=tteg->size; + if(strinf.bufstr==NULL)starts=num*numel; + } + if(strinf.bufstr==NULL){ + if(optimizespeed==TRUE){ + if(sized==1&&(num%2)==0){ + sized=2; + itok.number=(itok.number&255)|((itok.number<<8)&0xFF00); + } + if(chip>2&&sized==2&&(num%4)==0){ + sized=4; + itok.number=(itok.number&0xFFFF)|(itok.number<<16); + } + } + else{ + if(am32==FALSE){ + if(sized==1&&((num<7&&(num%2)==0)||(itok.number==0&&num==8))){ + sized=2; + itok.number=(itok.number&255)|((itok.number<<8)&0xFF00); + } + } + else if(chip>2&&sized!=4&&(num%4)==0&&itok.number==0)sized=4; + } + } + num/=sized; + if(num==1){ + oneloop++; + hnum=itok.number; + } + else if(num==2&&sized==2&&chip>2){ + oneloop++; + hnum=(itok.number&0xFFFF)|(itok.number<<16); + sized=4; + num=1; + } + else if(num==4&&sized==1&&chip>2){ + oneloop++; + itok.number&=255; + hnum=itok.number|(itok.number<<8)|(itok.number<<16)|(itok.number<<24); + sized=4; + num=1; + } + else{ + if(sized==1){ + if(itok.number==0)outword(0x00B0); + else{ + op(0xB0); + op(itok.number); + } + ConstToReg(itok.number,AX,r8); + } + else MovRegNum(sized,0,itok.number,EAX); + } +fillstr: +// itok.number=ptrs->recnumber; + itok.number=adr; + if(rstr.bufstr==NULL)itok.number+=starts; + itok.sib=(am32==FALSE?CODE16:CODE32); + if(localstr){ + if(comfile!=file_w32&&oneloop==FALSE){ + pushss(); + popes(); + } + if(ESPloc&&am32){ + itok.rm=rm_mod10|rm_sib; + itok.sib=0x24; + itok.number+=addESP; + } + else{ + itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + itok.segm=SS; + tok=tk_rmnumber; + itok.post=0; + itok.size=tteg->size; + compressoffset(&itok); + if(rstr.bufstr!=NULL)CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX); + } + else{ + if(comfile!=file_w32&&oneloop==FALSE){ + pushds(); + popes(); + } + itok.post=poststr; + itok.segm=DS; + itok.rm=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + itok.rec=NULL;//ptrs; + if(rstr.bufstr==NULL){ + if(itok.post!=0)tok=tk_postnumber; + else tok=tk_number; + } + else{ +// printf("bufrm=%s rstr=%s\n",bufrm,rstr.bufstr); + CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX); +// puts("end rm"); + tok=tk_rmnumber; + itok.size=tteg->size; // ???? trap + } + } + itok.flag=flagstr; + if(oneloop){ + switch(sized){ + case 1: + outseg(&itok,2); + op(0xC6); + op(itok.rm); + outaddress(&itok); + op(hnum); + break; + case 2: + case 4: + op66(sized); + if(hnum==0){ + outseg(&itok,2); + op(0x83); + op(itok.rm+0x20); + outaddress(&itok); + op(0); + break; + } + if((sized==4&&hnum==0xFFFFFFFF)||(sized==2&&hnum==0xFFFF)){ + outseg(&itok,2); + op(0x83); + op(itok.rm+0x8); + outaddress(&itok); + op(0xFF); + break; + } + if(optimizespeed==0&&sized==4&&short_ok(hnum,TRUE)){ + op(0x6A); + op(hnum); //push short number + op66(sized); + outseg(&itok,2); + op(0x8f); + op(itok.rm); + outaddress(&itok); + break; + } + outseg(&itok,2); + op(0xC7); //mov word[],number + op(itok.rm); + outaddress(&itok); + if(sized==2)outword(hnum); + else outdword(hnum); + break; + } + } + else{ + warningreg(regs[am32][DI]); + getintoreg_32(DI,(am32+1)*2,0,&ofsst); + if(num<=2||(num<=4&&(!optimizespeed))){ + for(unsigned int i=0;inewid; + if(ptrs->recpost==LOCAL)localstr2=TRUE; + poststr2=ptrs->recpost; + flagstr2=ptrs->flag; + } + num2=itok.size; +// ptrs2=itok.rec; +// tteg2=(structteg *)ptrs2->newid; +// numel2=itok.rm; //᫮ +// num2=tteg2->size; + if(usenumstr2!=FALSE){ + num2=tteg->size; + if(strinf.bufstr==NULL)starts=num2*numel2; + } +// if(itok.post==FALSE)num2*=ptrs2->recrm; // 㪠 - +// else if(strinf.bufstr==NULL)starts=num2*numel2; + if(strinf.bufstr==NULL)itok.number+=starts; + itok.sib=(am32==FALSE?CODE16:CODE32); + if(localstr2){ + itok.rm=rm_mod10; + if(strinf.bufstr==NULL){ + if(ESPloc&&am32){ + itok.rm|=rm_sib; + itok.sib=0x24; + } + else{ + itok.rm|=(am32==FALSE?rm_BP:rm_EBP); + } + } + else{ + CheckAllMassiv(bufrm,2,&strinf); + if(am32==FALSE)itok.rm|=rm_BPSI; + else{ + itok.sib=(ESPloc?0x34:0x35); + itok.rm=4|rm_mod10; + } + } + itok.segm=SS; + if(ESPloc&&am32)itok.number+=addESP; +// else itok.number-=localsize; + tok=tk_rmnumber; + itok.size=tteg2->size; + itok.post=0; + compressoffset(&itok); + } + else{ + itok.post=poststr2; + itok.rm=(am32==FALSE?rm_d16:rm_d32); //22.11.04 09:22//⠭ 㬮砭 + if(strinf.bufstr==NULL){ + if(itok.post==TRUE)tok=tk_postnumber; + else tok=tk_number; + } + else{ + CheckAllMassiv(bufrm,2,&strinf); + itok.rm=rm_mod10|(am32==FALSE?rm_SI:6); + tok=tk_rmnumber; + itok.size=tteg2->size; + } + itok.segm=DS; + } +///!new + itok.flag=flagstr2; + warningreg(regs[am32][SI]); +///!new +// printf("tok=%d rm=%08X %s",tok,itok.rm,itok.name); + getintoreg_32(SI,(am32+1)*2,0,&ofsst); + ClearReg(SI); + num=tteg->size; + starts=0; + if(usenumstr==FALSE)num*=tteg->size; //ptrs->recrm; // 㪠 - + else if(rstr.bufstr==NULL)starts=num*numel; + itok.number=adr;//ptrs->recnumber; + if(rstr.bufstr==NULL)itok.number+=starts; + itok.sib=(am32==FALSE?CODE16:CODE32); + if(localstr){ +// if(ptrs->recpost==LOCAL){ + if(ESPloc&&am32){ + itok.rm=rm_mod10|rm_sib; + itok.sib=0x24; + itok.number+=addESP; + } + else{ + itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + itok.segm=SS; + tok=tk_rmnumber; + itok.size=tteg->size; + itok.post=0; + compressoffset(&itok); + if(rstr.bufstr!=NULL)CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX); + } + else{ + itok.post=poststr;//ptrs->recpost; + itok.segm=DS; + itok.rm=(am32==FALSE?rm_d16:rm_d32); //⠭ 㬮砭 + if(rstr.bufstr==NULL){ + if(itok.post==TRUE)tok=tk_postnumber; + else tok=tk_number; + } + else{ + CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX); + tok=tk_rmnumber; + itok.size=tteg->size; + } + } +///!new + itok.flag=flagstr;//ptrs->flag; + warningreg(regs[am32][DI]); + if(num2>num)warnsize(); + ClearReg(DI); +///!new + usenumstr2=DS; + if(poststr2==LOCAL)usenumstr2=SS; + getintoreg_32(DI,(am32+1)*2,0,&ofsst); + num=num2; + sized=1; + if(optimizespeed){ + if((num%2)==0)sized=2; + if(chip>2&&(num%4)==0)sized=4; + } + else{ + if(am32==FALSE){ + if((num%2)==0)sized=2; + } + else{ + if(chip>2&&(num%4)==0)sized=4; + } + } + num/=sized; +///!new + if(num<=2||(num<=4&&(!optimizespeed&&usenumstr2!=SS))){ + for(unsigned int i=0;irecpost==LOCAL)pushss(); + else pushds(); + popes(); + } + op(0xF3); // REPZ + if(usenumstr2==SS)op(0x36); + if(sized==1)movsb(); + else if(sized==2)movsw(); + else movsd(); + } + break; + default: errstruct(); + } + } + else{ + nexttok(); + errstruct(); + } + if(ofsst)free(ofsst); +} + +int SaveStruct(int size,idrec *newrec) +{ +int i=0; + if((startStartup+size)recnumber=startStartup; // 砫 + newrec->recpost=FALSE; + startStartup+=size; + return TRUE; + } + } + return FALSE; +} + +int CheckAsmName(char *name) +{ +char buf[IDLENGTH]; + strcpy(buf,name); + strupr(buf); + return FastSearch((unsigned char *)asmMnem,ofsmnem,0,buf); +} + +void FastTok(int mode,int *tok4,ITOK *itok4) +{ +int useme; +int next=1; + *tok4=tokens; + itok4->type=tp_ucnovn; + whitespace(); //ய ᨬ + if(isalpha(cha)||(cha=='_')||cha>=0x80){ //䨪 + if(mode==1){ + int i=0; + do{ + itok4->name[i++]=cha; + nextchar(); + }while(CheckChar2()==TRUE&&iname[i]=0; + } + while(CheckChar2()==TRUE)nextchar(); // ᫮ + *tok4=tk_id; + return; + } + if(isdigit(cha)){//᫠ + if(mode==1){ + inptr--; + itok4->lnumber=scannumber(&itok4->rm); + } + else{ + do{ + nextchar(); + }while(isdigit(cha)); + } + *tok4=tk_number; + return; + } + else switch(cha){ + case '\"': + nextchar(); //ப ⠭ + while(cha!='\"'&&!endoffile){ + convert_char(); + nextchar(); + } + *tok4=tk_string; + break; + case '\'': //ᨬ쭠 ⠭ 1 ᨬ + nextchar(); + while(cha!='\''&&!endoffile){ // special character + convert_char(); + nextchar(); + } + break; + case '/': nextchar(); + switch(cha){ + case '*': nextchar(); //ᮬ਩ + useme=1; + if(mode==2)itok4->number=inptr-2; + while(!endoffile&&useme>0){ + whitespace(); + if(cha=='*'){ + nextchar(); + if(cha=='/')useme--; + else continue; + } + else if(cha=='/'){ + nextchar(); + if(cha=='*')useme++; + else continue; + } + nextchar(); + } + if(mode==2)*tok4=tk_comment2; + else FastTok(mode,tok4,itok4); + if(endoffile)*tok4=tk_eof; + return; + case '/': + if(mode==2)itok4->number=inptr-2; + do{ + nextchar(); + }while(!endoffile&&cha!=13); //ப + if(endoffile)*tok4=tk_eof; + if(mode==2)*tok4=tk_comment1; + else FastTok(mode,tok4,itok4); + return; + } + break; + case '#': + case '?': + nextchar(); +// tokscan(&tok,&itok,string); + FastTok(1,tok4,itok4); +// if((itok.number=GetDirective((char *)string))!=-1){ + if(*tok4==tk_id&&(itok4->number=GetDirective(itok4->name))!=-1){ + *tok4=tk_question; + } + return; + case ';': *tok4=tk_semicolon; break; + case '[': *tok4=tk_openblock; break; + case ']': *tok4=tk_closeblock; break; + case '(': *tok4=tk_openbracket; break; + case ')': *tok4=tk_closebracket; break; + case '{': *tok4=tk_openbrace; break; + case '}': *tok4=tk_closebrace; break; + case ',': *tok4=tk_camma; break; + case ':': *tok4=tk_colon; break; + case 26: *tok4=tk_eof; return; + case 13: *tok4=tk_endline; break; + case '\\': + nextchar(); + if(cha==13){ + FastTok(mode,tok4,itok4); + if(tok==tk_endline)FastTok(mode,tok4,itok4); + return; + } + break; + case '!': + nextchar(); + if(cha=='='){ + *tok4=tk_notequal; //!= + itok4->type=tp_compare; + } + else{ + *tok4=tk_not; + next=0; + } + break; + case '=': + nextchar(); + if(cha=='='){ + *tok4=tk_equalto; //== + itok4->type=tp_compare; + } + else{ + *tok4=tk_assign; //᢮ + next=0; + } + break; + case '>': + nextchar(); + switch(cha){ + case '>': + nextchar(); + if(cha=='=')*tok4=tk_rrequals; //ᤢ ࠢ ᢮ + else{ + *tok4=tk_rr; //ᤢ ࠢ + next=0; + itok4->type=tp_opperand; + } + break; + case '<': *tok4=tk_swap; break; // + case '=': *tok4=tk_greaterequal; itok4->type=tp_compare; break; // ࠢ + default: *tok4=tk_greater; next=0; itok4->type=tp_compare; break; // + } + break; + case '<': + nextchar(); + switch(cha){ + case '<': + nextchar(); + if(cha=='=')*tok4=tk_llequals; //ᤢ ᢮ + else{ + *tok4=tk_ll; //ᤢ + next=0; + itok4->type=tp_opperand; + } + break; + case '>': *tok4=tk_notequal; itok4->type=tp_compare; break; //!= + case '=': *tok4=tk_lessequal; itok4->type=tp_compare; break; // ࠢ + default: *tok4=tk_less; next=0; itok4->type=tp_compare; break;// + } + break; + } + if(next)nextchar(); +} + +void FindDirectiv() +//᪮७ ४⨢ +{ + inptr=inptr2; + cha=cha2; + linenumber=linenum2; + do{ + FastTok(0); + }while(tok!=tk_question&&tok!=tk_eof); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; +} + +unsigned long long scannumber(int *rm) +{ +int useme=0,binnum=0; +unsigned char c; +unsigned long long number=0; + *rm=tokens; + for(int i=inptr;;i++){ + c=input[i]; + unsigned char cc=c&(unsigned char)0x5f; + if(cc>='A'&&cc<='F'){ + if(cc=='B'&&binnum==1)binnum++; + else binnum=3; + useme=3; + } + else if(c<'0'||c>'9'){ + if(useme==0&&c=='.'&&input[i+1]!='.'){ //float + binnum=3; + useme++; + *rm=tk_double; + *(double *)&number=atof((char *)&input[inptr]); +// printf("float=%f %08X\n",*(float *)&number,*(long *)&number); + inptr=i+1; + do{ + nextchar(); + }while(isdigit(cha)); + if((cha&0x5f)!='E')break; + nextchar(); + if(isdigit(cha)||cha=='-'){ + do{ + nextchar(); + }while(isdigit(cha)); + } + break; + } + else if(cc=='H'){ //hex + useme=2; + binnum=3; + break; + } + break; + } + else if(c<'2'&&(binnum==0||binnum==2))binnum++; + } + if(binnum==2)goto cbinnum; + if(useme!=1){ + nextchar(); + if(useme==2)goto hexnum; + if(cha=='0'){ + nextchar(); + switch(cha&0x5f){ + case 'X': // hexadecimal number + nextchar(); +hexnum: + while(isxdigit(cha)){ + number*=16; + if(isdigit(cha))number+=cha-'0'; + else number+=(cha&0x5f)-'7'; + nextchar(); + } + if(useme==2)nextchar(); + useme++; + break; + case 'B': // binary number +cbinnum: + nextchar(); + while(cha=='0'||cha=='1'){ + number=number*2+(cha-'0'); + nextchar(); + } + if(binnum==2)nextchar(); + else useme++; + break; + case 'O': // octal number + nextchar(); + while(cha>='0'&&cha<='7'){ + number=number*8+(cha-'0'); + nextchar(); + } + useme++; + break; + } + } + if(useme==0||useme==3){ // decimal number + while(isdigit(cha)){ + number=number*10+(cha-'0'); + nextchar(); + } + } + } + c=(unsigned char)(cha&0x5F); + if(c=='I'){ + if(input[inptr]=='6'&&input[inptr+1]=='4'){ + inptr+=2; + nextchar(); + *rm=tk_qword; + } + } + else if(c=='L'||c=='U'||c=='F'||c=='Q'){ + if(c=='L')*rm=tk_dword; + if(c=='F'){ + *rm=tk_float; + *(float *)&number=*(double *)&number; + } + if(c=='Q')*rm=tk_qword; + nextchar(); + c=(unsigned char)(cha&0x5F); + if(c=='L'||c=='U'){ + if(c=='L')*rm=tk_dword; + nextchar(); + } + } + if(*rm==tokens){ + if(number<256)*rm=tk_byte; + else if(number<65536)*rm=tk_word; + else if(number<0x100000000LL)*rm=tk_dword; + else *rm=tk_qword; + } + return number; +} + +void tag_massiv(int *tok4,ITOK *itok4,unsigned char *string4) +{ +struct structteg *tteg; +int number,tok,rm; + tok=*tok4; + number=itok4->number; + nextchar(); +//14.09.04 18:52 + do{ + FastTok(1,tok4,itok4); + strcpy((char *)string4,itok4->name); + searchtree2(definestart,itok4,tok4,string4); + }while(*tok4==tk_endline); +/////////////////// +// printf("tok=%d %s\n",*tok4,itok4->name); + char *tn; + if((tn=strchr(itok4->name,'@'))!=NULL)*tn=0; + if((tteg=FindTeg(FALSE,itok4->name))!=NULL||(tteg=FindTeg(TRUE,itok4->name))!=NULL){ +// printf("tok=%d %s\n",*tok4,itok4->name); + itok4->number=0; + dostructvar2(tok4,itok4,tteg,string4); + rm=RegToRM(number,tok); +// printf("tok=%d rm=%d %s\n",*tok4,itok4->rm,itok4->name); + if(*tok4==tk_pointer&&itok4->type==tk_proc){ + itok4->sib=rm|rm_mod10; + itok4->flag&=~f_reloc; + } + else if(*tok4!=tk_proc&&*tok4!=tk_declare/*&&(itok4->flag&f_static)==0 䥪 ॣ*/){ + itok4->rm=rm_mod10|rm; + itok4->flag&=~f_reloc; + } + if(*tok4==tk_proc||*tok4==tk_declare||*tok4==tk_undefproc){ + structadr.sib=THIS_REG; + structadr.rm=number; + } + else if(*tok4==tk_id||*tok4==tk_ID||*tok4==tk_structvar){ + *tok4=tk_rmnumber; + itok4->segm=(splitdata==FALSE)?DS:CS; + itok4->post=0; + } + if(bufrm&&strcmp(bufrm,"&this;")==0){ + free(bufrm); + bufrm=NULL; + } +// printf("tok=%d rm=%d post=%d %s\n",*tok4,itok4->rm,itok4->post,itok4->name); +// if(strinf.bufstr)puts(strinf.bufstr); + } + else if(displaytokerrors){ + unknowntagstruct(itok4->name); + *tok4=tk_number; + } +} + +int RegToRM(int number,int tok4) +{ +int rm; + if(displaytokerrors){ + if(am32==FALSE&&tok4==tk_reg32)regBXDISIBPexpected(); + else if(am32&&tok4==tk_reg)reg32expected(); + } + if(am32==FALSE){ + switch(number){ + case BX: + rm=rm_BX; + break; + case DI: + rm=rm_DI; + break; + case SI: + rm=rm_SI; + break; + case BP: + rm=rm_BP; + break; + default: + if(displaytokerrors)regBXDISIBPexpected(); + break; + } + } + else rm=number; + return rm; +} + +int CheckResName(char *name) +{ +char buf[IDLENGTH]; + strcpy(buf,name); + strlwr(buf); + return FastSearch((unsigned char *)resMnem,ofsres,3,buf); +} + +int GetTokVar2() +{ +ITOK cstok; +int i; +unsigned char ocha=cha; +unsigned int oinptr=inptr; +int oline=linenumber; +char odisplay=displaytokerrors; + displaytokerrors=0; + tokscan(&i,&cstok,string2); + displaytokerrors=odisplay; + switch(i){ + case tk_number: + cha=ocha; + inptr=oinptr; + linenumber=oline; + case tk_int: + case tk_char: + case tk_long: + case tk_short: + case tk_byte: + case tk_word: + case tk_dword: + case tk_signed: + case tk_unsigned: + return i; + } + cha=ocha; + inptr=oinptr; + linenumber=oline; + return 0; +} + +void GetTypeVar(int *tok4) +{ +static int use=0; +int i; + if(use)return; + use=1; + i=GetTokVar2(); + if(*tok4==tk_signed){ + if(i==tk_char||i==tk_int||i==tk_long){ + *tok4=i; + i=GetTokVar2(); + if(*tok4==tk_long){ + if(i==tk_long)*tok4=tk_qword; + else if(i!=tk_int&&i!=0&&displaytokerrors)unknowntype(); + } + if(*tok4==tk_int&&am32)*tok4=tk_long; + } + else if(i==tk_short){ + i=GetTokVar2(); + *tok4=tk_int; + if(i!=0&&i!=tk_int&&displaytokerrors)unknowntype(); + } + else if(i==0)*tok4=(am32==0?tk_int:tk_long); + else if(displaytokerrors)unknowntype(); + } + else if(*tok4==tk_unsigned){ + switch(i){ + case tk_char: + *tok4=tk_byte; + break; + case tk_int: + *tok4=(am32==0?tk_word:tk_dword); + break; + case tk_long: + *tok4=tk_dword; + i=GetTokVar2(); + if(i==tk_long)*tok4=tk_qword; + else if(i!=tk_int&&i!=0&&displaytokerrors)unknowntype(); + break; + case tk_short: + *tok4=tk_word; + i=GetTokVar2(); + if(i!=0&&i!=tk_int&&displaytokerrors)unknowntype(); + break; + case 0: + *tok4=(am32==0?tk_word:tk_dword); + break; + default: + if(displaytokerrors)unknowntype(); + } + } + else if(i==tk_int&&(*tok4==tk_long||*tok4==tk_short))*tok4=i; + else if(*tok4==tk_short)*tok4=tk_int; + else if(*tok4==tk_int&&(!(idasm==TRUE&&i==tk_number))&&am32)*tok4=tk_long; + else if(i==tk_long&& *tok4==tk_long)*tok4=tk_qword; + use=0; +} + +int CheckDef() +{ +int otok; + if(skipfind!=LOCAL)return FALSE; + switch(tok2){ + case tk_semicolon: + case tk_assign: + case tk_openblock: + case tk_openbracket: + case tk_camma: + case tk_openbrace: + return FALSE; + } + otok=tok; + searchtree2(definestart,&itok,&tok,string); + if(tok==otok)return FALSE; + return TRUE; +} + +/* end of TOKA.C */ diff --git a/programs/develop/cmm/tokb.cpp b/programs/develop/cmm/tokb.cpp new file mode 100644 index 0000000000..b15ec75ebe --- /dev/null +++ b/programs/develop/cmm/tokb.cpp @@ -0,0 +1,12194 @@ +#define _TOKB_ +#include "tok.h" + +char badadr[]="Bad outrm value in outaddress();"; +char CXandDX[]="CX and DX"; +char ECXandEDX[]="ECX and EDX"; +char BXandFS[]="BX and FS"; +int divexpand=FALSE; +int optnumber=FALSE; +ITOK itok,itok2,ptok; +char *pbuf; +SINFO pstr; + +LISTFLOAT *floatnum=NULL; //ᯨ᮪ float ⠭ +unsigned int numfloatconst=0; +unsigned int maxnumfloatconst; +#define STEPFLOATCONST 16 +unsigned int ofsfloatlist=0; +unsigned char idxregs[5]={ESI,EDI,EBX,EDX,255}; + +int expandvar(); +int speedmul(unsigned long num, int razr); +int leamul32(unsigned long num,int reg,int razr); +void Float2reg32(int reg,int addop=0,int reg1=idxregs[0],int reg2=idxregs[1]); +void NegReg(int razr,int reg); +int RshiftReg(int razr,int reg,int sign); +void do_e_axmath2(int sign,int razr,int expand); +int MulReg(int reg,int razr); +void DivMod(int vop,int sign,int razr,int expand); +void DivNum2(unsigned long num,int razr,int sign); +void DivNum(unsigned long num,int razr,int sign); +void ClearDX(int razr,int sign); +void doalmath2(int sign); +void num2bits(ITOK *gtok,unsigned long num,int razr); +void reg2bits(ITOK *gtok,int razr); +void cwpointr(ITOK *wtok,char *&wbuf,SINFO *wstr,int *otok,int npointr,int ureg); +int CheckAddOnly(); +void optnumadd64(unsigned long long num,int r1,int r2,int vop); +void CallExternProc(char *name); +void getinto_reg(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int reg); +void intinstack(int addop); + +extern void warningoptnum(); +extern void segoperror(); +extern void segbyteerror(); +extern void regmathoperror(); +extern void begmathoperror(); +extern void negregerror(); +extern void regbyteerror(); +extern void begworderror(); +extern void regshifterror(); +extern void regmatherror(); +extern void DevideZero(); +extern void wordnotoper(); + +unsigned long long li[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100,0x200,0x400, +0x800,0x1000,0x2000,0x4000,0x8000,0x10000,0x20000,0x40000,0x80000,0x100000, +0x200000,0x400000,0x800000,0x1000000,0x2000000,0x4000000,0x8000000,0x10000000, +0x20000000,0x40000000,0x80000000,0x100000000LL,0x200000000LL,0x400000000LL +,0x800000000LL,0x1000000000LL,0x2000000000LL,0x4000000000LL,0x8000000000LL +,0x10000000000LL,0x20000000000LL,0x40000000000LL,0x80000000000LL +,0x100000000000LL,0x200000000000LL,0x400000000000LL,0x800000000000LL +,0x1000000000000LL,0x2000000000000LL,0x4000000000000LL,0x8000000000000LL +,0x10000000000000LL,0x20000000000000LL,0x40000000000000LL,0x80000000000000LL +,0x100000000000000LL,0x200000000000000LL,0x400000000000000LL,0x800000000000000LL +,0x1000000000000000LL,0x2000000000000000LL,0x4000000000000000LL,0x8000000000000000LL}; + +unsigned long leanum[24]={3,5,9,15,25,27,45,81,75,125,135,225,243,405,729, + 375,675,1215,2187,625,1125,2025,3645,6561}; + +unsigned int numleamul[24][4]={ + {3,0,0,0},{5,0,0,0},{9,0,0,0},{3,5,0,0},{5,5,0,0},{3,9,0,0},{5,9,0,0}, + {9,9,0,0},{5,5,3,0},{5,5,5,0},{9,5,3,0},{9,5,5,0},{9,9,3,0},{9,9,5,0}, + {9,9,9,0},{5,5,5,3},{5,5,9,3},{9,9,5,3},{9,9,9,3},{5,5,5,5},{9,5,5,5}, + {9,9,5,5},{9,9,9,5},{9,9,9,9}}; + +int RmEqualReg(int reg,int rm,int sib) +{ +int rm0; +int reg1=-1,reg2=-1; + rm0=rm&0x7; + if(sib==CODE16){ + switch(rm0){ + case 0: + reg1=BX; + reg2=SI; + break; + case 1: + reg1=BX; + reg2=DI; + break; + case 2: + reg1=BP; + reg2=SI; + break; + case 3: + reg1=BP; + reg2=DI; + break; + case 4: + reg1=SI; + break; + case 5: + reg1=DI; + break; + case 6: + if((rm&0xC0)!=0)reg1=BP; + break; + case 7: + reg1=BX; + break; + } + } + else{ + if(rm0==4){ + reg1=sib&7; + reg2=(sib>>3)&7; + if(reg1==5&&(rm&0xc0)==0)reg1=-1; + if(reg2==4)reg2=-1; + } + else{ + reg1=rm0; + if(reg1==5&&(rm&0xc0)==0)reg1=-1; + } + } + if(reg==reg1||reg==reg2)return TRUE; + return FALSE; +} + +void startmul(int razr) +{ + if(razr==r8)outword(0xE08A); //mov ah,al + else{ + op66(razr); + outword(0xD08B); //mov dx,ax + warningreg(regs[razr/2-1][2]); + } +} + +void lshiftmul(int num,int razr,int reg=AX) +{ + if(razr==r8){ + if(num==1)outword(0xC002); //add al,al + else{ + if(chip==0){ + op(0xB1); //mov cl,num + op(num); + outword(0xE0D2); //shl al,cl + warningreg(begs[1]); + } + else{ + outword(0xE0C0); //shl al,num + op(num); + } + } + } + else{ + if(num==1){ + op66(razr); + op(1); + op(0xC0+reg*9); //add reg,reg + } + else{ + if(chip==0){ + op(0xB1); //mov cl,num + op(num); + op(0xD3); + op(0xE0+reg); //shl ax,cl + warningreg(begs[1]); + } + else{ + if(chip>2&&optimizespeed&&leamul32(li[num],reg,razr))return; + op66(razr); + op(0xC1); + op(0xE0+reg); //shl ax,num + op(num); + } + } + } +} + +void submul(int razr) +{ + if(razr==r8)outword(0xC42A); //sub al,ah + else{ + op66(razr); + outword(0xC22B); //sub ax,dx + } +} + +void addmul(int razr) +{ + if(razr==r8)outword(0xC402); //add al,ah + else{ + op66(razr); + outword(0xC203); //add ax,dx + } +} + +int leamul32(unsigned long num,int reg,int razr) +{ + if(num==0)return FALSE; +int vop=0,i=8*reg+4; + switch(num){ + case 9: vop+=0x40; + case 5: vop+=0x40; + case 3: vop+=0x40; + op66(razr); + op67(r32); // AX * n = LEA AX,[EAX*n+?EAX] + op(0x8d); + op(reg==BP?i|rm_mod01:i); + op(vop+9*reg); + if(reg==BP)op(0); + return TRUE; + } +// if(chip>3&&chip<7)return FALSE; // AGI 486,p5,p5mmx + switch(num){ + case 2: vop=reg; break; + case 4: vop=0x85; break; + case 8: vop=0xc5; break; + default: return FALSE; + } + op66(razr); + op67(r32); // AX * n = LEA AX,[EAX*n+?EAX] + op(0x8d); + if(vop!=0x85&&vop!=0xc5&®==BP)i|=rm_mod01; + op(i); + op(vop+8*reg); + if(vop==0x85||vop==0xc5)outdword(0L); + else if(reg==BP)op(0); + return TRUE; +} + +int speedmul32(unsigned long num,int reg,int razr) +{ +int i; + for(i=3;i<24;i++){ + if(leanum[i]==num){ + leamul32(numleamul[i][0],reg,razr); + leamul32(numleamul[i][1],reg,razr); + leamul32(numleamul[i][2],reg,razr); + leamul32(numleamul[i][3],reg,razr); + return TRUE; + } + } + for(unsigned int j=1;jnum)break; + for(i=0;i<15;i++){ + unsigned long lm=leanum[i]*v; + if(lm==num){ + leamul32(numleamul[i][0],reg,razr); + lshiftmul(j,razr,reg); + leamul32(numleamul[i][1],reg,razr); + leamul32(numleamul[i][2],reg,razr); + return TRUE; + } + } + } + if(reg==EAX)return speedmul(num,r32); + return FALSE; +} + +int speedmul(unsigned long num, int razr) // 㬭 +//ᤢ ᫮ +{ +int first,second; + for(unsigned int j=1;jnum)break; + if((num%(v-1))==0){ + second=caselong(num/(v-1)); + if(second!=NUMNUM){ + first=caselong(v); + if(first!=1){ + startmul(razr); + lshiftmul(first,razr); + submul(razr); + if(second!=0)lshiftmul(second,razr); + setzeroflag=TRUE; + return TRUE; + } + } + } + if((v+1)>num)break; + if((num%(v+1))==0){ + second=caselong(num/(v+1)); + if(second!=NUMNUM){ + first=caselong(v); + startmul(razr); + lshiftmul(first,razr); + addmul(razr); + if(second!=0)lshiftmul(second,razr); + setzeroflag=TRUE; + return TRUE; + } + } + if(num>10){ + if((v-1)>(num-1))break; + if(((num-1)%(v-1))==0){ + second=caselong((num-1)/(v-1)); + if(second!=NUMNUM&&second!=1){ + first=caselong(v); + if(first!=1){ + startmul(razr); + lshiftmul(first,razr); + submul(razr); + lshiftmul(second,razr); + addmul(razr); + setzeroflag=TRUE; + return TRUE; + } + } + } + if((v+1)>(num-1))break; + if(((num-1)%(v+1))==0){ + second=caselong((num-1)/(v+1)); + if(second!=NUMNUM){ + first=caselong(v); + startmul(razr); + lshiftmul(first,razr); + addmul(razr); + lshiftmul(second,razr); + addmul(razr); + setzeroflag=TRUE; + return TRUE; + } + } + if((v-1)>(num+1))break; + if(((num+1)%(v-1))==0){ + second=caselong((num+1)/(v-1)); + if(second!=NUMNUM){ + first=caselong(v); + if(first!=1){ + startmul(razr); + lshiftmul(first,razr); + submul(razr); + lshiftmul(second,razr); + submul(razr); + setzeroflag=TRUE; + return TRUE; + } + } + } + if((v+1)>(num+1))break; + if(((num+1)%(v+1))==0){ + second=caselong((num+1)/(v+1)); + if(second!=NUMNUM&&second!=1){ + first=caselong(v); + startmul(razr); + lshiftmul(first,razr); + addmul(razr); + lshiftmul(second,razr); + submul(razr); + setzeroflag=TRUE; + return TRUE; + } + } + } + } + return FALSE; +} + +void CheckRegForLea(int reg,int *idx,int *base, int *zoom,unsigned long *val, + unsigned int *rflag,ITOK *posttok) +{ +// printf("in:reg=%02X base=%02X idx=%02X zoom=%02X\n",reg,*base,*idx,*zoom); + for(;;){ +// printf("tok=%d flag=%08X %s\n",tok2,itok2.flag,itok2.name); +// printf("tok=%d tok2=%d %s\n",tok,tok2,itok2.name); + if((tok==tk_plus||tok==tk_minus)&&(tok2==tk_minus|| + (tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double)|| + (tok2==tk_postnumber&&posttok->post==0)||(tok==tk_plus&&tok2==tk_rmnumber&&(itok2.flag&f_useidx)==0))){ + goto con1; + } + if((tok!=tk_plus&&(!(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double))) + ||(tok2!=tk_reg32&&tok2!=tk_number)||tok2==tk_rmnumber){ + break; + } + if(tok==tk_plus&&tok2==tk_reg32&&(itok2.number==reg||(*idx!=-1&&*base!=-1))){ + break; + } + if(tok==tk_mult&&(tok2!=tk_number||*zoom!=-1||*val!=0||*idx!=-1))break; +con1: + if(tok==tk_minus){ + if(tok2==tk_postnumber||(tok2==tk_number&&(itok2.flag&f_reloc)))break; + nexttok(); + if(tok==tk_minus){ + if(tok2!=tk_number)break; + nexttok(); + *val+=itok.number; + } + else *val-=itok.number; + if(tok==tk_number)*rflag^=itok.flag; + else *posttok=itok; + } + else if(tok==tk_plus){ + nexttok(); + if(tok==tk_number){ + *val+=itok.number; + *rflag^=itok.flag; + } + else if(tok==tk_postnumber){ + *val+=itok.number; + *posttok=itok; + } + else if(tok==tk_rmnumber){ + int r1,r2,z; + ExpandRm(itok.rm,itok.sib,&z,&r1,&r2); + if(z&&*zoom>0)break; + if(r1>=0&&r2>=0&&(*idx>=0||*base>=0))break; + *val+=itok.number; + if(*zoom<=0)*zoom=z; + if(*base==-1){ + if(r1>=0){ + *base=r1; + r1=-1; + } + else{ + *base=r2; + r2=-1; + } + } + if(*idx==-1){ + if(r1>=0)*idx=r1; + else if(r2>=0)*idx=r2; + } + } + else{ + if(*base==-1)*base=itok.number; + else *idx=itok.number; + } + } + else if(tok==tk_mult){ + *zoom=0; + switch(itok2.number){ + case 8: *zoom=*zoom+1; + case 4: *zoom=*zoom+1; + case 2: *zoom=*zoom+1; + case 1: + *idx=*base; + *base=-1; + break; + case 9: *zoom=*zoom+1; + case 5: *zoom=*zoom+1; + case 3: + *zoom=*zoom+1; + *idx=*base; + break; + default: *zoom=-1; + } + if(*zoom==-1)break; + nexttok(); + } + else break; + nexttok(); + if(*base!=-1&&*idx!=-1&&tok2!=tk_number)break; + } + if(*zoom==-1&&*base==-1){ + *base=*idx; + *idx=-1; + } +// printf("out:reg=%02X base=%02X idx=%02X zoom=%02X\n",reg,*base,*idx,*zoom); +} + +int OutLea(int reg,int idx,int base, int zoom,unsigned long val, + unsigned int rflag,ITOK *posttok) +{ +int mod=rm_mod00; +int q; + if(zoom==-1)zoom=0; + if(val!=0){ + if(short_ok(val,TRUE)!=0)mod=rm_mod01; + else mod=rm_mod10; + } + if((rflag&f_reloc)!=0||posttok->post)mod=rm_mod10; + if(idx==-1){ + idx=base; + base=-1; + } + if(base==-1){ + if(zoom==0){ + op66(r32); + op67(r32); + op(0x8d); + if(idx==5&&mod==rm_mod00)mod=rm_mod01; + op((reg*8+idx)|mod); + if(idx==4)op(idx*9); + } + else{ + if(idx==4)return FALSE; + mod=rm_mod10; + op66(r32); + op67(r32); + op(0x8d); + op(reg*8+4); + op(idx*8+5+(zoom<<6)); + } + } + else{ + if(idx==4){ + if(base==-1){ idx=-1; base=4;} + else if(zoom==0){ + q=base; + base=idx; + idx=q; + } + else return FALSE; + } + if(base==5&&mod==rm_mod00){ + if(idx!=-1&&idx!=5){ + if(zoom==0){ + q=base; + base=idx; + idx=q; + } + else mod=rm_mod01; + } + else mod=rm_mod01; + } + op66(r32); + op67(r32); + op(0x8d); + op((reg*8+4)|mod); //sib + op((zoom<<6)+(idx<<3)+base); + } + if(mod==rm_mod01)op(val); + else if(mod==rm_mod10){ + if(posttok->post)setwordpost(posttok); + else if((rflag&f_reloc)!=0)AddReloc(); + outdword(val); + } + else if(mod==rm_mod00&&base==5)outdword(val); + return TRUE; +} + +int Reg32ToLea2(int reg) //⨬ ᫮ 32- ॣ஢ LEA +{ +int idx,base,zoom; +unsigned long val; +int otok,otok2,otype2; +unsigned char ocha,next; +unsigned int oinptr,rflag; +int oline; +ITOK oitok; +ITOK posttok; + if(tok!=tk_minus&&tok!=tk_plus&&tok!=tk_mult)return FALSE; + if(tok==tk_minus&&(!((tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double)||tok2==tk_postnumber)))return FALSE; + if(tok==tk_mult&&(!(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double&&(itok2.flag&f_reloc)==0)))return FALSE; + if(tok==tk_plus&&tok2!=tk_reg32&&tok2!=tk_number&&tok2!=tk_postnumber&&(!(tok2==tk_rmnumber&&(itok2.flag&f_useidx)==0)))return FALSE; + if(cur_mod)return FALSE; + posttok.post=0; + idx=zoom=-1; + base=reg; + if(tok==tk_mult){ + zoom=0; + switch(itok2.number){ + case 8: zoom++; + case 4: zoom++; + case 2: zoom++; + case 1: + idx=reg; + base=-1; + break; +//new! + case 9: zoom++; + case 5: zoom++; + case 3: +// if(!(am32==FALSE&&tok!=tk_plus&&(!(tok2==tk_minus||tok2==tk_number)))){ + if(am32){ + zoom++; + idx=base=reg; + break; + } +// end new!! + default: return FALSE; + } + if(zoom==0){ + zoom=-1; + base=reg; + idx=-1; + } + } + val=0; + rflag=0; + oinptr=inptr2; + ocha=cha2; + otok=tok; + oitok=itok; + otok2=tok2; + otype2=itok2.type; + oline=linenumber; + if(tok==tk_mult){ + nexttok(); + nexttok(); + } + CheckRegForLea(reg,&idx,&base,&zoom,&val,&rflag,&posttok); + next=0; + if(idx==-1)next=1; + if(base==-1)next|=2; + if(zoom==-1)next|=4; + if(val==0&&rflag==0&&posttok.post==0)next|=8; +// printf("next=%d\n",next); + switch(next){ + case 1: // idx=-1 Rb+N + if(base==ESP&&val==1)goto retfalse; + case 4: // zoom=-1 Rb+Ri+N + if(val<2||val>127)goto retfalse; + break; + case 2: // base=-1 Ri*Z+N + if(zoom<3){ + if(zoom==2&&val>2){ + if(val<128)goto retfalse; + break; + } + goto retfalse; + } + case 0: + case 8: // val=0 Rb+Ri*Z + break; + default: +// case 12: // val=0 zoom=-1 Rb+Ri +// case 10: // val=0 base=-1 Ri*Z +// case 13: // val=0 idx=-1 zoom=-1 Rb +// case 5: // idx=-1 zoom=-1 Rb+N +// case 3: // idx=-1 base=-1 N +// case 6: // base=-1 zoom=-1 Ri+N +// case 11: // val=0 base=-1 idx=-1 - +// case 9: // val=0 idx=-1 Rb +// case 14: // val=0 base=-1 zoom=-1 Ri +// case 7: // idx=-1 base=-1 zoom=-1 N +// case 15: // val=0 base=-1 idx=-1 zoom=-1 +retfalse: + inptr2=oinptr; + cha2=ocha; + tok=otok; + itok=oitok; + tok2=otok2; + itok2.type=(unsigned short)otype2; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + endoffile=0; + linenum2=linenumber=oline; + return FALSE; + } + if(OutLea(reg,idx,base,zoom,val,rflag,&posttok)==FALSE)goto retfalse; + ClearReg(reg); +// printf("%s (%u) Combination %d\n",(startfileinfo+currentfileinfo)->filename,linenumber,next); + return TRUE; +} + +int RegEqualToLea(int reg) +{ +int idx,base,zoom; +unsigned long val; +int otok,otok2; +unsigned char ocha,next; +unsigned int oinptr,rflag; +ITOK oitok; +ITOK oitok2; +ITOK posttok; + if(cur_mod)return FALSE; + oinptr=inptr2; + ocha=cha2; + otok=tok; + oitok=itok; + otok2=tok2; + oitok2=oitok; + base=idx=zoom=-1; + val=0; + rflag=0; + posttok.post=0; + tok=tk_plus; + CheckRegForLea(reg,&idx,&base,&zoom,&val,&rflag,&posttok); + if(tok!=tk_semicolon)goto retfalse; + if(base==-1)base=reg; + else if(idx==-1)idx=reg; + else goto retfalse; + next=0; + if(idx==-1)next=1; + if(base==-1)next|=2; + if(zoom==-1)next|=4; + if(val==0&&rflag==0&&posttok.post==0)next|=8; +// printf("base=%d idx=%d zoom=%d val=%d next=%d\n",base,idx,zoom,val,next); + if(val==0&&rflag==0&&posttok.post==0)next|=8; + switch(next){ + case 5: // idx=-1 zoom=-1 Rb+N + if(reg==EAX&&(val>127||val<0xffffff80))goto retfalse; + if(val<3||val>0xfffffffd)goto retfalse; + if(base==ESP)goto retfalse; + break; + case 4: // zoom=-1 Rb+Ri+N + if(val==1||val==0xffffffff)goto retfalse; + break; + case 0: + case 8: // val=0 Rb+Ri*Z + break; + default: +// case 13: // val=0 idx=-1 zoom=-1 Rb +// case 3: // idx=-1 base=-1 N +// case 6: // base=-1 zoom=-1 Ri+N +// case 11: // val=0 base=-1 idx=-1 - +// case 9: // val=0 idx=-1 Rb +// case 14: // val=0 base=-1 zoom=-1 Ri +// case 7: // idx=-1 base=-1 zoom=-1 N +// case 15: // val=0 base=-1 idx=-1 zoom=-1 +retfalse: + inptr2=oinptr; + cha2=ocha; + tok=otok; + itok=oitok; + tok2=otok2; + itok2=oitok2; + endoffile=0; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } +// printf("return input=%08X inptr=%08X\n",input,inptr2); + return FALSE; + } +// printf("next=%d\n",next); + if(OutLea(reg,idx,base,zoom,val,rflag,&posttok)==FALSE)goto retfalse; + return TRUE; +} + +int Reg32ToLea(int reg) //⨬ ᫮ 32- ॣ஢ LEA +{ +int idx,base,zoom; +unsigned long val; +int otok,otok2,otype2; +unsigned char ocha,next; +unsigned int oinptr,rflag; +int oline; +ITOK oitok; +ITOK posttok; + if(tok!=tk_reg32&&tok!=tk_number&&tok!=tk_postnumber&&(!(tok==tk_rmnumber&&(itok.flag&f_useidx)==0)))return FALSE; + if(cur_mod)return FALSE; + posttok.post=0; + idx=base=zoom=-1; + val=0; + rflag=0; +// printf("input=%08X inptr=%08X\n",input,inptr2); + oinptr=inptr2; + ocha=cha2; + otok=tok; + oitok=itok; + otok2=tok2; + otype2=itok2.type; + oline=linenumber; +// printf("tok=%d type=%d %s\n",tok,itok.type,itok.name); + if(tok==tk_number){ + if(itok.rm==tk_float||itok.rm==tk_double||itok.rm==tk_qword)return FALSE; + val=doconstdwordmath(); + rflag=postnumflag; + if((rflag&f_reloc)&&tok==tk_mult)goto retfalse; + } + else if(tok==tk_postnumber){ + posttok=itok; + tok=tk_number; + val=doconstdwordmath(); + if(tok==tk_mult)goto retfalse; + } + else if(tok==tk_rmnumber){ + ExpandRm(itok.rm,itok.sib,&zoom,&base,&idx); + val=itok.number; + nexttok(); + } + else{ + base=itok.number; + nexttok(); + } + if(tok==tk_mult){ + nexttok(); + if(base==-1&&tok==tk_reg32){ + if(itok.number==reg)goto retfalse; + idx=itok.number; + } + else if(base!=-1&&tok==tk_number){ + if((itok.flag&f_reloc)&&(itok.rm==tk_float||itok.rm==tk_double||itok.rm==tk_qword))goto retfalse; + idx=base; + base=-1; + val=itok.number; + } + else goto retfalse; + nexttok(); + zoom=0; + switch(val){ + case 8: zoom++; + case 4: zoom++; + case 2: zoom++; + case 1: break; +//new! + case 9: zoom++; + case 5: zoom++; + case 3: +// if(!(am32==FALSE&&tok!=tk_plus&&(!(tok2==tk_minus||tok2==tk_number)))){ + if(am32||((tok==tk_plus||tok==tk_minus)&&(tok2==tk_number||tok2==tk_minus))){ + zoom++; + base=idx; + break; + } +// end new!! + default: + goto retfalse; + } + if(zoom==0){ + zoom=-1; + base=idx; + idx=-1; + } + val=0; + } + CheckRegForLea(reg,&idx,&base,&zoom,&val,&rflag,&posttok); + next=0; + if(idx==-1)next=1; + if(base==-1)next|=2; + if(zoom==-1)next|=4; + if(val==0&&rflag==0&&posttok.post==0)next|=8; + switch(next){ + case 5: // idx=-1 zoom=-1 Rb+N + case 1: // idx=-1 Rb+N + if(base==ESP&&val==1)goto retfalse; + case 12: // val=0 zoom=-1 Rb+Ri + if(base==reg)goto retfalse; + break; + case 10: // val=0 base=-1 Ri*Z + if(optimizespeed==FALSE||idx==reg)goto retfalse; + break; + case 2: // base=-1 Ri*Z+N + if(optimizespeed)break; + if(zoom<3){ + if(zoom==2&&val>2){ + if(val<128){ + if(idx!=reg)break; + goto retfalse; + } + break; + } + if(zoom==1&&val>3&&idx!=reg)break; + goto retfalse; + } + case 0: + case 4: // zoom=-1 Rb+Ri+N + case 8: // val=0 Rb+Ri*Z + break; + default: +// case 13: // val=0 idx=-1 zoom=-1 Rb +// case 3: // idx=-1 base=-1 N +// case 6: // base=-1 zoom=-1 Ri+N +// case 11: // val=0 base=-1 idx=-1 - +// case 9: // val=0 idx=-1 Rb +// case 14: // val=0 base=-1 zoom=-1 Ri +// case 7: // idx=-1 base=-1 zoom=-1 N +// case 15: // val=0 base=-1 idx=-1 zoom=-1 +retfalse: + inptr2=oinptr; + cha2=ocha; + tok=otok; + itok=oitok; + tok2=otok2; + itok2.type=(unsigned short)otype2; + linenum2=linenumber=oline; + endoffile=0; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } +// printf("return input=%08X inptr=%08X\n",input,inptr2); + return FALSE; + } +// printf("flag=%08X\n",rflag); + if(OutLea(reg,idx,base,zoom,val,rflag,&posttok)==FALSE)goto retfalse; + ClearReg(reg); + return TRUE; +} + +void CheckRegForLea16(int reg,int *idx,int *base,unsigned long *val,unsigned int *rflag,ITOK *posttok) +{ +int endloop=FALSE; + for(;;){ + if(tok!=tk_plus&&(!(tok==tk_minus&&((tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_qword&&itok2.rm!=tk_double)||tok2==tk_postnumber))))break; + if(tok2==tk_postnumber&&(posttok->post||tok==tk_minus))break; + if(tok2==tk_reg){ + if(itok2.number==reg)endloop=TRUE; + else if(*base==-1){ + switch(itok2.number){ + case BX: + case BP: + case SI: + case DI: + *base=itok2.number; + break; + default: endloop=TRUE; break; + } + } + else if(*idx==-1){ + switch(itok2.number){ + case BX: + case BP: + if(*base==BX||*base==BP)endloop=TRUE; + else{ + *idx=*base; + *base=itok2.number; + } + break; + case SI: + case DI: + if(*base==SI||*base==DI)endloop=TRUE; + else{ + *idx=itok2.number; + } + break; + default: endloop=TRUE; break; + } + } + else break; + if(endloop)break; + nexttok(); + } + else if(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_qword&&itok2.rm!=tk_double){ + if(tok==tk_plus)*val+=itok2.number; + else *val-=itok2.number; + nexttok(); + *rflag^=itok.flag; + } + else if(tok2==tk_postnumber){ + if(posttok->post)break; + if(tok==tk_plus)*val+=itok2.number; + else *val-=itok2.number; + nexttok(); + *posttok=itok; + } + else break; + nexttok(); + } +} + +void OutLea16(int reg,int idx,int base,unsigned int val,int rflag,ITOK *posttok) +{ +int mod=rm_mod00; +int rm; + if(val!=0){ + if(short_ok(val,FALSE)!=0)mod=rm_mod01; + else mod=rm_mod10; + } + if((rflag&f_reloc)!=0||posttok->post)mod=rm_mod10; + rm=CalcRm16(base,idx); + op66(r16); + op67(r16); + op(0x8D); + op((rm+reg*8)|mod); + if(mod==rm_mod01)op(val); + else if(mod==rm_mod10){ + if(posttok->post)setwordpost(posttok); + else if((rflag&f_reloc)!=0)AddReloc(); + outword(val); + } +} + +int Reg16ToLea(int reg) //⨬ ᫮ 16- ॣ஢ LEA +{ +int idx,base; +unsigned long val; +int otok,otok2,otype2; +unsigned char ocha,next; +unsigned int oinptr,rflag; +int oline; +ITOK oitok; +ITOK posttok; + if(cur_mod)return FALSE; + posttok.post=0; +// if(tok!=tk_reg&&tok!=tk_number&&am32!=0&&tok2!=tk_plus)return FALSE; + if(!((tok==tk_reg||(tok==tk_number&&itok.rm!=tk_float&&itok.rm!=tk_double)&&tok==tk_postnumber)&&tok2==tk_plus))return FALSE; + idx=base=-1; + if(tok==tk_reg){ + if(itok.number==reg)return FALSE; + switch(itok.number){ + case BX: + case BP: + case SI: + case DI: + base=itok.number; + break; + default: return FALSE; + } + } + val=0; + rflag=0; + oinptr=inptr2; + ocha=cha2; + otok=tok; + oitok=itok; + otok2=tok2; + otype2=itok2.type; + oline=linenumber; + if(tok==tk_postnumber){ + posttok=itok; + tok=tk_number; + } + if(tok==tk_number){ + val=doconstdwordmath(); + rflag=postnumflag; + } + else nexttok(); + CheckRegForLea16(reg,&idx,&base,&val,&rflag,&posttok); + next=0; + if(idx==-1)next=1; + if(base==-1)next|=2; + if(val==0&&rflag==0&&posttok.post==0)next|=4; + switch(next){ + case 0: //base+idx+num + case 1: //base+num +// case 2: //idx+num +// case 3: //num + case 4: //base+idx +// case 6: //idx +// case 7: // + break; + case 5: //base + if(am32==0)break; + default: +retfalse: + inptr2=oinptr; + cha2=ocha; + tok=otok; + itok=oitok; + tok2=otok2; + itok2.type=(unsigned short)otype2; + linenum2=linenumber=oline; + endoffile=0; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + return FALSE; + } + OutLea16(reg,idx,base,val,rflag,&posttok); + return TRUE; +} + +int Reg16ToLea2(int reg) //⨬ ᫮ 16- ॣ஢ LEA +{ +int idx,base; +unsigned long val; +int otok,otok2,otype2; +unsigned char ocha,next; +unsigned int oinptr,rflag; +int oline; +ITOK oitok; +ITOK posttok; + if(cur_mod)return FALSE; + posttok.post=0; + if(tok==tk_plus&&((tok2==tk_reg&&itok2.number!=reg)||(tok2==tk_number&&itok2.rm!=tk_float&&itok2.rm!=tk_double))&& + (reg==BX||reg==BP||reg==SI||reg==DI)){ + val=0; + rflag=0; + oinptr=inptr2; + ocha=cha2; + otok=tok; + oitok=itok; + otok2=tok2; + otype2=itok2.type; + oline=linenumber; + idx=-1; + base=reg; + CheckRegForLea16(reg,&idx,&base,&val,&rflag,&posttok); + next=0; + if(idx==-1)next=1; + if(base==-1)next|=2; + if(val==0&&rflag==0&&posttok.post==0)next|=4; + switch(next){ + case 1: //base+num + if(val<3&&rflag==0&&posttok.post==0)goto retfalse; + case 0: //base+idx+num +// case 2: //idx+num +// case 3: //num + case 4: //base+idx +// case 6: //idx +// case 7: // + break; +// case 5: //base + default: +retfalse: + inptr2=oinptr; + cha2=ocha; + tok=otok; + itok=oitok; + tok2=otok2; + itok2.type=(unsigned short)otype2; + endoffile=0; + linenum2=linenumber=oline; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + return FALSE; + } + OutLea16(reg,idx,base,val,rflag,&posttok); + return TRUE; + } + return FALSE; +} + +int OptimNum() //⨬ ஢ ࠭ +{ +int otok,oinptr,deistv,negflag,starttok; +char ocha2; +long long val; +unsigned int flag,oflag; +int plusreloc=0; + if(optnumber==FALSE||cur_mod)return FALSE; //⨬ ⪫祭 + if(tok==tk_minus&&(itok2.flag&f_reloc))return FALSE; + deistv=0; + negflag=0; + starttok=otok=tok; + oflag=itok.flag; + oinptr=inptr2; + ocha2=cha2; + nexttok(); + flag=itok.flag; + val=itok.lnumber; + switch(otok){ + case tk_minus: + val=-val; + case tk_plus: + for(;;){ //⨬ ᫮-⠭ + nexttok(); + if((tok!=tk_plus&&tok!=tk_minus)||tok2!=tk_number|| + (tok==tk_minus&&(itok2.flag&f_reloc)&&plusreloc==0)){// 㣮 ⢨ + tok=otok; + cha2=ocha2; + inptr2=oinptr; + endoffile=0; + if(deistv==0)break; //祣 뫮 ⨬஢ + warningoptnum(); + tok=tk_plus; + itok.lnumber=val; + itok.flag|=flag; + return TRUE; + } + deistv=tok; + nexttok(); + oinptr=inptr2; + ocha2=cha2; + if(deistv==tk_minus){ + val-=itok.lnumber; + if(itok.flag&f_reloc)plusreloc--; + } + else{ + val+=itok.lnumber; + if(itok.flag&f_reloc)plusreloc++; + } + flag^=itok.flag; + } + break; + case tk_divminus: + otok=tk_div; + goto LL1; + case tk_multminus: + otok=tk_mult; +LL1: + negflag=TRUE; + case tk_div: + case tk_mult: + for(;;){ + nexttok(); + if((tok!=tk_div&&tok!=tk_mult&&tok!=tk_divminus&&tok!=tk_multminus)|| + tok2!=tk_number|| + (otok!=tok&&((val>itok2.lnumber&&(val%itok2.lnumber)!=0) + ||(valitok.lnumber)val=val/itok.lnumber; + else if(val2&&(*expand==FALSE)&&optimizespeed&&leamul32(num,reg,razr)){ + setzeroflag=FALSE; + return; + } + switch(num){ + case 0: + ZeroReg(reg,razr); + setzeroflag=TRUE; + case 1: *expand=FALSE; break; /* AX * 1 = AX */ + case 2: /* AX * 2 = ADD AX,AX */ + if(*expand==TRUE){ + if(optimizespeed==FALSE)goto num_imul; + if(sign)cwdq(razr); + else{ + op66(razr); + outword(0xD231); + } + } + op66(razr); + op(1); + op(0xC0+9*reg); // ADD reg,reg + if(*expand==TRUE){ + op66(razr); + outword(0xd283); //adc dx,0 + op(0); + ClearReg(DX); + } + setzeroflag=TRUE; + break; + default: + vop=caselong(num); + if(vop!=NUMNUM){ + if(chip<1&&razr==r16){ + if(*expand==TRUE){ + if(optimizespeed==FALSE)goto num_imul; + op(0xB1); op(vop); /* MOV CL,num */ + op66(r16); + if(sign)op(0x99); + else outword(0xD231); + outdword(0xd213c001); //ADD AX,AX ADC DX,DX + outword(0xfae2); //LOOP -6 + warningreg(regs[0][2]); + ClearReg(DX); + } + else{ + if(reg==CX)goto num_imul; + if(vop>3){ + for(;vop!=0;vop--){ + op66(r16); + op(3); //add + op(0xc0+reg*9); + } + return; + } + op(0xB1); op(vop); /* MOV CL,num */ + op(0xD3); + op(0xE0+reg); //SHL reg,CL + } + ConstToReg(vop,CL,r8); + warningreg(begs[1]); + } + else{/* SHL AX,num */ + if(*expand==TRUE){ + if(optimizespeed==FALSE)goto num_imul; +// op66(razr); + ClearDX(razr,sign); +/* if(sign)cwdq(razr); + else{ + op66(razr); + outword(0xC031); + }*/ + if(chip<3&&razr==r16){ + op(0xB1); op(vop); /* MOV CL,num */ + outdword(0xd213c001); //ADD AX,AX ADC DX,DX + outword(0xfae2); //LOOP -6 + ConstToReg(vop,CL,r8); + warningreg(begs[1]); + } + else{ + op66(razr); + op(0x0f); + outword(0xC2a4); //SHLD DX,AX,num + op(vop); + op66(razr); + outword(0xE0C1); //SHL AX,num + op(vop); + } + ClearReg(DX); + warningreg(regs[razr/2-1][2]); + } + else{ + op66(razr); + op(0xc1); + op(0xe0+reg); // SHL reg,imm8 + op(vop); + if(cpu<2)cpu=2; + } + } + setzeroflag=TRUE; + break; + } + if(chip<7&&*expand==FALSE&&optimizespeed&&speedmul32(num,reg,razr))break; +num_imul: + if((razr==r16&&chip<2)||(*expand==TRUE)){ + if(reg==AX){ + op66(razr); + op(0xB9); /* MOV CX,# */ + if((flag&f_reloc)!=0)AddReloc(); + razr==r16?outword((unsigned int)num):outdword(num); + op66(razr); + if(sign)outword(0xE9F7); /* IMUL CX */ + else outword(0xE1F7); /* MUL CX */ + ConstToReg(num,CX,razr); + warningreg(regs[razr/2-1][1]); + } + else{ + op66(r16); + op(0x90+reg); //XCHG AX,reg + op66(r16); + op(reg!=DX?0xBA:0xB9); + outword(num); //mov DX,num + op66(r16); + op(0xF7); + op(reg!=DX?0xE2:0xE1); // mul DX + op66(r16); + op(0x90+reg); //XCHG AX,reg + warningreg(regs[0][reg!=DX?2:1]); + ClearReg(DX); + } + } + else{ + if((flag&f_reloc)==0&&short_ok(num,razr/2-1))i=2; //⪠ ଠ + op66(razr); + op(0x69+i); //imul + op(0xc0+reg*9); + if(i==2)op(num); + else{ + if((flag&f_reloc)!=0)AddReloc(); + razr==r16?outword((unsigned int)num):outdword(num); + } + } + setzeroflag=FALSE; + break; + } +} + +/* --------------- byte, char, word, int math starts ----------------- */ + +long long CalcNumber(int sign) +{ +long long hold; + switch(sign){ + case 0: + hold=doconstdwordmath(); + break; + case 1: + hold=doconstlongmath(); + break; + case 2: + hold=doconstfloatmath(); + break; + case 3: + hold=doconstdoublemath(); + break; + default: + hold=doconstqwordmath(); + break; + } + return hold; +} + +int OnlyNumber(int sign) +/*-----------------11.09.00 12:44------------------- + ஢ ப ⮨ ⮫쪮 . +--------------------------------------------------*/ +{ +ITOK oitok=itok; +unsigned char ocha=cha2; +unsigned int oinptr=inptr2; +unsigned int otok2=tok2; +int otype2=itok2.type; + itok.lnumber=CalcNumber(sign); +// printf("tok=%d num=%d type=%d\n",tok,itok.number,itok.type); + if(itok.type==tp_stopper){ + return TRUE; //⮫쪮 + } + cha2=ocha; //⠭ 室 ﭨ + inptr2=oinptr; + tok2=otok2; + tok=tk_number; + itok=oitok; + itok2.type=(unsigned short)otype2; + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + return FALSE; +} + +void MultiAssignFloat(int type,int npointr=0) +{ +int otok; +ITOK wtok; +char *wbuf; +SINFO wstr; +char *ofsstr=NULL; + if(tok!=type)illegalfloat(); + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + otok=tok; + nexttok(); +// getoperand(); +int numpointr=0; + nexttok(); + if(tok==tk_float||tok==tk_double)nexttok(); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign)MultiAssignFloat(type,numpointr); + else{ + if(tok==tk_pointer)cpointr(BX,numpointr); + if(tok==tk_floatvar&&tok2==tk_semicolon){ + tok=tk_dwordvar; + do_e_axmath(1,r32,&ofsstr); + } + else doeaxfloatmath(tk_reg32,AX); + } + if(otok==tk_pointer){ + if(wtok.type==tk_proc){ + wtok.rm=wtok.sib; + if(am32)wtok.sib=CODE32; + else wtok.sib=CODE16; + compressoffset(&wtok); + } + else{ + int razr=typesize(itok.type); + if(npointr<=wtok.npointr)getpointeradr(&wtok,wbuf,&wstr,npointr-1,razr,BX); + else unuseableinput(); + wtok=itok; + } + } + if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0))){ + op66(r32); + outseg(&wtok,1); + op(0xA3); /* MOV [word],AX */ + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); //???? + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,r32,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0x89); op(wtok.rm); /* MOV [rmword],reg */ + outaddress(&wtok); + } +} + +int MultiAssign(int razr,int usereg,int npointr) +{ +int otok; +ITOK wtok; +char *wbuf; +SINFO wstr; +int sign=0,rettype,nrazr,posiblret,pointr=0; +int hnumber=0; +int ureg; +char *ofsstr=NULL; + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + otok=tok; + if(tok==tk_bits){ + usereg=EAX;//USEONLY_AX; + nrazr=r32; + rettype=tk_dword; + int i=itok.bit.siz+itok.bit.ofs; + if(i<9){ + nrazr=r8; + rettype=tk_byte; + } + else if(i<17){ + rettype=tk_word; + nrazr=r16; + } + else if(i>32)nrazr=r64; + } + else{ + nrazr=GetVarSize(tok); + switch(tok){ + case tk_beg: + ureg=itok.number; + if(ureg>3)ureg-=4; + if(usereg>ureg)usereg=ureg; + break; + case tk_reg: + case tk_reg32: + if(usereg>itok.number)usereg=itok.number; + break; + } +// if(tok==tk_beg)usereg|=USEFIRST4REG; + } + posiblret=nrazr; + if(nrazr>razr&&nrazritok.npointr){ + unuseableinput(); + } + ureg=AX; + if(tok2==tk_assign){ + ureg=hnumber=MultiAssign(razr,usereg,numpointr); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + } + else{ + if(tok==tk_pointer){ + int reg=idxregs[2]; + if(reg==ureg)reg=idxregs[1]; + cpointr(reg,numpointr); + } + if(usereg==USEALLREG){ + switch(tok){ + case tk_reg: + case tk_reg32: + usereg=itok.number; + break; + case tk_beg: + usereg=(itok.number>3?itok.number-4:itok.number); + break; + default: + usereg=EAX; + break; + } + } + switch(rettype){ + case tk_char: + case tk_byte: + if(tok2==tk_semicolon&&usereg!=0&&usereg<4){ + ureg=hnumber=usereg; +// if(tok==tk_beg&&itok.number<4)ureg=hnumber=itok.number; + getintoreg(usereg,r16,sign,&ofsstr); + } +/* if(tok2==tk_semicolon&&tok==tk_beg&&usereg<2){ + if((usereg==1&&itok.number<4)||usereg==0){ + ureg=hnumber=itok.number; + nexttok(); + break; + } + }*/ + else doalmath(sign,&ofsstr); + if(ofsstr)IDZToReg(ofsstr,usereg,r8); + break; + case tk_int: + case tk_word: + if(tok2==tk_semicolon&&usereg!=0){ + ureg=hnumber=usereg; +// if(tok==tk_reg)ureg=hnumber=itok.number; + getintoreg(usereg,r16,sign,&ofsstr); + } + else do_e_axmath(sign,r16,&ofsstr); + if(ofsstr)IDZToReg(ofsstr,usereg,r16); + break; + case tk_float: + doeaxfloatmath(tk_reg32,AX); + break; + default: + if(tok2==tk_semicolon&&usereg!=0&&tok!=tk_floatvar){ + ureg=hnumber=usereg; +// if(tok==tk_reg32)ureg=hnumber=itok.number; + getintoreg(usereg,r32,sign,&ofsstr); + } + else{ + if(tok==tk_floatvar&&tok2==tk_semicolon)tok=tk_dwordvar; + do_e_axmath(sign,r32,&ofsstr); + } + if(ofsstr)IDZToReg(ofsstr,usereg,r32); + break; + } + } + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + switch ( nrazr ) { + case r8: + posiblret=tk_byte; + break; + case r16: + posiblret=tk_word; + break; + case r32: + posiblret=tk_dword; + break; + } + convert_returnvalue(posiblret,rettype); + if(otok==tk_pointer)cwpointr(&wtok,wbuf,&wstr,&otok,npointr,ureg); + switch ( otok ) { + case tk_intvar: + case tk_wordvar: + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: +#ifdef OPTVARCONST + CheckRegToConst(hnumber,&wtok,otok>tk_wordvar?r32:r16); +#endif + KillVar(wtok.name); + AddRegVar(hnumber,razr,&wtok); + if(hnumber==0&&((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(nrazr); + outseg(&wtok,1); + op(0xA3); /* MOV [word],AX */ + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); //???? + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,nrazr,&wstr,&wtok); + op66(nrazr); + outseg(&wtok,2); + op(0x89); op(wtok.rm+hnumber*8); /* MOV [rmword],reg */ + outaddress(&wtok); + } + break; + case tk_charvar: + case tk_bytevar: +#ifdef OPTVARCONST + CheckRegToConst(hnumber,&wtok,r8); +#endif + KillVar(wtok.name); + AddRegVar(hnumber,r8,&wtok); + if(hnumber==0&&((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + outseg(&wtok,1); + op(0xA2); /* MOV [byte],AL */ + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,1,&wstr,&wtok); + outseg(&wtok,2); /* MOV [rmbyte],AL */ + op(0x88); + op(wtok.rm+hnumber*8); + outaddress(&wtok); + } + break; + case tk_bits: + if(razr!=r64){ + op66(nrazr==r32?r32:r16); + op(0x50); //push eax + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; + reg2bits(&wtok,razr); + op66(nrazr==r32?r32:r16); + op(0x58); //pop eax + } + else{ + op66(r32); + op(0x50); //push eax + int siz=wtok.bit.siz; + op66(r32); + op(0x50); //push eax + wtok.bit.siz=32-wtok.bit.ofs; + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; + reg2bits(&wtok,r32); + op66(r32); + op(0x58); //pop eax + op66(r32); //shr eax,size + outword(0xE8C1); + op(wtok.bit.siz); + wtok.bit.siz=siz+wtok.bit.ofs-32; + wtok.bit.ofs=0; + wtok.number+=4; + reg2bits(&wtok,r8); + op66(r32); + op(0x58); //pop eax + } + break; + case tk_reg: + case tk_reg32: + if(wtok.number!=hnumber){ + if(RegToReg(hnumber,wtok.number,nrazr)==NOINREG){ + op66(nrazr); + op(0x89); + op(0xC0+wtok.number+hnumber*8); //mov reg,AX + } + else waralreadinitreg(regs[nrazr/4][wtok.number],regs[nrazr/4][hnumber]); + } + break; + case tk_beg: + if(razr>r8&&wtok.number>3&&(wtok.number%4)==hnumber)preerror("register AH,BH,CH,DH should be first"); + if(wtok.number!=hnumber){ + if(RegToReg(hnumber,wtok.number,r8)==NOINREG){ + op(0x88); + op(0xC0+wtok.number+hnumber*8); //mov beg,AL + } + else waralreadinitreg(begs[wtok.number],begs[hnumber]); + } + break; + case tk_seg: + op(0x8E); /* MOV SEG,AX */ + op(0xC0+wtok.number*8+hnumber); + break; + default: + thisundefined(wtok.name); + } + return hnumber; +} + +int do_d_wordvar(int sign,int razr,int terminater) //signed or unsigned 16 or 32 bit memory variable +{ +unsigned char next=1,getfromAX=0; +unsigned int vop=0,otok,rettype,posiblret; +ITOK wtok; +char *wbuf,*rbuf; +SINFO wstr; +int retrez=0,pointr=0,hnumber=EAX; +int numpointr=0; +char *ofsstr=NULL; +int reg1=idxregs[0],reg2=idxregs[1]; +#ifdef OPTVARCONST +int initconst=FALSE; +int operand; +#endif +unsigned int oaddESP=addESP; +// sign==0?rettype=(razr==r16?tk_word:tk_dword):rettype=(razr==r16?tk_int:tk_long); + posiblret=rettype=(sign==0?(razr==r16?tk_word:tk_dword):(razr==r16?tk_int:tk_long)); + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + otok=tok; + while(RmEqualReg(hnumber,itok.rm,itok.sib))hnumber++; + nexttok(); +#ifdef OPTVARCONST + operand=tok; +#endif + switch(tok){ + case tk_assign: //= + if(!((tok2==tk_reg||tok2==tk_reg32)&&ScanTok3()==terminater)){ + ofsstr=GetLecsem(terminater); + } + if(ofsstr){ + int retreg; + if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ + GetEndLex(terminater); + if(retreg==SKIPREG)retreg=AX; + if((GetRegVar(&wtok)&(1<itok.npointr){ + unuseableinput(); + } + if(tok2==tk_assign){ + hnumber=MultiAssign(razr,USEALLREG,numpointr); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + next=0; + goto getfromax; + } + if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); + CheckMinusNum(); +// printf("tok=%d tok2=%d\n",tok,tok2); + if(itok2.type==tp_opperand){ //᫮ ࠦ + if(tok==tk_number){ //஢ઠ 㬬஢ ᥫ + if(OnlyNumber(rettype==tk_float?2:sign)){ + next=0; + itok.flag=(unsigned char)postnumflag; + if(postnumflag==0)goto loadconst; + goto numbertovar; + } + } + goto labl1; + } + else{ +// if(hnumber!=EAX&&(tok==tk_reg||tok==tk_reg32)&&itok.number==EAX)goto labl1; +#ifdef OPTVARCONST + CheckConstVar3(&tok,&itok,razr); +#endif + switch(tok){ + case tk_number: +loadconst: + if((itok.flag&f_reloc)==0){ +#ifdef OPTVARCONST + if(razr==r16)itok.lnumber&=0xffff; + else itok.lnumber&=0xffffffff; + if((initconst=Const2Var(&wtok,itok.lnumber,itok.rm))==FALSE){ + waralreadinitvar(wtok.name,itok.number); + initconst=TRUE; + break; + } +#endif + if(itok.number==0){ + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + break; + } + if((razr==r32&&itok.number==0xFFFFFFFF)||(razr==r16&&itok.number==0xFFFF)){ + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x8); + outaddress(&wtok); + op(0xFF); + break; + } + if(regoverstack&&razr==r32&&short_ok(itok.number,TRUE)){ + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + op(0x6A); + op(itok.number); //push short number + op66(razr); + outseg(&wtok,2); + op(0x8f); + op(wtok.rm); + outaddress(&wtok); + break; + } + } + case tk_postnumber: + case tk_undefofs: +numbertovar: + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xC7); //mov word[],number + op(wtok.rm); + outaddress(&wtok); + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else if((itok.flag&f_reloc)!=0)AddReloc(); + if(razr==r16){ + if(am32!=FALSE&&tok!=tk_number)dwordvalexpected(); + outword((unsigned int)itok.number); + } + else outdword(itok.number); + break; + case tk_apioffset: + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xC7); //mov word[],number + op(wtok.rm); + outaddress(&wtok); + AddApiToPost(itok.number); + break; + case tk_reg32: +// if(razr==r16)goto labl1; + case tk_reg: + if(razr==r32&&tok==tk_reg)goto labl1; +regtovar: + if((unsigned int)itok.number==0){ + getfromAX=1; + hnumber=0; + } + else{ +// if(wbuf==0&&wstr.bufstr==NULL){ + KillVar(wtok.name); + AddRegVar(itok.number,razr,&wtok); + vop++; +// } + CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2); + op66(razr); + outseg(&wtok,2); + op(0x89); + op((unsigned int)itok.number*8+wtok.rm); + outaddress(&wtok); + } + break; + case tk_seg: + if(razr==r32)goto labl1; + CheckAllMassiv(wbuf,2,&wstr,&wtok); + op66(r16); + outseg(&wtok,2); + op(0x8C); + op((unsigned int)itok.number*8+wtok.rm); + outaddress(&wtok); + if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)if(cpu<3)cpu=3; + break; + case tk_string: + CheckAllMassiv(wbuf,1,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xC7); + op(wtok.rm); + outaddress(&wtok); + if(razr==r16){ + if(am32)dwordvalexpected(); + outword(addpoststring()); + } + else outdword(addpoststring()); + break; + case tk_doublevar: + vop=4; + case tk_floatvar: + intinstack(vop); + getfromAX=0; + CheckAllMassiv(wbuf,4,&wstr,&wtok); + outseg(&wtok,2); //fistp var + op(razr==r16?0xDF:0xDB); + op(wtok.rm+0x18); + outaddress(&wtok); + if(sign==0)warningretsign(); + fwait3(); + hnumber=EAX; + break; + case tk_new: + donew(); + getfromAX=1; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + hnumber=0; + break; + case tk_delete: + dodelete(); + terminater=next=0; + getfromAX=1; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + if(ofsstr)free(ofsstr); + hnumber=0; + break; + case tk_longvar: + case tk_dwordvar: + if((rettype==tk_long||rettype==tk_dword)&&hnumber&®overstack)goto pushvar; + goto labl1; + case tk_intvar: + case tk_wordvar: + if((rettype==tk_int||rettype==tk_word)&&hnumber&®overstack){ +pushvar: + CheckAllMassiv(bufrm,razr,&strinf); + op66(razr); + outseg(&itok,2); + op(0xFF); // PUSH [dword] + op(0x30+itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x8f); + op(wtok.rm); + outaddress(&wtok); + break; + } + goto labl1; + default: +labl1: + getfromAX=1; + if(rettype==tk_char||rettype==tk_byte){ + if(hnumber==0)retrez=doalmath(sign,&ofsstr); + else{ + retrez=getintoreg(hnumber,razr,sign,&ofsstr); + posiblret=rettype; + } + } + else if(rettype==tk_int||rettype==tk_word){ + if(hnumber==0)retrez=do_e_axmath(sign,r16,&ofsstr); + else retrez=getintoreg(hnumber,r16,sign,&ofsstr); + } + else if(rettype==tk_float||rettype==tk_double){ + doeaxfloatmath(tk_fpust,AX,rettype==tk_float?0:4); + getfromAX=0; + CheckAllMassiv(wbuf,4,&wstr,&wtok); + outseg(&wtok,2); //fistp var + op(razr==r16?0xDF:0xDB); + op(wtok.rm+0x18); + outaddress(&wtok); + if(sign==0)warningretsign(); + fwait3(); + hnumber=EAX; + } + else{ + if(hnumber==0)retrez=do_e_axmath(sign,r32,&ofsstr); + else retrez=getintoreg(hnumber,r32,sign,&ofsstr); + } + next=0; + break; + } + } + if(getfromAX){ +getfromax: +#ifdef OPTVARCONST + initconst=CheckRegToConst(hnumber,&wtok,razr); +#endif + if(retrez==0)retrez=razr==r16?tk_reg:tk_reg32; + convert_returnvalue(posiblret,rettype); + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; + if(wbuf==NULL&&wstr.bufstr==NULL&&hnumber==0&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(razr); + outseg(&wtok,1); + op(0xA3); // MOV [word],AX + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); //???? + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,razr,&wstr,&wtok,reg1,reg2); +// printf("flag=%08X rm=%d num=%d post=%d sib=%d\n",wtok.flag,wtok.rm,wtok.number,wtok.post,wtok.sib); + op66(razr); + outseg(&wtok,2); + op(0x89); op(wtok.rm+hnumber*8); // MOV [rmword],AX + outaddress(&wtok); + } + if(ofsstr)IDZToReg(ofsstr,hnumber,razr); + else ClearReg(hnumber); + KillVar(wtok.name); + AddRegVar(hnumber,razr,&wtok); + } + else{ +// printf("vop=%d %s\n",vop,wtok.name); + if(vop==0)KillVar(wtok.name); + } + if(ofsstr)free(ofsstr); + break; + case tk_minusminus: vop=0x8; + case tk_plusplus: +#ifdef OPTVARCONST + initconst=UpdVarConst(&wtok,1,tk_byte,tok); +#endif + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xFF); op(vop+wtok.rm); + outaddress(&wtok); + KillVar(wtok.name); + break; + case tk_cdecl: + case tk_pascal: + case tk_fastcall: + case tk_stdcall: + vop=tok; + nexttok(); + if(tok!=tk_openbracket){ + expected('('); + FindStopTok(); + } + case tk_openbracket: //맮 楤 ॣ + param[0]=0; + int i; + i=0; + switch ( vop ) { + case tk_cdecl: + case tk_stdcall: + i=swapparam(); + break; + case tk_pascal: + doparams(); + break; + case tk_fastcall: + doregparams(); + break; + default: + if(comfile==file_w32)swapparam(); + else doparams(); + } + if(vop!=tk_cdecl)i=0; + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); + op(0xFF); op(0x10+wtok.rm); + outaddress(&wtok); + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + if(i)CorrectStack(i); + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + getoperand(am32==TRUE?EAX:BX); + if(tok==tk_float){ + getoperand(am32==TRUE?EAX:BX); + doeaxfloatmath(tk_reg32,AX); + goto axtovar; + } + if(itok2.type==tp_opperand){ + if(tok==tk_number){ + if(OnlyNumber(sign)){ + next=0; + otok=tok; + tok=tk_number; + goto num; + } + } + retrez=razr==r16?tk_reg:tk_reg32; + do_e_axmath(sign,razr,&ofsstr); + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; +axtovar: + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x01+vop); op(wtok.rm); /* ADD [anyword],AX */ + outaddress(&wtok); + next=0; + } + else{ + switch(tok){ + case tk_number: + case tk_postnumber: + case tk_undefofs: +num: +#ifdef OPTVARCONST + if(tok==tk_number&&(itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); + } +#endif + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + if(tok==tk_number&&(itok.flag&f_reloc)==0&&itok.number==1&&(vop==0||vop==0x28)){ + if(vop)vop=8; + op(0xFF); op(vop+wtok.rm); + outaddress(&wtok); + } + else if(tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&& + short_ok(itok.number,razr/2-1)){ + op(0x83); + op(vop+wtok.rm); + outaddress(&wtok); + op((unsigned int)itok.number); + } + else{ + op(0x81); + op(vop+wtok.rm); + outaddress(&wtok); + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else if((itok.flag&f_reloc)!=0)AddReloc(); + razr==r16?outword(itok.number):outdword(itok.number); + } + if(next==0)tok=otok; + break; + case tk_apioffset: + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x81); + op(vop+wtok.rm); + outaddress(&wtok); + AddApiToPost(itok.number); + break; + case tk_reg32: + if(razr==r16)goto defxor; + case tk_reg: + if(tok==tk_reg&&razr==r32)goto defxor; +#ifdef OPTVARCONST + initconst=CheckUpdRegToConst(itok.number,&wtok,operand,razr); +#endif + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x01+vop); op((unsigned int)itok.number*8+wtok.rm); + outaddress(&wtok); + break; + default: +defxor: + retrez=razr==r16?tk_reg:tk_reg32; + do_e_axmath(sign,razr,&ofsstr); + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x01+vop); op(wtok.rm); /* ADD [anyword],AX */ + outaddress(&wtok); + next=0; + break; + } + } +// puts(wtok.name); + KillVar(wtok.name); + break; + case tk_multequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper){ + if(tok==tk_number){ + if(itok.number==1)break; + if(itok.number==0){ + ZeroReg(hnumber,razr); + goto getfromax; + } +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); + } +#endif + if(hnumber==0)getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); + else getinto_reg(otok,&wtok,wbuf,&wstr,razr,hnumber); + vop=0; + RegMulNum(hnumber,itok.number,razr,sign,(int *)&vop,itok.flag); + goto getfromax; + } + } + if(hnumber==0)do_e_axmath(sign,razr,&ofsstr); + else getintoreg(hnumber,razr,sign,&ofsstr); + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar)){ + wtok.number+=addESP-oaddESP; + oaddESP=addESP; + } + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + if(hnumber==0){ + outseg(&wtok,2); + op(0xF7); // imul/mul var + if(sign)op(0x28+wtok.rm); + else op(0x20+wtok.rm); + } + else{ + outseg(&wtok,3); + outword(0xaf0f); + op(wtok.rm+hnumber*8); + } + outaddress(&wtok); + next=0; + KillVar(wtok.name); + goto getfromax; + case tk_divequals: + getoperand(am32==TRUE?EAX:BX); + hnumber=0; + if(itok2.type==tp_stopper){ + if(tok==tk_number){ + if(itok.number==1)break; +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); + } +#endif + getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); + DivMod(0,sign,razr,0); + next=0; + goto getfromax; + } + getintoreg_32(CX,razr,sign,&ofsstr); + } + else{ + do_e_axmath(sign,razr,&ofsstr); + if(optimizespeed)outword(0xC88B); //mov CX,ax + else op(0x90+ECX); //xchg ax,Cx + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar)){ + wtok.number+=addESP-oaddESP; + oaddESP=addESP; + } + } + getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); + ClearDX(razr,sign); + op66(razr); + op(0xF7); + if(sign)op(0xF8+ECX); // IDIV CX + else op(0xF0+ECX); // DIV CX + next=0; + warningreg(regs[razr/2-1][ECX]); + KillVar(wtok.name); + goto getfromax; + case tk_swap: + KillVar(wtok.name); + int regdi; + regdi=TRUE; + getoperand(); + rbuf=bufrm; + bufrm=NULL; + if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; + switch(tok){ + case tk_reg32: + if(razr==r16)swaperror(); + case tk_reg: + if(tok==tk_reg&&razr==r32)swaperror(); +#ifdef OPTVARCONST + initconst=SwapVarRegConst(itok.number,&wtok,razr); +#endif + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x87); + op((unsigned int)itok.number*8+wtok.rm); + outaddress(&wtok); + ClearReg(itok.number); + break; + case tk_qwordvar: + case tk_longvar: + case tk_dwordvar: + if(razr==r16)swaperror(); + case tk_intvar: + case tk_wordvar: + if((tok==tk_intvar||tok==tk_wordvar)&&razr==r32)swaperror(); +#ifdef OPTVARCONST + ClearVarByNum(&itok); +#endif + if(hnumber==0)getinto_e_ax(sign,otok,&wtok,wbuf,&wstr,razr,TRUE); + else{ + if(regoverstack&&(!((bufrm||strinf.bufstr)&&(wbuf||wstr.bufstr)))){ + CheckAllMassiv(bufrm,razr,&strinf); + op66(razr); + outseg(&itok,2); + op(0xFF); // PUSH [dword] + op(0x30+itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xFF); // PUSH [dword] + op(0x30+wtok.rm); + outaddress(&wtok); + + CheckAllMassiv(bufrm,razr,&strinf); + op66(razr); + outseg(&itok,2); + op(0x8f); + op(itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0x8f); + op(wtok.rm); + outaddress(&wtok); + + break; + } + getinto_reg(otok,&wtok,wbuf,&wstr,razr,hnumber); + } + CheckAllMassiv(rbuf,razr,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + op66(razr); + outseg(&itok,2); + op(0x87); /* XCHG AX,[wloc] */ + op(itok.rm+hnumber*8); + outaddress(&itok); + goto getfromax; + case tk_seg: + if(razr==r32)swaperror(); + op66(r16); + op(0x8C); /* MOV AX,seg */ + op(0xC0+(unsigned int)itok.number*8); + CheckAllMassiv(wbuf,2,&wstr,&wtok); + op66(r16); + outseg(&wtok,2); + op(0x87); /* XCHG AX,[wloc] */ + op(wtok.rm); + outaddress(&wtok); + op66(r16); + op(0x8E); /* MOV seg,AX */ + op(0xC0+(unsigned int)itok.number*8); + break; + case tk_floatvar: + if(razr==r16)swaperror(); + if(sign==1){ + CheckAllMassiv(wbuf,4,&wstr,&wtok); + outseg(&wtok,2); //fild + op(0xDB); + op(wtok.rm); + outaddress(&wtok); + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fld val + op(0xd9); + op(itok.rm); + outaddress(&itok); + } + else{ + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + CheckAllMassiv(wbuf,4,&wstr,&wtok); + op66(r32); //push var + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; + addESP+=8; + outseg(&wtok,2); + op(0xFF); + op(wtok.rm+0x30); + outaddress(&wtok); + fildq_stack(); + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fld val + op(0xd9); + op(itok.rm); + outaddress(&itok); + RestoreBP(); + if(optimizespeed||am32==0){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + addESP-=8; + } + outseg(&wtok,2);//fistp var + op(0xDB); + op(wtok.rm+0x18); + outaddress(&wtok); + outseg(&itok,2); //fstp val + op(0xd9); + op(itok.rm+0x18); + outaddress(&itok); + fwait3(); + break; + default: swaperror(); break; + } + break; + case tk_rrequals: + vop=8; + if(sign)vop+=0x10; + case tk_llequals: + KillVar(wtok.name); + getoperand(am32==TRUE?ECX:BX); + if(itok2.type!=tp_stopper){ + doalmath(0,&ofsstr); // all shifts unsigned byte + ClearReg(AX); + ClearReg(CX); + outword(0xC188); // MOV CL,AL + if(addESP!=oaddESP&&am32&&ESPloc&&(wtok.type==tp_paramvar||wtok.type==tp_localvar))wtok.number+=addESP-oaddESP; + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xD3); op(0x20+vop+wtok.rm); // SHL [rmword],CL + outaddress(&wtok); + warningreg(begs[1]); + next=0; + } + else if(tok==tk_number){ +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&wtok,itok.lnumber,itok.rm,operand); + } +#endif + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + if((unsigned int)itok.number==1){ + op66(razr); + outseg(&wtok,2); + op(0xD1); op(0x20+vop+wtok.rm); /* SHL [rmword],1 */ + outaddress(&wtok); + } + else if((unsigned int)itok.number!=0){ + if(chip<2&&razr==r16){ + getintobeg(CL,&ofsstr); + op66(r16); + outseg(&wtok,2); + op(0xD3); op(0x20+vop+wtok.rm); /* SHL [rmword],CL */ + outaddress(&wtok); + warningreg(begs[1]); + ClearReg(CX); + next=0; + } + else{ + op66(razr); + outseg(&wtok,2); + op(0xC1); op(0x20+vop+wtok.rm); /* SHL [rmword],imm8 */ + outaddress(&wtok); + if(cpu<2)cpu=2; + } + op((unsigned int)itok.number); + } + } + else{ + if(tok!=tk_beg||(unsigned int)itok.number!=CL){ + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + ClearReg(CX); + next=0; + } + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + op66(razr); + outseg(&wtok,2); + op(0xD3); op(0x20+vop+wtok.rm); /* SHL [rmword],CL */ + outaddress(&wtok); + } + break; + default: operatorexpected(); break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&wtok); +#endif + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + if(razr==r32&&cpu<3)cpu=3; + return retrez; +} + +int dobytevar(int sign,int terminater) // byte, char +{ +unsigned char next=1,getfromAX=0; +unsigned int vop=0,otok,rettype,posiblret; +ITOK btok; +char *bbuf,*rbuf; +int retrez=0,pointr=0,hnumber=AL; +SINFO bstr; +int numpointr=0; +char *ofsstr=NULL; +#ifdef OPTVARCONST +int initconst=FALSE; +int operand; +#endif +unsigned int oaddESP=addESP; + sign==0?posiblret=rettype=tk_byte:posiblret=rettype=tk_char; + bstr=strinf; + strinf.bufstr=NULL; + btok=itok; + bbuf=bufrm; + bufrm=NULL; + otok=tok; + while(RmEqualReg(hnumber,itok.rm,itok.sib))hnumber++; + nexttok(); +#ifdef OPTVARCONST + operand=tok; +#endif + switch(tok){ + case tk_assign: + if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ + ofsstr=GetLecsem(terminater); + } + if(ofsstr){ + int retreg; + if((retreg=CheckIDZReg(ofsstr,AX,r8))!=NOINREG){ + GetEndLex(terminater); + tok=tk_beg; + itok.number=retreg==SKIPREG?AX:retreg; + goto regtovar; + } + } + nexttok(); + convert_type(&sign,(int *)&rettype,&pointr); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + hnumber=MultiAssign(r8,USEALLREG,numpointr); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + next=0; + goto getfromax; + } + if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); + CheckMinusNum(); + if(itok2.type==tp_opperand){ + if(rettype!=tk_float&&tok==tk_number){ //஢ઠ 㬬஢ ᥫ + if(OnlyNumber(sign)){ + next=0; + goto numbertovar; + } + } + goto labl1; + } + else{ +#ifdef OPTVARCONST + if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ + if(CheckConstVar(&itok))tok=tk_number; + } +#endif + switch(tok){ + case tk_number: +numbertovar: +#ifdef OPTVARCONST + if((initconst=Const2Var(&btok,itok.lnumber&0Xff,itok.rm))==FALSE){ + waralreadinitvar(btok.name,itok.number); + initconst=TRUE; + break; + } +#endif + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xC6); + op(btok.rm); + outaddress(&btok); + op((unsigned int)itok.number); + break; + case tk_reg32: + case tk_reg: + if((unsigned int)itok.number>BX)goto labl1; + case tk_beg: +regtovar: + if((unsigned int)itok.number==0){ + getfromAX=1; + hnumber=0; + } + else{ + KillVar(btok.name); + AddRegVar(itok.number,r8,&btok); + vop++; + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0x88); + op((unsigned int)itok.number*8+btok.rm); + outaddress(&btok); + } + break; + case tk_seg: segbyteerror(); break; + default: +labl1: + if(rettype==tk_char||rettype==tk_byte){ + if(hnumber==0)retrez=doalmath(sign,&ofsstr); + else retrez=getintobeg(hnumber,&ofsstr); + } + else if(rettype==tk_int||rettype==tk_word){ + if(hnumber==0)retrez=do_e_axmath(sign,r16,&ofsstr); + else retrez=getintoreg(hnumber,r16,sign,&ofsstr); + } + else if(rettype==tk_float){ + doeaxfloatmath(tk_reg32); + rettype=tk_long; + hnumber=0; + } + else{ + if(hnumber==0)retrez=do_e_axmath(sign,r32,&ofsstr); + else retrez=getintoreg(hnumber,r32,sign,&ofsstr); + } + getfromAX=1; + next=0; + break; + } + } + if(getfromAX){ +getfromax: +#ifdef OPTVARCONST + initconst=CheckRegToConst(hnumber,&btok,r8); +#endif + if(retrez==0)retrez=tk_reg; + convert_returnvalue(posiblret,rettype); + if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP; + if(bbuf==NULL&&bstr.bufstr==NULL&&hnumber==0&&((btok.rm==rm_d16&&btok.sib==CODE16)||(btok.rm==rm_d32&&(btok.sib==CODE32||btok.sib==0)))){ + outseg(&btok,1); + op(0xA2); // MOV [byte],AL + if(btok.post==UNDEF_OFSET){ + AddUndefOff(2,btok.name); + btok.post=0; + } + if(am32==FALSE)outword(btok.number); + else outdword(btok.number); + } + else{ + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); // MOV [rmbyte],AL + op(0x88); + op(btok.rm+hnumber*8); + outaddress(&btok); + } + if(ofsstr)IDZToReg(ofsstr,hnumber,r8); + else ClearReg(hnumber); + KillVar(btok.name); + AddRegVar(hnumber,r8,&btok); + } + else if(vop)KillVar(btok.name); + if(ofsstr)free(ofsstr); + break; + case tk_multequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper&&tok==tk_number){ + if(itok.number==1)break; + if(itok.number==0){ + outword(0xB0+hnumber); + goto getfromax; + } +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,tk_mult); + } +#endif + } + doalmath(sign,&ofsstr); + hnumber=0; + if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar)){ + btok.number+=addESP-oaddESP; + oaddESP=addESP; + } + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xF6); + if(sign)op(0x28+btok.rm); + else op(0x20+btok.rm); + outaddress(&btok); + next=0; + KillVar(btok.name); + goto getfromax; + case tk_divequals: + hnumber=0; + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper){ + if(tok==tk_number){ + if(itok.number==1)break; +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,tk_div); + } +#endif + } + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + } + else{ + doalmath(sign,&ofsstr); + outword(0xC88A); //mov Cl,al + if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar)){ + btok.number+=addESP-oaddESP; + oaddESP=addESP; + } + } + if(sign)cbw(); + else xorAHAH(); + getintoal(otok,&btok,bbuf,&bstr); + warningreg(begs[3]); + op(0xF6); + if(sign)op(0xF8+CL); // IDIV CL + else op(0xF0+CL); // DIV CL + next=0; + ClearReg(CX); + KillVar(btok.name); + goto getfromax; + case tk_minusminus: vop=0x8; + case tk_plusplus: +#ifdef OPTVARCONST + initconst=UpdVarConst(&btok,1,tk_byte,tok); +#endif + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xFE); + op(vop+btok.rm); + outaddress(&btok); + KillVar(btok.name); + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + KillVar(btok.name); + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_opperand){ + if(tok==tk_number){ + if(OnlyNumber(sign)){ + next=0; + otok=tok; + tok=tk_number; + goto num; + } + } + doalmath(sign,&ofsstr); + if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP; + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(vop); op(btok.rm); // ADD [anybyte],AL + outaddress(&btok); + next=0; + retrez=tk_reg; + } + else{ + switch(tok){ + case tk_number: +num: +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,operand); + } +#endif + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + if(itok.number==1&&(vop==0||vop==0x28)){ + if(vop)vop=8; + op(0xFE); + op(vop+btok.rm); + outaddress(&btok); + } + else{ + op(0x80); + op(vop+btok.rm); + outaddress(&btok); + op((unsigned int)itok.number); + } + if(next==0)tok=otok; + break; + case tk_beg: +#ifdef OPTVARCONST + initconst=CheckUpdRegToConst(itok.number,&btok,operand,r8); +#endif + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(vop); + op((unsigned int)itok.number*8+btok.rm); + outaddress(&btok); + break; + case tk_seg: segbyteerror(); break; + default: + retrez=tk_reg; + doalmath(sign,&ofsstr); + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(vop); op(btok.rm); /* ADD [anybyte],AL */ + outaddress(&btok); + next=0; + break; + } + } + break; + case tk_swap: + KillVar(btok.name); + getoperand(); + rbuf=bufrm; + bufrm=NULL; + switch(tok){ + case tk_beg: +#ifdef OPTVARCONST + initconst=SwapVarRegConst(itok.number,&btok,r8); +#endif + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0x86); /* XCHG beg,[anybloc] */ + op((unsigned int)itok.number*8+btok.rm); + outaddress(&btok); + ClearReg(itok.number>3?itok.number-4:itok.number); + break; + case tk_bytevar: + case tk_charvar: +#ifdef OPTVARCONST + initconst=SwapVarConst(&itok,&btok); +#endif + if(hnumber==0)getintoal(otok,&btok,bbuf,&bstr); + else getinto_reg(otok,&btok,bbuf,&bstr,r8,hnumber); + CheckAllMassiv(rbuf,1,&strinf,&itok,(am32!=FALSE&&bbuf!=NULL&&bstr.bufstr!=NULL)?BX:DI,DX); + outseg(&itok,2); + op(0x86); /* XCHG AL,[bloc] */ + op(itok.rm+hnumber*8); + outaddress(&itok); + KillVar(itok.name); + goto getfromax; + default: swaperror(); break; + } + break; + case tk_rrequals: + vop=8; + if(sign)vop+=0x10; + case tk_llequals: + KillVar(btok.name); + getoperand(am32==TRUE?ECX:BX); + if(itok2.type!=tp_stopper){ + doalmath(0,&ofsstr); // all shifts unsigned byte + outword(0xC188); // MOV CL,AL + if(addESP!=oaddESP&&am32&&ESPloc&&(btok.type==tp_paramvar||btok.type==tp_localvar))btok.number+=addESP-oaddESP; + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ + outaddress(&btok); + warningreg(begs[1]); + ClearReg(CX); + ClearReg(AX); + next=0; + } + else if(tok==tk_number){ +#ifdef OPTVARCONST + if((itok.flag&f_reloc)==0){ + initconst=UpdVarConst(&btok,itok.lnumber,itok.rm,operand); + } +#endif + if((unsigned int)itok.number==1){ + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xD0); op(0x20+vop+btok.rm); /* SHL [byte],1 */ + outaddress(&btok); + } + else if((unsigned int)itok.number!=0){ + CheckAllMassiv(bbuf,1,&bstr,&btok); + if(chip<2){ + getintobeg(CL,&ofsstr); + outseg(&btok,2); + op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ + outaddress(&btok); + warningreg(begs[1]); + ClearReg(CX); + next=0; + } + else{ + outseg(&btok,2); + op(0xC0); op(0x20+vop+btok.rm); /* SHL [byte],imm8 */ + outaddress(&btok); + if(cpu<2)cpu=2; + } + op((unsigned int)itok.number); + } + } + else{ + if(tok!=tk_beg||(unsigned int)itok.number!=CL){ + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + ClearReg(CX); + next=0; + } + CheckAllMassiv(bbuf,1,&bstr,&btok); + outseg(&btok,2); + op(0xD2); op(0x20+vop+btok.rm); /* SHL [byte],CL */ + outaddress(&btok); + } + break; + default: operatorexpected(); break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&btok); +#endif + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + return retrez; +} + +void getinto_reg(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int reg) +{ +unsigned int i=0; +int vop=0; +int reg1=SI,reg2=DI; + switch(gtok){ + case tk_dwordvar: + case tk_longvar: + i+=4; +longvar: + CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); + op66(razr); + outseg(gstok,2); + op(0x8B); + op(gstok->rm+reg*8); + outaddress(gstok); + ClearReg(reg); + break; + case tk_intvar: + vop=8; + case tk_wordvar: + i=2; + goto longvar; + case tk_bytevar: + case tk_charvar: + CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); + outseg(gstok,2); + op(0x8A); + op(gstok->rm+reg*8); + outaddress(gstok); + ClearReg(reg); + break; + } +} + +void getinto_e_ax(int sign,int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr,int razr,int useAX) +{ +unsigned int i=0; +int vop=0; +int reg1=idxregs[0],reg2=idxregs[1]; + if(am32){ + reg1=useAX==FALSE?EAX:idxregs[0]; + reg2=idxregs[3]; + } +// printf("tok=%u %s\n",gtok,gstok->name); + switch(gtok){ + case tk_bits: + vop=gstok->bit.siz+gstok->bit.ofs; + if(vop<=64)i=r64; + if(vop<=32)i=r32; + if(vop<=16)i=r16; + bits2reg(AX,((unsigned int)razr>i?razr:i)); + break; + case tk_postnumber: + op66(razr); + op(0xB8); /* MOV EAX,# */ + (gstok->flag&f_extern)==0?setwordpost(gstok):setwordext(&gstok->number); + razr==r16?outword(gstok->number):outdword(gstok->number); + ClearReg(AX); + break; + case tk_rmnumber: + CheckAllMassiv(gbuf,gstok->size,gstr,gstok,reg1,reg2); + if(gstok->rm||am32==0){ + op66(razr); + op67(gstok->sib==CODE16?r16:r32); + if(gstok->post==0)outseg(gstok,2); + op(0x8D); op(gstok->rm); + if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){ + if((gstok->flag&f_extern)==0){ + i=outptr; + if(am32&&gstok->rm==rm_sib)outptr++; + setwordpost(gstok); + outptr=i; + } + else setwordext(&gstok->number); + } + outaddress(gstok); /* LEA AX,[rm] */ + ClearReg(AX); + } + else nexttok(); + break; + case tk_doublevar: + vop=4; + case tk_floatvar: + CheckInitBP(); + if(cpu<3)cpu=3; + op66(r32); + op(0x50); //push EAX + if(ESPloc&&am32&&gstok->segm==SS)gstok->number+=4; + addESP+=4; + CheckAllMassiv(gbuf,4,gstr,gstok,reg1,reg2); + outseg(gstok,2); //fld floatvar + op(0xd9+vop); + op(gstok->rm); + outaddress(gstok); + fistp_stack(); + op66(r32); + op(0x58); //pop EAX + addESP-=4; + RestoreBP(); + ClearReg(AX); + break; + case tk_qwordvar: + i=4; + case tk_dwordvar: + case tk_longvar: + i+=4; +longvar: + if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ + op66(razr); + outseg(gstok,1); + op(0xA1); + if(gstok->post==UNDEF_OFSET)AddUndefOff(2,gstok->name); + if(am32==FALSE)outword((unsigned int)gstok->number); + else outdword(gstok->number); + } + else{ + CheckAllMassiv(gbuf,i,gstr,gstok,reg1,reg2); + op66(razr); + outseg(gstok,2); + op(0x8B); + op(gstok->rm); + outaddress(gstok); + } + ClearReg(AX); + break; + case tk_intvar: + vop=8; + case tk_wordvar: + i=2; + if(razr==r16)goto longvar; + i=1; + if(optimizespeed&&vop==0&&chip>3&&chip<7)goto optpent; +movxx: + CheckAllMassiv(gbuf,1+i,gstr,gstok,reg1,reg2); + op66(razr); + outseg(gstok,3); /* MOVSX EAX,[charvar] */ + op(0x0F); op(0xB6+vop+i); op(gstok->rm); + outaddress(gstok); + ClearReg(AX); + break; + case tk_charvar: + vop=8; + if(razr==r16){ + if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ + outseg(gstok,1); + op(0xA0); + if(am32==FALSE)outword(gstok->number); + else outdword(gstok->number); + } + else{ + CheckAllMassiv(gbuf,1,gstr,gstok,reg1,reg2); + outseg(gstok,2); + op(0x8A); op(gstok->rm); + outaddress(gstok); + } + cbw(); + ClearReg(AX); + break; + } + goto movxx; + case tk_bytevar: +optpent: + if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ + ZeroReg(EAX,razr); + if(i)op66(r16); + outseg(gstok,1); + op(0xA0+i); + if(am32==FALSE)outword(gstok->number); + else outdword(gstok->number); + ClearReg(AX); + break; + } + if((chip>=3&&(!optimizespeed))||RmEqualReg(AX,gstok->rm,gstok->sib))goto movxx; + ZeroReg(EAX,razr); + CheckAllMassiv(gbuf,1+i,gstr,gstok,SI,reg2); + if(i)op66(r16); + outseg(gstok,2); + op(0x8A+i); op(gstok->rm); + outaddress(gstok); + break; + case tk_beg: + if(gstok->number==AL&&(!sign)&&razr==r16){ + xorAHAH(); + ClearReg(AX); + break; + } + if(optimizespeed&&chip>3&&chip<7){ + if(sign){ + if(razr==r32)goto movxxr; + if(gstok->number!=AL){ + op(0x88); + op(0xC0+gstok->number*8); //mov al,beg + } + if(gstok->number!=AH)outword(0xC488); //mov ah,al + outword(0xFCC0); //sar ah,7 + op(7); + } + else{ + if(razr==r32&&(gstok->number==AL||gstok->number==AH)){ + /*if(chip==4)*/goto movxxr; +/* op(0x88); + op(0xC1+gstok->number*8); //mov cl,beg + xorEAXEAX(); + outword(0xC888); // mov al,cl + warningreg(begs[1]); + break;*/ + } + if(gstok->number==AH)outdword(0xE430E088); //mov al,ah xor ah,ah + else{ + ZeroReg(EAX,razr); + op(0x88); + op(0xC0+gstok->number*8); //mov al,beg + } + } + ClearReg(AX); + break; + } +movxxr: + if(chip>2||razr==r32){ + op66(razr); + if(sign)outword(0xBE0F); + else outword(0xB60F); + op(0xC0+(unsigned int)gstok->number); // MOVxX AX,beg + } + else{ + op(0x88); + op(0xC0+gstok->number*8); + if(sign)cbw(); + else xorAHAH(); + } + ClearReg(AX); + break; + case tk_reg: + if(razr==r32){ + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=gstok->number; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(r16); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + clearregstat(); + break; + } + if(optimizespeed&&(!sign)&&chip>3&&chip<7){ + if(gstok->number==AX){ + goto movxr; +/* op66(r16); + outword(0xC189); //mov cx,AX + xorEAXEAX(); + op66(r16); + outword(0xC889); //mov aX,cX + warningreg(regs[0][1]);*/ + } + else{ + xorEAXEAX(); + op66(r16); + op(0x89); + op(0xC0+gstok->number*8); //mov ax,reg + } + } + else{ +movxr: + op66(r32); + op(0x0F); /* MOVSX or MOVZX EAX,reg */ + if(sign)op(0xBF); + else op(0xB7); + op(0xC0+gstok->number); + } + RegToReg(AX,gstok->number,razr); + break; + } + case tk_reg32: + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=gstok->number; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(razr); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + break; + } + if(gstok->number!=AX){ + op66(razr); + op(0x89); + op(0xC0+gstok->number*8); + RegToReg(AX,gstok->number,razr); + } + break; + case tk_seg: + if(razr==r32)op66(r32); + op(0x8C); //mov var,SS + op(0xC0+gstok->number*8); + ClearReg(AX); + break; + case tk_string: + op66(razr); + op(0xB8); + if(razr==r16){ + if(am32)dwordvalexpected(); + outword(addpoststring(CS,gstok->number,gstok->flag)); + } + else outdword(addpoststring(CS,gstok->number,gstok->flag)); + ClearReg(AX); + break; + default: valueexpected(); break; + } + if(razr==r32&&cpu<3)cpu=3; +} + +int caselong(unsigned long val) +{ +int vop=0; +unsigned long num; + for(;vop0x20){ + op66(razr); + op(0x90+EDX); //xchg ax,dx + } + goto defreg32; + case tk_bits: + int vops; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + bits2reg(CX,(razr2||razr==r32){ + op66(razr); + op(0x0f); + outword(0xC2a4); //SHLD DX,AX,num + op(itok.number); + } + else{ + if((unsigned int)itok.number==1)outdword(0xd213c001); //ADD AX,AX ADC DX,DX + else if((unsigned int)itok.number!=0){ + getintobeg(CL,&ofsstr); + outdword(0xd213c001); //ADD AX,AX ADC DX,DX + outword(0xfae2); //LOOP -6 + warningreg(begs[1]); + next=0; + } + break; + } + } + lshiftmul(itok.number,razr); + setzeroflag=TRUE; + } + else goto llminus; + break; + case tk_llminus: + tok=tk_minus; // do optimization 286+ here later +llminus: + if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + } + else getoperand(); + next=0; + if(expand==TRUE){ + if(chip>2||razr==r32){ + op66(razr); + op(0x0f); + outword(0xC2a5); //SHLD DX,AX,CL + } + else + outdword(0xd213c001); //ADD AX,AX ADC DX,DX + outword(0xfae2); //LOOP -6 + break; + } + op66(razr); + outword(0xE0D3); /* SHL AX,CL */ + setzeroflag=TRUE; + break; + case tk_rr: + if(sign)vop=0x10; + getoperand(); + if(expand==TRUE){ + if(tok==tk_number){ + if((unsigned int)itok.number==1){ + op66(razr); + outword(0xead1); //shr dx,1 ror ax,1 + op66(razr); + outword(0xc8d1); //shr dx,1 ror ax,1 + setzeroflag=TRUE; + } + else if((unsigned int)itok.number!=0){ + if(chip>2||razr==r32){ + op66(razr); + op(0x0f); + outword(0xd0ac); //shrd ax,dx,num + op(itok.number); + op66(razr); + op(0xc1); op(0xea+vop);//s?r dx,num + op(itok.number); + setzeroflag=TRUE; + } + else{ + next=0; + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + op(0xd1); op(0xea+vop);//s?r dx,1 + outdword(0xfae2d8d1); //rcr ax,1 LOOP -6 + setzeroflag=FALSE; + } + } + } + else goto rrminus; + } + else{ + RshiftReg(razr,EAX,vop); + setzeroflag=TRUE; + next=0; + } + break; + case tk_rrminus: + if(sign)vop=0x10; + tok=tk_minus; // do optimization 286+ here later +rrminus: + if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + } + else getoperand(); + if(expand==TRUE){ + if(chip>2||razr==r32){ + op66(razr); + op(0x0f); + outword(0xd0ad); //shrd ax,dx,cl + op66(razr); + op(0xd3); op(0xea+vop);//s?r dx,num + setzeroflag=TRUE; + } + else{ + op(0xd1); op(0xea+vop);//s?r dx,1 + outdword(0xfae2d8d1); //rcr ax,1 //LOOP -6 + setzeroflag=FALSE; + } + } + else{ + op66(razr); + op(0xD3); op(0xE8+vop); /* SR AX,CL */ + setzeroflag=TRUE; + } + next=0; + break; + default: operatorexpected(); break; + } + calcnumber=FALSE; + ClearReg(EAX); + if(negflag){ + NegReg(razr,EAX); + setzeroflag=TRUE; + negflag=0; + } + if(next)nexttok(); + } + calcnumber=FALSE; + ClearReg(EAX); + if(tok==tk_eof)unexpectedeof(); + if(razr==r32&&cpu<3)cpu=3; +} + +void getintoal(int gtok,ITOK *gstok,char *&gbuf,SINFO *gstr) // AH may also be changed +{ +unsigned int i=0; + switch(gtok){ + case tk_bits: + int razr; + i=gstok->bit.siz+gstok->bit.ofs; + if(i<=64)razr=r64; + if(i<=32)razr=r32; + if(i<=16)razr=r16; + if(i<=8)razr=r8; + bits2reg(AL,razr); + break; + case tk_number: + op(0xB0); /* MOV AL,# */ + op(gstok->number); + ConstToReg(gstok->number,AL,r8); + break; + case tk_rmnumber: + CheckAllMassiv(gbuf,gstok->size,gstr,gstok); + op66(r16); + op67(gstok->sib==CODE16?r16:r32); + if(gstok->post==0)outseg(gstok,2); + op(0x8D); /* LEA AX,[rm] */ + op(gstok->rm); + if(gstok->post!=0&&gstok->post!=UNDEF_OFSET){ + if((gstok->flag&f_extern)==0){ + i=outptr; + if(am32&&gstok->rm==rm_sib)outptr++; + setwordpost(gstok); + outptr=i; + } + else setwordext(&gstok->number); + } + outaddress(gstok); + ClearReg(AL); + break; + case tk_postnumber: + op66(r16); + op(0xB8); /* MOV AX,# */ + (gstok->flag&f_extern)==0?setwordpost(gstok):setwordext(&gstok->number); + outword(gstok->number); + ClearReg(AL); + break; + case tk_floatvar: + if(cpu<3)cpu=3; + CheckInitBP(); + op66(r32); + outword(0x6a); //push 0 + if(ESPloc&&am32&&gstok->segm==SS)gstok->number+=4; + addESP+=4; + CheckAllMassiv(gbuf,4,gstr,gstok); + outseg(gstok,2); //fld floatvar + op(0xd9); + op(gstok->rm); + outaddress(gstok); + fistp_stack(); + op66(r32); + op(0x58); //pop EAX + addESP-=4; + RestoreBP(); + ClearReg(AL); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_bytevar: + case tk_charvar: + i++; + if((gstok->rm==rm_d16&&gstok->sib==CODE16)||(gstok->rm==rm_d32&&(gstok->sib==CODE32||gstok->sib==0))){ + outseg(gstok,1); + op(0xA0); //mov AL, + if(gstok->post==UNDEF_OFSET)AddUndefOff(2,gstok->name); + if(am32==FALSE)outword(gstok->number); + else outdword(gstok->number); + } + else{ + CheckAllMassiv(gbuf,i,gstr,gstok); + outseg(gstok,2); + op(0x8A); + op(gstok->rm); + outaddress(gstok); + } + ClearReg(AL); + break; + case tk_reg32: + if(gstok->number>BX){ + i=1; + if(gstok->number!=AX)op66(r32); + } + goto beg1; + case tk_reg: + if(gstok->number>BX){ + i=1; + if(gstok->number!=AX)op66(r16); + } + case tk_beg: +beg1: + if(gstok->number!=AL){ + op(0x88+i); //mov [],AL + op(0xC0+gstok->number*8); + } + ClearReg(AL); + break; + case tk_seg: + op66(r16); + op(0x8C); op(0xC0+gstok->number*8); break; + ClearReg(AL); + default: bytevalexpected(0); break; + } +} + +int doalmath(int sign,char **ofsstr) +{ +int negflag=0,i=0; +int rettype=tk_beg; + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + negflag=1; + getoperand(am32==TRUE?EAX:BX); + } + } +#ifdef OPTVARCONST + if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ + if(CheckConstVar(&itok)){ + tok=tk_number; + calcnumber=TRUE; + } + } +#endif + switch(tok){ + case tk_number: + op(0xB0); //mov AL,num + i=CalcNumber(sign); + op(i); + ConstToReg(i,AL,r8); + break; + case tk_at: + getoperand(am32==TRUE?EAX:BX); + i++; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; + if((!i)||macros(sign!=0?tk_char:tk_byte)==0)procdo(sign!=0?tk_char:tk_byte); + nexttok(); + if(*ofsstr){ + free(*ofsstr); + *ofsstr=NULL; + } + break; + default: + SINFO bstr=strinf; + strinf.bufstr=NULL; + ITOK btok; + char *bbuf; + btok=itok; + bbuf=bufrm; + bufrm=NULL; + getintoal(tok,&btok,bbuf,&bstr); nexttok(); break; + } +#ifdef OPTVARCONST + calcnumber=FALSE; +#endif + if(negflag){ + if(optimizespeed&&(chip==5||chip==6))outdword(0xC0FEFF34); //xor AL,-1 AL++ + else outword(0xD8F6);// NEG AL + setzeroflag=TRUE; + } + if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ + doalmath2(sign); + rettype=tk_beg; + } + return rettype; +} + +void doalmath2(int sign) +{ +int vop,i,next; +int expand=FALSE,optnum=FALSE; +int negflag=0; +char *ofsstr=NULL; + while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ + vop=0; + i=0; + next=1; +#ifdef OPTVARCONST + if(tok2>=tk_charvar&&tok2<=tk_doublevar&&itok2.npointr==0){ + if(CheckConstVar(&itok2)){ + tok2=tk_number; + calcnumber=TRUE; + } + } +#endif + if(tok2==tk_number)optnum=OptimNum(); + int oldtok=tok; + switch(tok){ + case tk_xor: vop+=0x08; + case tk_minus: vop+=0x08; + case tk_and: vop+=0x18; + case tk_or: vop+=0x08; + case tk_plus: + if(optnum==FALSE)getoperand(); + else{ + tok=tk_number; + optnum=FALSE; + } + switch(tok){ + case tk_number: + if(itok.number==0&&oldtok!=tk_and)break; + if(itok.number==255&&oldtok==tk_and)break; + op(0x04+vop); + op((unsigned int)itok.number); /* OPT AL,num */ + break; + case tk_rmnumber: + CheckAllMassiv(bufrm,itok.size,&strinf); + op66(r16); + op67(itok.sib==CODE16?r16:r32); + if(itok.post==0)outseg(&itok,2); + op(0x8D); /* LEA CX,[rm] */ + op(0x8+itok.rm); + if(itok.post!=0&&itok.post!=UNDEF_OFSET){ + if((itok.flag&f_extern)==0){ + unsigned int ooutptr=outptr; + if(am32&&itok.rm==rm_sib)outptr++; + setwordpost(&itok); + outptr=ooutptr; + } + else setwordext(&itok.number); + } + outaddress(&itok); + op(vop); /* OPT AL,CL */ + op(0xC8); + warningreg(regs[0][1]); + break; + case tk_postnumber: + op66(r16); + op(0x05+vop); /* OPT AX,# */ + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + outword((unsigned int)itok.number); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0x02+vop); op(itok.rm); + outaddress(&itok); + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + op66(r16); + op(0x50); //push AX + addESP+=2; +unsigned char oaddstack; + oaddstack=addstack; + addstack=FALSE; + procdo(sign!=0?tk_char:tk_byte); + addstack=oaddstack; + addESP-=2; + op66(r16); + op(0x58+CX); + itok.number=CX; + warningreg(regs[0][CX]); + if(vop>0x20){ + op66(r16); + op(0x90+CX); //xchg ax,Cx + } + goto defbeg; + case tk_bits: + int razr; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)razr=r64; + if(i<=32)razr=r32; + if(i<=16)razr=r16; + if(i<=8)razr=r8; + bits2reg(CL,razr); + itok.number=CL; + if(razr==r64)razr=r32; + warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); + goto defbeg; + case tk_doublevar: + i=4; + case tk_floatvar: + Float2reg32(EAX,i); + itok.number=0; + case tk_beg: +defbeg: + op(vop); + op(0xC0+(unsigned int)itok.number*8); + break; + case tk_reg32: + case tk_reg: + if((unsigned int)itok.number>BX){ + op66(r16); + op(0x89); /* MOV CX,reg */ + warningreg(regs[0][1]); + op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ + itok.number=CL; + } + goto defbeg; + default: valueexpected(); break; + } + setzeroflag=TRUE; + if(expand==TRUE){ + if(oldtok==tk_plus){ + outword(0xd480); //ADC AH,0 + op(0); + } + else if(oldtok==tk_minus){ + outword(0xdc80); //SBB AH,0 + op(0); + } + setzeroflag=FALSE; + } + break; + case tk_modminus: negflag=1; + case tk_mod: negflag=1-negflag; vop=1; + case tk_divminus: negflag=1-negflag; + case tk_div: + if(optnum==FALSE)getoperand(); + else{ + tok=tk_number; + optnum=FALSE; + } + if(tok==tk_number){ + if(negflag){ + itok.number=-itok.number; + negflag=0; + } + itok.number&=255; + if(vop){ //% + if(itok.number==0)DevideZero(); + if(caselong(itok.number)!=NUMNUM){ + op(0x24); /* AND AL,number-1 */ + op((unsigned int)itok.number-1); + setzeroflag=TRUE; + } + else{ + if(expand==FALSE){ + if(sign)cbw(); + else xorAHAH(); + } + op(0xB1); op((unsigned int)itok.number); /* MOV CL,# */ + if(sign)outword(0xF9F6); /* IDIV CL */ + else outword(0xF1F6); /* DIV CL */ + outword(0xE088);// MOV AL,AH + setzeroflag=FALSE; + warningreg(begs[1]); + break; + } + } + else{ + switch((unsigned int)itok.number){ + case 0: + DevideZero(); + break; + case 1: break; + case 2: + op(0xd0+expand); + if(sign)op(0xf8); + else op(0xE8);// SHR AL,1 + setzeroflag=TRUE; + break; + default: + vop=caselong(itok.number); + if(vop!=NUMNUM){ + if(chip<2){ + op(0xB1); op(vop); /* MOV CL,num */ + op(0xd2+expand); + if(sign)op(0xF8); // SAR AL,CL + else op(0xE8); // SHR AL,CL + warningreg(begs[1]); + } + else{ + op(0xc0+expand); + if(sign)op(0xF8); /* SAR AL,num */ + else op(0xE8); /* SHR AL,num */ + op(vop); + if(cpu<2)cpu=2; + } + setzeroflag=TRUE; + } + else{ + if(expand==FALSE){ + if(optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){ //for signed needed new algoritm + // 㬭 + itok.number=256/(unsigned int)itok.number+1; + if(chip>4){ + xorAHAH(); + op66(r16); + outword(0xC06B); //imul AX,num + op(itok.number); + warningreg(regs[0][2]); + } + else{ + op(0xB2); //mov DL,num + op(itok.number); + outword(0xE2F6); //mul DL + warningreg(begs[2]); + } + outword(0xE088); //mov AL.AH + setzeroflag=FALSE; + break; + } + if(sign)cbw(); + else xorAHAH(); + } + op(0xB1); /* MOV CL,# */ + op((unsigned int)itok.number); + if(sign)outword(0xF9F6); /* IDIV CL */ + else outword(0xF1F6); /* DIV CL */ + setzeroflag=FALSE; + warningreg(begs[1]); + } + } + } + } + else{ + case tk_doublevar: + i=4; + if(tok==tk_floatvar){ + Float2reg32(ECX,i); + itok.number=ECX; + tok=tk_beg; + sign=1; + } + if(expand==FALSE){ + if(sign)cbw(); + else xorAHAH(); + } + switch(tok){ + case tk_rmnumber: + case tk_postnumber: + getintoreg_32(CX,r16,sign,&ofsstr,FALSE); + if(sign)outword(0xF9F6); // IDIV CL + else outword(0xF1F6); // DIV CL + setzeroflag=FALSE; + warningreg(regs[0][1]); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0xF6); + if(sign)op(0x38+itok.rm); + else op(0x30+itok.rm); + outaddress(&itok); + setzeroflag=FALSE; + break; + case tk_bits: + int razr; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)razr=r64; + if(i<=32)razr=r32; + if(i<=16)razr=r16; + if(i<=8)razr=r8; + bits2reg(CL,razr); + itok.number=CL; + if(razr==r64)razr=r32; + warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); + goto defdiv; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + op66(r16); + op(0x50); //push AX + addESP+=2; +unsigned char oaddstack; + oaddstack=addstack; + addstack=FALSE; + procdo(sign!=0?tk_char:tk_byte); + addstack=oaddstack; + addESP-=2; + op66(r16); + op(0x58+CX); + itok.number=CX; + warningreg(regs[0][CX]); + op66(r16); + op(0x90+CX); //xchg ax,cx + case tk_beg: +defdiv: + op(0xF6); + if(sign)op(0xF8+(unsigned int)itok.number); + else op(0xF0+(unsigned int)itok.number); + setzeroflag=FALSE; + break; + case tk_reg32: + case tk_reg: + if((unsigned int)itok.number>BX){ + op66(r16); + op(0x89); /* MOV CX,reg */ + warningreg(regs[0][1]); + op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ + itok.number=CL; + } + goto defdiv; + default: valueexpected(); break; + } + if(vop)outword(0xE088);// MOV AL,AH + } + expand=FALSE; + break; + case tk_multminus: negflag=1; + case tk_mult: + expand=expandvar(); + if(optnum==FALSE)getoperand(); + else{ + tok=tk_number; + optnum=FALSE; + } + switch(tok){ + case tk_number: + if(negflag){ + itok.number=-itok.number; + negflag=0; + } + itok.number&=255; + switch((unsigned int)itok.number){ + case 0: /* AL * 0 = MOV AL,0 */ + outword(0x00B0); + case 1: + expand=FALSE; + setzeroflag=FALSE; + break; /* AL * 1 = AL */ + case 2: + if(expand==TRUE){ + if(sign)cbw(); + else xorAHAH(); + } + outword(0xC000+expand); // AL * 2 = ADD AL,AL + setzeroflag=TRUE; + break; + default: + vop=caselong(itok.number); + if(vop!=NUMNUM){ + if(chip<1){ + if(expand==TRUE){ + if(optimizespeed==FALSE&&sign==FALSE)goto num_imul; + if(sign)cbw(); + else xorAHAH(); + } + op(0xB1); op(vop); /* MOV CL,num */ + outword(0xE0D2+expand);// SHL AL,CL + warningreg(begs[1]); + } + else{ + if(expand==TRUE){ + if(optimizespeed==FALSE&&sign==FALSE)goto num_imul; + if(sign)cbw(); + else xorAHAH(); + op66(r16); + } + outword(0xe0c0+expand); //SHL AX/L,num + op(vop); + if(cpu<1)cpu=1; + } + setzeroflag=TRUE; + } + else if(expand==FALSE&&optimizespeed!=FALSE&& + speedmul(itok.number,r8)!=FALSE); + else{ +num_imul: + op(0xB1); /* MOV CL,# */ + op((unsigned int)itok.number); + if(sign)outword(0xE9F6);// IMUL CL + else outword(0xE1F6); // MUL CL + setzeroflag=FALSE; + warningreg(begs[1]); + } + } + break; + case tk_rmnumber: + case tk_postnumber: + getintoreg_32(CX,r16,sign,&ofsstr,FALSE); + if(sign)outword(0xE9F6); // IMUL CL + else outword(0xE1F6); // MUL CL + setzeroflag=FALSE; + warningreg(regs[0][1]); + break; + case tk_doublevar: + i=4; + case tk_floatvar: + Float2reg32(ECX,i); + itok.number=ECX; + outword(0xE9F6); // IMUL CL + setzeroflag=FALSE; + warningreg(begs[1]); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0xF6); + if(sign)op(0x28+itok.rm); + else op(0x20+itok.rm); + outaddress(&itok); + setzeroflag=FALSE; + break; + case tk_bits: + int razr; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)razr=r64; + if(i<=32)razr=r32; + if(i<=16)razr=r16; + if(i<=8)razr=r8; + bits2reg(CL,razr); + itok.number=CL; + if(razr==r64)razr=r32; + warningreg(razr==r8?begs[1]:(regs[razr/2-1][1])); + goto defmul; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + op66(r16); + op(0x50); //push AX + addESP+=2; +unsigned char oaddstack; + oaddstack=addstack; + addstack=FALSE; + procdo(sign!=0?tk_char:tk_byte); + addstack=oaddstack; + addESP-=2; + op66(r16); + op(0x58+DX); + itok.number=DX; + warningreg(regs[0][DX]); + case tk_beg: +defmul: + op(0xF6); + if(sign)op(0xE8+(unsigned int)itok.number); + else op(0xE0+(unsigned int)itok.number); + setzeroflag=FALSE; + break; + case tk_reg32: + case tk_reg: + if((unsigned int)itok.number>BX){ + op66(r16); + op(0x89); /* MOV CX,reg */ + warningreg(regs[0][1]); + op(0xC1+(unsigned int)itok.number*8); /* MOV instr */ + itok.number=CL; + } + goto defmul; + default: valueexpected(); break; + } + break; + case tk_xorminus: vop+=0x10; + case tk_andminus: vop+=0x18; + case tk_orminus: vop+=0x08; + getoperand(); + if(tok==tk_number){ + itok.number=-itok.number; + op(0x04+vop); + op((unsigned int)itok.number); + } + else{ + getintobeg(CL,&ofsstr); + if(optimizespeed&&(chip==5||chip==6)){ + op(0x80); + outdword(0xC1FEFFE1); //and CL,-1 inc CL + } + else outword(0xD9F6); // NEG CL + op(0x00+vop); + op(0xC8); /* opt AL,CL */ + warningreg(begs[1]); + next=0; + } + setzeroflag=TRUE; + break; + case tk_rr: + vop=8; + if(sign)vop+=0x10; + case tk_ll: + getoperand(); + if(tok==tk_number){ + if((unsigned int)itok.number==1){ + if(expand==TRUE)op66(r16); + op(0xD0+expand); op(0xE0+vop); /* SR AL,1 */ + } + else if((unsigned int)itok.number!=0){ + if(chip<2) goto llminus; + else{ + if(expand==TRUE)op66(r16); + op(0xC0+expand); op(0xE0+vop); /* SR AL,imm8 */ + op((unsigned int)itok.number); + if(cpu<2)cpu=2; + } + } + setzeroflag=TRUE; + } + else goto llminus; + break; + case tk_rrminus: + vop=8; + if(sign)vop+=0x10; + case tk_llminus: + tok=tk_minus; // need 286+ opt some time +llminus: + if(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==1)){ + getintobeg(CL,&ofsstr); + warningreg(begs[1]); + } + else getoperand(); + if(expand==TRUE)op66(r16); + op(0xD2+expand); op(0xE0+vop); + setzeroflag=TRUE; + next=0; + break; + default: operatorexpected(); break; + } + if(negflag){ + if(optimizespeed&&(chip==5||chip==6))outdword(0xC0FEFF34); //xor AL,-1 AL++ + else outword(0xD8F6);// NEG AL + negflag=0; + setzeroflag=TRUE; + } + if(next)nexttok(); + ClearReg(AX); + } +#ifdef OPTVARCONST + calcnumber=FALSE; +#endif + if(tok==tk_eof)unexpectedeof(); +} + +/* =============== doreg_32(), dobeg(), doseg() ===============*/ + +int doreg_32(int reg,int razr,int terminater) +{ +unsigned char next=1; +int vop=0,sign=0; +int i; +int reg1=idxregs[0],reg2=idxregs[1]; +unsigned long ii; +int rettype=tk_reg; +int rrettype,pointr=0; +int numpointr=0; +char *ofsstr=NULL; + if(reg==reg1){ + reg1=idxregs[1]; + reg2=idxregs[2]; + } + if(reg==reg2)reg2=idxregs[2]; + if(reg==ESP)RestoreStack(); + rrettype=razr==r16?tk_word:tk_dword; + nexttok(); + switch(tok){ + case tk_assign://= + if(am32)idxregs[4]=reg; + if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ + ofsstr=GetLecsem(terminater); + } + else{ + nexttok(); + switch(tok){ + case tk_beg: + i=r8; + break; + case tk_reg: + i=r16; + break; + case tk_reg32: + i=r32; + break; + } + if(i!=razr||RegToReg(reg,itok.number,i)==NOINREG)goto nn1; + waralreadinitreg(regs[razr/4][itok.number],regs[razr/4][reg]); + if(am32)idxregs[4]=255; + break; + } + if(ofsstr){ + int retreg; + if((retreg=CheckIDZReg(ofsstr,reg,razr))!=NOINREG){ + GetEndLex(terminater); + if(razr==r16)tok=tk_reg; + else tok=tk_reg32; + itok.number=retreg==SKIPREG?reg:retreg; + goto nn1; + } + } + nexttok(); + convert_type(&sign,&rrettype,&pointr,am32==TRUE?reg:BX); + if(rrettype==tk_float||rrettype==tk_double){ + if(am32)idxregs[4]=255; + doeaxfloatmath(tk_reg32,reg,rrettype==tk_float?0:4); + next=0; + if(ofsstr){ + IDZToReg(ofsstr,reg,razr); + free(ofsstr); + } + break; + } + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + int hnumber=MultiAssign(razr,USEALLREG,numpointr); +// puts("end MultAssign"); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + if(reg!=hnumber){ + op66(razr); + op(0x89); + op(0xC0+reg+hnumber*8); //mov reg,AX + } + next=0; +/* if(ofsstr){ + IDZToReg(ofsstr,reg,razr); + free(ofsstr); + }*/ + if(am32)idxregs[4]=255; + break; + } +// printf("tok=%d %s\n",tok,itok.name); + if(tok==tk_pointer)cpointr(am32==TRUE?reg:BX,numpointr); + if(tok==tk_new||tok==tk_delete){ + if(tok==tk_new)donew(); + else{ + dodelete(); + terminater=next=0; + } + if(am32)idxregs[4]=255; + if(reg!=AX){ + GenRegToReg(reg,AX,(am32+1)*2); + } + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + break; + } +nn1: + if(am32)idxregs[4]=255; + if(reg==AX){ + if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr); + else if(rrettype==tk_int||rrettype==tk_word)rettype=do_e_axmath(sign,r16,&ofsstr); + else rettype=do_e_axmath(sign,r32,&ofsstr); + convert_returnvalue(razr==r16?tk_word:tk_dword,rrettype); + } + else{ + if(rrettype==tk_char||rrettype==tk_byte&®<=BX){ + rettype=getintobeg(reg,&ofsstr); + if(itok.type!=tp_stopper&&tok!=tk_eof){ + dobegmath(reg); + rettype=tk_beg; + } + op66(razr); + op(0x0F); + if(!sign)op(0xB6); + else op(0xBE); + op(0xC0+reg*9); + } + else{ + if(rrettype==tk_int||rrettype==tk_word)next=r16; + else next=r32; + rettype=getintoreg(reg,next,sign,&ofsstr); + if(next==r16&&razr==r32){ + op66(r32); + op(0x0F); + if(!sign)op(0xB7); + else op(0xBF); + op(0xC0+reg*9); + } + } + } + next=0; + if(ofsstr){ + IDZToReg(ofsstr,reg,razr); + free(ofsstr); + } + break; + case tk_plusplus: op66(razr); op(0x40+reg); + ClearReg(reg); + break; + case tk_minusminus: op66(razr); op(0x48+reg); + ClearReg(reg); + break; + case tk_cdecl: + case tk_pascal: + case tk_fastcall: + case tk_stdcall: + vop=tok; + nexttok(); + if(tok!=tk_openbracket){ + expected('('); + FindStopTok(); + } + case tk_openbracket: //맮 楤 ॣ + param[0]=0; + i=0; + switch ( vop ) { + case tk_cdecl: + case tk_stdcall: + i=swapparam(); + break; + case tk_pascal: + doparams(); + break; + case tk_fastcall: + doregparams(); + break; + default: + if(comfile==file_w32)swapparam(); + else doparams(); + } + if(vop!=tk_cdecl)i=0; + op66(razr); + op(0xFF); + op(0xD0+reg); /* CALL reg with stack params */ + if(i)CorrectStack(i); + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + break; + case tk_swap: + getoperand(reg==BX?SI:BX); + switch(tok){ + case tk_qwordvar: + case tk_longvar: + case tk_dwordvar: + if(razr==r16)swaperror(); + i=4; + goto swapint; + case tk_intvar: + case tk_wordvar: + i=2; + if(razr==r32)swaperror(); +swapint: + ClearReg(reg); + CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); + op66(razr); + outseg(&itok,2); + op(0x87); + op(reg*8+itok.rm); + outaddress(&itok); + break; + case tk_reg32: + if(razr==r16)swaperror(); + goto swapreg; + case tk_reg: + if(razr==r32)swaperror(); +swapreg: + if(reg!=(int)itok.number){ + if(RegSwapReg(reg,itok.number,razr)==NOINREG){; + op66(razr); + if(reg==AX)op(0x90+(unsigned int)itok.number); + else if((unsigned int)itok.number==AX)op(0x90+reg); + else{ + op(0x87); + op(0xC0+(unsigned int)itok.number+reg*8); + } + } + else waralreadinitreg(regs[razr/4][reg],regs[razr/4][itok.number]); + } + break; + default: swaperror(); break; + } + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + ClearReg(reg); + if(am32&&uselea&&tok==tk_plusequals){ + if(RegEqualToLea(reg)){ + next=0; + break; + } + } + if(CheckAddOnly()){ + inptr2--; + cha2=' '; + if(tok==tk_plusequals)tok=tk_plus; + else tok=tk_minus; + if(reg==EAX)do_e_axmath2(0,razr,0); + else doregmath_32(reg,razr,0,&ofsstr); + next=0; + break; + } + getoperand(reg==BX?SI:BX); + if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&&tok!=tk_postnumber)goto defadd; + CheckMinusNum(); + idrec *rrec; + int opost; + i=tok; + switch(tok){ + case tk_postnumber: + case tk_undefofs: + ii=itok.number; + rrec=itok.rec; + opost=itok.post; + char uname[IDLENGTH]; + strcpy(uname,itok.name); + if(itok.flag&f_extern)goto addnum; + tok=tk_number; + case tk_number: + ii=doconstdwordmath(); + next=0; + if(itok.type==tp_opperand){ + if(reg==EAX){ + sign=ECX; + if((tok2==tk_reg||tok2==tk_reg32)&&itok2.number==ECX)sign=EDX; + warningreg(regs[razr/2-1][sign]); + } + if(i==tk_postnumber||i==tk_undefofs){ + op66(razr); + op(0xB8+reg); // MOV reg,# + if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); + else{ + if((postnumflag&f_reloc)!=0)AddReloc(); + if(i==tk_undefofs)AddUndefOff(2,uname); + } + razr==r16?outword(ii):outdword(ii); + } + else MovRegNum(razr,postnumflag&f_reloc,ii,sign); + if(sign==EAX)do_e_axmath2(0,razr,0); + else doregmath_32(sign,razr,0,&ofsstr); + itok.number=sign; + goto addreg; + } + if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber&&optnumadd(ii,reg,razr,vop))break; +addnum: + op66(razr); + if(reg==AX)op(0x05+vop); + else{ + op(0x81); + op(0xC0+vop+reg); + } + itok.rec=rrec; + itok.post=opost; + if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); + else{ + if((postnumflag&f_reloc)!=0)AddReloc(); + if(i==tk_undefofs)AddUndefOff(2,uname); + } + razr==r16?outword(ii):outdword(ii); + break; + case tk_qwordvar: + case tk_longvar: + case tk_dwordvar: + i=4; + goto wordadd; + case tk_intvar: + case tk_wordvar: + i=2; + if(razr==r32)valueexpected(); +wordadd: + CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); + op66(razr); + outseg(&itok,2); + op(0x03+vop); + op(reg*8+itok.rm); + outaddress(&itok); + break; + case tk_reg: + if(razr==r32)valueexpected(); + case tk_reg32: +addreg: + op66(razr); + op(0x01+vop); + op(0xC0+reg+(unsigned int)itok.number*8); + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: +unsigned char oaddstack; + if(reg==EAX){ + op66(razr); + op(0x50); //push AX + addESP+=razr==r16?2:4; + warningreg(regs[razr/2-1][EDX]); + oaddstack=addstack; + addstack=FALSE; + } + procdo(razr==r16?tk_word:tk_dword); + if(itok2.type==tp_opperand){ + nexttok(); + do_e_axmath2(0,razr,0); + next=0; + } + if(reg==EAX){ + addstack=oaddstack; + addESP-=razr==r16?2:4; + op66(razr); + op(0x58+EDX); //pop dx + if(vop>0x20){ + op66(razr); + op(0x90+EDX); //xchg ax,dx + } + op66(razr); + op(0x01+vop); + op(0xc0+EDX*8); //add ax,dx + } + else{ + op66(razr); + op(0x01+vop); + op(0xc0+reg); //add reg,ax + } + break; + case tk_seg: + if(razr==r32)valueexpected(); + case tk_bytevar: + case tk_charvar: + case tk_beg: +defadd: + if(reg==AX){ + getintoreg_32(ECX,razr,sign,&ofsstr); + doregmath_32(ECX,razr,sign,&ofsstr); + sign=CX; //sign ஬ ॣ + } + else{ + do_e_axmath(0,razr,&ofsstr); + sign=EAX; + } + warningreg(regs[razr/2-1][sign]); + op66(razr);// OPT reg32,ECX + op(0x01+vop); + op(0xC0+reg+sign*8); + next=0; + break; + default: valueexpected(); break; + } + break; + case tk_rrequals: vop+=0x08; + case tk_llequals: + ClearReg(reg); + getoperand(am32==TRUE?ECX:reg==BX?SI:BX); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstlongmath(); + next=0; + if(itok.type==tp_opperand){ + if(reg==ECX)regshifterror(); + op(0xB0+CL); op(ii); //mov CL,num + dobegmath(CL); + warningreg(begs[1]); + ConstToReg(ii,CL,r8); + goto shiftcl; + } + if(ii==1){ + op66(razr); + op(0xD1); op(0xE0+reg+vop); + } /* SHL reg,1 */ + else if(ii!=0){ + if(chip<2&&razr==r16){ + op(0xB0+CL); op(ii); //mov CL,num + warningreg(begs[1]); + ConstToReg(ii,CL,r8); + goto shiftcl; + } + else{ + op66(razr); + op(0xC1); op(0xE0+reg+vop); /* SHL reg,imm8 */ + op(ii); + if(cpu<2)cpu=2; + } + } + } + else if(reg!=CX){ + if(!(itok2.type==tp_stopper&&(tok==tk_beg||tok==reg||tok==tk_reg32)&&itok.number==CL)){ + getintobeg(CL,&ofsstr); + dobegmath(CL); + warningreg(begs[1]); + ClearReg(CL); + next=0; + } +shiftcl: + op66(razr); + op(0xD3); op(0xE0+vop+reg); /* SHL AX,CL */ + } + else regshifterror(); + break; + case tk_multequals: + ClearReg(reg); + getoperand(reg==BX?SI:BX); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstlongmath(); + next=0; + if(itok.type==tp_opperand){ + if(reg==EAX)sign=ECX; + MovRegNum(razr,postnumflag&f_reloc,ii,sign); + if(sign==EAX)do_e_axmath2(0,razr,0); + else doregmath_32(ECX,razr,0,&ofsstr); + ConstToReg(ii,sign,razr); + goto mulreg; + } + i=0; + RegMulNum(reg,ii,razr,0,&i,itok.flag); + } + else{ + if(itok2.type==tp_stopper)next=(unsigned char)MulReg(reg,razr); + else{ + if(reg==AX){ + getintoreg_32(ECX,razr,sign,&ofsstr); + doregmath_32(ECX,razr,sign,&ofsstr); + sign=CX; //sign ஬ ॣ + } + else{ + do_e_axmath(0,razr,&ofsstr); + sign=EAX; + } +mulreg: + warningreg(regs[razr/2-1][sign]); + ClearReg(sign); + op66(razr); + outword(0xAF0F); + op(0xC0+reg*8+sign); + next=0; + } + } + break; + case tk_divequals: + getoperand(reg==BX?SI:BX); + ClearReg(reg); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstlongmath(); + next=0; + if(itok.type==tp_opperand){ + op66(razr); + op(0x50+reg); //push reg + addESP+=razr==r16?2:4; + MovRegNum(razr,postnumflag&f_reloc,ii,EAX); + do_e_axmath2(0,razr,0); + ClearReg(AX); + goto divreg; + } + if((vop=caselong(ii))!=NUMNUM&&(!(reg==ECX&&chip<2))){ + if(vop!=0){ + if(chip<2&&razr==r16){ + op(0xB1); op(vop); /* MOV CL,num */ + op(0xD3); + op(0xE8+reg); // SHR reg,CL + warningreg(begs[1]); + ClearReg(CX); + } + else{ + op66(razr); + op(0xC1); + op(0xE8+reg); // SHR reg,num + op(vop); + } + } + } + else{ + if(reg!=EAX){ + op66(razr); + op(0x90+reg); //xchg reg,AX + } + DivNum(ii,razr,0); + if(reg!=EAX){ + op66(razr); + op(0x90+reg); //xchg reg,AX + warningreg(regs[razr/2-1][EAX]); + ClearReg(AX); + } + } + } + else if(itok2.type==tp_stopper){ + if(reg!=EAX){ + op66(razr); + op(0x90+reg); //xchg reg,AX + } + DivMod(0,0,razr,0); + next=0; + if(reg!=EAX){ + op66(razr); + op(0x90+reg); //xchg reg,AX + warningreg(regs[razr/2-1][EAX]); + ClearReg(AX); + } + } + else{ + op66(razr); + op(0x50+reg); //push reg + addESP+=razr==r16?2:4; + do_e_axmath(0,razr,&ofsstr); +divreg: + op66(razr); + sign=reg; + if(reg==EAX){ + sign=ECX; + warningreg(regs[razr/2-1][ECX]); + ClearReg(CX); + } + addESP-=razr==r16?2:4; + op(0x58+sign); //pop sign + op66(razr); + op(0x90+sign); //xchg AX,sign + op66(razr); + op(0xF7); + op(0xF0+sign); // DIV reg + op66(razr); + if(reg!=EAX){ + if(optimizespeed){ + op(0x89); + op(0xC0+reg); //mov reg,AX + } + else op(0x90+reg); //xchg AX,sign + } + warningreg(regs[razr/2-1][EAX]); + ClearReg(AX); + next=0; + } + break; + default: operatorexpected(); break; + } + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + if(razr==r32&&cpu<3)cpu=3; +// puts("return doreg_32"); + return rettype; +} + +int optnumadd(unsigned long num,int reg,int razr,int vop) +{ +int nrazr=0; + if(num==0){ + if(vop==0x20){ //&= + ZeroReg(reg,razr); + setzeroflag=TRUE; + } + return TRUE; //+= -= |= ^= + } + if(vop==8){ //|= + if(num<65536&&razr==r32)nrazr=razr=r16; + if((unsigned short)num<256&&razr==r16&®<4){ + if(reg==AX)op(0x0C); + else{ + op(0x80); + op(0xc8+reg); + } + op(num); + return TRUE; + } + if(nrazr==r16){ + op66(r16); + if(reg==AX)op(0x0D); + else{ + op(0x81); + op(0xc8+reg); + } + outword(num); + return TRUE; + } + } + if(num==1){ + if(vop==0x28){ //-= + op66(razr); + op(0x48+reg); + setzeroflag=TRUE; + return TRUE; + } + if(vop==0){ //+= + op66(razr); + op(0x40+reg); + setzeroflag=TRUE; + return TRUE; + } + } + if(!optimizespeed&&num==2&&((razr==r16&&am32==FALSE)||(razr==r32&&am32))){ + if(vop==0x28){ //-= + op(0x48+reg); + op(0x48+reg); + setzeroflag=TRUE; + return TRUE; + } + if(vop==0){ //+= + op66(razr); + op(0x40+reg); + op66(razr); + op(0x40+reg); + setzeroflag=TRUE; + return TRUE; + } + } + if((razr==r16&&(unsigned short)num==0xffff)|| + (razr==r32&&num==0xffffffff)){ + if(vop==0x28){ //-= + op66(razr); + op(0x40+reg); + setzeroflag=TRUE; + return TRUE; + } + if(vop==0){ //+= + op66(razr); + op(0x48+reg); + setzeroflag=TRUE; + return TRUE; + } + if(vop==0x20)return TRUE; //&= + if(vop==0x30){ //^= + if(optimizespeed&&(chip==5||chip==6))return FALSE; + op66(razr); + op(0xF7); + op(0xD0+reg); //Not reg + setzeroflag=FALSE; + return TRUE; + } + } + if(vop==0x20){ //&= + if(num>=0xFFFF0000&&razr==r32)nrazr=razr=r16; + if(razr==r16&&(unsigned short)num>=0xFF00&®<4){ + if(reg==AL)op(0x24); + else{ + op(128); + op(0xE0+reg); + } + op(num); + return TRUE; + } + if(nrazr==r16){ + op66(r16); + if(reg==AX)op(0x25); + else{ + op(129); + op(0xE0+reg); + } + outword(num); + return TRUE; + } + } + if(!optimizespeed&&(razr==r16&&(unsigned short)num==0xfffe&&am32==FALSE)|| + (razr==r32&&num==0xfffffffe&&am32)){ + if(vop==0x28){ //-= + op(0x40+reg); + op(0x40+reg); + setzeroflag=TRUE; + return TRUE; + } + if(vop==0){ //+= + op(0x48+reg); + op(0x48+reg); + setzeroflag=TRUE; + return TRUE; + } + } + if(short_ok(num,razr/2-1)){ + op66(razr); + op(0x83); + op(0xC0+vop+reg); + op(num); + setzeroflag=TRUE; + return TRUE; + } + return FALSE; +} + +int dobeg(int beg,int terminater) +{ +unsigned char next=1; +int vop=0,i=0,sign=0; +int rettype=tk_beg,pointr=0;; +int rrettype=tk_byte; +int numpointr=0; +char *ofsstr=NULL; + nexttok(); + switch(tok){ + case tk_assign: + if(!((tok2==tk_reg||tok2==tk_reg32||tok2==tk_beg)&&ScanTok3()==terminater)){ + ofsstr=GetLecsem(terminater); + } + else{ + nexttok(); + if(RegToReg(beg,itok.number,r8)==NOINREG)goto nn1; + waralreadinitreg(begs[itok.number],begs[beg]); + break; + } + if(ofsstr){ + int retreg; + if((retreg=CheckIDZReg(ofsstr,beg,r8))!=NOINREG){ + GetEndLex(terminater); + tok=tk_beg; + itok.number=retreg==SKIPREG?beg:retreg; + goto nn1; + } + } + nexttok(); + convert_type(&sign,&rrettype,&pointr,am32==TRUE?(beg>3?beg-4:beg):BX); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + int hnumber=MultiAssign(r8,(beg>3?beg-4:beg),numpointr); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + if(beg!=hnumber){ + op(0x88); + op(0xC0+beg+hnumber*8); //mov beg,AL + } + next=0; + if(ofsstr){ + IDZToReg(ofsstr,beg,r8); + free(ofsstr); + } + break; + } + if(tok==tk_pointer)cpointr(am32==TRUE?(beg>3?beg-4:beg):BX,numpointr); +nn1: + if(beg==AL){ + if(rrettype==tk_char||rrettype==tk_byte)rettype=doalmath(sign,&ofsstr); + else if(rrettype==tk_int||rrettype==tk_word)rettype=do_e_axmath(sign,r16,&ofsstr); + else rettype=do_e_axmath(sign,r32,&ofsstr); + next=0; + } + else{ + if(rrettype==tk_char||rrettype==tk_byte||beg>BL){ + rettype=getintobeg(beg,&ofsstr); + if(itok.type!=tp_stopper&&tok!=tk_eof){ + dobegmath(beg); + rettype=tk_beg; + } + } + else{ + if(rrettype==tk_int||rrettype==tk_word)next=r16; + else next=r32; + rettype=getintoreg(beg,next,sign,&ofsstr); + } + next=0; + } + if(ofsstr){ + IDZToReg(ofsstr,beg,r8); + free(ofsstr); + } + break; + case tk_plusplus: op(0xFE); op(0xC0+beg); + ClearReg(beg>3?beg%4:beg); + break; + case tk_minusminus: op(0xFE); op(0xC8+beg); + ClearReg(beg>3?beg%4:beg); + break; + case tk_swap: + getoperand(beg==BL||beg==BH?SI:BX); + switch(tok){ + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(bufrm,1,&strinf); + outseg(&itok,2); + op(0x86); + op(beg*8+itok.rm); + outaddress(&itok); + KillVar(itok.name); + ClearReg(beg>3?beg-4:beg); + break; + case tk_beg: + if(beg!=(int)itok.number){ + if(RegSwapReg(beg,itok.number,r8)==NOINREG){ + op(0x86); + op(0xC0+(unsigned int)itok.number+beg*8); + } + else waralreadinitreg(begs[beg],begs[itok.number]); + } + break; + default: swaperror(); break; + } + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + ClearReg(beg>3?beg%4:beg); + if(CheckAddOnly()){ + inptr2--; + cha2=' '; + if(tok==tk_plusequals)tok=tk_plus; + else tok=tk_minus; + if(beg==AL)doalmath2(0); + else dobegmath(beg); + next=0; + break; + } + getoperand(beg==BL||beg==BH?SI:BX); + if(itok2.type==tp_opperand&&tok!=tk_number){ + if(beg==AL){ + getintobeg(CL,&ofsstr); + dobegmath(CL); + sign=CL; //sign ஬ ॣ + } + else{ + doalmath(0,&ofsstr); + sign=EAX; + } + warningreg(begs[sign]); + op(0x00+vop); + op(0xC0+beg+sign*8); + next=0; + break; + } + switch(tok){ + case tk_number: + i=doconstlongmath(); + next=0; + if(i==0&&(vop==0||vop==0x28||vop==8))break; + if(i==255&&vop==0x20)break; + if(beg==AL)op(0x04+vop); + else{ + op(0x80); + op(0xC0+vop+beg); + } + op(i); + break; + case tk_qwordvar: + i+=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0x02+vop); + op(beg*8+itok.rm); + outaddress(&itok); + break; + case tk_beg: + op(0x00+vop); + op(0xC0+beg+(unsigned int)itok.number*8); + break; + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + case tk_ID: + case tk_id: + op66(r16); + i=beg<4?beg:beg-4; + op(0x50+i); + addESP+=2; + warningreg(regs[0][i]); + procdo(tk_byte); + if(itok2.type==tp_opperand){ + nexttok(); + doalmath2(0); + next=0; + } + addESP-=2; + op66(r16); + op(0x58+(i!=AX?i:CX)); + if(i!=AX){ + op(0x00+vop); + op(0xc0+beg); + } + else{ + if(vop>0x20){ + op(0x86); + op(0xC0+CL+beg); //xchg al,cl + } + op(0x00+vop); + op(0xc0+CL*8+beg); + } + break; + case tk_reg: + if((unsigned int)itok.number3?beg%4:beg); + if(itok2.type==tp_stopper&&tok==tk_number){ + if((unsigned int)itok.number==1){ + op(0xD0); op(0xE0+beg+vop); + } /* SHL beg,1 */ + else if((unsigned int)itok.number!=0){ + if(chip<2)goto shiftbeg; + else{ + op(0xc0); + op(0xe0+beg+vop); + op((unsigned int)itok.number); + } + } + } + else{ +shiftbeg: + if(beg!=CL){ + if(itok2.type==tp_stopper&&tok==tk_beg&&itok.number==CL){ + op(0xD2); op(0xE0+vop+beg); /* SHL beg,CL */ + } + else{ + ClearReg(CL); + getintobeg(CL,&ofsstr); + dobegmath(CL); + next=0; + warningreg(begs[1]); + op(0xD2); op(0xE0+vop+beg); /* SHL beg,CL */ + } + } + else regshifterror(); + } + break; + default: operatorexpected(); break; + } + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + return rettype; +} + +void doseg(int seg) +{ +unsigned char next=1; +int numpointr=0; +char *ofsstr=NULL; + if(seg==CS)preerror("CS not used for destention"); + if(seg==FS||seg==GS)if(cpu<3)cpu=3; + if(seg==SS)RestoreStack(); + nexttok(); + KillVar(segs[seg]); + if(tok==tk_assign){ + nexttok(); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + itok.number=MultiAssign(r16,USEALLREG,numpointr); + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + goto getfromreg; + } + if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); + if(itok2.type!=tp_opperand){ + switch(tok){ + case tk_reg: +getfromreg: + op(0x8E); + op(0xC0+seg*8+(unsigned int)itok.number); /* MOV seg,reg */ + break; + case tk_intvar: + case tk_wordvar: + case tk_longvar: + case tk_dwordvar: + case tk_qwordvar: + CheckAllMassiv(bufrm,2,&strinf); + op66(r16); + outseg(&itok,2); + op(0x8E); + op(seg*8+itok.rm); + outaddress(&itok); /* MOV seg,[wordvar] */ + break; + case tk_seg: + if(optimizespeed==FALSE||(regoverstack&&chip>2)){ + PushSeg((unsigned int)itok.number); + PopSeg(seg); + break; + } + goto segax; + case tk_number: + if(regoverstack&&chip>1){ +// op66(r16); + if(short_ok(itok.number)&&(itok.flag&f_reloc)==0){ + op(0x6A); + op(itok.number); + } + else{ + op(0x68); + if((itok.flag&f_reloc)!=0)AddReloc(); + if(am32)outdword(itok.number); + else outword(itok.number); + } + PopSeg(seg); + if(cpu<2)cpu=2; + break; + } + goto segax; + default: goto segax; + } + } + else{ +segax: + do_e_axmath(0,r16,&ofsstr); + op(0x8E); /* MOV SEG,AX */ + op(0xC0+seg*8); + next=0; + } + } + else if(tok==tk_swap){ + getoperand(); + switch(tok){ + case tk_intvar: + case tk_wordvar: + KillVar(itok.name); + op66(r16); + op(0x8C); + op(0xC0+seg*8); /* MOV AX,SEG */ + CheckAllMassiv(bufrm,2,&strinf); + op66(r16); + outseg(&itok,2); + op(0x87); + op(itok.rm); + outaddress(&itok); /* XCHG AX,[word] */ + op66(r16); + op(0x8E); + op(0xC0+seg*8); /* MOV seg,AX */ + break; + case tk_seg: + KillVar(segs[itok.number]); + PushSeg(seg); + PushSeg(itok.number); + PopSeg(seg); + PopSeg(itok.number); + break; + default: preerror("Only int, word variables valid for segment register ><"); + break; + } + } + else segoperror(); + if(next)nextseminext(); + else seminext(); +} + +void PushSeg(int seg) +{ + switch(seg){ + case DS: op(0x1E); break; + case CS: op(0x0E); break; + case SS: op(0x16); break; + case ES: op(0x06); break; + case FS: outword(0xA00F); if(cpu<3)cpu=3; break; + case GS: outword(0xA80F); if(cpu<3)cpu=3; break; + } +} + +void PopSeg(int seg) +{ + switch(seg){ + case DS: op(0x1F); break; + case SS: op(0x17); break; + case ES: op(0x07); break; + case FS: outword(0xA10F); if(cpu<3)cpu=3; break; + case GS: outword(0xA90F); if(cpu<3)cpu=3; break; + } +} + +// =============== doregmath_32(), dobegmath() =============== + +void doregmath_32(int reg,int razr,int sign,char **ofsstr,int fdiv) // math done is on all regs except AX +// all other registers preserved +{ +int vop,i,optnum,negflag=FALSE; + while(itok.type!=tp_stopper&&tok!=tk_eof){ + if(negflag){ + NegReg(razr,reg); + negflag=FALSE; + } + i=vop=0; + optnum=FALSE; +#ifdef OPTVARCONST + CheckConstVar3(&tok2,&itok2,razr); + if(tok2==tk_number)calcnumber=TRUE; +#endif + if(uselea){ + if(razr==r32){ + if(Reg32ToLea2(reg))continue; //⨬ ᫮ 32- ॣ஢ LEA + } + else if(Reg16ToLea2(reg))continue; + if(itok.type==tp_stopper||tok==tk_eof)break; + } + if(tok2==tk_number)optnum=OptimNum(); + switch(tok){ + case tk_xor: vop+=0x08; + case tk_minus: vop+=0x08; + case tk_and: vop+=0x18; + case tk_or: vop+=0x08; + case tk_plus: + if(optnum==FALSE)getoperand(reg==BX?SI:BX); + else tok=tk_number; + switch(tok){ + case tk_number: + if((itok.flag&f_reloc)==0&&optnumadd(itok.number,reg,razr,vop))break; + case tk_postnumber: + case tk_undefofs: + op66(razr); + op(0x81); + op(0xC0+vop+reg); + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else if((itok.flag&f_reloc)!=0)AddReloc(); + razr==r16?outword((unsigned int)itok.number):outdword(itok.number); + break; + case tk_apioffset: + op66(razr); + op(0x81); + op(0xC0+vop+reg); + AddApiToPost(itok.number); + break; + case tk_doublevar: + i=4; + case tk_floatvar: + Float2reg32(EAX,i); + itok.number=EAX; + warningreg(regs[1][EAX]); + goto defreg32; + case tk_bits: + int vops,reg2s; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + if(vops=tk_charvar&&tok2<=tk_doublevar&&itok2.npointr==0){ + if(CheckConstVar(&itok2)){ + tok2=tk_number; + calcnumber=TRUE; + } + } +#endif + if(tok2==tk_number)optnum=OptimNum(); + int oldtok=tok; + switch(tok){ + case tk_xor: vop+=0x08; + case tk_minus: vop+=0x08; + case tk_and: vop+=0x18; + case tk_or: vop+=0x08; + case tk_plus: + if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX); + else{ + tok=tk_number; + optnum=FALSE; + } + switch(tok){ + case tk_number: + if(itok.number==0&&oldtok!=tk_and)break; + else if(itok.number==1){ + if(oldtok==tk_plus){ + op(0xFE); + op(0xC0+beg); + break; + } + if(oldtok==tk_minus){ + op(0xFE); + op(0xC8+beg); + break; + } + } + else if((unsigned char)itok.number==0xff){ + if(oldtok==tk_minus){ + op(0xFE); + op(0xC0+beg); + break; + } + if(oldtok==tk_plus){ + op(0xFE); + op(0xC8+beg); + break; + } + } + op(0x80); + op(0xC0+vop+beg); + op((unsigned int)itok.number); + break; + case tk_bits: + int vops,reg2s; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + if(i<=8)vops=r8; + reg2s=CL; + if(beg==CL)reg2s=BL; + bits2reg(reg2s,vops); + if(vops==r64)vops=r32; + warningreg(vops==r8?begs[reg2s]:regs[vops/2-1][reg2s]); + itok.number=reg2s; + case tk_beg: + op(0x00+vop); + op(0xC0+beg+(unsigned int)itok.number*8); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_bytevar: + case tk_charvar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0x02+vop); + op(beg*8+itok.rm); + outaddress(&itok); + break; + case tk_postnumber: + case tk_reg: + case tk_rmnumber: begworderror(); break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc:// begcallerror(); break; + case tk_declare: + procdo(tk_byte); + if(beg!=AL){ + op(0x00+vop); + op(0xc0+beg); + } + break; + default: valueexpected(); break; + } + break; + case tk_xorminus: vop+=0x10; + case tk_andminus: vop+=0x18; + case tk_orminus: vop+=0x08; + getoperand(beg==BL||beg==BH?SI:BX); + if(tok==tk_number){ + itok.number=-itok.number; + op(0x80); + op(0xC0+vop +beg); + op((unsigned int)itok.number); + } + else negregerror(); + break; + case tk_rr: + vop=8; + case tk_ll: + nexttok(); + if(tok==tk_number){ + if((unsigned int)itok.number==1){ + if(vop==0){ + op(2); + op(0xC0+9*beg); // ADD reg,reg + } + else{ + op(0xD0); op(0xE8+beg); /* SHR reg,1 */ + } + } + else if((unsigned int)itok.number!=0){ + if(chip<2)begmathoperror(); + else{ + op(0xc0); + op(0xe0+beg+vop); // SHL reg,imm8 + op((unsigned int)itok.number); + if(cpu<2)cpu=2; + } + } + } + else if(tok==tk_beg&&itok.number==CL&&beg!=CL){ + op(0xD2); + op(0xE0+beg+vop); // SHL xXX,CL + } + else begmathoperror(); + break; + case tk_multminus: negflag=TRUE; + case tk_mult: + if(optnum==FALSE)getoperand(beg==BL||beg==BH?SI:BX); + else{ + tok=tk_number; + optnum=FALSE; + } + if(negflag&&tok==tk_number){ + itok.number=-itok.number; + negflag=FALSE; + } + switch(tok){ + case tk_number: + itok.number&=255; + switch((unsigned int)itok.number){ + case 0: // beg * 0 = MOV beg,0 + outword(0x00B0+beg); + case 1: break; //beg*1=beg + case 2: + op(0); + op(0xC0+9*beg); // beg * 2 = ADD beg,beg + break; + default: + vop=caselong(itok.number); + if(vop!=NUMNUM){ + if(chip<1)begmathoperror(); + else{ + op(0xc0); + op(0xe0+beg); //SHL beg,num + op(vop); + if(cpu<1)cpu=1; + } + } + else begmathoperror(); + } + break; + default: begmathoperror(); break; + } + break; + case tk_divminus: + case tk_modminus: + case tk_div: + case tk_mod: + case tk_rrminus: + case tk_llminus: + begmathoperror(); break; + default: operatorexpected(); break; + } +#ifdef OPTVARCONST + calcnumber=FALSE; +#endif + nexttok(); + ClearReg(beg%4); + } +} + +// ============= getintoreg_32(), getintobeg() ============ + +int getintoreg_32(int reg,int razr,int sign,char **ofsstr,int useloop) // get into word reg (except AX) with enum +{ +int negflag=0,next=1,i=0; +int swap=0,oflag=0; +unsigned long holdnumber=0; +int reg1=idxregs[0],reg2=idxregs[1]; +int rettype=tk_reg; +int loop=0,otok; +// printf("line %d tok=%d %s\n",linenumber,tok,itok.name); + if(!am32){ + if(reg==idxregs[1]||reg==idxregs[2]){ + reg1=reg; + if(reg==idxregs[1])reg2=idxregs[0]; + } + } + else{ + reg1=reg; + if(reg==idxregs[1])reg2=idxregs[0]; + } + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + negflag=1; + getoperand(am32==FALSE?BX:reg); + } + } +loopswitch: + + if(uselea){ + if(razr==r32){ + if(cpu<3)cpu=3; + if(Reg32ToLea(reg)){ + return tk_reg; + } + } + else + if(Reg16ToLea(reg)){ + return tk_reg; + } + } +loopswitch1: + +#ifdef OPTVARCONST + CheckConstVar3(&tok,&itok,razr); + if(tok==tk_number)calcnumber=TRUE; +#endif + otok=tok; +// printf("reg=%d tok=%d\n",reg,tok); + switch(tok){ + case tk_number: + if(useloop==FALSE)MovRegNum(razr,itok.flag&f_reloc,itok.number,reg); + else{ + holdnumber=CalcNumber(sign); + if(loop==0)oflag=postnumflag; + else oflag^=postnumflag; + loop++; + if(tok==tk_mult){ + nexttok(); + swap=1; + goto loopswitch1; + } + if(tok==tk_plus&&tok2==tk_postnumber){ + nexttok(); +// getoperand(am32==TRUE?EAX:BX); + goto loopswitch1; + } + MovRegNum(razr,oflag&f_reloc,holdnumber,reg); + next=0; + } + break; + case tk_postnumber: + case tk_undefofs: + if(!swap){ + op66(razr); + op(0xB8+reg); /* MOV AX,# */ + swap=1; + } + if(tok==tk_undefofs){ + AddUndefOff(2,itok.name); +// AddUndefOff(0,itok.name); +// itok.flag=0; //new 07.07.04 23:57 + } + else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(useloop==FALSE)holdnumber=itok.number; + else{ + tok=tk_number; + holdnumber+=doconstdwordmath(); + if(otok!=tk_postnumber){ + if(loop==0)oflag=postnumflag; + else oflag^=postnumflag; + loop++; + } + if(tok==tk_plus&&tok2==tk_postnumber){ + nexttok(); + goto loopswitch1; + } + swap=0; + next=0; + } + if(useloop&&(oflag&f_reloc))AddReloc(); + if(razr==r16)outword(holdnumber); + else outdword(holdnumber); + ClearReg(reg); + break; + case tk_apioffset: + op66(razr); + op(0xB8+reg); /* MOV AX,# */ + AddApiToPost(itok.number); + ClearReg(reg); + break; + case tk_rmnumber: + CheckAllMassiv(bufrm,itok.size,&strinf,&itok,reg1,reg2); + if((am32&&itok.rm==reg&®!=EBP&®!=ESP)||(am32==0&®==itok.rm&& + (reg==SI||reg==DI||reg==BX)))break; + op66(razr); + op67(itok.sib==CODE16?r16:r32); + if(itok.post==0)outseg(&itok,2); + op(0x8D); // LEA reg,[rm] + op(reg*8+itok.rm); + if(itok.post!=0&&itok.post!=UNDEF_OFSET){ + if((itok.flag&f_extern)==0){ + unsigned int ooutptr=outptr; + if(am32&&itok.rm==rm_sib)outptr++; + setwordpost(&itok); + outptr=ooutptr; + } + else setwordext(&itok.number); + } + if(useloop==FALSE)outaddress(&itok); + else{ +ITOK oitok; + oitok=itok; + tok=tk_number; + itok.rm=tk_dword; + oitok.number=doconstdwordmath(); + outaddress(&oitok); + next=0; + } + ClearReg(reg); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=4; +dwordvar: + CheckAllMassiv(bufrm,i,&strinf,&itok,reg1,reg2); + op66(razr); + outseg(&itok,2); + op(0x8B); + op(reg*8+itok.rm); + outaddress(&itok); + ClearReg(reg); + break; + case tk_intvar: + case tk_wordvar: + i=2; + if(razr==r16)goto dwordvar; + CheckAllMassiv(bufrm,2,&strinf,&itok,reg1,reg2); + if(tok==tk_wordvar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ + ZeroReg(reg,r32); + op66(r16); + outseg(&itok,2); //mov reg,var + op(0x8B); + } + else{ + op66(r32); + outseg(&itok,3); //movxx reg,var + op(0x0F); op(tok==tk_wordvar?0xB7:0xBF); + } + op(reg*8+itok.rm); + outaddress(&itok); + ClearReg(reg); + break; + case tk_doublevar: + i=4; + case tk_floatvar: + Float2reg32(reg,i,reg1,reg2); + ClearReg(reg); + break; + case tk_bytevar: + case tk_charvar: + if(chip>2||razr==r32){ + CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); + if(reg<=EBX&&tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ + ZeroReg(reg,razr); + outseg(&itok,2); + op(0x8A); + } + else{ + op66(razr); + outseg(&itok,3); + op(0xf); + if(tok==tk_bytevar)op(0xb6); + else op(0xbe); + } + op(reg*8+itok.rm); // MOVZX regL,[byte] + outaddress(&itok); + ClearReg(reg); + break; + } + if(reg<=BX){ + if(reg==AX&&itok.rm==rm_d16&&itok.sib==CODE16){ + outseg(&itok,1); + op(0xA0); // MOV AL,[byte] + outword((unsigned int)itok.number); + } + else{ + CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); + outseg(&itok,2); + op(0x8A); + op(reg*8+itok.rm); // MOV regL,[byte] + outaddress(&itok); + } + ClearReg(reg); + op(0x30); op(0xC0+(reg+4)*9); // XOR regH,regH + } + else regbyteerror(); + break; + case tk_reg: + if(razr==r32){ + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=itok.number; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(r16); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ + itok.number=0; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + } + if(optimizespeed&&chip>3&&chip<7&®!=(int)itok.number){ + ZeroReg(reg,r32); + op(0x89); + op(0xC0+reg+(unsigned int)itok.number*8); + } + else{ + op66(r32); + outword(0xB70F); + op(0xC0+reg*8+(unsigned int)itok.number); + } + RegToReg(reg,itok.number,r32); + break; + } + case tk_reg32: + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=itok.number; + reg2=tok==tk_reg32?r32:r16; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(reg2); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ + itok.number=0; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + } + if(reg!=(int)itok.number){ + op66(razr); + op(0x89); + op(0xC0+reg+(unsigned int)itok.number*8); + RegToReg(reg,itok.number,r32); + } + break; + case tk_bits: + int vops; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + bits2reg(reg,(razr2||razr==r32){ + if(optimizespeed&&chip>3&&chip<7&®<4&®!=(int)(itok.number%4)){ + ZeroReg(reg,razr); + op(0x88); + op(0xC0+reg+(unsigned int)itok.number*8); // MOV regL,beg + } + else{ + op66(razr); + outword(0xb60f); + op(0xC0+reg*8+(unsigned int)itok.number); // MOVZX regL,beg + } + } + else if(reg>BX)regbyteerror(); + else{ + op(0x88); op(0xC0+reg+(unsigned int)itok.number*8); // MOV regL,beg + op(0x30); op(0xC0+(reg+4)*9); // XOR regH,regH + } + ClearReg(reg); + break; + case tk_at: + getoperand(am32==FALSE?BX:reg); + i++; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + if(itok.flag&f_retproc)rettype=(itok.flag&f_retproc)/256+tk_overflowflag-1; + if((!i)||macros(razr==r16?tk_word:tk_dword)==0)procdo(razr==r16?tk_word:tk_dword); + itok.number=0; + tok=(razr==r16?tk_reg:tk_reg32); + if(*ofsstr!=NULL){ + free(*ofsstr); + ofsstr=NULL; + } +// printf("tok=%d num=%d tok2=%d\n",tok,itok.number,tok2); + goto loopswitch; +// break; + case tk_string: + op66(razr); + op(0xB8+reg); + if(razr==r16){ + if(am32)dwordvalexpected(); + outword(addpoststring()); + } + else outdword(addpoststring()); + ClearReg(reg); + break; + default: valueexpected(); break; + } +#ifdef OPTVARCONST + calcnumber=FALSE; +#endif + if(negflag)NegReg(razr,reg); + if(swap){ + negflag=0; + RegMulNum(reg,holdnumber,razr,0,&negflag,oflag); + ClearReg(reg); + } + if(next)nexttok(); +// printf("tok=%d num=%d tok2=%d\n",tok,itok.number,tok2); + return rettype; +} + +int getintobeg(int beg,char **ofsstr) // get into beg (CL,DL,BL not others) with enum +{ +int negflag=0,i=0; +int rettype=tk_beg; + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + negflag=1; + getoperand(am32==TRUE?(beg>3?beg-4:beg):BX); + } + } +#ifdef OPTVARCONST + if(tok>=tk_charvar&&tok<=tk_doublevar&&itok.npointr==0){ +// printf("type1=%d type2=%d\n",itok.type,itok2.type); + if(CheckConstVar(&itok)){ + tok=tk_number; + calcnumber=TRUE; + } + } +#endif + switch(tok){ + case tk_number: + op(0xB0+beg); + i=(int)doconstlongmath(); + op(i); + ConstToReg(i,beg,r8); + break; + case tk_rmnumber: + CheckAllMassiv(bufrm,itok.size,&strinf); + op66(r16); + op67(itok.sib==CODE16?r16:r32); + if(itok.post==0)outseg(&itok,2); + op(0x8D); // LEA reg,[rm] + op(beg*8+itok.rm); + if(itok.post!=0&&itok.post!=UNDEF_OFSET){ + if((itok.flag&f_extern)==0){ + unsigned int ooutptr=outptr; + if(am32&&itok.rm==rm_sib)outptr++; + setwordpost(&itok); + outptr=ooutptr; + } + else setwordext(&itok.number); + } + outaddress(&itok); + ClearReg(beg%4); + break; + case tk_postnumber: + op66(r16); + op(0xB8+beg); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + outword((unsigned int)itok.number); + nexttok(); + ClearReg(beg%4); + break; + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0x8A); + op(beg*8+itok.rm); + outaddress(&itok); + nexttok(); + ClearReg(beg%4); + break; + case tk_doublevar: + i=4; + case tk_floatvar: + Float2reg32((beg<4?beg:beg-4),i); + if(beg>3){ + op(0x88); + op(0xC0+beg+8*(beg-4)); + } + nexttok(); + ClearReg(beg%4); + break; + case tk_bits: + int vops; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + if(i<=8)vops=r8; + if(beg>BX&&vops!=r8){ + op66(vops==r64?r32:vops); + op(0x50); + if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; + addESP+=vops==r16?2:4; + bits2reg(AX,vops); + op(0x88); + op(0xC0+beg); + op66(vops==r64?r32:vops); + addESP-=vops==r16?2:4; + op(0x58); + } + else bits2reg(beg,vops); + nexttok(); + break; + case tk_beg: + if(beg!=(int)itok.number){ + op(0x88); + op(0xC0+beg+(unsigned int)itok.number*8); + RegToReg(beg,itok.number,r8); + } + nexttok(); + break; + case tk_reg32: + case tk_reg: + if(begrm; + if(outtok->sib==CODE16){ + if(rm==rm_d16){ + if(outtok->post==UNDEF_OFSET){ + AddUndefOff(2,outtok->name); + outtok->post=0; + } + outword(outtok->number); + } + else{ + rm&=rm_mod11; + if(rm==rm_mod11)internalerror(badadr); + else if(rm==rm_mod10){ + if(outtok->post==UNDEF_OFSET){ + AddUndefOff(2,outtok->name); + outtok->post=0; + } + outword(outtok->number); + } + else if(rm!=rm_mod00)op(outtok->number); + } + } + else{ + if(rm==rm_d32){ + if(outtok->post==UNDEF_OFSET){ + AddUndefOff(2,outtok->name); + outtok->post=0; + } + outdword(outtok->number); + } + else{ + if((rm&7)==rm_sib){ + op(outtok->sib); + if(rm==4&&(outtok->sib&7)==5){ + if(outtok->post==UNDEF_OFSET){ + AddUndefOff(2,outtok->name); + outtok->post=0; + } + outdword(outtok->number); + } + } + rm&=rm_mod11; + if(rm==rm_mod11)internalerror(badadr); + else if(rm==rm_mod10){ + if(outtok->post==UNDEF_OFSET){ + AddUndefOff(2,outtok->name); + outtok->post=0; + } + outdword(outtok->number); + } + else if(rm==rm_mod01)op(outtok->number); + } + } +} + +/*-----------------05.01.00 23:37------------------- + ࠡ⪠ float + 樨 ६묨 ⨯ float + --------------------------------------------------*/ +int dofloatvar(int addop,int retrez,int terminater) +{ +unsigned char next=1, getfromEAX=0; +unsigned int vop=0,rettype=tk_float,posiblret=tk_float,sign=0; +char *wbuf,*rbuf; +ITOK wtok; +SINFO wstr; +int pointr=0; +int razr,i=0; +int type=tk_floatvar; + if(addop){ + rettype=posiblret=tk_double; + razr=8; + type=tk_doublevar; + } + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + KillVar(itok.name); +char *ofsstr=NULL; + nexttok(); + switch(tok){ + case tk_assign: //= + getoperand(am32==TRUE?EAX:BX); + convert_type((int *)&sign,(int *)&rettype,&pointr); + if(tok2==tk_assign){ + MultiAssignFloat(type); + next=0; + goto getfromeax; + } + CheckMinusNum(); + if(itok2.type==tp_opperand){ //⠢ + if(tok==tk_number){ //஢ઠ 㬬஢ ᥫ + if(OnlyNumber(rettype==tk_float?2:3)){ + next=0; + itok.flag=(unsigned char)postnumflag; + itok.rm=rettype; + goto numbertovar; + } + } + getfromEAX=1; + if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr); + else if(rettype==tk_int||rettype==tk_word)do_e_axmath(sign,r16,&ofsstr); + else if(rettype==tk_long||rettype==tk_dword)do_e_axmath(sign,r32,&ofsstr); + else goto labl1; + } + else{ + switch(tok){ + case tk_number: +numbertovar: + if(rettype==tk_float){ + if(itok.rm==tk_double)itok.fnumber=itok.dnumber; + else if(itok.rm!=tk_float){ + float temp=itok.number; + *(float *)&itok.number=temp; + } + } + else{ + if(itok.rm==tk_float)itok.dnumber=itok.fnumber; + else if(itok.rm!=tk_double)itok.dnumber=itok.lnumber; + } + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + for(i=0;i<2;i++){ + op66(r32); + if((itok.flag&f_reloc)==0&&itok.number==0){ + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + } + else if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){ + op(0x6A); + op(itok.number); //push short number + op66(r32); + outseg(&wtok,2); + op(0x8f); + op(wtok.rm); + outaddress(&wtok); + } + else{ + outseg(&wtok,2); + op(0xC7); //mov word[],number + op(wtok.rm); + outaddress(&wtok); + if((itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + if(i==1||rettype==tk_float)break; + itok.lnumber>>=32; + wtok.number+=4; + compressoffset(&wtok); + } + break; + case tk_doublevar: + case tk_floatvar: + if(tok!=type)goto labl1; + ITOK w1tok; + char *w1buf; + w1buf=bufrm; + bufrm=NULL; + w1tok=itok; + SINFO w1str; + w1str=strinf; + strinf.bufstr=NULL; + getinto_e_ax(0,tok==tk_floatvar?tk_dwordvar:tk_qwordvar,&w1tok,w1buf,&w1str,r32); + if(tok==tk_doublevar){ + if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){ + op66(r32); + outseg(&wtok,1); + op(0xA3); // MOV [dword],EAX + if(am32)outdword(wtok.number); + else outword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,4,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0x89); op(wtok.rm); // MOV [rmdword],EAX + outaddress(&wtok); + } + itok.number+=4; + compressoffset(&itok); + wtok.number+=4; + compressoffset(&wtok); + ITOK w1tok; + char *w1buf; + w1buf=bufrm; + bufrm=NULL; + w1tok=itok; + SINFO w1str; + w1str=strinf; + strinf.bufstr=NULL; + getinto_e_ax(0,tk_qwordvar,&w1tok,w1buf,&w1str,r32); + } + getfromEAX=1; + break; + default: +labl1: + if((i=doeaxfloatmath(tk_fpust))==tk_fpust||i==tk_double){ + getfromEAX=0; + if(retrez==tk_floatvar||retrez==tk_doublevar){ + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + else retrez=tk_fpust; + } + else getfromEAX=1; + next=0; + } + } + if(getfromEAX){ +getfromeax: + retrez=tk_reg32; + convert_returnvalue(posiblret,rettype); + if((wtok.rm==rm_d16&&wtok.sib==CODE16)||(wtok.rm==rm_d32&&wtok.sib==CODE32)){ + op66(r32); + outseg(&wtok,1); + op(0xA3); // MOV [dword],EAX + if(am32)outdword(wtok.number); + else outword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,4,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0x89); op(wtok.rm); // MOV [rmdword],EAX + outaddress(&wtok); + } + } + break; + case tk_minusminus: + vop=0x28; + case tk_plusplus: +incvar: + outword(0xe8d9); //fld1 + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fadd var + op(0xd8+addop); + op(wtok.rm+vop); + outaddress(&wtok); + if(retrez==tk_floatvar||retrez==tk_doublevar){ + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + break; + case tk_divequals: vop+=0x10; + case tk_minusequals: vop+=0x20; + case tk_multequals: vop+=8; + case tk_plusequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper){ + if(tok==tk_number){ + if((itok.rm==tk_float&&itok.fnumber==1.0)|| + (itok.rm==tk_double&&itok.dnumber==1.0)|| + (itok.rm!=tk_float&&itok.rm!=tk_double&&itok.lnumber==1)){ + if(vop==0||vop==0x28)goto incvar; + break; + } + if((itok.rm==tk_float&&itok.fnumber==0.0)|| + (itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){ + switch(vop){ + case 0x38: + DevideZero(); + break; + case 8: + outword(0xEED9); //FLDZ + if(retrez==tk_floatvar||retrez==tk_doublevar){ + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + break; + } + break; + } + } + } + if(itok2.type==tp_opperand){ + doeaxfloatmath(tk_fpust); +endequals: + next=0; +endequals1: + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fsubr var + op(0xd8+addop); + op(wtok.rm+vop); + outaddress(&wtok); + if(retrez==tk_floatvar||retrez==tk_doublevar){ + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + } + else{ + switch(tok){ + case tk_number: + if(rettype==tk_float){ + if(itok.rm==tk_double)itok.fnumber=itok.dnumber; + else if(itok.rm!=tk_float){ + float temp=itok.number; + *(float *)&itok.number=temp; + } + } + else{ + if(itok.rm==tk_float)itok.dnumber=itok.fnumber; + else if(itok.rm!=tk_double)itok.dnumber=itok.lnumber; + } + + if(vop==0x38){ // div 22.12.05 22:10 + vop=8; //mult + if(itok.rm==tk_float)itok.fnumber=1/itok.fnumber; + else itok.dnumber=1/itok.dnumber; + } + + op66(r32); + op(0xD9+addop); + op((am32==FALSE?0x06:0x05)); //fld + AddFloatConst(itok.lnumber,rettype); + outword(0); + if(am32)outword(0); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fsubr var + op(0xd8+addop); + op(wtok.rm+vop); + outaddress(&wtok); + if(retrez==tk_floatvar||retrez==tk_doublevar){ + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + break; + case tk_longvar: + sign=2; + case tk_floatvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,2); //fld val or fild val + op(0xd9+sign); + op(itok.rm); + outaddress(&itok); + goto endequals1; + case tk_qwordvar: + sign=2; + i=0x28; + case tk_doublevar: + CheckAllMassiv(bufrm,8,&strinf); + outseg(&itok,2); //fldq val or fild val + op(0xdd+sign); + op(itok.rm+i); + outaddress(&itok); + goto endequals1; + case tk_dwordvar: + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; + addESP+=4; + CheckAllMassiv(bufrm,4,&strinf); + op66(r32); //push var + outseg(&itok,2); + op(0xFF); + op(itok.rm+0x30); + outaddress(&itok); + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; + addESP+=4; + fildq_stack(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fsubr var + op(0xd8+addop); + op(wtok.rm+vop); + outaddress(&wtok); + if(optimizespeed||am32==0){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + addESP-=8; + if(retrez==tk_floatvar||retrez==tk_doublevar){ + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + RestoreBP(); + break; + case tk_reg32: // ࠡ 樨 float, long + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + op66(r32); //push reg32 + op(0x50+(unsigned int)itok.number); + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; + addESP+=8; + fildq_stack(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fsubr var + op(0xd8+addop); + op(wtok.rm+vop); + outaddress(&wtok); + if(optimizespeed||am32==0){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + addESP-=8; + if(retrez==tk_floatvar||retrez==tk_doublevar){ + outseg(&wtok,2); //fstp var + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + RestoreBP(); + break; + default: + if(doeaxfloatmath(tk_fpust)==tk_assign){ + CheckInitBP(); + op66(r32); //push EAX + op(0x50); + op(0xD9+addop); + fld_stack(4+localsize); + fwait3(); + RestoreBP(); + op66(r32); + op(0x58); + } + goto endequals; + } + } + break; + case tk_swap: + int regdi; + regdi=TRUE; + getoperand(); + rbuf=bufrm; + bufrm=NULL; + if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; + switch(tok){ + case tk_reg32: // ࠡ 樨 float, long + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + op66(r32); //push reg32 + op(0x50+(unsigned int)itok.number); + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; + addESP+=8; + fildq_stack(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9+addop); + op(wtok.rm); + outaddress(&wtok); + op(0xdb); + if(am32){ + if(optimizespeed)outword(0x241c); //fistp ssdword[bp-8]/ssdword[esp] + else{ + outword(0x245C); + op(4); + } + } + else{ + int dob; + dob=8; + if(!optimizespeed)dob=4; + if(short_ok(localsize+dob,FALSE)==0){ + op(0x9E); + outword(-dob-localsize); + } + else{ + op(0x5E); + op(-dob-localsize); + } + } + outseg(&wtok,2);//fstp val + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + op66(r32); // pop reg32 + op(0x58+(unsigned int)itok.number); + if(!optimizespeed){ + op66(r32); // pop reg32 + op(0x58+(unsigned int)itok.number); + } + else{ + outword(0xC483); + op(4); + } + addESP-=8; + RestoreBP(); + break; + case tk_longvar: + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fild + op(0xDB); + op(itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9+addop); + op(wtok.rm); + outaddress(&wtok); + outseg(&itok,2);//fistp var + op(0xDB); + op(itok.rm+0x18); + outaddress(&itok); + outseg(&wtok,2); //fstp val + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + break; + case tk_qwordvar: + CheckAllMassiv(rbuf,8,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fildq val + op(0xdd); + op(itok.rm+0x28); + outaddress(&itok); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9+addop); + op(wtok.rm); + outaddress(&wtok); + outseg(&itok,2); //fistp val + op(0xdf); + op(itok.rm+0x38); + outaddress(&itok); + outseg(&wtok,2); //fstp val + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + break; + case tk_dwordvar: + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; + addESP+=4; + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + op66(r32); //push var + outseg(&itok,2); + op(0xFF); + op(itok.rm+0x30); + outaddress(&itok); + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; + addESP+=4; + fildq_stack(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9+addop); + op(wtok.rm); + outaddress(&wtok); + if(optimizespeed||am32==FALSE){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + addESP-=8; + outseg(&itok,2);//fistp var + op(0xDB); + op(itok.rm+0x18); + outaddress(&itok); + outseg(&wtok,2); //fstp val + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + RestoreBP(); + break; + case tk_floatvar: + if(rettype==tk_double){ + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fld val + op(0xd9); + op(itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + outseg(&wtok,2); //fstp val + op(0xdd); + op(wtok.rm); + outaddress(&wtok); + outseg(&itok,2); //fstp val + op(0xd9); + op(itok.rm+0x18); + outaddress(&itok); + outseg(&wtok,2); //fstp val + op(0xdd); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + else{ + getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + op66(r32); + outseg(&itok,2);// XCHG EAX,[dword] + op(0x87); op(itok.rm); + outaddress(&itok); + goto getfromeax; + } + break; + case tk_doublevar: + if(rettype==tk_float){ + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + outseg(&itok,2); //fldq val + op(0xdd); + op(itok.rm); + outaddress(&itok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9); + op(wtok.rm); + outaddress(&wtok); + outseg(&itok,2); //fstp val + op(0xdd); + op(itok.rm+0x18); + outaddress(&itok); + outseg(&wtok,2); //fstp val + op(0xd9); + op(wtok.rm+0x18); + outaddress(&wtok); + fwait3(); + } + else{ + getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); + CheckAllMassiv(rbuf,4,&strinf,&itok,regdi==FALSE?idxregs[2]:idxregs[1],idxregs[3]); + op66(r32); + outseg(&itok,2);// XCHG EAX,[dword] + op(0x87); op(itok.rm); + outaddress(&itok); + goto getfromeax; + } + break; + case tk_fpust: + if(itok.number>6)fpustdestroed(); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + outseg(&wtok,2); //fld val + op(0xd9+addop); + op(wtok.rm); + outaddress(&wtok); + op(0xD9); + op(0xC8+itok.number+1); + outseg(&wtok,2); //fstp val + op(0xd9+addop); + op(wtok.rm+0x18); + outaddress(&wtok); + break; + default: swaperror(); break; + } + break; + default: operatorexpected(); break; + } + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + if(cpu<3)cpu=3; + return retrez; +} + +void fildq2_stack(int size) +{ + op(0xdf); + if(am32)outword(0x242c); //fildq ssdword[bp-8]/ssdword[esp] + else{ + if(short_ok(size,FALSE)==0){ + op(0xAE); + outword(-size); + } + else{ + op(0x6E); + op(-size); + } + } +} + +void fildq_stack() +{ + fildq2_stack(localsize+8); +} + +void fistp2_stack(int size) +{ + if(am32)outword(0x241c); //fistp ssdword[ebp+2]/ssdword[esp] + else{ + if(short_ok(size,FALSE)==0){ + op(0x9E); + outword(-size); + } + else{ + op(0x5E); + op(-size); + } + } +} + +void fistp_stack(int addop) +{ + op(0xDB+addop); + fistp2_stack(localsize+4+addop); +} + +void fld_stack(int size) +{ + if(am32)outword(0x2404); //fld ssdword[ebp+2]/ssdword[esp] + else{ + if(short_ok(size,FALSE)==0){ + op(0x86); + outword(-size); + } + else{ + op(0x46); + op(-size); + } + } +} + +void FloatToNumer(int addop) +// float ᫮ +{ + CheckInitBP(); + op(0xD9+addop); + fld_stack(4+localsize+addop); + fistp_stack(); + RestoreBP(); + fwait3(); + op66(r32); + op(0x58); //pop reg + if(cpu<3)cpu=3; +} + +void Float2reg32(int reg,int addop,int reg1,int reg2) +{ + CheckInitBP(); + op66(r32); + op(0x50); //push AX + if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; + addESP+=4; + CheckAllMassiv(bufrm,4+addop,&strinf,&itok,reg1,reg2); + outseg(&itok,2); //fld floatvar + op(0xd9+addop); + op(itok.rm); + outaddress(&itok); + fistp_stack(); + fwait3(); + op66(r32); + op(0x58+reg); //pop reg + addESP-=4; + if(cpu<3)cpu=3; + RestoreBP(); +} + +void byteinstack(int *numstak,int *nums) +{ + CheckInitBP(); + CheckAllMassiv(bufrm,1,&strinf); + op66(r16); + if(tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7){ + outword(0xC031); //xor ax,ax + outseg(&itok,2); + op(0x8A); + } + else{ + outseg(&itok,3); + op(0xf); + if(tok==tk_bytevar)op(0xb6); + else op(0xbe); + } + op(itok.rm); + outaddress(&itok); + op66(r16); + outword(0xDF50); //push ax + *numstak+=2; + addESP+=2; + fld_stack(*nums+*numstak); +} + +void reginstack(int *numstak,int *nums) +{ + CheckInitBP(); + op66(tok==tk_reg32?r32:r16); + if(tok==tk_beg){ + if(optimizespeed&&chip>3&&chip<7&&itok.number!=AL&&itok.number!=AH){ + xorAXAX(); + op(0x88); + op(0xC0+itok.number*8); //mov al,beg + } + else if(itok.number==AL)xorAHAH(); + else{ + outword(0xB60F); /* MOVZX AX,beg */ + op(0xC0+itok.number); + } + itok.number=0; + } + else outword(0x6a); //push 0 + op66(tok==tk_reg32?r32:r16); + op(0x50+itok.number); //push AX + if(tok==tk_reg){ + op(0xDB); + *numstak+=4; + addESP+=4; + fld_stack(*nums+*numstak); + } + else if(tok==tk_beg){ + op(0xdf); + *numstak+=2; + addESP+=2; + fld_stack(*nums+*numstak); + } + else{ + *numstak+=8; + addESP+=8; + fildq2_stack(*nums+*numstak); + } +} + +void wordinstack(int *numstak,int *nums) +{ + CheckInitBP(); + op66(tok==tk_wordvar?r16:r32); + outword(0x6a); //push 0 + if(ESPloc&&am32&&itok.segm==SS)itok.number+=4; + CheckAllMassiv(bufrm,tok==tk_wordvar?2:4,&strinf); + op66(tok==tk_wordvar?r16:r32); + outseg(&itok,2); //push var + op(0xFF); + op(itok.rm+0x30); + outaddress(&itok); + if(tok==tk_wordvar){ + op(0xDB); + addESP+=4; + *numstak+=4; + fld_stack(*nums+*numstak); + } + else{ + addESP+=8; + *numstak+=8; + fildq2_stack(*nums+*numstak); + } +} + +void intinstack(int addop) +{ + CheckAllMassiv(bufrm,tok==tk_intvar?2:4+addop,&strinf); + outseg(&itok,2); //fild intvar + if(tok==tk_intvar||tok==tk_qwordvar)op(0xDF); + else if(tok==tk_floatvar||tok==tk_doublevar)op(0xd9+addop); + else op(0xDB); + op(itok.rm+(tok==tk_qwordvar?0x28:0)); + outaddress(&itok); +} + +int doeaxfloatmath(int itreturn,int reg,int addop) +{ +int vop,negflag=0,next,numstak=0; +static int nums=0; +int i=0; +long long lnumber; +int ols; + ols=localsize; + nums+=localsize; + next=1; + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + negflag=1; + getoperand(am32==TRUE?EAX:BX); + } + } + if(tok==tk_number){ +// printf("rm=%d %e %e %08X\n",itok.rm,itok.fnumber,itok.dnumber,itok.number); + if(addop==0/*itok.rm==tk_float*/){ + itok.number=doconstfloatmath(); + itok.rm=tk_float; + } + else{ + itok.lnumber=doconstdoublemath(); + itok.rm=tk_double; + } + next=0; + if(itok.type==tp_stopper){ +// if(itok.rm==tk_float&&addop==4)itok.dnumber=itok.fnumber; +// if(itok.rm==tk_double&&addop==0)itok.fnumber=itok.dnumber; + if(itreturn==tk_stackstart){ + if(itok.rm==tk_double){ + lnumber=itok.lnumber; + itok.lnumber=lnumber>>32; + } + for(i=0;i<2;i++){ + op66(r32); + if(short_ok(itok.number,TRUE)){ //PUSH number + op(0x6A); + op(itok.number); + } + else{ + op(0x68); + outdword(itok.number); + } + if(itok.rm!=tk_double)break; + if(i==1)break; + itok.number=lnumber; + } + return itreturn; + } + if(itreturn==tk_reg32){ + MovRegNum(r32,0,itok.number,reg); + return itreturn; + } + if(itreturn==tk_reg64){ + MovRegNum(r32,0,itok.number,reg&255); + MovRegNum(r32,0,itok.lnumber>>=32,reg/256); + return itreturn; + } + } + } + if(itreturn==tk_stackstart&&(!am32)){ + op66(r32); + op(0x50); //push eax + if(addop){ + op66(r32); + op(0x50); //push eax + } + op(0x55); //push bp + outword(0xe589);//mov bp,sp + if(initBP>1)initBP++; + localsize=-6-addop; + } + if(next==0)goto casenumber; + switch(tok){ + case tk_number: +casenumber: +// printf("rm=%d %e %e %08X\n",itok.rm,itok.fnumber,itok.dnumber,itok.number); + if((itok.rm==tk_float&&itok.fnumber==1.0)|| + (itok.rm==tk_double&&itok.dnumber==1.0)|| + (itok.rm!=tk_float&&itok.rm!=tk_double&&itok.lnumber==1)){ + outword(0xE8D9); //FLD1 + break; + } + if((itok.rm==tk_float&&itok.fnumber==0.0)|| + (itok.rm==tk_double&&itok.dnumber==0.0)||itok.lnumber==0){ + outword(0xEED9); //FLDZ + break; + } + op(0xD9+(itok.rm==tk_float?0:4)); + op((am32==FALSE?0x06:0x05)); //fld + AddFloatConst(itok.lnumber,itok.rm); + outword(0); + if(am32)outword(0); + break; + case tk_at: + getoperand(am32==TRUE?EAX:BX); + macros(tk_fpust); + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_declare: + case tk_undefproc: +int onums; + onums=nums; + nums=-(int)localsize; + vop=procdo(tk_fpust); // 楤 + nums=onums; + if(tok2==tk_semicolon&&vop!=tk_fpust&&vop!=tk_double){ + nexttok(); + return tk_assign; + } + break; + case tk_qwordvar: + case tk_doublevar: + i=4; + case tk_floatvar: + case tk_longvar: + case tk_intvar: + intinstack(i); + break; + case tk_dwordvar: + case tk_wordvar: + wordinstack(&numstak,&nums); + break; + case tk_charvar: + case tk_bytevar: + byteinstack(&numstak,&nums); + break; + case tk_beg: + case tk_reg32: + case tk_reg: + reginstack(&numstak,&nums); + break; + case tk_fpust: + if(itok.number){ + op(0xD9); + op(0xC8+itok.number); + } + break; + default: valueexpected(); break; + } + if(negflag){ + outword(0xe0d9); //fchs + negflag=0; + } + if(next==1)nexttok(); + while(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare){ + next=1; + vop=0; + i=0; + switch(tok){ + case tk_multminus: negflag=1; goto mult; + case tk_divminus: negflag=1; + case tk_div: vop+=0x10; + case tk_minus: vop+=0x20; +mult: + case tk_mult: vop+=8; + case tk_plus: + getoperand(); + switch(tok){ + case tk_number: + if(itok.rm!=tk_float&&itok.rm!=tk_double){ + itok.dnumber=itok.lnumber; + itok.rm=tk_double; + } + if((itok.rm==tk_float&&itok.fnumber==1.0)|| + (itok.rm==tk_double&&itok.dnumber==1.0)){ +num1: + if(vop==0||vop==0x28){ // + - + outword(0xE8D9); //FLD1 + op(0xDE); + op(0xC1+vop); + } + break; + } + op(0xd8+(itok.rm==tk_float?0:4)); + + if(vop==0x38){ // div 22.12.05 22:10 + vop=8; //mult + if(itok.rm==tk_float)itok.fnumber=1/itok.fnumber; + else itok.dnumber=1/itok.dnumber; + } + if(/*vop==0x38||*/vop==0x28)vop-=8; + + op((am32==FALSE?0x06:0x05)+vop); + AddFloatConst(itok.lnumber,itok.rm); + outword(0); + if(am32)outword(0); + break; + case tk_doublevar: + i=4; + case tk_floatvar: + if(vop==0x38||vop==0x28)vop-=8; + CheckAllMassiv(bufrm,4+i,&strinf); + outseg(&itok,2); //fsubr var + op(0xd8+i); + op(itok.rm+vop); + outaddress(&itok); + break; + case tk_longvar: + case tk_intvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,2); //fsubr var + op(tok==tk_intvar?0xDE:0xDA); + if(vop==0x38||vop==0x28)vop-=8; + op(itok.rm+vop); + outaddress(&itok); + break; + case tk_qwordvar: + intinstack(4); + op(0xde); + op(0xC1+vop);//fsubpr st1 + break; + case tk_dwordvar: + case tk_wordvar: + wordinstack(&numstak,&nums); + op(0xde); + op(0xC1+vop);//fsubpr st1 + break; + case tk_beg: + case tk_reg32: + case tk_reg: + reginstack(&numstak,&nums); + op(0xde); + op(0xC1+vop);//fsubpr st1 + break; + case tk_charvar: + case tk_bytevar: + byteinstack(&numstak,&nums); + op(0xde); + op(0xC1+vop);//fsubpr st1 + break; + case tk_fpust: + if(vop==0x38||vop==0x28)vop-=8; + op(0xd8); + op(0xC0+vop+itok.number);//fsubpr st + break; + default: valueexpected(); break; + } + break; + default: illegalfloat(); break; + } + if(negflag){ + outword(0xe0d9); //fchs + negflag=0; + } + if(next)nexttok(); + } + if(tok==tk_eof)unexpectedeof(); + if(itreturn==tk_stackstart){ + if(!am32){ + op(0xD9+addop); + outword(0x025e); //fstp ssdword[bp+2] + numstak-=2; + } + else{ + if(numstak<4){ + op66(r32); + op(0x50); //push eax + addESP+=4; + } + else numstak-=4; + if(addop){ + if(numstak<4){ + op66(r32); + op(0x50); //push eax + addESP+=4; + } + else numstak-=4; + } + op(0xD9+addop); + if(numstak==0)outword(0x241C); //fstp ssdword[esp] + else{ + outword(0x245C); //fstp ssdword[esp+numstak] + op(numstak); + } + } + fwait3(); + } + else if(itreturn==tk_reg32||itreturn==tk_reg64){ + i=4; + if(itreturn==tk_reg64)i=8; + if(numstak6)fpustdestroed(); +// outword(0xf6d9); //fdecstp + doeaxfloatmath(tk_fpust); + if(num){ + op(0xD9); + op(0xC8+num); + } +} + +void dofloatstack(int num) +{ +int vop=0; + nexttok(); + switch(tok){ + case tk_assign: //= + getoperand(am32==TRUE?EAX:BX); + float2stack(num); + break; + case tk_divequals: vop+=0x10; + case tk_minusequals: vop+=0x20; + case tk_multequals: vop+=8; + case tk_plusequals: + getoperand(am32==TRUE?EAX:BX); + float2stack(0); +// doeaxfloatmath(tk_fpust); + op(0xdc); + op(0xC0+vop+num);//fsubpr st + break; + case tk_swap: + getoperand(am32==TRUE?EAX:BX); + switch(tok){ + case tk_fpust: + op(0xD9); + op(0xC8+num); + op(0xD9); + op(0xC8+itok.number); + op(0xD9); + op(0xC8+num); + break; + case tk_doublevar: + vop=4; + case tk_floatvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,2); //fld val + op(0xd9+vop); + op(itok.rm); + outaddress(&itok); + op(0xD9); + op(0xC8+num+1); + outseg(&itok,2); //fstp val + op(0xd9+vop); + op(itok.rm+0x18); + outaddress(&itok); + break; + default: + swaperror(); + break; + } + nexttok(); + break; + default: + illegalfloat(); break; + } +} + +void RestoreBP() +{ + if(am32==0&&initBP==2){ + Leave(); + initBP=0; + } +} + +void CheckInitBP() +{ + if(am32==0&&initBP==0){ + op(0x55); //push bp + outword(0xe589);//mov bp,sp + initBP=2; + } +} + +void AddReloc(int segm) +{ + if(FixUp!=FALSE){ + CheckPosts(); + if(segm==DS){ + (postbuf+posts)->type=(unsigned short)(am32==FALSE?FIX_VAR:FIX_VAR32); + (postbuf+posts)->loc=outptrdata; + } + else{ + (postbuf+posts)->type=(unsigned short)(am32==FALSE?FIX_CODE:FIX_CODE32); + (postbuf+posts)->loc=outptr; + } + posts++; + } + postnumflag&=(~f_reloc); +} + +void fwait3() +{ + if(chip<4&&tok2!=tk_floatvar&&tok2!=tk_doublevar&&tok2!=tk_float&&tok2!=tk_double)op(0x9B); +} + +void AddFloatConst(long long fnumber,int type) +{ +unsigned int i; +unsigned int ofs; + for(i=0;itype){ + ofs=(floatnum+i)->ofs; + if(type==tk_float){ + if(*(long *)&fnumber==(floatnum+i)->num[0])goto endp; + } + else if(*(double *)&fnumber==(floatnum+i)->dnum)goto endp; + } + } + if(numfloatconst==0){ + floatnum=(LISTFLOAT *)MALLOC(sizeof(LISTFLOAT)*STEPFLOATCONST); + maxnumfloatconst=STEPFLOATCONST; +// memset(floatnum,0,sizeof(LISTFLOAT)*STEPFLOATCONST); + } + else if((numfloatconst+1)==maxnumfloatconst){ + floatnum=(LISTFLOAT *)REALLOC(floatnum,(maxnumfloatconst+STEPFLOATCONST)*sizeof(LISTFLOAT)); + maxnumfloatconst+=STEPFLOATCONST; + } + numfloatconst++; + (floatnum+i)->type=type; + ofs=(floatnum+i)->ofs=ofsfloatlist; + if(type==tk_float)(floatnum+i)->num[0]=*(unsigned long *)&fnumber; + else (floatnum+i)->dnum=*(double *)&fnumber; + ofsfloatlist+=(type==tk_float?4:8); +endp: + CheckPosts(); + (postbuf+posts)->type=POST_FLOATNUM; + (postbuf+posts)->loc=outptrdata; + (postbuf+posts)->num=ofs; + posts++; +} + +void setwordext(long *id) +{ + CheckPosts(); + (postbuf+posts)->type=EXT_VAR; + (postbuf+posts)->loc=outptr; + (postbuf+posts)->num=*id&0xFFFF; //id 譥 ६ + *id>>=16; // 祭 + posts++; +} + +void setwordpost(ITOK *stok) /* for post word num setting */ +{ + CheckPosts(); + if(stok->post==USED_DIN_VAR){ + (postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32); +// printf("Add tok=%d %s\n",stok->rec->rectok,stok->rec->recid); +// printf("rec=%08X\n",stok->rec); + if(stok->rec->rectok==tk_structvar&&stok->rec->recsib==tp_gvar){ + (postbuf+posts)->num=(int)stok->rec;//02.09.05 17:11 ->right; + } + else (postbuf+posts)->num=(int)stok->rec; + } + else if(stok->post>=CODE_SIZE&&stok->post<=STACK_SIZE32)(postbuf+posts)->type=stok->post; + else (postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_VAR:POST_VAR32); + (postbuf+posts)->loc=outptr; + posts++; +} + +void MovRegNum(int razr,int relocf,unsigned long number,int reg) +{ +unsigned long num; +int nreg; + op66(razr); + if(relocf==0){ + if(number!=0&&GetRegNumber(reg,&num,razr)==reg){ + ConstToReg(number,reg,razr); + if(num==number)return; + else if(num2||razr==r32)&&chip!=5&&chip!=6){ + outdword(0x01d0ac0f); //shrd ax,dx,1 + setzeroflag=TRUE; + } + else{ + outword(0xead1); //shr dx,1 rcr ax,1 + op66(razr); + outword(0xd8d1); + setzeroflag=FALSE; + } + ClearReg(AX); + ClearReg(DX); + break; + } + op66(razr); + if(sign)outword(0xF8D1);// SAR AX,1 + else outword(0xE8D1); // SHR AX,1 + setzeroflag=TRUE; + ClearReg(AX); + break; + default: + vop=caselong(itok.number); + if(vop!=NUMNUM){ + if(expand==TRUE){ + if(chip>2||razr==r32){ + op66(razr); + op(0x0f); + outword(0xd0ac); //shrd ax,dx,vop + op(vop); + setzeroflag=TRUE; + ClearReg(AX); + ClearReg(DX); + } + else{ + if(optimizespeed==FALSE)goto divin; + op(0xB1); op(vop); /* MOV CL,num */ + if(sign)outword(0xFad1); // SAR AX,1 + else outword(0xEad1); // SHR AX,1 + outdword(0xfae2d8d1); //rcr ax,1 LOOP -6 + warningreg(begs[1]); + setzeroflag=FALSE; + ClearReg(AX); + ConstToReg(vop,CL,r8); + } + } + else{ + if(chip<2&&razr==r16){ + op(0xB1); op(vop); /* MOV CL,num */ + if(sign)outword(0xF8D3); // SAR AX,CL + else outword(0xE8D3); // SHR AX,CL + warningreg(begs[1]); + ClearReg(AX); + ConstToReg(vop,CL,r8); + } + else{ + op66(razr); + if(sign)outword(0xF8C1); // SAR AX,num + else outword(0xE8C1); // SHR AX,num + op(vop); + ClearReg(AX); + } + setzeroflag=TRUE; + } + } + else{ + if(expand==FALSE)DivNum(itok.number,razr,sign); + else{ +divin: + + if(!expand)ClearDX(razr,sign); + DivNum2(itok.number,razr,sign); + } + } + } + } + } + else{ + if(tok==tk_doublevar){ + i=4; + tok=tk_floatvar; + } + if(tok==tk_floatvar){ + Float2reg32(ECX,i); + warningreg(regs[razr/2-1][1]); + itok.number=ECX; + tok=(razr==r16?tk_reg:tk_reg32); + sign=1; + } + switch(tok){ + case tk_qwordvar: + i=4; + case tk_longvar: + case tk_dwordvar: + i+=2; + case tk_intvar: + case tk_wordvar: + if(razr==r32&&(tok==tk_intvar||tok==tk_wordvar))goto defdiv; + i+=2; + CheckAllMassiv(bufrm,i,&strinf); + if(expand==FALSE)ClearDX(razr,sign); + op66(razr); + outseg(&itok,2); + op(0xF7); + if(sign)op(0x38+itok.rm); /* IDIV word ptr [#] */ + else op(0x30+itok.rm); /* DIV word ptr [#] */ + outaddress(&itok); + ClearReg(AX); + break; + case tk_reg: + if(razr==r32){ + i=itok.number; + getintoreg_32(i,r32,0,&ofsstr,FALSE); + if(expand==FALSE)ClearDX(razr,sign); + op66(r32); + op(0xF7); + if(sign)op(0xF8+i); /* IDIV ECX */ + else op(0xF0+i); /* DIV ECX */ + next=0; + warningreg(regs[1][2]); + ClearReg(AX); + ClearReg(CX); + break; + } + case tk_reg32: + if(expand==FALSE)ClearDX(razr,sign); + op66(razr); + op(0xF7); + if(sign)op(0xF8+(unsigned int)itok.number); + else op(0xF0+(unsigned int)itok.number); + ClearReg(AX); + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + op66(razr); + op(0x50); //push AX + addESP+=razr==r16?2:4; +unsigned char oaddstack; + oaddstack=addstack; + addstack=FALSE; + procdo(razr==r16?(sign==0?tk_word:tk_int):(sign==0?tk_dword:tk_long)); + addstack=oaddstack; + addESP-=razr==r16?2:4; + op66(razr); + op(0x90+ECX); //xchg AX,CX + op66(razr); + op(0x58); //pop AX + if(expand==FALSE)ClearDX(razr,sign); + op66(razr); + op(0xF7); + if(sign)op(0xF8+ECX); /* IDIV ECX */ + else op(0xF0+ECX); /* DIV ECX */ + warningreg(regs[razr/2-1][ECX]); + break; + case tk_undefofs: + case tk_seg: + case tk_charvar: + case tk_beg: + case tk_bytevar: + case tk_rmnumber: + case tk_postnumber: + case tk_apioffset: +defdiv: + getintoreg_32(CX,razr,0,&ofsstr,FALSE); + if(expand==FALSE)ClearDX(razr,sign); + op66(razr); + if(sign)outword(0xF9F7); /* IDIV CX */ + else outword(0xF1F7); /* DIV CX */ + next=0; + warningreg(regs[razr/2-1][ECX]); + ClearReg(CX); + ClearReg(AX); + break; + default: valueexpected(); break; + } + setzeroflag=FALSE; +/* if(vop){ + op66(razr); + if(optimizespeed)outword(0xC28B); //mov ax,dx + else op(0x92); //xchg ax,dx + }*/ + } + if(next)nexttok(); +} + +void DivNum(unsigned long num,int razr,int sign) +{ +/*int i; +unsigned long num2; + if(num<65536&&optimizespeed&&(itok.flag&f_reloc)==0&&sign==0){ //for signed needed new algoritm + if(razr==r16&&chip>2){ + num2=65536/(unsigned int)num+1; + if((65535/num2)!=num)goto stddiv; + op66(r32); + op(0x25); + outdword(0xffff); //and EAX,ffff + if(short_ok(num2,FALSE))i=2; //⪠ ଠ + op66(r32); + op(0x69+i); //imul EAX,num + op(0xc0); + if(i==2)op(num2); + else outdword(num2); + op66(r32); + outword(0xE8C1); + op(0x10); //shr EAX,16 + setzeroflag=TRUE; + } + else{ + if(razr==r32)num=(unsigned long)0xFFFFFFFFL/num+1; + else num=65536/(unsigned int)num+1; + op66(razr); + op(0xBA); //mov DX,num + if(razr==r16)outword(num); + else outdword(num); + op66(razr); + outword(0xE2F7); //mul DX + op66(razr); + outword(0xD089); //mov AX,DX + setzeroflag=FALSE; + warningreg(regs[razr/2-1][2]); + } + return; + } +stddiv:*/ + ClearDX(razr,sign); + DivNum2(num,razr,sign); +} + +void ClearDX(int razr,int sign) +{ + if(sign)cwdq(razr); + else{ + op66(razr); + outword(0xD231); + } + warningreg(regs[razr/2-1][EDX]); + ClearReg(DX); +} + +void DivNum2(unsigned long num,int razr,int sign) +{ + MovRegNum(razr,itok.flag&f_reloc,num,ECX); + op66(razr); + if(sign)outword(0xF9F7); /* IDIV CX */ + else outword(0xF1F7); /* DIV CX */ + warningreg(regs[razr/2-1][ECX]); + ClearReg(CX); + ClearReg(AX); +} + +int getintoreg(int reg,int razr,int sign,char **ofsstr) +{ +ITOK oitok,oitok2; +int oline,oendinptr; +int oinptr,otok,otok2; +unsigned char *oinput; +unsigned char ocha; +int useeax=FALSE; +int operand=tk_plus; +int rettype=tk_reg; +char *obuf; +SINFO ostr; +int i=0; +int j=0; +int onlynum=FALSE; +COM_MOD *bmod; + switch(tok){ + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + break; + default: +// if(cur_mod)break; //10.08.04 22:50 - define ४ + obuf=bufrm; + bufrm=NULL; + ostr=strinf; + strinf.bufstr=NULL; + oitok=itok; + oitok2=itok2; + otok=tok; + otok2=tok2; + oline=linenum2; + oinptr=inptr2; + oinput=input; + oendinptr=endinptr; + bmod=cur_mod; + while(bmod){ + bmod->freze=TRUE; + bmod=bmod->next; + } + bmod=cur_mod; + ocha=cha2; +// printf("input=%08X inptr=%08X %s\n",input,inptr2,input+inptr2); + if(tok==tk_number)onlynum=TRUE; + while((!useeax)&&itok.type!=tp_stopper&&tok!=tk_eof){ + nexttok(); + if(itok.type==tp_stopper)break; + if(itok.type==tp_opperand)operand=tok; + else{ + i++; + if(bufrm)free(bufrm); + if(strinf.bufstr)free(strinf.bufstr); + switch(operand){ + case tk_div: + case tk_mod: + case tk_divminus: + case tk_modminus: + if(j==0)j=1; + if((tok==tk_reg||tok==tk_reg32)&&itok.number==reg)useeax=TRUE; + if(j==1){ + if(tok==tk_number){ + if(onlynum==FALSE&&caselong(itok.number)==NUMNUM)j++; + } + else{ + j++; + onlynum=FALSE; + } + } + break; + } + } + } + if(bmod!=cur_mod){ + if(bmod&&bmod->freze){ + cur_mod=bmod; + while(bmod){ + bmod->freze=FALSE; + bmod=bmod->next; + } + } + else{ + do{ + COM_MOD *temp=cur_mod; + cur_mod=cur_mod->next; +// printf("bmod=%08X cur_mod=%08X\n",bmod,cur_mod); + if(temp->paramdef)free(temp->paramdef); + free(temp); + }while(bmod!=cur_mod); + while(bmod){ + bmod->freze=FALSE; + bmod=bmod->next; + } + } + input=oinput; + } + endinptr=oendinptr; + itok=oitok; + itok2=oitok2; + tok=otok; + tok2=otok2; + linenum2=oline; + inptr2=oinptr; + cha2=ocha; + endoffile=0; +// printf("input=%08X inptr=%08X %s\n",input,inptr2,input+inptr2); +// if(bufrm)free(bufrm); +// if(strinf.bufstr)free(strinf.bufstr); + bufrm=obuf; + strinf=ostr; + break; + } + if(useeax){ + op66(razr); + op(0x50); + addESP+=razr==r16?2:4; + do_e_axmath(0,razr,ofsstr); + op66(razr); + if(optimizespeed){ + op(0x89); + op(0xC0+reg); + } + else op(0x90+reg); + op66(razr); + addESP-=razr==r16?2:4; + op(0x58); + } + else{ + if(i==1&&j>=2){ + i=EAX; + j=1; + } + else i=reg; + rettype=getintoreg_32(i,razr,sign,ofsstr); + if(itok.type!=tp_stopper&&itok.type!=tp_compare&&tok!=tk_eof){ + doregmath_32(reg,razr,sign,ofsstr,j); + rettype=tk_reg; + } + } + return rettype; +} + +void dobits() +{ +ITOK wtok; +char *wbuf; +SINFO wstr; +int razr,i,sign=0,posiblret,pointr=0; +unsigned int rettype; +int numpointr=0; +char *ofsstr=NULL; + posiblret=rettype=tk_dword; + razr=r32; + i=itok.bit.siz+itok.bit.ofs; + if(i<9){ + razr=r8; + posiblret=rettype=tk_byte; + } + else if(i<17){ + posiblret=rettype=tk_word; + razr=r16; + } + else if(i>32)razr=r64; + if(tok2==tk_assign){ + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + nexttok(); + nexttok(); + convert_type(&sign,(int *)&rettype,&pointr); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr)unuseableinput(); + if(tok2==tk_assign){ + MultiAssign(razr,EAX,numpointr); + goto axtobit; + } + if(tok==tk_pointer)cpointr(am32==TRUE?EAX:BX,numpointr); + CheckMinusNum(); + if(tok==tk_number){ + if(itok2.type==tp_opperand){ //᫮ ࠦ + if(!OnlyNumber(0))goto labl1; + itok.flag=(unsigned char)postnumflag; + } + else{ + unsigned long num=itok.number; + nexttok(); + itok.number=num; + } + CheckAllMassiv(wbuf,razr,&wstr,&wtok); + if(razr!=r64)num2bits(&wtok,itok.number,razr); + else{ + int siz=wtok.bit.siz; + wtok.bit.siz=32-wtok.bit.ofs; + num2bits(&wtok,itok.number,r32); + wtok.bit.siz=siz+wtok.bit.ofs-32; + wtok.bit.ofs=0; + itok.number=itok.number>>(32-wtok.bit.siz); + wtok.number+=4; + num2bits(&wtok,itok.number,r8); + } + } + else{ +labl1: + if(rettype==tk_char||rettype==tk_byte)doalmath(sign,&ofsstr); + else if(rettype==tk_int||rettype==tk_word)do_e_axmath(sign,r16,&ofsstr); + else if(rettype==tk_float)doeaxfloatmath(tk_reg32,AX); + else do_e_axmath(sign,r32,&ofsstr); + convert_returnvalue(posiblret,rettype); + CheckAllMassiv(wbuf,razr,&wstr,&wtok); +axtobit: + if(razr!=r64)reg2bits(&wtok,razr); + else{ + int siz=wtok.bit.siz; + op66(r32); + op(0x50); //push eax + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=4; + addESP+=4; + wtok.bit.siz=32-wtok.bit.ofs; + reg2bits(&wtok,r32); + op66(r32); + op(0x58); //pop eax + addESP-=4; + op66(r32); //shr eax,size + outword(0xE8C1); + op(wtok.bit.siz); + wtok.bit.siz=siz+wtok.bit.ofs-32; + wtok.bit.ofs=0; + wtok.number+=4; + reg2bits(&wtok,r8); + } + return; + } + } + else{ + bits2reg(AX,razr); + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + switch(razr){ + case r8: + dobeg(AL); + break; + case r16: + case r32: + doreg_32(AX,razr); + break; + case r64: + doreg_32(AX,r32); + break; + } + goto axtobit; + } + seminext(); +} + +void bits2reg(int reg,int razr) +{ +int i,j,skip66=FALSE; + i=itok.bit.siz+itok.bit.ofs; + j=~GetBitMask(itok.bit.ofs,itok.bit.siz); + ITOK wtok; + char *wbuf; + wbuf=bufrm; + bufrm=NULL; + wtok=itok; + SINFO wstr; + wstr=strinf; + strinf.bufstr=NULL; + switch(razr){ + case r8: + if(reg==AL){ + getintoal(tk_bytevar,&wtok,wbuf,&wstr); + if(i!=8){ + op(4+0x20); //and al,j + op(j); + } + } + else{ + CheckAllMassiv(bufrm,1,&strinf); + outseg(&itok,2); + op(0x8A); + op(reg*8+itok.rm); + outaddress(&itok); + if(i!=8){ + op(128); + op(128+64+reg+0x20); + op(j); + } + } + if(itok.bit.ofs){ //shr al,ofs + if(itok.bit.ofs==1){ + op(0xD0); + op(0xE8+reg); + } + else{ + op(0xC0); + op(0xE8+reg); + op(itok.bit.ofs); + } + } + break; + case r16: + case r32: + if(reg==AX){ + getinto_e_ax(0,(razr==r16?tk_wordvar:tk_dwordvar),&wtok,wbuf,&wstr,razr); + if(razr==r16&&i!=16){ + op66(razr); //and (e)ax,j + op(4+1+0x20); + outword(j); + } + else if(razr==r32&&i!=32){ + op66(razr); //and (e)ax,j + if(short_ok(j,TRUE)){ + op(128+2+1); + op(128+64+0x20); + op((int)j); + } + else{ + op(4+1+0x20); + outdword(j); + } + } + if(j<65536&&razr==r32)skip66=TRUE; + if(itok.bit.ofs){ //shr (e)ax,ofs + if(!skip66)op66(razr); + if(itok.bit.ofs==1)outword(0xE8D1); + else{ + outword(0xE8C1); + op(itok.bit.ofs); + } + } + } + else{ +int reg1=idxregs[0],reg2=idxregs[1]; + if(!am32){ + if(reg==idxregs[2]||reg==idxregs[1]){ + reg1=reg; + if(reg==idxregs[1])reg2=idxregs[0]; + } + } + else{ + reg1=reg; + if(reg==idxregs[1])reg2=idxregs[0]; + } + CheckAllMassiv(bufrm,razr==r32?4:2,&strinf,&itok,reg1,reg2); + op66(razr); + outseg(&itok,2); + op(0x8B); + op(reg*8+itok.rm); + outaddress(&itok); + if((razr==r16&&i!=16)||(razr==r32&&i!=32)){ + op66(razr); //and reg,j + if(short_ok(j,razr==r16?FALSE:TRUE)){ + op(128+2+1); + op(128+64+reg+0x20); + op(j); + } + else{ + op(128+1); + op(128+64+reg+0x20); + if(razr==r16)outword(j); + else outdword(j); + } + } + if(itok.bit.ofs){ //shr reg,ofs + op66(razr); + if(itok.bit.ofs==1){ + op(0xD1); + op(0xE8+reg); + } + else{ + op(0xC1); + op(0xE8+reg); + op(itok.bit.ofs); + } + } + } + break; + case r64: + if(reg==AX){ + getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32); + itok.number+=4; + outseg(&itok,2); + op(0x8B); + op(DX*8+itok.rm); + outaddress(&itok); + if(itok.bit.siz!=32){ + op(128); + op(128+64+DL+0x20); + op(li[itok.bit.siz+itok.bit.ofs-32]-1); + } + op66(r32); + outword(0xAC0F); //shrd edx,eax,ofs + op(0xC2); + op(itok.bit.ofs); + itok.number-=4; + warningreg(regs[1][EDX]); + } + else{ + int reg1=DX; + if(reg==DX)reg1=CX; + CheckAllMassiv(bufrm,4,&strinf,&itok); + op66(r32); + outseg(&itok,2); + op(0x8B); + op(reg*8+itok.rm); + outaddress(&itok); + itok.number+=4; + outseg(&itok,2); + op(0x8B); + op(reg1*8+itok.rm); + outaddress(&itok); + if(itok.bit.siz!=32){ + op(128+(reg1<4?0:3)); + op(128+64+reg1+0x20); + op(li[itok.bit.siz+itok.bit.ofs-32]-1); + } + itok.number-=4; + op66(r32); + outword(0xAC0F); //shrd edx,eax,ofs + op(0xc0+reg1+reg*8); + op(itok.bit.ofs); + warningreg(regs[1][reg1]); + } + ClearReg(DX); + break; + } + ClearReg(AX); + ClearReg(reg); +} + +void num2bits(ITOK *gtok,unsigned long num,int razr) +{ +unsigned int j,mask; + mask=GetBitMask(gtok->bit.ofs,gtok->bit.siz); + j=li[gtok->bit.siz]-1; + if((num&j)!=j){ + if(razr!=r8){ + op66(razr); //and bits,mask + outseg(gtok,2); + if((postnumflag&f_reloc)==0&&short_ok(mask,razr/2-1)){ + op(128+2+1); + op(gtok->rm+0x20); + outaddress(gtok); + op(mask); + } + else{ + op(128+1); + op(gtok->rm+0x20); + outaddress(gtok); + if((postnumflag&f_reloc)!=0)AddReloc(); + if(razr==r16)outword(mask); + else outdword(mask); + } + } + else{ + outseg(gtok,2); //and bits,mask + op(128); + op(gtok->rm+0x20); + outaddress(gtok); + op(mask); + } + } + num=(num&j)<bit.ofs; //or bits,mask + if(num<65536&&razr==r32)razr=r16; + if(num<256&&razr==r16)razr=r8; + if(razr!=r8){ + op66(razr); + outseg(gtok,2); + if((postnumflag&f_reloc)==0&&short_ok(num,razr/2-1)){ + op(128+2+1); + op(gtok->rm+8); + outaddress(gtok); + op(num); + } + else{ + op(128+1); + op(gtok->rm+8); + outaddress(gtok); + if((postnumflag&f_reloc)!=0)AddReloc(); + if(razr==r16)outword(num); + else outdword(num); + } + } + else{ + if((unsigned char)num!=0){ + outseg(gtok,2); + op(128); + op(gtok->rm+8); + outaddress(gtok); + op(num); + } + } +} + +void reg2bits(ITOK *gtok,int razr) +{ +int i,j,mask; + j=li[gtok->bit.siz]-1; + mask=GetBitMask(gtok->bit.ofs,gtok->bit.siz); + i=gtok->bit.ofs+gtok->bit.siz; + switch(razr){ + case r8: + if(i!=8){ + op(4+0x20); //and al,size + op(j); + } + outseg(gtok,2); //and bits,mask + op(128); + op(gtok->rm+0x20); + outaddress(gtok); + op(mask); + if(gtok->bit.ofs)lshiftmul(gtok->bit.ofs,razr); + outseg(gtok,2); + op(8); + op(gtok->rm); + outaddress(gtok); + break; + case r16: + case r32: + if(razr==r16&&i!=16){ + op66(razr); //and (e)ax,size + op(4+1+0x20); + outword(j); + } + else if(razr==r32&&i!=32){ + op66(razr); //and (e)ax,size + if(short_ok(j,TRUE)){ + op(128+2+1); + op(128+64+0x20); + op((int)j); + } + else{ + op(4+1+0x20); + outdword(j); + } + } + op66(razr); //and bits,mask + outseg(gtok,2); + if(short_ok(mask,razr/2-1)){ + op(128+2+1); + op(gtok->rm+0x20); + outaddress(gtok); + op(mask); + } + else{ + op(128+1); + op(gtok->rm+0x20); + outaddress(gtok); + if(razr==r16)outword(mask); + else outdword(mask); + } + if(gtok->bit.ofs)lshiftmul(gtok->bit.ofs,razr); + op66(razr); + outseg(gtok,2); + op(1+8); + op(gtok->rm); + outaddress(gtok); + break; + } +} + +void getoperand(int reg) +{ +unsigned int numpointr=0; + nexttok(); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr){ + unuseableinput(); + } + if(tok==tk_pointer){ + cpointr(reg,numpointr); + } + CheckMinusNum(); +} + +void cpointr(int reg,int numpointr) +{ + if(itok.type==tk_proc){ + if(tok2==tk_openbracket){ + tok=tk_proc; + } + else{ + itok.rm=itok.sib; + if(am32){ + itok.sib=CODE32; + tok=tk_dwordvar; + } + else{ + itok.sib=CODE16; + tok=tk_wordvar; + } + compressoffset(&itok); + } + return; + } + int razr=typesize(itok.type); + if(numpointr==itok.npointr){ + getpointeradr(&itok,bufrm,&strinf,numpointr-1,razr,reg); + if(itok.type>=tk_char&&itok.type<=tk_float)tok=tk_charvar+itok.type-tk_char; + else tok=(am32==FALSE?tk_wordvar:tk_dwordvar); + } + else if(numpointrtype==tk_proc){ + wtok->rm=wtok->sib; + if(am32){ + wtok->sib=CODE32; + *otok=tk_dwordvar; + } + else{ + wtok->sib=CODE16; + *otok=tk_wordvar; + } + compressoffset(wtok); + } + else{ + int razr=typesize(wtok->type); + int reg=idxregs[2]; + if(reg==ureg)reg=idxregs[1]; + if(npointr==wtok->npointr){ + getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg); + if(wtok->type>=tk_char&&wtok->type<=tk_float)*otok=tk_charvar+wtok->type-tk_char; + else *otok=(am32==FALSE?tk_wordvar:tk_dwordvar); + } + else if(npointrnpointr){ + *otok=(am32==FALSE?tk_wordvar:tk_dwordvar); + if(npointr)getpointeradr(wtok,wbuf,wstr,npointr-1,razr,reg); + else return; + } + else unuseableinput(); + memcpy(wtok,&itok,sizeof(ITOK)); + } +} + +int CheckAddOnly() +{ +ITOK oitok,oitok2; +int oline; +int oinptr,otok,otok2; +unsigned char ocha; +char *obuf; +SINFO ostr; +int retval=TRUE; +int j=3; +int changesign=0; + if(tok==tk_minusequals)changesign++; + else if(tok!=tk_plusequals)return FALSE; + if(itok2.type==tp_stopper)return FALSE; +newloop: + obuf=bufrm; + bufrm=NULL; + ostr=strinf; + strinf.bufstr=NULL; + oitok=itok; + oitok2=itok2; + otok=tok; + otok2=tok2; + oline=linenum2; + oinptr=inptr2; + ocha=cha2; + while(tok2==tk_minus||tok2==tk_mult)nexttok(); + while(itok.type!=tp_stopper&&tok!=tk_eof){ + nexttok(); + switch(tok){ + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + retval=FALSE; + itok.type=tp_stopper; + break; + } + if(itok.type==tp_stopper)break; + if(itok.type==tp_opperand){ + if(tok!=tk_plus&&tok!=tk_minus){ + retval=FALSE; + break; + } + else if(changesign==2){ + int i=inptr2-1; + char c; + do{ + i--; + c=input[i]; + i--; + }while(c!='-'&&c!='+'); + i++; + if(c=='-')c='+'; + else c='-'; + input[i]=c; + } + while(itok2.type==tp_opperand&&tok!=tk_eof)nexttok(); + } + else{ + if(tok!=tk_number&&tok!=tk_postnumber&&tok!=tk_undefofs){ + if(j>1)j=0; + if(bufrm)free(bufrm); + if(strinf.bufstr)free(strinf.bufstr); + } + else if(j>1)j--; + } + } + itok=oitok; + itok2=oitok2; + tok=otok; + tok2=otok2; + linenum2=oline; + inptr2=oinptr; + cha2=ocha; + endoffile=0; + bufrm=obuf; + strinf=ostr; + if(j==1)retval=FALSE; + else if(changesign==1){ + changesign++; + goto newloop; + } + return retval; +} + +int doqwordvar(int terminater) //64 bit memory variable +{ +unsigned char next=1,getfromAX=0; +unsigned int vop=0,otok,rettype; +int sign,i; +ITOK wtok; +char *wbuf,*rbuf; +SINFO wstr; +int retrez=0,pointr=0; +int numpointr=0; +int reg; +char *ofsstr=NULL; +int reg1=idxregs[0],reg2=idxregs[1]; + rettype=tk_qword; + sign=0; + wstr=strinf; + strinf.bufstr=NULL; + wtok=itok; + wbuf=bufrm; + bufrm=NULL; + otok=tok; + nexttok(); + switch(tok){ + case tk_assign: //= + nexttok(); + convert_type(&sign,(int *)&rettype,&pointr); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr){ + unuseableinput(); + } + CheckMinusNum(); + if(itok2.type==tp_opperand){ //᫮ ࠦ + if(tok==tk_number){ //஢ઠ 㬬஢ ᥫ + switch(rettype){ + case tk_float: sign=2; break; + case tk_double: sign=3; break; + case tk_qword: sign=4; break; + } + if(OnlyNumber(sign)){ + next=0; + itok.flag=(unsigned char)postnumflag; + goto numbertovar; + } + } + goto labl1; + } + else{ + switch(tok){ + case tk_number: + if((itok.flag&f_reloc)==0){ + if(itok.lnumber==0){ + CheckAllMassiv(wbuf,8,&wstr,&wtok); + for(i=0;i<2;i++){ + op66(r32); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + if(i==1)break; + wtok.number+=4; + compressoffset(&wtok); + } + break; + } + if(itok.lnumber==0xFFFFFFFFFFFFFFFFLL){ + CheckAllMassiv(wbuf,8,&wstr,&wtok); + for(i=0;i<2;i++){ + op66(r32); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x8); + outaddress(&wtok); + op(0xFF); + if(i==1)break; + wtok.number+=4; + compressoffset(&wtok); + } + break; + } + } +numbertovar: + CheckAllMassiv(wbuf,8,&wstr,&wtok); + for(i=0;i<2;i++){ + op66(r32); + if(regoverstack&&short_ok(itok.number,TRUE)&&(itok.flag&f_reloc)==0){ + op(0x6A); + op(itok.number); //push short number + op66(r32); + outseg(&wtok,2); + op(0x8f); + op(wtok.rm); + outaddress(&wtok); + } + else{ + outseg(&wtok,2); + op(0xC7); //mov word[],number + op(wtok.rm); + outaddress(&wtok); + if((itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + if(i==1)break; + itok.lnumber>>=32; + wtok.number+=4; + compressoffset(&wtok); + } + break; + case tk_apioffset: + case tk_postnumber: + case tk_undefofs: + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0xC7); //mov word[],number + op(wtok.rm); + outaddress(&wtok); + if(tok==tk_apioffset)AddApiToPost(itok.number); + else{ + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); +// else if((itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + wtok.number+=4; + compressoffset(&wtok); + op66(r32); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + break; + case tk_reg64: + goto getfromreg; + case tk_reg32: + if(itok.number==AX&&wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA3); // MOV [word],AX + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x89); + op((unsigned int)itok.number*8+wtok.rm); + outaddress(&wtok); + } + wtok.number+=4; + compressoffset(&wtok); + op66(r32); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + break; + case tk_string: + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0xC7); + op(wtok.rm); + outaddress(&wtok); + outdword(addpoststring()); + wtok.number+=4; + compressoffset(&wtok); + op66(r32); + outseg(&wtok,2); + op(0x83); + op(wtok.rm+0x20); + outaddress(&wtok); + op(0); + break; + default: +labl1: + reg=EAX|(EDX*256); + getintoreg64(reg); + doregmath64(reg); + getfromAX=1; + next=0; + break; + } + } + if(getfromAX){ +getfromax: + itok.number=EAX|(EDX*256); +getfromreg: + reg=itok.number&255; + for(i=0;i<2;i++){ + if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA3); // MOV [word],AX + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x89); + op((unsigned int)reg*8+wtok.rm); + outaddress(&wtok); + } + if(i==1)break; + wtok.number+=4; + compressoffset(&wtok); + reg=itok.number/256; + } + warningreg(regs[1][EAX]); + warningreg(regs[1][EDX]); + ClearReg(AX); + ClearReg(DX); + retrez=tk_reg64; + } + break; + case tk_minusminus: vop=0x8; + case tk_plusplus: + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); +incdec: + op(0xFF); op(vop+wtok.rm); + outaddress(&wtok); + wtok.number+=4; + compressoffset(&wtok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0x83); op(0x10+vop+wtok.rm); + outaddress(&wtok); + op(0); + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_opperand){ + if(tok==tk_number){ + if(OnlyNumber(4)){ + next=0; + otok=tok; + tok=tk_number; + goto num; + } + } + goto defxor; + } + else{ + switch(tok){ + case tk_number: + case tk_postnumber: + case tk_undefofs: + case tk_apioffset: +num: + for(i=0;i<2;i++){ + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + if(tok==tk_number&&(itok.flag&f_reloc)==0&&(vop==0||vop==0x28)){ + if(i==0&&itok.lnumber==1){ + if(vop)vop=8; + if(next==0)tok=otok; + goto incdec; + } + if(itok.number==1){ + op(0xFF); op((vop!=0?8:0)+wtok.rm); + outaddress(&wtok); + goto conl; + } + } + if(i==1){ + if(vop==0)vop+=0x10; + else if(vop==0x28)vop-=0x10; + } + if(tok!=tk_apioffset&&tok!=tk_undefofs&&tok!=tk_postnumber&&(itok.flag&f_reloc)==0&& + short_ok(itok.number,TRUE)){ + op(0x83); + op(vop+wtok.rm); + outaddress(&wtok); + op((unsigned int)itok.number); + } + else{ + op(0x81); + op(vop+wtok.rm); + outaddress(&wtok); + if(tok==tk_apioffset)AddApiToPost(itok.number); + else{ + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else if((itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + } +conl: + wtok.number+=4; + compressoffset(&wtok); + itok.lnumber>>=32; + } + if(next==0)tok=otok; + break; + case tk_reg64: + reg=itok.number&255; + for(i=0;i<2;i++){ + if(i==1){ + if(vop==0)vop+=0x10; + else if(vop==0x28)vop-=0x10; + } + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0x01+vop); op((unsigned int)reg*8+wtok.rm); + outaddress(&wtok); + if(i==1)break; + wtok.number+=4; + compressoffset(&wtok); + reg=itok.number/256; + } + break; + default: +defxor: + reg=EAX|(EDX*256); + getintoreg64(reg); + doregmath64(reg); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + reg=EAX; + for(i=0;i<2;i++){ + op66(r32); + op(0x01+vop); + op(wtok.rm+reg*8); + outaddress(&wtok); + if(i==1)break; + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + reg=EDX; + wtok.number+=4; + compressoffset(&wtok); + } + next=0; + retrez=tk_reg64; + warningreg(regs[1][EAX]); + warningreg(regs[1][EDX]); + break; + } + } + break; + case tk_multequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper&&tok==tk_number&&(itok.flag&f_reloc)==0){ + if(itok.lnumber==1)break; + if(itok.lnumber==0){ + ZeroReg(EAX,r32); + ZeroReg(EDX,r32); + goto getfromax; + } + if((i=caselong(itok.number))!=NUMNUM){ + if(wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA1); // MOV EAX,[dword] + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x8B); + op(wtok.rm); + outaddress(&wtok); + } + wtok.number+=4; + compressoffset(&wtok); + ClearReg(AX); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,3); + op(0x0F); + op(0xA4+vop); + op(wtok.rm); // SHLD [rmword],CL + outaddress(&wtok); + op(i); + wtok.number-=4; + compressoffset(&wtok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0xC1); + op(0x20+wtok.rm); + outaddress(&wtok); + op(i); + break; + } + } + CheckAllMassiv(wbuf,8,&wstr,&wtok); + wtok.number+=4; + compressoffset(&wtok); + for(i=0;i<2;i++){ + op66(r32); + outseg(&wtok,2); + op(0xFF); op(0x30+wtok.rm); + outaddress(&wtok); + if(i==1)break; + wtok.number-=4; + compressoffset(&wtok); + } + reg=ECX|(EAX*256); + getintoreg64(reg); + doregmath64(reg); + CallExternProc("__llmul"); + next=0; + goto getfromax; + case tk_divequals: + getoperand(am32==TRUE?EAX:BX); + if(itok2.type==tp_stopper&&tok==tk_number&&(itok.flag&f_reloc)==0){ + if(itok.number==0){ + DevideZero(); + break; + } + if(itok.number==1)break; + if((i=caselong(itok.number))!=NUMNUM){ + wtok.number+=4; + compressoffset(&wtok); + if(wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA1); // MOV EAX,[dword] + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x8B); + op(wtok.rm); + outaddress(&wtok); + } + wtok.number-=4; + compressoffset(&wtok); + ClearReg(AX); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,3); + op(0x0F); + op(0xAC); + op(wtok.rm); // SHLD [rmword],CL + outaddress(&wtok); + op(i); + wtok.number+=4; + compressoffset(&wtok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(0xC1); + op(0x28+wtok.rm); + outaddress(&wtok); + op(i); + break; + } + unsigned long number; + number=itok.lnumber>>32; + for(i=0;i<2;i++){ + op66(r32); + if((itok.flag&f_reloc)==0&&short_ok(number,1)){ + op(0x6A); + op(number); + } + else{ + op(0x68); + if(i==0&&(itok.flag&f_reloc)!=0)AddReloc(); + outdword(number); + } + if(i==1)break; + number=itok.number; + } + goto divcont; + } + reg=EAX|(EDX*256); + getintoreg64(reg); + doregmath64(reg); + op66(r32); + op(0x50+EDX); + op66(r32); + op(0x50+EAX); + next=0; +divcont: + addESP+=8; + if(ESPloc&&am32&&wtok.segm==SS)wtok.number+=8; + reg=EAX; + for(i=0;i<2;i++){ + if(reg==AX&&wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA1); + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x8B); + op(reg*8+wtok.rm); + outaddress(&wtok); + } + if(i==1)break; + wtok.number+=4; + compressoffset(&wtok); + reg=EDX; + } + CallExternProc("__lludiv"); + addESP-=8; + wtok.number-=4; + compressoffset(&wtok); + goto getfromax; + case tk_swap: + int regdi; + regdi=TRUE; + getoperand(); + rbuf=bufrm; + bufrm=NULL; + if(am32!=FALSE&&wbuf!=NULL&&wstr.bufstr!=NULL)regdi=FALSE; + switch(tok){ + case tk_reg64: + CheckAllMassiv(wbuf,8,&wstr,&wtok); + reg=itok.number&255; + for(i=0;i<2;i++){ + op66(r32); + outseg(&wtok,2); + op(0x87); + op(reg*8+wtok.rm); + outaddress(&wtok); + ClearReg(reg); + if(i==1)break; + reg=itok.number/256; + wtok.number+=4; + compressoffset(&wtok); + } + break; + case tk_qwordvar: + for(i=0;i<2;i++){ + getinto_e_ax(0,tk_dwordvar,&wtok,wbuf,&wstr,r32,TRUE); + CheckAllMassiv(rbuf,8,&strinf,&itok,regdi==FALSE?BX:DI,DX); + op66(r32); + outseg(&itok,2); + op(0x87); // XCHG AX,[wloc] + op(itok.rm); + outaddress(&itok); + KillVar(itok.name); + if(wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA3); /* MOV [word],AX */ + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); //???? + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x89); op(wtok.rm); /* MOV [rmword],AX */ + outaddress(&wtok); + } + if(i==1)break; + itok.number+=4; + compressoffset(&itok); + wtok.number+=4; + compressoffset(&wtok); + } + warningreg(regs[1][EAX]); + ClearReg(EAX); + break; + default: swaperror(); break; + } + break; + case tk_rrequals: + vop=8; + wtok.number+=4; + compressoffset(&wtok); + case tk_llequals: + getoperand(am32==TRUE?ECX:BX); + if(itok2.type!=tp_stopper){ + getintobeg(CL,&ofsstr); + ClearReg(CX); + warningreg(begs[1]); + next=0; + i=1; + } + else if(tok==tk_number){ + i=0; + } + else{ + if(tok!=tk_beg||(unsigned int)itok.number!=CL){ + getintobeg(CL,&ofsstr); + ClearReg(CX); + warningreg(begs[1]); + next=0; + } + i=1; + } + if(wbuf==NULL&&wstr.bufstr==NULL&& + ((wtok.rm==rm_d16&&wtok.sib==CODE16)|| + (wtok.rm==rm_d32&&(wtok.sib==CODE32||wtok.sib==0)))){ + op66(r32); + outseg(&wtok,1); + op(0xA1); // MOV EAX,[dword] + if(wtok.post==UNDEF_OFSET){ + AddUndefOff(2,wtok.name); + wtok.post=0; + } + if(am32==FALSE)outword(wtok.number); + else outdword(wtok.number); + } + else{ + CheckAllMassiv(wbuf,8,&wstr,&wtok,reg1,reg2); + op66(r32); + outseg(&wtok,2); + op(0x8B); + op(wtok.rm); + outaddress(&wtok); + } + if(vop)wtok.number-=4; + else wtok.number+=4; + compressoffset(&wtok); + ClearReg(AX); + warningreg(regs[1][EAX]); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,3); + op(0x0F); + op(0xA4+vop+i); + op(wtok.rm); // SHLD [rmword],CL + outaddress(&wtok); + if(i==0)op((unsigned int)itok.number); + if(vop)wtok.number+=4; + else wtok.number-=4; + compressoffset(&wtok); + CheckAllMassiv(wbuf,8,&wstr,&wtok); + op66(r32); + outseg(&wtok,2); + op(i==0?0xC1:0xD3); + op(0x20+vop+wtok.rm); + outaddress(&wtok); + if(i==0)op(itok.number); + break; + default: operatorexpected(); break; + } + KillVar(wtok.name); + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + if(cpu<3)cpu=3; + return retrez; +} + +void Select2FreeReg(int r1,int r2,int *reg1,int *reg2) +{ + *reg1=idxregs[0]; + *reg2=idxregs[1]; + if(r1==idxregs[0]){ + if(r2==idxregs[1]){ + *reg1=idxregs[2]; + *reg2=idxregs[3]; + } + else{ + *reg1=idxregs[1]; + if(r2==idxregs[2])*reg2=idxregs[3]; + else *reg2=idxregs[2]; + } + } + if(r1==idxregs[1]){ + if(r2==idxregs[0]){ + *reg1=idxregs[2]; + *reg2=idxregs[3]; + } + else{ + *reg1=idxregs[0]; + if(r2==idxregs[2])*reg2=idxregs[3]; + else *reg2=idxregs[2]; + } + } +} + +void doreg64(int reg,int terminater) +{ +unsigned char next=1; +int vop=0,sign=0; +int i; +int reg1,reg2; +unsigned long long ii; +int r1,r2; +char *ofsstr=NULL; +int rettype; +int pointr=0; +int numpointr=0; + rettype=tk_qword; + r1=reg&255; + r2=reg/256; + Select2FreeReg(r1,r2,®1,®2); + if(r1==ESP||r2==ESP)RestoreStack(); + nexttok(); + switch(tok){ + case tk_assign://= + nexttok(); + /*-----------------31.08.05 18:39------------------- + + --------------------------------------------------*/ + convert_type(&sign,(int *)&rettype,&pointr); + while(tok==tk_mult){ + nexttok(); + numpointr++; + } + if(numpointr>itok.npointr){ + unuseableinput(); + } + CheckMinusNum(); + if(tok==tk_number){ //஢ઠ 㬬஢ ᥫ + switch(rettype){ + case tk_float: sign=2; break; + case tk_double: sign=3; break; + case tk_qword: sign=4; break; + } + if(OnlyNumber(sign)){ + MovRegNum(r32,postnumflag&f_reloc,itok.number,r1); + MovRegNum(r32,0,itok.lnumber>>32,r2); + next=0; + break; + } + } + if(rettype==tk_float||rettype==tk_double){ + doeaxfloatmath(tk_stackstart,0,rettype==tk_float?0:4); + op66(r32); + op(0x58+r1); + op66(r32); + if(rettype==tk_float){ + op(0x31); op(0xC0+r2*9); + } + else op(0x58+r2); + next=0; + break; + } + /*-----------------31.08.05 18:39------------------- + + --------------------------------------------------*/ + getintoreg64(reg); + doregmath64(reg); + next=0; + break; + case tk_plusplus: op66(r32); op(0x40+r1); + op66(r32); + op(0x83); + op(0xD0+r2); + op(0); + break; + case tk_minusminus: op66(r32); op(0x48+r1); + op66(r32); + op(0x83); + op(0xD8+r2); + op(0); + break; + case tk_swap: + getoperand(reg1); + switch(tok){ + case tk_qwordvar: + reg=r1; + for(i=0;i<2;i++){ + CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); + op66(r32); + outseg(&itok,2); + op(0x87); + op(reg*8+itok.rm); + outaddress(&itok); + itok.number+=4; + compressoffset(&itok); + reg=r2; + } + break; + case tk_reg64: + reg=r1; + vop=itok.number; + itok.number&=255; + for(i=0;i<2;i++){ + if(reg!=(int)itok.number){ + if(RegSwapReg(reg,itok.number,r32)==NOINREG){; + op66(r32); + if(reg==AX)op(0x90+(unsigned int)itok.number); + else if((unsigned int)itok.number==AX)op(0x90+reg); + else{ + op(0x87); + op(0xC0+(unsigned int)itok.number+reg*8); + } + } + else waralreadinitreg(regs[1][reg],regs[1][itok.number]); + } + reg=r2; + itok.number=vop/256; + } + break; + default: swaperror(); break; + } + break; + case tk_xorequals: vop+=0x08; + case tk_minusequals: vop+=0x08; + case tk_andequals: vop+=0x18; + case tk_orequals: vop+=0x08; + case tk_plusequals: + if(CheckAddOnly()){ + inptr2--; + cha2=' '; + if(tok==tk_plusequals)tok=tk_plus; + else tok=tk_minus; + doregmath64(reg); + next=0; + break; + } + getoperand(reg1); + if(itok2.type==tp_opperand&&tok!=tk_number&&tok!=tk_undefofs&& + tok!=tk_postnumber)goto defadd; + CheckMinusNum(); + idrec *rrec; + int opost; + i=tok; + switch(tok){ + case tk_postnumber: + case tk_undefofs: + ii=itok.number; + rrec=itok.rec; + opost=itok.post; + char uname[IDLENGTH]; + strcpy(uname,itok.name); + if(itok.flag&f_extern)goto addnum; + tok=tk_number; + case tk_number: + ii=doconstqwordmath(); + next=0; + if(itok.type==tp_opperand){ + sign=reg1|(reg2*256); + if(i==tk_postnumber||i==tk_undefofs){ + op66(r32); + op(0xB8+r1); // MOV reg,# + if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); + else{ + if((postnumflag&f_reloc)!=0)AddReloc(); + if(i==tk_undefofs)AddUndefOff(2,uname); + } + outdword(ii); + ZeroReg(r2,r32); + } + else{ + MovRegNum(r32,postnumflag&f_reloc,ii,reg1); + MovRegNum(r32,postnumflag&f_reloc,ii>>=32,reg2); + } + doregmath64(sign); + itok.number=sign; + goto addreg; + } + if((postnumflag&f_reloc)==0&&i!=tk_undefofs&&i!=tk_postnumber){ + optnumadd64(ii,r1,r2,vop); + break; + } +addnum: + op66(r32); + if(r1==AX)op(0x05+vop); + else{ + op(0x81); + op(0xC0+vop+r1); + } + itok.rec=rrec; + itok.post=opost; + if(i==tk_postnumber)(postnumflag&f_extern)==0?setwordpost(&itok):setwordext((long *)&ii); + else{ + if((postnumflag&f_reloc)!=0)AddReloc(); + if(i==tk_undefofs)AddUndefOff(2,uname); + } + outdword(ii); + ii>>=32; + if(vop==0)vop=0x10; + else if(vop==0x28)vop=0x18; + op66(r32); + if(r2==AX)op(0x05+vop); + else{ + op(0x81); + op(0xC0+vop+r2); + } + outdword(ii); + break; + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); + op66(r32); + outseg(&itok,2); + op(0x03+vop); + op(r1*8+itok.rm); + outaddress(&itok); + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + break; + case tk_qword: + CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); + reg=r1; + for(i=0;i<2;i++){ + op66(r32); + outseg(&itok,2); + op(0x03+vop); + op(reg*8+itok.rm); + outaddress(&itok); + if(i==1)break; + reg=r2; + itok.number+=4; + compressoffset(&itok); + } + break; + case tk_reg64: +addreg: + reg=r1; + reg2=itok.number&255; + for(i=0;i<2;i++){ + op66(r32); + op(0x01+vop); + op(0xC0+reg+reg2*8); + if(i==1)break; + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + reg2=itok.number/256; + reg=r2; + } + break; + case tk_reg32: + op66(r32); + op(0x01+vop); + op(0xC0+reg+(unsigned int)itok.number*8); + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: +unsigned char oaddstack; + oaddstack=addstack; + if(r1==EAX||r2==EAX){ + op66(r32); + op(0x50); //push AX + warningreg(regs[1][EAX]); + addESP+=4; + ClearReg(EAX); + addstack=FALSE; + } + if(r1==EDX||r2==EDX){ + op66(r32); + op(0x50+EDX); //push DX + addESP+=4; + warningreg(regs[1][EDX]); + ClearReg(EDX); + addstack=FALSE; + } + procdo(tk_qword); + addstack=oaddstack; + if(itok2.type==tp_opperand){ + nexttok(); + doregmath64(EAX|(EDX*256)); + next=0; + } + if(r1==EDX||r2==EDX){ + op66(r32); + op(0x89); + op(0xC0+reg2+EDX*8); //mov reg,EDX + op66(r32); + op(0x58+EDX); //pop dx + addESP-=4; + } + else reg2=EDX; + if(r1==EAX||r2==EAX){ + op66(r32); + op(0x89); + op(0xC0+reg1+EAX*8); //mov reg,EAX + op66(r32); + op(0x58); //pop ax + addESP-=4; + } + else reg1=EAX; + op66(r32); + op(0x01+vop); + op(0xc0+r1+reg1*8); //add reg,ax + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + op66(r32); + op(0x01+vop); + op(0xc0+r2+reg2*8); //add reg,ax + break; + case tk_bytevar: + case tk_charvar: + case tk_beg: + case tk_reg: + case tk_intvar: + case tk_wordvar: +defadd: + sign=reg1|(reg2*256); + getintoreg64(sign); + doregmath64(sign); + warningreg(regs[1][reg1]); + warningreg(regs[1][reg2]); + ClearReg(reg1); + ClearReg(reg2); + op66(r32); + op(0x01+vop); + op(0xc0+r1+reg1*8); //add reg,ax + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + op66(r32); + op(0x01+vop); + op(0xc0+r2+reg2*8); //add reg,ax + next=0; + break; + default: valueexpected(); break; + } + break; + case tk_rrequals: vop+=0x08; + case tk_llequals: + getoperand(reg1); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstqwordmath(); + next=0; + if(itok.type==tp_opperand){ + if(r1==ECX||r2==ECX)regshifterror(); + op(0xB0+CL); op(ii); //mov CL,num + ConstToReg(ii,CL,r8); + dobegmath(CL); + warningreg(begs[1]); + ClearReg(CL); + goto shiftcl; + } + if(vop){ + reg=r1; + r1=r2; + r2=reg; + } + if(ii<32){ + op66(r32); + op(0x0F); + op(0xA4+vop); + op(0xC0+r2+r1*8); + op(ii); + op66(r32); + if(ii==1){ + op(0xD1); op(0xE0+r1+vop); + } + else{ + op(0xC1); + op(0xE0+r1+vop); //shl ax,num + op(ii); + } + } + else{ + op66(r32); + op(0x89); + op(0xC0+r2+r1*8); + ii-=32; + if(ii!=0){ + op66(r32); + if(ii==1){ + op(0xD1); + op(0xE0+vop+r1); //shr ax,1 + } + else{ + op(0xC1); + op(0xE0+r2+vop); //shl ax,num + op(ii); + } + } + ZeroReg(r1,r32); + } + } + else if(reg!=CX){ + if(!(itok2.type==tp_stopper&&(tok==tk_beg||tok==reg||tok==tk_reg32)&&itok.number==CL)){ + getintobeg(CL,&ofsstr); + dobegmath(CL); + warningreg(begs[1]); + ClearReg(CL); + next=0; + } +shiftcl: + op66(r32); + op(0x0F); + op(0xA5+vop); + if(vop){ + reg=r1; + r1=r2; + r2=reg; + } + op(0xC0+r2+r1*8); + op66(r32); + op(0xD3); + op(0xE0+vop+r1); // SHL xXX,CL + } + else regshifterror(); + break; + case tk_multequals: + getoperand(reg1); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstqwordmath(); + next=0; + if(itok.type==tp_opperand){ + op66(r32); + op(0x50+r2); + op66(r32); + op(0x50+r1); + addESP+=8; + MovRegNum(r32,postnumflag&f_reloc,ii,reg1); + MovRegNum(r32,0,ii>>32,reg2); + ConstToReg(ii,reg1,r32); + ConstToReg(ii>>32,reg2,r32); + doregmath64(reg1|(reg2*256)); + goto mul; + } + i=0; + if((postnumflag&f_reloc)==0){ + if(ii==0){ + ZeroReg(r1,r32); + ZeroReg(r2,r32); + break; + } + if(ii==1)break; + if(ii==2){ + op66(r32); + op(1); + op(0xC0+9*r1); // ADD r1,r1 + op66(r32); + op(0x83); + op(0xC2+r2*8); //adc r2,0 + op(0); + break; + } + if((i=caselonglong(ii))!=NUMNUM64){ + if(i<32){ + op66(r32); + outword(0xA40F); + op(0xC0+r2+r1*8); + op(i); + op66(r32); + op(0xC1); + op(0xE0+r1); //shl ax,num + op(i); + } + else{ + op66(r32); + op(0x89); + op(0xC0+r2+r1*8); + i-=32; + if(i!=0){ + op66(r32); + if(i==1){ + op(1); + op(0xC0+r2*9); //add reg,reg + } + else{ + op(0xC1); + op(0xE0+r2); //shl ax,num + op(i); + } + } + ZeroReg(r1,r32); + } + break; + } + } + op66(r32); + op(0x50+r2); + op66(r32); + op(0x50+r1); + addESP+=8; + MovRegNum(r32,postnumflag&f_reloc,ii,ECX); + MovRegNum(r32,0,ii>>32,EAX); + goto mul; + } + op66(r32); + op(0x50+r2); + op66(r32); + op(0x50+r1); + addESP+=8; + reg=ECX|(EAX*256); + warningreg(regs[1][ECX]); + getintoreg64(reg); + doregmath64(reg); +mul: + CallExternProc("__llmul"); + addESP-=8; +endmul: + ClearReg(EAX); + warningreg(regs[1][EAX]); + ClearReg(EDX); + warningreg(regs[1][EDX]); + next=0; + if(r1!=EAX){ + if(r1==EDX){ + if(r2==EAX){ + op66(r32); + op(0x90+EDX); + break; + } + op66(r32); + op(0x89); + op(0xC0+r2+EDX*8); //mov reg,EDX + op66(r32); + op(0x89); + op(0xC0+r1+EAX*8); //mov reg,EAX + break; + } + op66(r32); + op(0x89); + op(0xC0+r1+EAX*8); //mov reg,EAX + } + if(r2!=EDX){ + op66(r32); + op(0x89); + op(0xC0+r2+EDX*8); //mov reg,EDX + } + break; + case tk_divequals: + getoperand(reg1); + CheckMinusNum(); + if(tok==tk_number){ + ii=doconstqwordmath(); + next=0; + if(itok.type==tp_opperand){ + MovRegNum(r32,postnumflag&f_reloc,ii,reg1); + MovRegNum(r32,0,ii>>32,reg2); + ConstToReg(ii,reg1,r32); + ConstToReg(ii>>32,reg2,r32); + doregmath64(reg1|(reg2*256)); + op66(r32); + op(0x50+reg2); + op66(r32); + op(0x50+reg1); + addESP+=8; + warningreg(regs[1][reg1]); + warningreg(regs[1][reg2]); + goto divcont; + } + if((postnumflag&f_reloc)==0){ + if(ii==0){ + DevideZero(); + break; + } + if(ii==1)break; + if((i=caselonglong(ii))!=NUMNUM64){ + if(i<32){ + op66(r32); + outword(0xAC0F); + op(0xC0+r1+r2*8); + op(i); + op66(r32); + op(0xc1); + op(0xe8+r2); // SHR reg,imm8 + op(i); + } + else{ + op66(r32); + op(0x89); + op(0xC0+r1+r2*8); + i-=32; + if(i!=0){ + op66(r32); + if(i==1){ + op(0xD1); + op(0xE8+r1); //shr ax,1 + } + else{ + op(0xC1); + op(0xE8+r1); //shr ax,num + op(i); + } + } + ZeroReg(r2,r32); + } + break; + } + } + unsigned long number; + number=ii>>32; + for(i=0;i<2;i++){ + op66(r32); + if((postnumflag&f_reloc)==0&&short_ok(number,1)){ + op(0x6A); + op(number); + } + else{ + op(0x68); + if(i==0&&(postnumflag&f_reloc)!=0)AddReloc(); + outdword(number); + } + if(i==1)break; + number=ii; + } + addESP+=8; + goto divcont; + } + reg=reg1|(reg2*256); + getintoreg64(reg); + doregmath64(reg); + op66(r32); + op(0x50+reg2); + op66(r32); + op(0x50+reg1); + addESP+=8; + warningreg(regs[1][reg1]); + warningreg(regs[1][reg2]); + next=0; +divcont: + if(r1!=EAX){ + if(r2==EAX){ + if(r1==EDX){ + op66(r32); + op(0x90+EDX); + goto sdiv; + } + op66(r32); + op(0x89); + op(0xC0+EDX+r2*8); //mov EDX,r2 + op66(r32); + op(0x89); + op(0xC0+EAX+r1*8); //mov EAX,r1 + goto sdiv; + } + op66(r32); + op(0x89); + op(0xC0+EAX+r1*8); //mov EAX,r1 + } + if(r2!=EDX){ + op66(r32); + op(0x89); + op(0xC0+EDX+r2*8); //mov EDX,r2 + } +sdiv: + CallExternProc("__lludiv"); + addESP-=8; + goto endmul; + default: operatorexpected(); break; + } + ClearReg(r1); + ClearReg(r2); + if(next)nexttok(); + if(terminater==tk_semicolon)seminext(); + if(cpu<3)cpu=3; +} + +void optnumadd64(unsigned long long num,int r1,int r2,int vop) +{ +int i,reg; + if(num==0){ + if(vop==0x20){ //&= + reg=r1; + for(i=0;i<2;i++){ + ZeroReg(reg,r32); + reg=r2; + } + setzeroflag=TRUE; + } + return; //+= -= |= ^= + } + if(num==1){ + if(vop==0x28){ //-= + op66(r32); + op(0x48+r1); + op66(r32); + op(0x83); + op(0xD8+r2); + op(0); + setzeroflag=TRUE; + return; + } + if(vop==0){ //+= + op66(r32); + op(0x40+r1); + op66(r32); + op(0x83); + op(0xD0+r2); + op(0); + setzeroflag=TRUE; + return; + } + } + if(vop==8){ //|= + if(num<65536){ + if((unsigned short)num<256&&r1<4){ + if(r1==AX)op(0x0C); + else{ + op(0x80); + op(0xc8+r1); + } + op(num); + return; + } + op66(r16); + if(r1==AX)op(0x0D); + else{ + op(0x81); + op(0xc8+r1); + } + outword(num); + return; + } + if(num<0x100000000LL){ + op66(r32); + if(r1==AX)op(0x0D); + else{ + op(0x81); + op(0xc8+r1); + } + outdword(num); + return; + } + } + if(vop==0x20){ //&= + if(num>=0xFFFFFFFF00000000LL){ + if((unsigned long)num>=0xFFFF0000){ + if((unsigned short)num>=0xFF00&&r1<4){ + if(r1==AL)op(0x24); + else{ + op(128); + op(0xE0+r1); + } + op(num); + return; + } + op66(r16); + if(r1==AX)op(0x25); + else{ + op(129); + op(0xE0+r1); + } + outword(num); + return; + } + op66(r32); + if(r1==AX)op(0x25); + else{ + op(129); + op(0xE0+r1); + } + outdword(num); + return; + } + } + reg=r1; + int j=0; + for(i=0;i<2;i++){ + if((unsigned long)num==0)j++; + if(optnumadd(num,reg,r32,vop)==FALSE){ + op66(r32); + if(short_ok((unsigned long)num,TRUE)){ + op(0x83); + op(0xC0+vop+reg); + op(num); + } + else{ + if(reg==EAX)op(5+vop); + else{ + op(0x81); + op(0xC0+vop+reg); + } + outdword(num); + } + } + num>>=32; + if(j==0&&(vop==0||vop==0x28)){ + if(vop)vop=8; + op66(r32); + if(short_ok((unsigned long)num,TRUE)){ + op(0x83); + op(0xD0+vop+r2); + op(num); + } + else{ + if(r2==EAX)op(0x15+vop); + else{ + op(0x81); + op(0xD3+vop+r2); + } + outdword(num); + } + break; + } + reg=r2; + } + setzeroflag=TRUE; +} + +void doregmath64(int reg) +{ +int vop,i,optnum,negflag=FALSE; +int r1,r2,next=1; +int reg1,reg2; +char *ofsstr=NULL; + r1=reg&255; + r2=reg/256; + Select2FreeReg(r1,r2,®1,®2); + while(itok.type!=tp_stopper&&tok!=tk_eof){ + if(negflag){ + op66(r32); + op(0xF7); + op(0xD8+r2); // NEG reg + op66(r32); + op(0xF7); + op(0xD8+r1); // NEG reg + op66(r32); + op(0x83); + op(0xD8+r2); + op(0); + ClearReg(r1); + ClearReg(r2); + negflag=FALSE; + } + vop=0; + next=1; + optnum=FALSE; + if(tok2==tk_number)optnum=OptimNum(); + switch(tok){ + case tk_xor: vop+=0x08; + case tk_minus: vop+=0x08; + case tk_and: vop+=0x18; + case tk_or: vop+=0x08; + case tk_plus: + if(optnum==FALSE)getoperand(reg1); + else tok=tk_number; + switch(tok){ + case tk_number: + if((itok.flag&f_reloc)==0){ + optnumadd64(itok.lnumber,r1,r2,vop); + break; + } + case tk_postnumber: + case tk_undefofs: + case tk_apioffset: + op66(r32); + op(0x81); + op(0xC0+vop+r1); + if(tok==tk_apioffset)AddApiToPost(itok.number); + else{ + if(tok==tk_postnumber)(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + else if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else if((itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + break; + case tk_rmnumber: + case tk_charvar: + case tk_beg: + case tk_bytevar: + getintoreg_32(reg2,r32,0,&ofsstr,FALSE); + op66(r32); + op(0x01+vop); + op(0xC0+r1+reg2*8); /* OPT AX,CX */ + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + warningreg(regs[r32/2-1][reg2]); + next=0; + break; + case tk_reg: + op66(r32); + outword(0xB70F); + if(itok.number==r1||itok.number==r2)itok.number=reg1; + op(0xC0+itok.number*9); + warningreg(regs[1][itok.number]); + case tk_reg32: +defreg32: + op66(r32); + op(0x01+vop); + op(0xC0+r1+(unsigned int)itok.number*8); + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + break; + case tk_reg64: + int reg2; + reg=r1; + reg2=itok.number&255; + for(i=0;i<2;i++){ + op66(r32); + op(0x01+vop); + op(0xC0+reg+reg2*8); + if(i==1)break; + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + reg2=itok.number/256; + reg=r2; + } + break; + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf); + op66(r32); + outseg(&itok,2); + op(0x03+vop); + op(r1*8+itok.rm); + outaddress(&itok); + if(vop==0x20){ //&= + ZeroReg(r2,r32); + } + else{ + if(vop==0||vop==0x28){ + if(vop)vop=8; + op66(r32); + op(0x83); + op(0xD0+vop+r2); + op(0); + } + } + break; + case tk_qwordvar: + reg=r1; + for(i=0;i<2;i++){ + CheckAllMassiv(bufrm,8,&strinf); + op66(r32); + outseg(&itok,2); + op(0x03+vop); + op(reg*8+itok.rm); + outaddress(&itok); + if(i==1)break; + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + itok.number+=4; + compressoffset(&itok); + reg=r2; + } + break; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + procdo(tk_qword); + op66(r32); + op(0x01+vop); + op(0xc0+r1); + warningreg(regs[1][0]); + if(vop==0)vop=0x10; + if(vop==0x28)vop=0x18; + op66(r32); + op(0x01+vop); + op(0xc0+r2+EDX*8); + warningreg(regs[1][EDX]); + break; + default: valueexpected(); break; + } + break; + case tk_rrminus: + if(r1==ECX||r2==ECX){ + regshifterror(); + break; + } + tok=tk_minus; + goto rshift2; + case tk_rr: + getoperand(ECX); + if(tok==tk_number){ + op66(r32); + outword(0xAC0F); + op(0xC0+r1+r2*8); + op(itok.number); + op66(r32); + if((unsigned int)itok.number==1){ + op(0xD1); op(0xE8+r2); // SHR reg,1 + } + else if((unsigned int)itok.number!=0){ + op(0xc1); + op(0xe8+r2); // SHR reg,imm8 + op((unsigned int)itok.number); + } + } + else if(r1==ECX||r2==ECX)regshifterror(); + else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL)goto rshift; + else{ +rshift2: + getintobeg(CL,&ofsstr); + next=0; + warningreg(begs[1]); +rshift: + op66(r32); + outword(0xAD0F); + op(0xC0+r1+r2*8); + op66(r32); + op(0xD3); + op(0xE8+r2); // SHL xXX,CL + } + break; + case tk_llminus: + if(r1==ECX||r2==ECX){ + regshifterror(); + break; + } + tok=tk_minus; + goto llshift; + case tk_ll: + getoperand(ECX); + if(tok==tk_number){ + op66(r32); + outword(0xA40F); + op(0xC0+r2+r1*8); + op(itok.number); + op66(r32); + if((unsigned int)itok.number==1){ + op(1); + op(0xC0+r1*9); //add reg,reg + } + else{ + op(0xC1); + op(0xE0+r1); //shl ax,num + op(itok.number); + } + } + else if(r1==ECX||r2==ECX)regshifterror(); + else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&itok.number==CL)goto lshift; + else{ +llshift: + getintobeg(CL,&ofsstr); + next=0; + warningreg(begs[1]); +lshift: + op66(r32); + outword(0xA50F); + op(0xC0+r2+r1*8); + op66(r32); + op(0xD3); + op(0xE0+r1); // SHL xXX,CL + } + break; + case tk_multminus: negflag=TRUE; + case tk_mult: + getoperand(reg1); + if(negflag&&tok==tk_number){ + itok.lnumber=-itok.lnumber; + negflag=FALSE; + } + if(tok==tk_number&&((itok.number&f_reloc)==0)){ + if(itok.lnumber==0){ + ZeroReg(r1,r32); + ZeroReg(r2,r32); + break; + } + if(itok.lnumber==1)break; + if(itok.lnumber==2){ + op66(r32); + op(1); + op(0xC0+9*r1); // ADD r1,r1 + op66(r32); + op(0x83); + op(0xC2+r2*8); //adc r2,0 + op(0); + break; + } + if((i=caselonglong(itok.lnumber))!=NUMNUM64){ + if(i<32){ + op66(r32); + outword(0xA40F); + op(0xC0+r2+r1*8); + op(i); + op66(r32); + op(0xC1); + op(0xE0+r1); //shl ax,num + op(i); + } + else{ + op66(r32); + op(0x89); + op(0xC0+r2+r1*8); + i-=32; + if(i!=0){ + op66(r32); + if(i==1){ + op(1); + op(0xC0+r2*9); //add reg,reg + } + else{ + op(0xC1); + op(0xE0+r2); //shl ax,num + op(i); + } + } + ZeroReg(r1,r32); + } + break; + } + op66(r32); + op(0x50+r2); + op66(r32); + op(0x50+r1); + addESP+=8; + MovRegNum(r32,postnumflag&f_reloc,itok.number,ECX); + MovRegNum(r32,0,itok.lnumber>>32,EAX); + goto mul; + } + //맮 楤 __llmul + op66(r32); + op(0x50+r2); + op66(r32); + op(0x50+r1); + addESP+=8; + reg=ECX|(EAX*256); + getintoreg64(reg); +// doregmath64(reg); + next=0; +mul: + CallExternProc("__llmul"); + addESP-=8; +endmul: + if(r1!=EAX){ + if(r1==EDX){ + if(r2==EAX){ + op66(r32); + op(0x90+EDX); + break; + } + op66(r32); + op(0x89); + op(0xC0+r2+EDX*8); //mov reg,EDX + op66(r32); + op(0x89); + op(0xC0+r1+EAX*8); //mov reg,EAX + break; + } + op66(r32); + op(0x89); + op(0xC0+r1+EAX*8); //mov reg,EAX + } + if(r2!=EDX){ + op66(r32); + op(0x89); + op(0xC0+r2+EDX*8); //mov reg,EDX + } + break; + case tk_modminus: negflag=TRUE; + case tk_mod: + vop=1; + goto divcalc;; + case tk_divminus: negflag=TRUE; + case tk_div: +divcalc: + getoperand(reg1); + if(negflag&&tok==tk_number){ + itok.lnumber=-itok.lnumber; + negflag=FALSE; + } + if(tok==tk_number&&((itok.flag&f_reloc)==0)){ + if(itok.lnumber==0){ + DevideZero(); + break; + } + if(itok.lnumber==1){ + if(vop){ //mod + ZeroReg(r1,r32); + ZeroReg(r2,r32); + } + break; + } + if((i=caselonglong(itok.lnumber))!=NUMNUM64){ + if(vop){ //mod + optnumadd64(itok.lnumber-1,r1,r2,0x20); + } + else{ + if(i<32){ + op66(r32); + outword(0xAC0F); + op(0xC0+r1+r2*8); + op(i); + op66(r32); + op(0xc1); + op(0xe8+r2); // SHR reg,imm8 + op(i); + } + else{ + op66(r32); + op(0x89); + op(0xC0+r1+r2*8); + i-=32; + if(i!=0){ + op66(r32); + if(i==1){ + op(0xD1); + op(0xE8+r1); //shr ax,1 + } + else{ + op(0xC1); + op(0xE8+r1); //shr ax,num + op(i); + } + } + ZeroReg(r2,r32); + } + } + break; + } + unsigned long number; + number=itok.lnumber>>32; + for(i=0;i<2;i++){ + op66(r32); + if((itok.flag&f_reloc)==0&&short_ok(number,1)){ + op(0x6A); + op(number); + } + else{ + op(0x68); + if(i==0&&(itok.flag&f_reloc)!=0)AddReloc(); + outdword(number); + } + if(i==1)break; + number=itok.number; + } + addESP+=8; + goto divcont; + } + reg=reg1|(reg2*256); + getintoreg64(reg); + op66(r32); + op(0x50+reg2); + op66(r32); + op(0x50+reg1); + addESP+=8; + next=0; +divcont: + if(r1!=EAX){ + if(r2==EAX){ + if(r1==EDX){ + op66(r32); + op(0x90+EDX); + goto sdiv; + } + op66(r32); + op(0x89); + op(0xC0+EDX+r2*8); //mov EDX,r2 + op66(r32); + op(0x89); + op(0xC0+EAX+r1*8); //mov EAX,r1 + goto sdiv; + } + op66(r32); + op(0x89); + op(0xC0+EAX+r1*8); //mov EAX,r1 + } + if(r2!=EDX){ + op66(r32); + op(0x89); + op(0xC0+EDX+r2*8); //mov EDX,r2 + } +sdiv: + CallExternProc((char*)(vop==0?"__lludiv":"__llumod")); + addESP-=8; + goto endmul; + default: operatorexpected(); break; + } + if(next)nexttok(); + } + ClearReg(r1); + ClearReg(r2); + if(cpu<3)cpu=3; +} + +void getintoreg64(int reg) +{ +int negflag=0,next=1,i=0; +unsigned long long holdnumber=0; +int r1,r2; +int reg1,reg2; + r1=reg&255; + r2=reg/256; + Select2FreeReg(r1,r2,®1,®2); + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + negflag=1; + getoperand(am32==FALSE?BX:r1); + } + } + switch(tok){ + case tk_number: + holdnumber=CalcNumber(4); + MovRegNum(r32,postnumflag&f_reloc,holdnumber,r1); + MovRegNum(r32,0,holdnumber>>32,r2); + next=0; + break; + case tk_postnumber: + case tk_undefofs: + case tk_apioffset: + op66(r32); + op(0xB8+r1); /* MOV AX,# */ + if(tok==tk_apioffset)AddApiToPost(itok.number); + else{ + if(tok==tk_undefofs)AddUndefOff(0,itok.name); + else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + tok=tk_number; + holdnumber+=doconstdwordmath(); + outdword(holdnumber); + MovRegNum(r32,0,holdnumber>>32,r2); + next=0; + } + ClearReg(r1); + ClearReg(r2); + break; + case tk_rmnumber: + CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); + if(!(am32&&itok.rm==r1&&r1!=EBP&&r1!=ESP)){ + op66(r32); + op67(itok.sib==CODE16?r16:r32); + if(itok.post==0)outseg(&itok,2); + op(0x8D); // LEA reg,[rm] + op(r1*8+itok.rm); + if(itok.post!=0&&itok.post!=UNDEF_OFSET){ + if((itok.flag&f_extern)==0){ + unsigned int ooutptr=outptr; + if(am32&&itok.rm==rm_sib)outptr++; + setwordpost(&itok); + outptr=ooutptr; + } + else setwordext(&itok.number); + } + outaddress(&itok); + ClearReg(r1); + } + ZeroReg(r2,r32); + break; + case tk_qwordvar: + reg=r1; + for(i=0;i<2;i++){ + if(reg==EAX&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ + op66(r32); + outseg(&itok,1); + op(0xA1); + if(itok.post==UNDEF_OFSET)AddUndefOff(2,itok.name); + if(am32==FALSE)outword((unsigned int)itok.number); + else outdword(itok.number); + } + else{ + CheckAllMassiv(bufrm,8,&strinf,&itok,reg1,reg2); + op66(r32); + outseg(&itok,2); + op(0x8B); + op(reg*8+itok.rm); + outaddress(&itok); + } + ClearReg(reg); + if(i==1)break; + itok.number+=4; + compressoffset(&itok); + reg=r2; + } + break; + case tk_longvar: + case tk_dwordvar: + if(reg==EAX&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ + op66(r32); + outseg(&itok,1); + op(0xA1); + if(itok.post==UNDEF_OFSET)AddUndefOff(2,itok.name); + if(am32==FALSE)outword((unsigned int)itok.number); + else outdword(itok.number); + } + else{ + CheckAllMassiv(bufrm,4,&strinf,&itok,reg1,reg2); + op66(r32); + outseg(&itok,2); + op(0x8B); + op(r1*8+itok.rm); + outaddress(&itok); + } + ZeroReg(r2,r32); + ClearReg(r1); + break; + case tk_intvar: + case tk_wordvar: + CheckAllMassiv(bufrm,2,&strinf,&itok,reg1,reg2); + if(tok==tk_wordvar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ + ZeroReg(r1,r32); + op66(r16); + outseg(&itok,2); //mov reg,var + op(0x8B); + } + else{ + op66(r32); + outseg(&itok,3); //movxx reg,var + op(0x0F); op(tok==tk_wordvar?0xB7:0xBF); + } + op(r1*8+itok.rm); + outaddress(&itok); + ClearReg(r1); + ZeroReg(r2,r32); + break; + case tk_bytevar: + case tk_charvar: + CheckAllMassiv(bufrm,1,&strinf,&itok,reg1,reg2); + if(reg<=EBX&&tok==tk_bytevar&&optimizespeed&&chip>3&&chip<7&&RmEqualReg(reg,itok.rm,itok.sib)==FALSE){ + ZeroReg(r1,r32); + outseg(&itok,2); + op(0x8A); + } + else{ + op66(r32); + outseg(&itok,3); + op(0xf); + if(tok==tk_bytevar)op(0xb6); + else op(0xbe); + } + op(r1*8+itok.rm); // MOVZX regL,[byte] + outaddress(&itok); + ClearReg(r1); + ZeroReg(r2,r32); + break; + case tk_reg: + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=itok.number; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(r16); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ + itok.number=0; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + } + if(optimizespeed&&chip>3&&chip<7&®!=(int)itok.number){ + ZeroReg(r1,r32); + op(0x89); + op(0xC0+r1+(unsigned int)itok.number*8); + } + else{ + op66(r32); + outword(0xB70F); + op(0xC0+r1*8+(unsigned int)itok.number); + } + RegToReg(r1,itok.number,r32); + ZeroReg(r2,r32); + break; + case tk_reg32: + if(tok2==tk_openbracket){ //맮 楤 ॣ + reg1=itok.number; + nexttok(); + param[0]=0; + if(comfile==file_w32)swapparam(); + else doparams(); + op66(r32); + op(0xFF); + op(0xD0+reg1); /* CALL reg with stack params */ + itok.number=0; + clearregstat(); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + } + if(r1!=(int)itok.number){ + op66(r32); + op(0x89); + op(0xC0+r1+(unsigned int)itok.number*8); + RegToReg(r1,itok.number,r32); + } + ZeroReg(r2,r32); + break; + case tk_reg64: + reg1=itok.number&255; + reg2=itok.number/256; +movreg64: + if(r1==reg2){ + if(r2==reg1){ + op66(r32); + if(r1==AX)op(0x90+r2); + else if(r2==AX)op(0x90+r1); + else{ + op(0x87); + op(0xC0+r1+r2*8); + } + break; + } + int temp; + temp=r2; + r2=r1; + r1=temp; + temp=reg2; + reg2=reg1; + reg1=temp; + } + if(r2==reg1){ + int temp; + temp=r2; + r2=r1; + r1=temp; + temp=reg2; + reg2=reg1; + reg1=temp; + } + if(r1!=reg1){ + op66(r32); + op(0x89); + op(0xC0+r1+reg1*8); + RegToReg(r1,reg1,r32); + } + if(r2!=reg2){ + op66(r32); + op(0x89); + op(0xC0+r2+reg2*8); + RegToReg(r2,reg2,r32); + } + break; + case tk_bits: + int vops; + i=itok.bit.siz+itok.bit.ofs; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + bits2reg(r1,(r323&&chip<7&®<4&®!=(int)(itok.number%4)){ + ZeroReg(r1,r32); + op(0x88); + op(0xC0+r1+(unsigned int)itok.number*8); // MOV regL,beg + } + else{ + op66(r32); + outword(0xb60f); + op(0xC0+r1*8+(unsigned int)itok.number); // MOVZX regL,beg + } + ClearReg(reg); + ZeroReg(r2,r32); + break; + case tk_at: + getoperand(am32==FALSE?BX:reg); + i++; + case tk_ID: + case tk_id: + case tk_proc: + case tk_apiproc: + case tk_undefproc: + case tk_declare: + if((!i)||macros(tk_qword)==0)procdo(tk_qword); + reg1=EAX; reg2=EDX; + goto movreg64; + case tk_string: + op66(r32); + op(0xB8+r1); + outdword(addpoststring()); + ClearReg(r1); + ZeroReg(r2,r32); + break; + default: valueexpected(); break; + } + if(negflag){ + op66(r32); + op(0xF7); + op(0xD8+r2); // NEG reg + op66(r32); + op(0xF7); + op(0xD8+r1); // NEG reg + op66(r32); + op(0x83); + op(0xD8+r2); + op(0); + ClearReg(r1); + ClearReg(r2); + } + if(next)nexttok(); +} + +void CallExternProc(char *name) +{ +ITOK itok4; +int tok4=tk_id; +char string4[256]; +struct idrec *ptrs; + memset(&itok4,0,sizeof(ITOK)); + strcpy(string4,name); + searchtree(&itok4,&tok4,(unsigned char *)string4); + ptrs=itok4.rec; + switch(tok4){ + case tk_id: + tok4=tok; + itok4=itok; + strcpy((char *)itok.name,string4); + string[0]=0; + itok.flag=tp_stdcall; + tok=tk_undefproc; + itok.number=secondcallnum; + itok.segm=NOT_DYNAMIC; + itok.rm=tk_qword; + itok.post=0; + addtotree(itok.name); + addacall(secondcallnum++,CALL_NEAR); + tok=tok4; + itok=itok4; + callloc0(); + break; + case tk_declare: + ptrs->rectok=tk_undefproc; + case tk_undefproc: + addacall(itok4.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR)); + callloc0(); /* produce CALL [#] */ + break; + case tk_proc: + if(itok4.segm==DYNAMIC)itok4.segm=ptrs->recsegm=DYNAMIC_USED; + if(itok4.segm /* O_ constant definitions */ +#include "tok.h" + +void GetFileTime(int fd,struct ftime *buf); + +#define MAXIF 32 + +//idrec *crec=NULL; + +char invaliddecrem[]="invalid token to be decremented"; +char mesLOOPNZ[]="LOOPNZ"; +char mesIF[]="IF"; +char mesELSE[]="ELSE"; +char mesWHILE[]="WHILE"; +char mesFOR[]="FOR"; +char mesRETURN[]="RETURN"; +int tok,tok2; /* token holders current, next */ +unsigned char string[STRLEN],string2[STRLEN+20], + string3[STRLEN]; // +unsigned int posts=0; /* number of post entrys */ +postinfo *postbuf; +unsigned int maxposts=MAXPOSTS; +unsigned int secondcallnum=1; /* # of different second calls and labels */ +unsigned int externnum=0; +unsigned long postsize=0; /* total size of all post vars */ +unsigned int poststrptr=0; /* post string index in output */ +unsigned int outptrsize=MAXDATA; // +unsigned int outdatasize=MAXDATA; // +long runfilesize; +int error=0; /* current error number holder */ +unsigned char dos1=0,dos2=0; /* DOS version required for program execution */ +unsigned char cpu=0; /* CPU required, 2 for 80286, 3 for 80386, ... */ +unsigned int paramsize=0; /* byte size of all procedure parameters */ +unsigned int localsize=0; /* byte size of all procedure local variables */ +unsigned int procedure_start=0; /* address of start of procedure */ +unsigned int current_proc_type; /* current procedure type */ +int returntype; /* return type, (void, byte, word, ...) */ +unsigned char warning; +/*+++++++++++++++++++++++ +++++++++++++++++++++++*/ +unsigned char am32 = FALSE; // 32 +unsigned char comfile = file_com; // output file format +unsigned char optimizespeed = 1; // optimize for size or speed flag +unsigned char alignword = 1; // flag whether or not to align words +unsigned char aligner = 0; // value used to align words +unsigned char header = 1; // output SPHINX C-- Ver1 Ver2 header +unsigned char chip = 0; // CPU optimization (286,386,486,...) +unsigned char killctrlc = 0; // add disable CTRL-C code in header +unsigned int stacksize = 2048; // stack size (2048 default) +unsigned char splitdata=FALSE; // +unsigned char AlignCycle=FALSE; // +/*+++++++++++++++++++ end of flexable compiler options ++++++++++++++++++++*/ +unsigned char notdoneprestuff = TRUE; // flag if initial stuff has been entered +unsigned int datasize=0,alignersize=0; /* size of data and other */ +unsigned int outptr=0x100,outptrdata=0x100; /* ptr to output */ +unsigned char *output; +unsigned char *outputdata=NULL; +unsigned int linenumber=0; +unsigned char dynamic_flag=0; // + +unsigned char *input; /* dynamic input buffer */ +unsigned int endinptr; /* end index of input array */ +unsigned int inptr; /* index in input buffer */ +unsigned char cha; /* pipe byte for token production */ +char endoffile; /* end of input file flag */ +unsigned char insertmode=FALSE; +unsigned int numblocks=0; // +treelocalrec *tlr=NULL; // +treelocalrec *btlr=NULL; // +RETLIST *listreturn=NULL; +unsigned int numreturn=0; +idrec *staticlist; +unsigned char stat_reg[8]; // + +int sizestack=0; // +unsigned char addstack=TRUE; + +extern char shorterr[]; +extern unsigned long long li[]; + +/*-----------------01.05.98 19:22------------------- + BREAK CONTINUE +--------------------------------------------------*/ +#define MAXIN 100 // +unsigned int numbr=0; // LOOP DO-WHILE... +unsigned int listbr[MAXIN]; // +unsigned int usebr[MAXIN]; // break +unsigned int useco[MAXIN]; // continue +unsigned int curbr=0,curco=0; // +unsigned int startStartup=0x100; +unsigned int endStartup=0; +unsigned char useStartup=FALSE; +unsigned char notpost=FALSE; +int retproc; +int lastcommand; // +unsigned char FastCallApi=TRUE; // API +unsigned char FixUp=FALSE; // +unsigned char AlignProc=FALSE; +//------- union --------------------------------------------- +char param[256]; // +char *BackTextBlock; // +int SizeBackBuf=0,MaxSizeBackBuf; +struct FILEINFO *startfileinfo=NULL; +unsigned int totalmodule=0; +unsigned int currentfileinfo; +unsigned char setzeroflag; // zero flag +unsigned char notunreach=FALSE; +unsigned int initBP=0; +int inlineflag=0; // flag for disabling entry and exit codes production +unsigned char fstatic=FALSE; + +unsigned long addESP=0; // +unsigned char blockproc=FALSE; // + +unsigned int updatelocalvar(char *str,int tok,unsigned int num); +void setuprm(); +void doloop(unsigned int typeb); /* both short and long loops */ +void doBREAK(unsigned char typeb); +void doCONTINUE(unsigned char typeb); +void dowhile(unsigned int typeb); +void MakeContinue(unsigned char typeb); +void dofor(unsigned int typeb); +void dodo(); +void globalvar(); /* both initialized and unitialized combined */ +void doswitch(); +void CalcRegPar(int reg,int def,char *&ofsstr); +void JXorJMP(); +int loadinputfile(char *inpfile); +int SaveStartUp(int size,char *var_name); +void LoadData(unsigned int size,int filehandle); +void SetNewTok(int type,int typev); +void doreturn(int type=tokens); /* do return(...); */ +void notnegit(int notneg); +void insertcode(); // force code procedure at specified location +void interruptproc(); +void dobigif(); +void doif(void); +void doasmblock(); +void declareextern(); +unsigned long dounion(int,int); +void RunBackText(); +int FindDublString(int segm,unsigned int len,int term); +void *liststring=NULL; // +void GetNameLabel(int type,int num); +void CheckPosts(); +SAVEPAR *SRparam(int save,SAVEPAR *par); //save or restore global param compiler +void AddRetList(int pos,int line,int type); +void CheckRealizable(); +void declare_procedure(int oflag,int orm,int npointr); +void labelindata(); +void AddRegistr(int razr,int reg); +void ClearRegister(); +int GetRegister(int mode=0); +void RegAddNum(int reg); +void dowhilefast(unsigned int typeb); +int getrazr(int type); +void RestoreSaveReg(); +void killlocals(/*int endp=TRUE*/); +void leaveproc(); +int IsSaveReg(); +void CorrectParamVar(); + +extern void ManyLogicCompare(); +extern void maxdataerror(); +extern void CompareOr(); +extern void dynamiclabelerror(); +extern void retvoid(); +extern int numberbreak; + +SAVEREG savereg; +SAVEREG *psavereg=&savereg; + +int loadfile(char *filename,int firstflag) +{ +int hold; + + for(int i=0;i<=numfindpath;i++){ + sprintf((char *)string2,"%s%s",findpath[(firstflag==0?i:numfindpath-i)],filename); + if((hold=loadinputfile((char *)string2))!=-2)break; + if(firstflag==2||(firstflag==0&&(i+1)==numfindpath))break; + } + if(hold==-2){ + unableopenfile(filename); // + exit(e_cannotopeninput); // + } + return hold; +} + +void compilefile(char *filename,int firstflag) +{ +int hold; + + hold=loadfile(filename,firstflag); + if(hold==1||hold==-1)return; + if(strcmp(filename,"startup.h--")==0)startupfile=currentfileinfo; + + inptr=0; + endoffile=0; + startline=(char*)input; + endinput=startline+endinptr; + warning=gwarning; + nextchar(); + cha2=cha; // + inptr2=inptr; // + linenum2=1; // + { // + char *a; + if((a=strrchr(filename,'.'))!=NULL){ + if(stricmp(a,".rc")==0){ + input_res(); + free(input); + return; + } + } + } + + nexttok(); // + while(tok!=tk_eof){ // + while(tok==tk_question){ + directive();// + if(tok==tk_semicolon)nexttok(); + } + usedirectiv=FALSE; + if(notdoneprestuff==TRUE)doprestuff();//startup + switch(tok){ + case tk_ID: + case tk_id: + if(FindTeg(TRUE)!=NULL){ + InitStruct(); + break; + } + if(tok2==tk_colon){ + labelindata(); + break; + } + case tk_far: + case tk_cdecl: + case tk_pascal: + case tk_stdcall: + case tk_fastcall: + case tk_declare: + case tk_undefproc: + case tk_float: + case tk_long: + case tk_dword: + case tk_word: + case tk_byte: + case tk_char: + case tk_int: + case tk_void: + case tk_export: + case tk_qword: + case tk_double: + case tk_fpust: + if((hold=testInitVar())==FALSE)define_procedure(); + else if(hold==TRUE)globalvar(); + break; + case tk_struct: InitStruct(); break; + case tk_interrupt: interruptproc(); break; + case tk_at: insertcode(); break; // + case tk_colon: + nexttok(); + dynamic_flag=2; + break;// + case tk_inline: + if(testInitVar()){ + preerror("Bad header dynamic function"); + nexttok(); + } + dynamic_proc(); + break; + case tk_static: + fstatic=2; + nexttok(); + break; + case tk_enum: doenum(); break; + case tk_from: nexttok(); dofrom(); nextseminext(); break; + case tk_extract: nexttok(); doextract(); seminext(); break; + case tk_loop: + case tk_while: + case tk_do: + case tk_else: + case tk_ELSE: + case tk_if: + case tk_IF: + case tk_interruptproc: + case tk_proc: + case tk_charvar: + case tk_intvar: + case tk_bytevar: + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + case tk_qwordvar: + case tk_doublevar: + case tk_wordvar: idalreadydefined(); break; + case tk_reg32: + case tk_debugreg: + case tk_controlreg: + case tk_testreg: + case tk_reg: + case tk_seg: + case tk_beg: + case tk_reg64: + preerror("register name cannot be used as an identifier"); + nexttok(); + case tk_eof: break; + case tk_locallabel: internalerror("local label token found outside function block."); break; + case tk_extern: declareextern(); break; + case tk_union: dynamic_flag=0; dounion(TRUE,fstatic==0?0:f_static); break; + case tk_semicolon: nexttok(); break; + case tk_asm: + if(tok2==tk_openbrace)doasmblock(); + else doasm(); + break; + case tk_idasm: doasm(TRUE); break; + case tk_dollar: doasm(FALSE); break; + default: unuseableinput(); +/* while(itok.type==tp_stopper&&tok!=tk_eof)*/nexttok(); + break; + } + if(fstatic)fstatic--; + else if(dynamic_flag)dynamic_flag--; + } + (startfileinfo+currentfileinfo)->stlist=staticlist; + free(input); +} + +/* ------------------- output procedures start ------------------- */ +int CheckCodeSize() +// +{ + if(!am32){ + maxoutputerror(); + return FALSE; + } + outptrsize+=MAXDATA; + output=(unsigned char *)REALLOC(output,outptrsize); + if(splitdata==FALSE)outputdata=output; + return TRUE; +} + +int CheckDataSize() +// +{ + if(!am32){ + maxoutputerror(); + return FALSE; + } + outdatasize+=MAXDATA; + outputdata=(unsigned char *)REALLOC(outputdata,outdatasize); + return TRUE; +} + +void op(int byte) +{ + if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return; + output[outptr++]=(unsigned char)byte; + if(splitdata==FALSE)outptrdata=outptr; + retproc=FALSE; +} + +void opd(int byte) +{ + if(splitdata==FALSE){ + if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return; + output[outptr++]=(unsigned char)byte; + outptrdata=outptr; + } + else{ + if(outptrdata>=outdatasize&&CheckDataSize()==FALSE)return; + outputdata[outptrdata++]=(unsigned char)byte; + } +} + +void CorrectOfsBit(int bitofs) +{ + bitofs=(bitofs+7)/8; + if(splitdata)outptrdata+=bitofs; + else{ + outptr+=bitofs; + outptrdata=outptr; + } +} + +long GetBitMask(int ofs,int size) +{ + return (~((li[size]-1)<=outptrsize&&CheckCodeSize()==FALSE)return; + } + else{ + if((outptrdata+s+8)>=outdatasize&&CheckDataSize()==FALSE)return; + } + if(size!=32)num=num&(li[size]-1); + s=outptrdata+ofs/8; + ofs=ofs%8; + *(long *)&outputdata[s]&=GetBitMask(ofs,size); + *(long *)&outputdata[s]|=(num<32){ + *(long *)&outputdata[s+4]&=GetBitMask(0,ofs+size-32); + *(long *)&outputdata[s+4]|=(num>>(64-ofs-size)); +// printf("continue ofs=%Xh mask=%X value=%X\n",s+4,GetBitMask(0,ofs+size-32),num>>(64-ofs-size)); + } +} + +void outword(unsigned int num) +{ + op(num); + op(num/256); +} + +void outwordd(unsigned int num) +{ + opd(num); + opd(num/256); +} + +void outdword(unsigned long num) +{ + outword((unsigned int)(num&0xFFFFL)); + outword((unsigned int)(num/0x10000L)); +} + +void outdwordd(unsigned long num) +{ + outwordd((unsigned int)(num&0xFFFFL)); + outwordd((unsigned int)(num/0x10000L)); +} + +void outqword(unsigned long long num) +{ + outdword((unsigned long)(num&0xFFFFFFFFL)); + outdword((unsigned long)(num/0x100000000LL)); +} + +void outqwordd(unsigned long long num) +{ + outdwordd((unsigned long)(num&0xFFFFFFFFL)); + outdwordd((unsigned long)(num/0x100000000LL)); +} + +void doasmblock() +{ + nexttok(); + useasm=TRUE; + expecting(tk_openbrace); + for(;;){ + if(tok==tk_closebrace)break; + if(tok==tk_eof){ + unexpectedeof(); + break; + } + lastcommand=tok; + if(dbg)AddLine(); + doasm(TRUE); + } + useasm=FALSE; + nexttok(); +} + +void doblock() +{ + expecting(tk_openbrace); + doblock2(); +/* for(;;){ + if(tok==tk_closebrace)break; + if(tok==tk_eof){ + unexpectedeof(); + break; + } + docommand(); + } + RestoreStack();*/ +} + +void doblock2() +{ + for(;;){ + if(tok==tk_closebrace)break; + if(tok==tk_eof){ + unexpectedeof(); + break; + } + docommand(); + } + if(numblocks==1&&addstack&&sizestack&&localsize&&am32&&ESPloc&&IsSaveReg()==FALSE){ + localsize+=sizestack; + sizestack=0; + } + else RestoreStack(); +} + +void gotodo() +{ + nexttok(); + if(gotol(0))nexttok(); + seminext(); +} + +void GOTOdo() +{ + nexttok(); + if(GOTO())nexttok(); + seminext(); +} + +void docommand() /* do a single command */ +{ +unsigned int useflag; + useflag=0; + if(dbg)AddLine(); +//loops: + lastcommand=tok; +// printf("tok=%d %s\n",tok,itok.name); + switch(tok){ + case tk_ID: useflag++; + case tk_id: + if((useflag=doid((char)useflag,tk_void))!=tokens){ + nextseminext(); + if(useflag==tk_fpust)preerror("function returned parametr in FPU stack"); + } + else if(tok!=tk_closebrace)docommand(); + break; + case tk_apiproc: + case tk_undefproc: + case tk_declare: + if(doanyundefproc()!=tokens)nextseminext(); + else if(tok!=tk_closebrace)docommand(); + break; + case tk_proc: + doanyproc(); + nextseminext(); + break; + case tk_interruptproc: + outword(0x0E9C); //pushf //push cs + useflag=itok.post; + callloc(itok.number); + nexttok(); + expecting(tk_openbracket); + expecting(tk_closebracket); +#ifdef OPTVARCONST + FreeGlobalConst(); +#endif + seminext(); + clearregstat(useflag); + break; + case tk_bits: + dobits(); + break; + case tk_charvar: useflag=1; + case tk_bytevar: + dobytevar(useflag); + break; + case tk_intvar: useflag=1; + case tk_wordvar: + do_d_wordvar(useflag,r16); + break; + case tk_longvar: useflag=1; + case tk_dwordvar: + do_d_wordvar(useflag,r32); + break; + case tk_doublevar: + useflag=4; + case tk_floatvar: + dofloatvar(useflag,tk_floatvar,tk_semicolon); + break; + case tk_qwordvar: + doqwordvar(); + break; + case tk_fpust: + dofloatstack(itok.number); + break; + case tk_structvar: + dostruct(); + break; + case tk_pointer: + dopointer(); + break; + case tk_mult: + dovalpointer(); + break; + case tk_RETURN: + case tk_return: + RestoreStack(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + doreturn(tok); + CheckRealizable(); + break; + case tk_at: + nexttok(); + if(tok2==tk_colon){ + LLabel(); + if(tok!=tk_closebrace)docommand(); + } + else if(macros(tk_void)!=0)nextseminext(); + break; + case tk_if: RestoreStack(); doif(); break; + case tk_IF: RestoreStack(); dobigif(); break; + case tk_loopnz: + case tk_LOOPNZ: + case tk_loop: RestoreStack(); doloop(tok); break; + case tk_while: + case tk_WHILE: RestoreStack(); dowhilefast(tok); break; + case tk_do: RestoreStack(); dodo(); break; + case tk_for: + case tk_FOR: RestoreStack(); dofor(tok); break; + case tk_reg32: doreg_32((unsigned int)itok.number,r32); break; + case tk_reg: doreg_32((unsigned int)itok.number,r16); break; + case tk_beg: dobeg((unsigned int)itok.number); break; + case tk_reg64: doreg64(itok.number); break; + case tk_seg: doseg((unsigned int)itok.number); break; + case tk_openbrace: + startblock(); + doblock(); + nexttok(); + endblock(); + break; + case tk_from: nexttok(); dofrom(); nextseminext(); break; + case tk_extract: nexttok(); doextract(); seminext(); break; + case tk_minus: useflag=8; + case tk_not: + notnegit(useflag); + nextseminext(); + break; + case tk_locallabel: RestoreStack(); define_locallabel(); break; + case tk_camma: + case tk_semicolon: nexttok(); break; + case tk_else: + preerror("else without preceeding if or IF"); + nexttok(); + break; + case tk_ELSE: + preerror("ELSE without preceeding IF or if"); + nexttok(); + break; + case tk_eof: unexpectedeof(); break; + case tk_void: + case tk_long: + case tk_dword: + case tk_word: + case tk_byte: + case tk_int: + case tk_char: + preerror("cannot declare variables within function { } block"); + nexttok(); + break; + case tk_GOTO: + RestoreStack(); + GOTOdo(); + CheckRealizable(); + break; + case tk_goto: + RestoreStack(); + gotodo(); + CheckRealizable(); + break; + case tk_BREAK: + RestoreStack(); + doBREAK(BREAK_SHORT); + CheckRealizable(); + break; + case tk_break: + RestoreStack(); + doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32)); + CheckRealizable(); + break; + case tk_CONTINUE: + RestoreStack(); + doCONTINUE(CONTINUE_SHORT); + CheckRealizable(); + break; + case tk_continue: + RestoreStack(); + doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32)); + CheckRealizable(); + break; + case tk_asm: + if(tok2==tk_openbrace)doasmblock(); + else doasm(); + break; + case tk_idasm: + useflag=TRUE; + case tk_dollar: + doasm(useflag); + break; + case tk_SWITCH: + case tk_switch: RestoreStack(); doswitch(); break; + case tk_delete: dodelete(); break; + case tk_new: donew(); seminext(); break; + case tk_question: +// calcnumber=FALSE; + while(tok==tk_question)directive(); + break; +/* case tk_openbracket: + nexttok(); + nexttok(); + expectingoperand(tk_closebracket); + goto loops;*/ + default: unuseableinput(); break; + } + notunreach=FALSE; +} + +void doBREAK(unsigned char typeb) +{ + if(curbr==0)preerror("'BREAK' or 'break' use only in loop, do-while.."); + else MakeBreak(typeb); + nextseminext(); +} + +void doCONTINUE(unsigned char typeb) +{ + if(curco==0)preerror("'CONTINUE' or 'continue' use only in loop, do-while.."); + else MakeContinue(typeb); + nextseminext(); +} + +void MakeBreak(unsigned char typeb) +{ +unsigned int nbr=0; + if(tok2==tk_number){ + nexttok(); + nbr=itok.number; + if(nbr>=curbr)preerror("'BREAK' or 'break' on incorrect number skip cycle"); + } + numberbreak=nbr; + nbr=curbr-1-nbr; + if(usebr[nbr]==0){ + GetNameLabel(tk_break,nbr); + addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE); + usebr[nbr]=secondcallnum; + secondcallnum++; + } + addacall(usebr[nbr],typeb); + if(typeb==BREAK_SHORT)outword(0x00EB); // JMP SHORT + else jumploc0(); +} + +void MakeContinue(unsigned char typeb) +{ +unsigned int nbr=0; + if(tok2==tk_number){ + nexttok(); + nbr=itok.number; + if(nbr>=curco)preerror("'CONTINUE' or 'continue' on incorrect number skip cycle"); + } + nbr=curco-1-nbr; + if(useco[nbr]==0){ + GetNameLabel(tk_continue,nbr); +// printf("%s nbr=%d\n",(char *)string2,nbr); + addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE); + useco[nbr]=secondcallnum; + secondcallnum++; + } + addacall(useco[nbr],typeb); + if(typeb==CONTINUE_SHORT)outword(0x00EB); // JMP SHORT + else jumploc0(); +} + +int CheckExitProc() +{ + if(strcmp(itok.name,"EXIT")==0||strcmp(itok.name,"ABORT")==0)return TRUE; + return FALSE; +} + +void LLabel() +{ +localrec *ptr; +#ifdef OPTVARCONST + ClearLVIC(); +#endif + RestoreStack(); + clearregstat(); + switch(tok){ + case tk_id: + case tk_ID: + FindOff((unsigned char *)itok.name,CS); + ptr=addlocalvar(itok.name,tk_number,outptr,TRUE); + if(FixUp)ptr->rec.flag=f_reloc; + break; + case tk_undefproc: + ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);// + if(FixUp)ptr->rec.flag=f_reloc; + updatecall((unsigned int)itok.number,outptr,procedure_start);// + break; + default: + preerror("error declaretion local label"); + break; + } + nexttok(); + nexttok(); +} + +void AddApiToPost(unsigned int num) +{ + CheckPosts(); + (postbuf+posts)->type=CALL_32I; + (postbuf+posts)->loc=outptr; + (postbuf+posts)->num=num; + posts++; + outdword(0); +} + +/* ---------------------- Procedure Calling Starts -------------------- */ + +int doanyundefproc(int jumpsend) +{ +unsigned int cnum,snum; +int returnvalue; +int regs; +char fname[IDLENGTH]; + if(tok2==tk_colon){ // if a label +#ifdef OPTVARCONST + ClearLVIC(); +#endif + RestoreStack(); + clearregstat(); + if(CidOrID()==tk_ID){//local label that has been used, but not placed + localrec *ptr=addlocalvar(itok.name,tk_number,outptr,TRUE); + if(FixUp)ptr->rec.flag=f_reloc; + updatecall((unsigned int)itok.number,outptr,procedure_start);// + } + else{ // + tok=tk_proc; + itok.number=outptr; + string[0]=0; + updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0); + } + nexttok(); // move past id + nexttok(); // move past : + return(tokens); + } + if(tok2==tk_openbracket){ + strcpy(fname,itok.name); + if(tok==tk_declare){ // + tok=tk_undefproc; + updatetree(); + if(itok.flag&f_classproc)AddUndefClassProc(); + } + cnum=(unsigned int)itok.number; + regs=itok.post; + returnvalue=itok.rm; + unsigned int tproc=itok.flag; + unsigned char apiproc=FALSE; + unsigned int oaddESP=addESP; + int sizestack=-1; + if(tok==tk_apiproc){ + apiproc=TRUE; + sizestack=itok.size; // + } +#ifdef OPTVARCONST + if(tproc&f_useidx)ClearLVIC(); + else FreeGlobalConst(); +#endif + int exitproc=CheckExitProc(); + snum=initparamproc(); + if(sizestack!=-1){ + if(snum>(unsigned int)sizestack)extraparam(fname); + else if(snum<(unsigned int)sizestack)missingpar(fname); + } + if((tproc&f_typeproc)!=tp_cdecl){ + snum=0; + addESP=oaddESP; + } + if(FastCallApi==TRUE&&apiproc!=FALSE){ + if(jumpsend)outword(0x25ff); + else outword(0x15FF); + AddApiToPost(cnum); + } + else{ + addacall(cnum,(unsigned char)((tproc&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR))); + if(jumpsend)jumploc0(); + else callloc0(); /* produce CALL [#] */ + } + clearregstat(regs); + if(snum!=0&&jumpsend==FALSE)CorrectStack(snum); + retproc=exitproc; + return(returnvalue); + } + thisundefined(itok.name); + nexttok(); + return(tk_long); +} + +void CorrectStack(unsigned int num) +{ + if(addstack){ + sizestack+=num; +// printf("%s(%d)> Add %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,num); + } + else{ + if(short_ok(num)){ + outword(0xC483); + op(num); + } + else{ + outword(0xC481); + if(am32==FALSE)outword(num); + else outdword(num); + } + addESP-=num; + } +} + +unsigned int initparamproc() +{ +unsigned int typep=itok.flag,snum=0; +ITOK ostructadr=structadr; + strcpy(param,(char *)string); + nexttok(); + switch(typep&f_typeproc){ + case tp_cdecl: + case tp_stdcall: + snum=swapparam(); + break; + case tp_pascal: + doparams(); + break; + case tp_fastcall: + doregparams(); + break; + } +// if(crec)printf("after doparams num=%08X\n",crec->recnumber); + if((typep&f_classproc)&&(!(typep&f_static))){ + if((current_proc_type&f_static)&&structadr.sib==THIS_PARAM )return snum; + structadr=ostructadr; + if(structadr.sib==THIS_PARAM){ + if(structadr.number==0){ + op(0xff); + if(ESPloc&&am32){ + int num; + num=localsize+addESP+4; + if(short_ok(num,TRUE)){ + outword(0x2474); + op(num); + } + else{ + outword(0x24B4); + outdword(num); + } + } + else outword(am32==FALSE?0x0476:0x0875);//push[ebp+4] + } + else{ + int reg=GetRegister(1); + op(0x8B); + if(ESPloc&&am32){ + int num; + num=localsize+addESP+4; + if(short_ok(num,TRUE)){ + op(4+reg*8+64); + op(0x24); + op(num); + } + else{ + op(4+reg*8+128); + op(0x24); + outdword(num); + } + } + else{ + op((am32==FALSE?6:5)+reg*8+64); + op((am32==FALSE?4:8));//mov ESI,[ebp+4] + } + RegAddNum(reg); + op(0x50+reg); //push reg + warningreg(regs[am32][reg]); + } + } + else if(structadr.sib==THIS_REG){ + if(structadr.number/*size*/!=0){ + int reg=GetRegister(1); + if(reg==structadr.rm)RegAddNum(reg); + else{ + if(am32==FALSE){ + switch(structadr.rm){ + case BX: + structadr.rm=7; + break; + case DI: + structadr.rm=5; + break; + case SI: + structadr.rm=4; + break; + case BP: + structadr.rm=6; + break; + default: + regBXDISIBPexpected(); + } + structadr.sib=CODE16; + } + else structadr.sib=CODE32; + structadr.rm|=(structadr.number<128?rm_mod01:rm_mod10); + op(0x8d); //lea reg [reg2+num] + op(structadr.rm+reg*8); + outaddress(&structadr); + } + op(0x50+reg); + warningreg(regs[am32][reg]); + } + else op(0x50+structadr.rm); + } + else if(structadr.sib==THIS_NEW){ + RunNew(structadr.number); + op(0x50); + } + else if(structadr.sib==THIS_ZEROSIZE){ + outword(0x6a); //push 0 + } + else{ +// printf("post=%d\n",structadr.post); + if(structadr.post==LOCAL){ + int reg=GetRegister(1); + structadr.post=0; + outseg(&structadr,2); + op(0x8d); + op(structadr.rm+reg*8); + outaddress(&structadr); + op(0x50+reg); + warningreg(regs[am32][reg]); + } + else{ + if(strinf.bufstr){ + int reg=GetRegister(1); + int newreg; + if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,reg))!=NOINREG){ + if(newreg!=SKIPREG){ + if(am32==FALSE&&newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt; + waralreadinitreg(regs[am32][reg],regs[am32][newreg]); + reg=newreg; + } + free(strinf.bufstr); + goto cont1; + } +noopt: + if(newreg=CheckMassiv(strinf.bufstr,strinf.size,reg)!=-1)reg=newreg; +cont1: + strinf.bufstr=NULL; + RegAddNum(reg); + op(0x50+reg); + } + else{ + op(0x68); + if(structadr.post/*&&structadr.post!=USED_DIN_VAR*/)setwordpost(&structadr); + else if(FixUp)AddReloc(); + if(am32==FALSE)outword((unsigned int)structadr.number); + else outdword(structadr.number); + } + } + } + snum+=(am32==FALSE?2:4); + addESP+=(am32==FALSE?2:4); + } + if(typep&f_far)op(0x0e); //push cs + return snum; +} + +int doanyproc(int jumpsend) +{ +unsigned int cloc,snum; +int returnvalue,dynamicindex; +int regs; + if(tok2==tk_colon){ + preerror("dublication global label"); + nexttok(); + return 0; + } + cloc=(unsigned int)itok.number; /* get address or handle */ + returnvalue=itok.rm; + regs=itok.post; +// printf("regs=%08X name=%s\n",regs,itok.name); + int flag=itok.flag; + if(itok.npointr)dopointerproc(); + else{ + if((itok.flag&f_inline)!=0&&(useinline==TRUE||(useinline==2&&optimizespeed))){ + if(macros(tk_void)!=0)return(returnvalue); + } + dynamicindex=itok.segm; + +// printf("%s %08X seg=%d\n",rec->recid/*itok.name*/,itok.flag,itok.segm); + if(itok.segm==DYNAMIC){ + itok.segm=DYNAMIC_USED; + updatetree(); + } + unsigned int oaddESP=addESP; + snum=initparamproc(); + if((flag&f_typeproc)!=tp_cdecl){ + snum=0; + addESP=oaddESP; + } + if(dynamicindexrec.flag=f_reloc; + } + else{ + tok=tk_proc; + itok.rm=tk_void; + itok.number=outptr; + itok.segm=NOT_DYNAMIC; + itok.flag=0; + string[0]=0; + itok.type=tp_ucnovn; + addtotree(itok.name); + itok.rec->count=cnum; + } + nexttok(); // move past id + nexttok(); // move past : + return(tokens); + } + if(tok2==tk_openbracket){ + if((cnum=CheckMacros())!=tokens)return cnum; + tobedefined(am32==FALSE?CALL_NEAR:CALL_32,expectedreturn); + cnum=posts-1; + param[0]=0; + int flag=itok.flag; + int exitproc=CheckExitProc(); + unsigned int oaddESP=addESP; + if(itok.flag==tp_stdcall){ + nexttok(); + swapparam(); + } + else{ + nexttok(); + if(uppercase)doregparams(); + else doparams(); + } + (postbuf+cnum)->loc=outptr+1; + callloc0(); /* produce CALL [#] */ + clearregstat(); + addESP=oaddESP; +#ifdef OPTVARCONST + if(flag&f_useidx)ClearLVIC(); + else FreeGlobalConst(); +#endif + retproc=exitproc; + return(expectedreturn); + } + thisundefined(itok.name); + return(tk_long); +} + +int typesize(int vartype) // +{ + switch(vartype){ + case tk_char: + case tk_byte: return(1); + case tk_int: + case tk_word: return(2); + case tk_float: + case tk_dword: + case tk_long: return(4); + case tk_double: + case tk_qword: return 8; + } + return(0); +} + +void FpuSt2Number() +{ + op66(r32); //push EAX + op(0x50); + CheckInitBP(); + fistp_stack(); + RestoreBP(); + fwait3(); + op66(r32); + op(0x58); //pop EAX + if(cpu<3)cpu=3; +} + +void FpuSt2QNumber() +{ + op66(r32); //push EAX + op(0x50); + op66(r32); //push EAX + op(0x50); + CheckInitBP(); + fistp_stack(4); + RestoreBP(); + fwait3(); + op66(r32); + op(0x58+EDX); //pop EAX + op66(r32); + op(0x58); //pop EAX + if(cpu<3)cpu=3; +} + +void fwait3_4() +{ + if(chip<4)op(0x9B); +} + +void convert_returnvalue(int expectedreturn,int actualreturn) +{ + if(expectedreturn==tk_void)return; //17.09.05 17:52 + if(actualreturn==tk_void/*||expectedreturn==tk_void*/){ + retvoid(); + return; + } + switch(expectedreturn){ + case tk_byte: + case tk_char: + case tk_word: + case tk_int: + if(actualreturn==tk_float||actualreturn==tk_double){ + op66(r32); + op(0x50); + FloatToNumer(actualreturn==tk_float?0:4); + } + else if(actualreturn==tk_fpust)FpuSt2Number(); + else if(expectedreturn==tk_word||expectedreturn==tk_int){ + if(actualreturn==tk_char)cbw(); + else if(actualreturn==tk_byte)xorAHAH(); + } + break; + case tk_long: + case tk_dword: + switch(actualreturn){ + case tk_char: + op66(r32); + op(0x0F); outword(0xC0BE); //MOVSX EAX,AL + break; + case tk_byte: /* MOVZX EAX,AL */ + op66(r32); + op(0x0F); outword(0xC0B6); + break; + case tk_word: /* MOVZX EAX,AX */ + op66(r32); + op(0x0F); outword(0xC0B7); + break; + case tk_int: /* MOVSX EAX,AX */ + op66(r32); + op(0x0F); outword(0xC0BF); + break; + case tk_double: + case tk_fpust: + FpuSt2Number(); + break; +// case tk_double: + case tk_float: + op66(r32); + op(0x50); + FloatToNumer(/*actualreturn==tk_float?0:4*/); + break; + } + if(cpu<3)cpu=3; + break; + case tk_qword: + switch(actualreturn){ + case tk_char: + op66(r32); + op(0x0F); outword(0xC0BE); //MOVSX EAX,AL + cwdq(r32); + break; + case tk_byte: /* MOVZX EAX,AL */ + op66(r32); + op(0x0F); outword(0xC0B6); + ZeroReg(EDX,r32); + break; + case tk_word: /* MOVZX EAX,AX */ + op66(r32); + op(0x0F); outword(0xC0B7); + case tk_dword: + ZeroReg(EDX,r32); + break; + case tk_int: /* MOVSX EAX,AX */ + op66(r32); + op(0x0F); outword(0xC0BF); + case tk_long: + cwdq(r32); + break; + case tk_fpust: + case tk_double: + FpuSt2QNumber(); + break; + case tk_float: + op66(r32); + op(0x50); + FloatToNumer(actualreturn==tk_float?0:4); + cwdq(r32); + break; + } + if(cpu<3)cpu=3; + break; + case tk_fpust: + if(tok2==tk_semicolon)break; + switch(actualreturn){ + case tk_char: + CheckInitBP(); + cbw(); + op66(r32); + outword(0xDF50); //push EAX + goto endfxld; //fild ss[bp-4]/[esp] + case tk_byte: + CheckInitBP(); + xorAHAH(); + op66(r32); + outword(0xDF50); //push EAX + goto endfxld; //fild ss[bp-4]/[esp] + case tk_word: + CheckInitBP(); + op66(r16); + outword(0x6A); //push 0 + op66(r16); + outword(0xDB50); //push AX + goto endfxld; //fild ss[bp-4]/[esp] + case tk_int: + CheckInitBP(); + op66(r32); + outword(0xDF50); //push eax + goto endfxld; //fild ss[bp-4]/[esp] + case tk_dword: + CheckInitBP(); + op66(r32); //push 0L + outword(0x6A); + op66(r32); + op(0x50); //push EAX + fildq_stack(); + RestoreBP(); + op66(r32); + op(0x58); //pop eax + op66(r32); + op(0x58); //pop eax + break; + case tk_long: + CheckInitBP(); + op66(r32); + outword(0xDB50); //push EAX + goto endfxld; //fild ss[bp-4]/[esp] + case tk_float: + CheckInitBP(); + op66(r32); + outword(0xd950); //push EAX +endfxld: + fld_stack(4+localsize); + RestoreBP(); + op66(r32); + op(0x58); //pop eax + break; + case tk_qword: +// case tk_double: + CheckInitBP(); + op66(r32); + op(0x50+EDX); //push EDX + op66(r32); + op(0x50); //push EAX +/* if(actualreturn==tk_double){ + op(0xDD); + fld_stack(8+localsize); + } + else*/ fildq_stack(); + RestoreBP(); + op66(r32); + op(0x58); //pop eax + op66(r32); + op(0x58); //pop eax + break; + } + if(cpu<3)cpu=3; + break; + default: +// printf("expectedreturn=%d %s %d\n",expectedreturn,(startfileinfo+currentfileinfo)->filename,linenumber); + break; + } +} + +int procdo(int expectedreturn) +{ +int actualreturn; +char idflag=0; + switch(tok){ + case tk_ID: idflag++; + case tk_id: + actualreturn=doid(idflag,expectedreturn); + break; + case tk_proc: + actualreturn=doanyproc(); + break; + case tk_apiproc: + case tk_undefproc: + case tk_declare: +// if((actualreturn=doanyundefproc())==tk_void)actualreturn=expectedreturn; + actualreturn=doanyundefproc(); //17.09.05 17:56 + break; + default: internalerror("Bad tok in procdo();"); break; + } + convert_returnvalue(expectedreturn,actualreturn); + return actualreturn; +} + +/* +++++++++++++++++++++++ loops and ifs start ++++++++++++++++++++++++ */ + +void endcmpfloat() +{ + fwait3(); + outword(0xE0DF);//fstsw ax + op(0x9E); + RestoreBP(); +} + +int outcmp(int swapped,int ctok,ITOK *cstok,char *&cbuf,SINFO *cstr,int ctok2,ITOK *cstok2,char *&cbuf2,SINFO *cstr2,int typet) +{ +unsigned char err=0; +int typef=0; +int vop=0; +long long lnumber; +unsigned int ofs; +int i,reg,reg1; + if(typetnumber/256; + switch(ctok2){ + case tk_reg64: + reg1=cstok2->number/256; + for(i=0;i<2;i++){ + op66(r32); + op(0x39); //cmp reg,reg + op(0xC0+reg+reg1*8); + if(i==1)break; + outword(0x75); + ofs=outptr; + reg=cstok->number&255; + reg1=cstok2->number&255; + } + output[ofs-1]=outptr-ofs; + break; + case tk_number: + case tk_postnumber: + case tk_undefofs: + lnumber=cstok2->lnumber>>32; + for(i=0;i<2;i++){ + op66(r32); + // + if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&& + short_ok(lnumber,TRUE)){ + if(!lnumber){ + op(0x85); //test reg,reg + op(0xc0+reg*9); + } + else{ + op(0x83); //cmp reg, + op(0xF8+reg); + op(lnumber); + } + } + else{ + if(reg==AX)op(0x3D); + else{ + op(0x81); + op(0xF8+reg); + } + if(i==1){ + if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name); + } + outdword(cstok2->number); + } + if(i==1)break; + outword(0x75); + ofs=outptr; + reg=cstok->number&255; + } + output[ofs-1]=outptr-ofs; + break; + default: + if(swapped)err=1; + else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet)); + break; + } + break; + case tk_reg32: + case tk_reg: + switch(ctok2){ + case tk_reg: + case tk_reg32: + if(ctok!=ctok2)err=1; + else{ + op66(typet); + op(0x39); //cmp reg,reg + op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8); + } + break; + case tk_number: + if(cstok2->number==0&&(cstok2->flag&f_reloc)==0){ + op66(typet); + op(0x85); //test reg,reg + op(0xc0+(unsigned int)cstok->number*9); + break; + } + case tk_postnumber: + case tk_undefofs: + op66(typet); + // + if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&& + short_ok(cstok2->number,ctok==tk_reg?FALSE:TRUE)){ + op(0x83); //cmp reg, + op(0xF8+(unsigned int)cstok->number); + op(cstok2->number); + break; + } + if(cstok->number==AX)op(0x3D); + else{ + op(0x81); + op(0xF8+(unsigned int)cstok->number); + } + if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name); + if(ctok==tk_reg)outword((unsigned int)cstok2->number); + else outdword(cstok2->number); + break; + default: + if(swapped)err=1; + else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet)); + break; + } + break; + case tk_qwordvar: + cstok->number+=4; + compressoffset(cstok); + switch(ctok2){ + case tk_postnumber: + case tk_number: + case tk_undefofs: + lnumber=cstok2->lnumber>>32; + CheckAllMassiv(cbuf,8,cstr,cstok); + for(i=0;i<2;i++){ + op66(r32); + outseg(cstok,2); + // + if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&& + short_ok(lnumber,1)){ + op(0x83); + op(0x38+cstok->rm); + outaddress(cstok); + op(lnumber); + } + else{ + op(0x81); + op(0x38+cstok->rm); + outaddress(cstok); + if(i==1){ + if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name); + } + outdword(lnumber); + } + if(i==1)break; + outword(0x75); + ofs=outptr; + cstok->number-=4; + compressoffset(cstok); + lnumber=cstok2->lnumber; + } + output[ofs-1]=outptr-ofs; + break; + case tk_reg64: + CheckAllMassiv(cbuf,8,cstr,cstok); + reg=cstok2->number/256; + for(i=0;i<2;i++){ + op66(r32); + outseg(cstok,2); + op(0x39); /* CMP [word],AX */ + op(cstok->rm+reg*8); + outaddress(cstok); + if(i==1)break; + reg=cstok2->number&255; + outword(0x75); + ofs=outptr; + cstok->number-=4; + compressoffset(cstok); + } + output[ofs-1]=outptr-ofs; + break; + default: + i=EAX|(EDX*256); + getintoreg64(i); + doregmath64(i); + CheckAllMassiv(cbuf,8,cstr,cstok); + reg=EDX; + for(i=0;i<2;i++){ + op66(r32); + outseg(cstok,2); + op(0x39); /* CMP [word],AX */ + op(cstok->rm+reg*8); + outaddress(cstok); + if(i==1)break; + reg=EAX; + outword(0x75); + ofs=outptr; + cstok->number-=4; + compressoffset(cstok); + } + output[ofs-1]=outptr-ofs; + break; + } + break; + case tk_intvar: + case tk_wordvar: + if(swapped&&typet==r32)typet=r16; + case tk_longvar: + case tk_dwordvar: + switch(ctok2){ + case tk_reg32: + case tk_reg: + CheckAllMassiv(cbuf,typet,cstr,cstok); + op66(typet); + outseg(cstok,2); + op(0x39); + op((unsigned int)cstok2->number*8+cstok->rm); + outaddress(cstok); + break; + case tk_postnumber: + case tk_number: + case tk_undefofs: + CheckAllMassiv(cbuf,typet,cstr,cstok); + op66(typet); + outseg(cstok,2); + // + if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&& + short_ok(cstok2->number,typet/2-1)){ + op(0x83); + op(0x38+cstok->rm); + outaddress(cstok); + op(cstok2->number); + break; + } + op(0x81); + op(0x38+cstok->rm); + outaddress(cstok); + if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name); + if(typet==r16)outword((unsigned int)cstok2->number); + else outdword(cstok2->number); + break; + case tk_charvar: + case tk_intvar: + getinto_e_ax(1,ctok2,cstok2,cbuf2,cstr2,typet); + CheckAllMassiv(cbuf,typet,cstr,cstok); + op66(typet); + outseg(cstok,2); + op(0x39); /* CMP [word],AX */ + op(cstok->rm); + outaddress(cstok); + break; + default: + getinto_e_ax(0,ctok2,cstok2,cbuf2,cstr2,typet); +// ClearReg(AX); + CheckAllMassiv(cbuf,typet,cstr,cstok); + op66(typet); + outseg(cstok,2); + op(0x39); /* CMP [word],AX */ + op(cstok->rm); + outaddress(cstok); + break; + } + break; + case tk_number: + if(ctok2==tk_postnumber){ + op(0xB8); /* MOV AX,# */ + if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm); + if(am32==FALSE)outword((unsigned int)cstok->number); + else outdword(cstok->number); + op(0x3D); /* CMP AX,# */ + (cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + if(am32==FALSE)outword((unsigned int)cstok2->number); + else outdword(cstok2->number); + } + if(ctok2==tk_number){ + if(cstok2->rm!=tk_float&&cstok->rm!=tk_float){ + if((unsigned long)cstok2->number<256&&(unsigned long)cstok->number<256){ + op(0xB0); //mov al,number + op(cstok->number); + op(0x3C); //cmp Al,number + op(cstok2->number); + } + else if((unsigned long)cstok2->number<65536&& cstok->number<65536){ + op66(r16); + op(0xB8); /* MOV AX,# */ + if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm); + outword((unsigned int)cstok->number); + op66(r16); + op(0x3D); /* CMP AX,# */ + if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + outword((unsigned int)cstok2->number); + } + else{ + op66(r32); + op(0xB8); /* MOV AX,# */ + if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm); + outdword(cstok->number); + op66(r32); + op(0x3D); /* CMP AX,# */ + if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + outdword(cstok2->number); + } + } + else{ + op(0x55); //push bp + outword(0xe589);//mov bp,sp + op66(r32); + if(short_ok(cstok->number,TRUE)){ //push num + op(0x6A); + op(cstok->number); + } + else{ + op(0x68); + outdword(cstok->number); + } + op66(r32); + if(short_ok(cstok2->number,TRUE)){ //push num + op(0x6A); + op(cstok2->number); + } + else{ + op(0x68); + outdword(cstok2->number); + } + outword(am32==FALSE?0x46d9:0x45d9); + op(0xfC);//fld ssdword[bp-4] + op(0xD8); + outword(0xF85e - am32); //fcomp [bp-8] + endcmpfloat(); + } + } + else{ + if(swapped)err=1; + else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet)); + } + break; + case tk_postnumber: + if(ctok2==tk_number||ctok2==tk_postnumber){ + op(0xB8); /* MOV AX,# */ + (cstok->flag&f_extern)==0?setwordpost(cstok):setwordext(&cstok->number); + if(am32==FALSE)outword((unsigned int)cstok->number); + else outdword(cstok->number); + op(0x3D); /* CMP AX,# */ + if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number); + else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm); + if(am32==FALSE)outword((unsigned int)cstok2->number); + else outdword(cstok2->number); + } + else{ + if(swapped)err=1; + else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet)); + } + break; + case tk_charvar: + case tk_bytevar: + switch(ctok2){ + case tk_number: + CheckAllMassiv(cbuf,1,cstr,cstok); + outseg(cstok,2); + op(0x80); /* CMP [byte],# */ + op(0x38+cstok->rm); + outaddress(cstok); + op((unsigned int)cstok2->number); + break; + case tk_reg: + case tk_reg32: + if(cstok2->number>3)goto defchar; + case tk_beg: + CheckAllMassiv(cbuf,1,cstr,cstok); + outseg(cstok,2); + op(0x38); /* CMP [byte],beg */ + op((unsigned int)cstok2->number*8+cstok->rm); + outaddress(cstok); + break; + default: +defchar: + getintoal(ctok2,cstok2,cbuf2,cstr2); + CheckAllMassiv(cbuf,1,cstr,cstok); + outseg(cstok,2); + op(0x38); /* CMP [byte],AL */ + op(cstok->rm); + outaddress(cstok); + break; + } + break; + case tk_beg: + switch(ctok2){ + case tk_number: + if(cstok2->number==0){ + op(0x84); //test beg,beg + op(0xc0+(unsigned int)cstok->number*9); + break; + } + if((unsigned int)cstok->number==AL)op(0x3C); + else{ + op(0x80); + op(0xF8+(unsigned int)cstok->number); + } + op((unsigned int)cstok2->number); + break; + case tk_beg: + op(0x38); + op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8); + break; + case tk_reg: + if((unsigned int)cstok2->number<=BX){ /* CMP beg,beg */ + op(0x38); + op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8); + } + else{ + op66(r16); + op(0x89); /* MOV AX,reg */ + op(0xC0+(unsigned int)cstok2->number*8); + op(0x38); /* CMP beg,AL */ + op(0xC0+(unsigned int)cstok->number); + } + break; + default: + if(swapped)err=1; + else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet)); + break; + } + break; + case tk_doublevar: + vop=4; + goto cont_float; + case tk_fpust: + typef++; + if(cstok->type==tp_modif)typef++; + else{ + if(cstok->number!=0){ + op(0xd9); //fld st(x) + op(0xC0+cstok->number); + typef++; + } + } + case tk_floatvar: +cont_float: + switch(ctok2){ + case tk_beg: + CheckInitBP(); + switch(cstok2->rm){ + case tk_char: + case tk_int: + case tk_long: + outword(0xBE0F); /* MOVSX AX,beg */ + op(0xC0+(unsigned int)cstok2->number); + break; + default: + if((optimizespeed&&chip>3&&chip<7)||cstok2->number==AL){ + xorAHAH(); + if(cstok2->number!=AL){ + op(0x88); + op(0xC0+cstok2->number*8); //mov al,beg + } + } + else{ + outword(0xB60F); // MOVZX AX,beg + op(0xC0+(unsigned int)cstok2->number); + } + break; + } + outword(0xDF50); //push AX + fld_stack(2+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op(0x58); // pop EAX + endcmpfloat(); + swapped=1; + break; + case tk_reg: + CheckInitBP(); + op66(r32); + switch(cstok2->rm){ + case tk_char: + case tk_int: + case tk_long: + outword(0xBF0F); /* MOVSX EAX,reg */ + break; + default: + if(optimizespeed&&chip>3&&chip<7&&cstok2->number!=AX){ + outword(0xC031); // xor EAX,EAX + op66(r16); + op(0x8B); + } + else outword(0xB70F); // MOVZX EAX,reg + break; + } + op(0xC0+(unsigned int)cstok2->number); + op66(r32); + outword(0xDB50); //push EAX + fld_stack(4+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op66(r32); + op(0x58); // pop EAX + endcmpfloat(); + swapped=1; + break; + case tk_reg32: + CheckInitBP(); + if(cstok2->rm==tk_float){ + op66(r32); + op(0x50+(unsigned int)cstok2->number); //push reg32 + op(0xd9); + fld_stack(4+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op66(r32); + op(0x58); // pop EAX + } + else{ + if(cstok2->rm!=tk_char&&cstok2->rm!=tk_int&&cstok2->rm!=tk_long){ + typet=tk_word; + op66(r32); + outword(0x6a); //$push 0 + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + } + op66(r32); + op(0x50+cstok2->number); //push reg32 + if(typet!=r16)fildq_stack(); + else{ + op(0xdb); + fld_stack(4+localsize); + } + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + if(typet!=r16){ + if(optimizespeed||am32==FALSE){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + } + else{ + op66(r32); + op(0x58); // pop EAX + } + } + endcmpfloat(); + swapped=1; + break; + case tk_charvar: + CheckAllMassiv(cbuf2,1,cstr2,cstok2); + outseg(cstok2,3); /* MOVSX AX,[charvar] */ + outword(0xBE0F); op(cstok2->rm); + outaddress(cstok2); + CheckInitBP(); + outword(0xdf50); //push ax + fld_stack(2+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op(0x58); // pop EAX + endcmpfloat(); + swapped=1; + break; + case tk_intvar: + CheckAllMassiv(cbuf2,2,cstr2,cstok2); + outseg(cstok2,2); + if(typef){ + op(0xDE); //ficomp var2 + op(cstok2->rm+0x08+typef*8); + outaddress(cstok2); + } + else{ + op(0xdf); //fild var + op(cstok2->rm); + outaddress(cstok2); + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + swapped=1; + } + fwait3_4(); + outword(0xE0DF);//fstsw ax + op(0x9E); + break; + case tk_bytevar: + CheckAllMassiv(cbuf2,1,cstr2,cstok2); + if(optimizespeed&&chip>3&&chip<7){ + outword(0xC031); + outseg(cstok2,2); + op(0x8A); + } + else{ + outseg(cstok2,3); + outword(0xB60F); + } + op(cstok2->rm); // MOVZX regL,[byte] + outaddress(cstok2); + CheckInitBP(); + outword(0xDF50); //push ax + fld_stack(2+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op(0x58); // pop EAX + endcmpfloat(); + swapped=1; + break; + case tk_wordvar: + CheckInitBP(); + op66(r16); + outword(0x6a); //push 0 + CheckAllMassiv(cbuf2,2,cstr2,cstok2); + op66(r16); + outseg(cstok2,2); //push var + op(0xFF); + op(cstok2->rm+0x30); + outaddress(cstok2); + op(0xDB); + fld_stack(4+localsize); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + op66(r32); + op(0x58); // pop EAX + endcmpfloat(); + swapped=1; + break; + case tk_dwordvar: + CheckInitBP(); + op66(r32); //push 0L + outword(0x6a); + CheckAllMassiv(cbuf2,4,cstr2,cstok2); + op66(r32); //push var + outseg(cstok2,2); + op(0xFF); + op(cstok2->rm+0x30); + outaddress(cstok2); + fildq_stack(); + if(typef==2)outword(0xD9DE); //FCOMPP + else if(typef==1)outword(0xD9D8); //FCOMP + else{ + if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=8; + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + if(optimizespeed||am32==FALSE){ + outword(0xC483); + op(8); + } + else{ + op(0x58); // pop EAX + op(0x58); // pop EAX + } + endcmpfloat(); + swapped=1; + break; + case tk_longvar: + CheckAllMassiv(cbuf2,4,cstr2,cstok2); + outseg(cstok2,2); + if(typef){ + op(0xDA); //ficomp var2 + op(cstok2->rm+0x08+typef*8); + outaddress(cstok2); + } + else{ + op(0xdb); //fild var + op(cstok2->rm); + outaddress(cstok2); + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + swapped=1; + } + endcmpfloat(); + break; + case tk_number: + if(!typef){ + CheckAllMassiv(cbuf,4,cstr,cstok); + outseg(cstok,2); //fld val + op(0xd9); + op(cstok->rm); + outaddress(cstok); + } + if(cstok2->rm!=tk_double&&cstok2->rm!=tk_float){ + cstok2->dnumber=cstok2->lnumber; + cstok2->rm=tk_double; + } + else if(vop==4&&cstok2->rm==tk_float){ + cstok2->dnumber=cstok2->fnumber; + cstok2->rm=tk_double; + } + if(am32&&(cstok2->rm==tk_float&&cstok2->fnumber==0.0)|| + (cstok2->rm==tk_double&&cstok2->dnumber==0.0)||cstok2->lnumber==0){ + outword(0xe4d9); //ftst + if(typef!=1)outword(0xC0DD); //ffree + } + else{ + op66(r32); + int rm; + rm=(am32==FALSE?0x1eD8:0x1DD8); + if(typef==1)rm-=0x800; + if(cstok2->rm==tk_double||vop==4)rm+=4; + outword(rm); //fcom(p) + AddFloatConst(cstok2->lnumber,cstok2->rm); + outword(0); + if(am32)outword(0); + } + endcmpfloat(); + break; + case tk_floatvar: + if(!typef){ + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fld val + op(0xd9+vop); + op(cstok->rm); + outaddress(cstok); + } + CheckAllMassiv(cbuf2,4,cstr2,cstok2); + outseg(cstok2,2); //fcomp var + op(0xd8); + op(cstok2->rm+(typef==1?0x10:0x18)); + outaddress(cstok2); + endcmpfloat(); + break; + case tk_doublevar: + if(!typef){ + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fld val + op(0xd9+vop); + op(cstok->rm); + outaddress(cstok); + } + CheckAllMassiv(cbuf2,8,cstr2,cstok2); + outseg(cstok2,2); //fcomp var + op(0xd8+4); + op(cstok2->rm+(typef==1?0x10:0x18)); + outaddress(cstok2); + endcmpfloat(); + break; + case tk_fpust: + if(typef==2){ //fcomp + if(chip>=7){ //fcomip + op(0xDF); + op(0xF0+cstok2->number+1); + swapped=1; + break; + } + op(0xD8); + op(0xD8+cstok2->number+1); + } + else if(typef==1){ //fcom + if(chip>=7){ //fcomi + op(0xDB); + op(0xF0+cstok2->number); + swapped=1; + break; + } + op(0xD8); + op(0xD0+cstok2->number); + } + else{ + if(cstok2->type!=tp_modif){ + op(0xd9); //fld st(x) + op(0xC0+cstok2->number); + } + CheckAllMassiv(cbuf,4+vop,cstr,cstok); + outseg(cstok,2); //fcomp var + op(0xd8+vop); + op(cstok->rm+0x18); + outaddress(cstok); + } + endcmpfloat(); + swapped=1; + break; + default: + err=1; + break; + } + break; + default: err=1; break; + } + if(err)preerror("unable to create comparison, check restrictions"); + return(swapped); +} + +int CheckCompareTok(int reg) +{ +int comparetok=tk_equalto; + if(itok.type==tp_compare)comparetok=tok; + else unknowncompop(); + getoperand(reg); + return comparetok; +} + +int typenumber(int vtok) +{ + switch(vtok){ + case tk_char: + case tk_beg: + case tk_byte: + return tk_byte; + case tk_int: + case tk_reg: + case tk_word: + return tk_word; + case tk_reg64: + case tk_qword: + return tk_qword; + case tk_floatvar: + case tk_float: + return tk_float; + case tk_doublevar: + case tk_double: + return tk_double; + } + return tk_dword; +} + +#ifdef OPTVARCONST +int constructcompare(int invertflag,unsigned int startloc,LVIC *comconst) +#else +int constructcompare(int invertflag,unsigned int startloc) +#endif +/* build cmp for IF, if and do {} while */ +{ +int comparetok=0,jumptype,vartype=tokens,notflag=FALSE; +int ittok,ittok2=tokens,type2=tokens;//,retcompare=tokens; +int razr=r_undef; +char *ibuf,*ibuf2; +ITOK htok,htok2; +SINFO hstr,hstr2; +int preg=(am32==TRUE?EAX:SI); +int use_cxz=0; +char *ofsstr=NULL,*ofsstr2=NULL; +int usereg=-1; +int usereg2=-1; + +//////04.10.04 13:45 +int bracket=0; +unsigned char oinline=useinline; + useinline=0; + do{ + nexttok(); +// printf("tok=%d tok2=%d\n",tok,tok2); + if(tok==tk_openbracket)bracket++; + if(tok==tk_not)notflag=(notflag+1)%2; + }while(tok2==tk_openbracket||tok2==tk_not); + if(bracket==0)expected('('); +///////////////// + + setzeroflag=FALSE; + ofsstr=GetLecsem(tk_closebracket,tk_eof,tp_compare); + getoperand(); //NEW 04.10.04 13:45 + if(tok==tk_openbracket){ + bracket++; + getoperand(); + } + if(tok==tk_not){ + notflag=(notflag+1)%2; + getoperand(); + } + switch(tok){ + case tk_closebracket: + useinline=oinline; + getoperand(); + return voidcompr; + case tk_asm: + if(tok2==tk_openbrace){ + nexttok(); + type2=tok; + } + case tk_dollar: + nexttok(); + case tk_idasm: + if(stricmp(itok.name,"test")==0){ + if(iTest(1)==FALSE)InvOperComp(); + ittok=0x75; + if(type2==tk_openbrace)expecting(tk_closebrace); + goto endcomp; + } + else preerror("Only 'TEST' possible use in compare"); + break; + case tk_qword: + case tk_double: + razr+=4; + case tk_beg: + case tk_reg32: + case tk_reg: vartype=tok; break; + case tk_float: + case tk_long: + case tk_dword: + razr+=2; + case tk_int: + case tk_word: + razr++; + case tk_char: + case tk_byte: + razr++; + vartype=tok; + getoperand(); + if(tok==tk_closebracket&&bracket>1){ + bracket--; + getoperand(); + } + break; + case tk_undefproc: + case tk_declare: +// if(itok.rm==tk_void)itok.rm=(am32==FALSE?tk_word:tk_dword); + case tk_proc: + case tk_apiproc: + vartype=itok.rm; + if(vartype==tokens)vartype=(am32==FALSE?tk_word:tk_dword); + else if(vartype==tk_void&&(itok.flag&f_retproc)==0){ + retvoid(); + vartype=itok.rm=(am32==FALSE?tk_word:tk_dword); + } + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + break; + case tk_bytevar: vartype=tk_byte; break; + case tk_charvar: vartype=tk_char; break; + case tk_intvar: vartype=tk_int; break; + case tk_wordvar: vartype=tk_word; break; + case tk_dwordvar: vartype=tk_dword; break; + case tk_longvar: vartype=tk_long; break; + case tk_floatvar: vartype=tk_float; break; + case tk_qwordvar: vartype=tk_qword; break; + case tk_fpust: + case tk_doublevar: vartype=tk_double; break; + case tk_bits: + int i; + i=itok.bit.ofs+itok.bit.siz; + if(i<=64){ + vartype=tk_dword; + razr=r64; + } + if(i<=32){ + vartype=tk_dword; + razr=r32; + } + if(i<=16){ + vartype=tk_word; + razr=r16; + } + if(i<=8){ + vartype=tk_byte; + razr=r8; + } + break; + case tk_at: + if(ofsstr){ + free(ofsstr); + ofsstr=NULL; + } + nexttok(); + if(itok.flag&f_retproc){ + comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1; +// notflag=(notflag==FALSE?TRUE:FALSE); + vartype=tk_ID; + ittok2=macros(vartype); + if(tok2==tk_closebracket){ + nexttok(); + ittok=0x70+comparetok-tk_overflowflag; + goto endcomp; + } + if(ittok2==0){ + vartype=itok.rm; + break; + } + goto mac1; + } + if((itok.flag&f_typeproc)==tp_fastcall&&itok.segm!=NOT_DYNAMIC)vartype=itok.rm; + else vartype=tk_ID; + if((ittok2=macros(vartype))==0){ + vartype=itok.rm; + break; + } +mac1: + vartype=ittok2; + switch(vartype){ + case tk_byte: + case tk_char: tok=tk_beg; break; + case tk_int: + case tk_word: tok=tk_reg; break; + case tk_float: + case tk_dword: + case tk_long: tok=tk_reg32; break; + case tk_double: + case tk_qword: tok=tk_reg64; break; + default: + preerror("Macro has a return type of void"); + tok=tk_reg; + vartype=tk_word; + break; + } + itok.number=AX; // or AL or EAX + break; + default: + if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ + ittok=0x70+tok-tk_overflowflag; + nexttok(); + if(tok!=tk_closebracket&&(tok==tk_oror||tok==tk_andand||tok==tk_notequal||tok==tk_equalto)){ + int oper; + int oper2; + oper=tok; + nexttok(); + ittok^=notflag; + notflag=0; + if(tok==tk_not){ + notflag=TRUE; + nexttok(); + } + if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ + ittok-=0x70; + ittok2=tok-tk_overflowflag; + ittok2^=notflag; + notflag=0; + nexttok(); + switch(oper){ + case tk_oror: + if((ittok==2&&ittok2==4)||(ittok==4&&ittok2==2))ittok=6; + else if(ittok==4&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1; + else unknowncompop(); + break; + case tk_andand: + if((ittok==3&&ittok2==5)||(ittok==5&&ittok2==3))ittok=7; + else if(ittok==5&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1; + else unknowncompop(); + break; + case tk_notequal: + if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=12; + else unknowncompop(); + break; + case tk_equalto: + if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=13; + else unknowncompop(); + break; + } + if(tok!=tk_closebracket&&(tok==tk_notequal||tok==tk_equalto)){ + oper2=tok; + nexttok(); + if(tok==tk_not){ + notflag=TRUE; + nexttok(); + } + if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ + ittok2=tok-tk_overflowflag; + ittok2^=notflag; + notflag=0; + nexttok(); + if(oper2==tk_notequal){ + if(oper==tk_oror&&((ittok==5&&ittok2==8)||(ittok==13&&ittok2==0)))ittok=14; + else unknowncompop(); + } + else{ + if(oper==tk_andand&&((ittok==6&&ittok2==8)||(ittok==14&&ittok2==0)))ittok=15; + else unknowncompop(); + } + } + else unknowncompop(); + } + } + else unknowncompop(); + ittok+=0x70; + } + goto endcomp; + } + vartype=(am32==FALSE?tk_word:tk_dword); + break; + } + CheckMinusNum(); + if(itok2.type!=tp_compare&&tok2!=tk_closebracket){ // + if(ofsstr){ + int retreg; + razr=getrazr(vartype); + if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ + GetEndLex(tk_closebracket,tk_semicolon,tp_compare); + nexttok(); + if(razr==r16)ittok=tk_reg; + else if(razr==r32)ittok=tk_reg32; + else ittok=tk_beg; + usereg=htok.number=retreg==SKIPREG?AX:retreg; + goto nn1; + } + } + comparetok=0;// + ittok=tok; + htok=itok; + ibuf=NULL; + hstr.bufstr=NULL; + ittok2=tok2; + preg=BX; + switch(tok2){ + case tk_assign: + case tk_plusplus: + case tk_minusminus: + case tk_divequals: + case tk_minusequals: + case tk_multequals: + case tk_plusequals: + switch(tok){ + case tk_charvar: comparetok=1; + case tk_bytevar: + if((comparetok=dobytevar(comparetok,0))==tk_reg||comparetok==tk_beg){ + usereg=htok.number=AX; + ittok=tk_beg; + } + break; + case tk_intvar: comparetok=1; + case tk_wordvar: + if((comparetok=do_d_wordvar(comparetok,r16,0))==tk_reg){ + usereg=htok.number=AX; + ittok=tk_reg; + } + break; + case tk_longvar: comparetok=1; + case tk_dwordvar: + if((comparetok=do_d_wordvar(comparetok,r32,0))==tk_reg32){ + usereg=htok.number=AX; + ittok=tk_reg32; + } + break; + case tk_floatvar: + if(dofloatvar(0,tk_fpust,0)==tk_fpust){ + ittok=tk_fpust; + htok.type=tp_modif; + } + break; + case tk_qwordvar: + if((comparetok=doqwordvar(0))==tk_reg64){ + ittok=tk_reg64; + usereg=htok.number=EAX|(EDX*256); + } + break; + case tk_reg64: + usereg=itok.number; + getintoreg64(itok.number); + doregmath64(itok.number); + comparetok=tk_reg64; + break; + case tk_reg32: + usereg=itok.number; + comparetok=doreg_32((unsigned int)itok.number,r32,0); +// printf("comparetok=%d\n",comparetok); + break; + case tk_reg: + usereg=itok.number; + comparetok=doreg_32((unsigned int)itok.number,r16,0); + break; + case tk_beg: + usereg=itok.number; + comparetok=dobeg((unsigned int)itok.number,0); + break; + default: InvOperComp(); break; + } + if(ittok=tk_overflowflag&&comparetok<=tk_plusflag))){ + if(ittok2!=tk_assign&&ittok2!=tk_divequals&&ittok2!=tk_multequals){ + if(tok==tk_closebracket){ + ittok=0x75; + goto endcomp; + } + if(tok2==tk_number&&itok2.number==0){ + if((ittok2==tk_plusplus||ittok2==tk_minusminus)&& + tok!=tk_notequal&&tok!=tk_equalto)break; + comparetok=CheckCompareTok(BX); + nexttok(); + goto createopcode; + } + } + } + break; + default: + switch(vartype){ + case tk_int: comparetok=do_e_axmath(1,r16,&ofsstr); ittok=tk_reg; break; + case tk_reg: + case tk_word: comparetok=do_e_axmath(0,r16,&ofsstr); ittok=tk_reg; break; + case tk_char: comparetok=doalmath(1,&ofsstr); ittok=tk_beg; break; + case tk_beg: + case tk_byte: comparetok=doalmath(0,&ofsstr); ittok=tk_beg; break; + case tk_long: comparetok=do_e_axmath(1,r32,&ofsstr); ittok=tk_reg32; break; + case tk_reg32: + case tk_dword: + comparetok=do_e_axmath(0,r32,&ofsstr); + ittok=tk_reg32; + break; + case tk_qword: + usereg=htok.number=EAX|(EDX*256); + getintoreg64(usereg); + doregmath64(usereg); + comparetok=ittok=tk_reg64; + break; + case tk_float: + doeaxfloatmath(tk_fpust); + ittok=tk_fpust; + htok.type=tp_modif; + break; + default: + if(itok.flag&f_retproc){ + comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1; +// printf("tok=%d flag=%08X comparetok=%u %s\n",tok,itok.flag,comparetok,itok.name); +// notflag=(notflag==FALSE?TRUE:FALSE); + switch(tok){ + case tk_undefproc: + case tk_declare: + case tk_apiproc: + doanyundefproc(); + break; + case tk_proc: + doanyproc(); + break; + } + nexttok(); + if(tok!=tk_closebracket){ + retvoid(); + do{ + nexttok(); + }while(tok!=tk_closebracket); + } + } + else{ + internalerror("Bad vartype value in constructcompare();"); + tok=tk_reg; break; + } + } + if(ittok!=tk_reg64)usereg=htok.number=AX; // same value as AL and EAX + } + RestoreStack(); + } + else{ +#ifdef OPTVARCONST + CheckConstVar3(&tok,&itok,razr); +#endif + if(tok>=tk_charvar&&tok<=tk_doublevar){ + switch(vartype){ + case tk_int: tok=tk_intvar; break; + case tk_word: tok=tk_wordvar; break; + case tk_char: tok=tk_charvar; break; + case tk_byte: tok=tk_bytevar; break; + case tk_long: tok=tk_longvar; break; + case tk_dword: tok=tk_dwordvar; break; + case tk_float: tok=tk_floatvar; break; + case tk_qword: tok=tk_qwordvar; break; + case tk_double: tok=tk_doublevar; break; + } + } + else if(tok==tk_number){ + if(tok2==tk_closebracket){ + invertflag=(itok.number==0?zerocompr:voidcompr); + nexttok(); + getoperand(); + useinline=oinline; + return invertflag; + } + if(itok.rm==tk_float)vartype=tk_float; + } + else if(tok==tk_bits){ + bits2reg(AX,razr); + switch(razr){ + case r64: + case r32: + tok=tk_reg32; + break; + case r16: + tok=tk_reg; + break; + case r8: + tok=tk_beg; + break; + } + itok.number=0; + } + if(tok==tk_beg||tok==tk_reg||tok==tk_reg32)itok.rm=vartype; // reg32 + ittok=tok; + htok=itok; + ibuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nexttok(); + } +nn1: + if(razr==r_undef){ + switch(vartype){ + case tk_qword: + case tk_double: + razr+=4; + case tk_long: + case tk_dword: + case tk_float: + case tk_reg32: + razr+=2; + case tk_int: + case tk_word: + case tk_reg: + razr++; + case tk_char: + case tk_byte: + case tk_beg: + razr++; + } + } + if(tok!=tk_closebracket){ // + ofsstr2=GetLecsem(tk_closebracket); + comparetok=CheckCompareTok(preg); + if(tok>=tk_char&&tok<=tk_double){ + type2=tok; + if(ofsstr2)free(ofsstr2); + ofsstr2=GetLecsem(tk_closebracket); + getoperand(preg); + } + if(tok==tk_minus){ + if(CheckMinusNum()==FALSE){ + preerror("only negative of constants valid within compairsons"); + nexttok(); + } + } +#ifdef OPTVARCONST + CheckConstVar3(&tok,&itok,razr); +#endif + if(tok==tk_number){ + switch(vartype){ + case tk_long: + case tk_int: + case tk_char: + htok2.number=doconstlongmath(); + itok.flag=(unsigned char)postnumflag; + break; + case tk_dword: + case tk_reg32: + case tk_beg: + case tk_reg: + case tk_word: + case tk_byte: + htok2.number=doconstdwordmath(); + itok.flag=(unsigned char)postnumflag; + break; + case tk_float: + htok2.number=doconstfloatmath(); + break; + case tk_reg64: + case tk_qword: + htok2.lnumber=doconstqwordmath(); + itok.flag=(unsigned char)postnumflag; + break; + case tk_double: + htok2.lnumber=doconstdoublemath(); + break; + } + htok2.rm=typenumber(vartype); + ittok2=tk_number; + htok2.flag=itok.flag; + } + else{ + if(ittok>=tk_charvar&&ittok<=tk_doublevar&&(tok==tk_proc||tok==tk_id|| + tok==tk_undefproc||tok==tk_declare||tok==tk_apiproc||tok==tk_ID|| + itok2.type==tp_opperand||(tok>=tk_charvar&&tok<=tk_doublevar))){ + if(ofsstr2){ + int retreg; + razr=getrazr(vartype); + if((retreg=CheckIDZReg(ofsstr2,AX,razr))!=NOINREG){ + GetEndLex(tk_closebracket); + usereg2=retreg==SKIPREG?AX:retreg; + if(razr==r16)ittok2=tk_reg; + else if(razr==r32)ittok2=tk_reg32; + else ittok2=tk_beg; + htok2.number=usereg2; + nexttok(); + goto en2; + } + } + int sign=0; + switch(ittok){ + case tk_charvar: sign=1; + case tk_bytevar: + doalmath(sign,&ofsstr2); + usereg2=htok2.number=AX; + ittok2=tk_beg; + break; + case tk_intvar: sign=1; + case tk_wordvar: + do_e_axmath(sign,r16,&ofsstr2); + usereg2=htok2.number=AX; + ittok2=tk_reg; + break; + case tk_longvar: sign=1; + case tk_dwordvar: + do_e_axmath(sign,r32,&ofsstr2); + usereg2=htok2.number=AX; + ittok2=tk_reg32; + break; + case tk_floatvar: + doeaxfloatmath(tk_fpust); + ittok2=tk_fpust; + htok2.type=tp_modif; + htok2.number=0; + ClearReg(AX); + break; + case tk_doublevar: + doeaxfloatmath(tk_fpust,0,4); + ittok2=tk_fpust; + htok2.type=tp_modif; + htok2.number=0; + ClearReg(AX); + break; + case tk_qwordvar: + usereg2=htok2.number=EAX|(EDX*256); + getintoreg64(usereg2); + doregmath64(usereg2); + ittok2=tk_reg64; + ClearReg(AX); + ClearReg(DX); + break; + } + } + else{ + if(tok==tk_bits){ + int i=itok.bit.ofs+itok.bit.siz; + int vops; + if(i<=64)vops=r64; + if(i<=32)vops=r32; + if(i<=16)vops=r16; + if(i<=8)vops=r8; + if(vops=tk_overflowflag)&&(comparetok<=tk_plusflag)){ + ittok=0x70+comparetok-tk_overflowflag; + goto endcomp; + } + htok2.rm=typenumber(vartype); + comparetok=tk_notequal; + ittok2=tk_number; + htok2.number=0; + htok2.flag=0; + } + if(ittok2==tk_number&&htok2.number==0&&(htok2.flag&f_reloc)==0){ + if(setzeroflag){ + if(comparetok==tk_notequal){ + ittok=0x75; + goto endcomp; + } + if(comparetok==tk_equalto){ + ittok=0x74; + goto endcomp; + } + } + if(htok.number==CX&&optimizespeed==0){ + if(ittok==tk_reg||ittok==tk_reg32){ + if(comparetok==tk_notequal)use_cxz=notflag==0?cxnzcompr:cxzcompr; + else if(comparetok==tk_equalto)use_cxz=notflag==TRUE?cxnzcompr:cxzcompr; + } + } + } +en2: + if(ittok>=tk_charvar&&ittok<=tk_floatvar){ + if(ofsstr){ + int retreg; + razr=getrazr(vartype); + if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ + usereg=retreg==SKIPREG?AX:retreg; + if(!((ittok2==tk_reg||ittok2==tk_reg32||ittok2==tk_beg)&&usereg==htok2.number)){ + if(razr==r16)ittok=tk_reg; + else if(razr==r32)ittok=tk_reg32; + else ittok=tk_beg; + htok.number=usereg; + if(ibuf){ + free(ibuf); + ibuf=NULL; + } + if(hstr.bufstr){ + free(hstr.bufstr); + hstr.bufstr=NULL; + } + } + else{ + usereg=-1; + } + } + else{ + if(ittok==tk_floatvar)ClearReg(AX); + else if(ittok>=tk_intvar&&ittok=tk_charvar&&ittok<=tk_doublevar&&ittok2==tk_number&& + (htok2.flag&f_reloc)==0&&htok.rec&&(htok.flag&f_useidx)==0){ + comconst->rec=htok.rec; + comconst->lnumber=htok2.lnumber; + comconst->contype=htok2.rm; + } + else if(ittok2>=tk_charvar&&ittok2<=tk_doublevar&&ittok==tk_number&& + (htok.flag&f_reloc)==0&&htok2.rec&&(htok2.flag&f_useidx)==0){ + comconst->rec=htok2.rec; + comconst->lnumber=htok.lnumber; + comconst->contype=htok.rm; + } + comconst->typevar=comparetok; + if(notflag)comconst->typevar=(comparetok==tk_equalto?tk_notequal:tk_equalto); + } + } +#endif + if(outcmp(0,ittok,&htok,ibuf,&hstr,ittok2,&htok2,ibuf2,&hstr2,razr)){ + switch(comparetok){ + case tk_less: comparetok=tk_greater; break; + case tk_lessequal: comparetok=tk_greaterequal; break; + case tk_greater: comparetok=tk_less; break; + case tk_greaterequal: comparetok=tk_lessequal; break; + } + } +createopcode: + jumptype=0; + if(vartype==tk_char||vartype==tk_int||vartype==tk_long)jumptype=1; + switch(comparetok){ + case tk_equalto: ittok=0x74; break; + case tk_notequal: ittok=0x75; break; + case tk_greater: + ittok=(jumptype==0?0x77:0x7F); + break; + case tk_less: + ittok=(jumptype==0?0x72:0x7C); + break; + case tk_greaterequal: + ittok=(jumptype==0?0x73:0x7D); + break; + case tk_lessequal: + ittok=(jumptype==0?0x76:0x7E); + break; + default: unknowncompop(); break; + } +endcomp: + if(ofsstr){ + if(usereg!=-1)IDZToReg(ofsstr,usereg,razr); + free(ofsstr); + } + if(ofsstr2){ +// printf("usereg2=%08X %s\n",usereg2,ofsstr2); + if(usereg2!=-1)IDZToReg(ofsstr2,usereg2,razr); + free(ofsstr2); + } + if(invertflag==2)invertflag=((outptr+2-startloc)>128?1:0); + ittok^=invertflag; + ittok^=notflag; + op(ittok); /* output instruction code */ + expecting(tk_closebracket); + useinline=oinline; + return invertflag|use_cxz; +} + +#ifdef OPTVARCONST +ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst) +#else +ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg) +#endif +{ +unsigned int i; +ICOMP *icomp; +int j=0; +int ifline=linenumber; +int ptok=tk_oror; +int rcompr; +int useor=FALSE; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; + if(am32)j=2; + icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); // + i=0; + + do{ +#ifdef OPTVARCONST + if((rcompr=constructcompare(0,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1; +#else + if((rcompr=constructcompare(0,outptr))==voidcompr||rcompr==zerocompr)i=1; +#endif + if(i){ + if(rcompr==voidcompr&&ptok==tk_andand){ + i=0; + ptok=tok; + } + continue; + } + op(0x03+j); + if(tok!=tk_oror){ + JXorJMP(); + if(am32!=FALSE)outword(0); + outword(0); + } + (icomp+*numcomp)->loc=outptr; + (icomp+*numcomp)->type=tok; +// (icomp+*numcomp)->use_cxz=rcompr&0xFC; + (*numcomp)++ ; + if(*numcomp==MAXIF){ + ManyLogicCompare(); + free(icomp); + return NULL; + } + ptok=tok; +/* if(tok!=tk_andand&&tok!=tk_oror&&bakregstat==NULL){ + bakregstat=BakRegStat(); + changeregstat=BakRegStat(); + }*/ + }while(tok==tk_oror||tok==tk_andand); + if(tok==tk_closebracket)nexttok(); + for(i=0;i<*numcomp;i++){ + unsigned long temp=outptr-(icomp+i)->loc; + if((icomp+i)->type==tk_oror){ +#ifdef OPTVARCONST + if(comconst)comconst->rec=NULL; +#endif + if(temp>127)CompareOr(); + output[(icomp+i)->loc-1]=(unsigned char)temp; + clearregstat(); + useor=TRUE; + } + else if(chip>2){ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)temp; + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)temp; + } + } + + if(bakregstat==NULL){ + bakregstat=BakRegStat(); + changeregstat=BakRegStat(); + } + if(type==tk_if&&rcompr!=zerocompr){ + if(rcompr==voidcompr)warcompeqconst(); + if(tok==tk_return||tok==tk_RETURN){ + if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){ + if(insertmode||(!optimizespeed)){ + if(tok==tk_return||tok==tk_RETURN)goto merge_if; + } + } + startblock(); + doreturn(tok); + endblock(); + int di; + if(rcompr==voidcompr)di=0; + else di=am32==FALSE?2:4; + for(unsigned int i=0;i<*numcomp;i++){ + if((icomp+i)->type!=tk_oror){ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-di]=(unsigned short)(outptr-(icomp+i)->loc); + else *(unsigned long *)&output[(icomp+i)->loc-di]=(unsigned long)(outptr-(icomp+i)->loc); + } + } + if((outptr-icomp->loc)<=127)warningjmp(mesIF,ifline); + if(tok==tk_else||tok==tk_ELSE){ + notunreach=TRUE; + nexttok(); + docommand(); + } + free(icomp); + return NULL; + } + if(tok==tk_break||tok==tk_BREAK||tok==tk_continue||tok==tk_CONTINUE||tok==tk_goto||tok==tk_GOTO){ +merge_if: + if(rcompr==voidcompr)goto endp; + if(chip<3){ + for(i=0;i<*numcomp;i++){ + if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-3-j); + else{ + if((icomp+i)->type!=tk_andand)output[(icomp+i)->loc-5-j]=(unsigned char)(output[(icomp+i)->loc-5-j]^1); + else{ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); + } + } + } + outptr-=3+j; + } + else{ + for(i=0;i<*numcomp;i++){ + if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-2-j); + else{ + if((icomp+i)->type!=tk_andand){ + output[(icomp+i)->loc-4-j]=(unsigned char)(output[(icomp+i)->loc-3-j]-0x10); + output[(icomp+i)->loc-3-j]=(unsigned char)(3+j); + } + else{ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc+1); + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc+1); + } + } + } + outptr-=2+j; + if(cpu<3)cpu=3; + } + int delta=0; //new 07.06.06 20:27 + + if(tok==tk_break||tok==tk_BREAK){ + if(useor==FALSE){ + int ooutptr=outptr-2; + int otok=tok; + i=(unsigned char)(output[ooutptr]^1); + outptr--; + if(tok==tk_break)i+=0x10; + else outptr--; + doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32))); + if(otok==tk_break){ + output[ooutptr]=0x0f; + output[ooutptr+1]=i; + delta=-1; + } + else{ + output[ooutptr]=i; + delta=(am32==TRUE?-5:-3); + } + } + else{ + if(tok==tk_BREAK){ + output[outptr-1]-=(am32==TRUE?3:1); + } + doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32))); + } + } + else if(tok==tk_return||tok==tk_RETURN){ +//new 07.06.06 21:12 + if(useor==FALSE){ + int ooutptr=outptr-2; + int otok=tok; + i=(unsigned char)(output[ooutptr]^1); + outptr--; + if(tok==tk_return){ + i+=0x10; + } + else outptr--; + AddRetList(outptr+1,linenumber,tok); + if(tok2==tk_openbracket){ + nexttok(); + nexttok(); + } + if(otok==tk_return){ + output[ooutptr]=0x0f; + output[ooutptr+1]=i; + delta=-1; + } + else{ + output[ooutptr]=i; + delta=(am32==TRUE?-5:-3); + } + } + else{ + if(tok==tk_RETURN)output[outptr-1]-=(am32==TRUE?3:1); + AddRetList(outptr+1,linenumber,tok); + if(tok==tk_return&&tok2==tk_openbracket){ + nexttok(); + nexttok(); + } + } + nextseminext(); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + } + else if(tok==tk_goto||tok==tk_GOTO){ + int ooutptr=outptr; + if(useor==FALSE){ + if(tok==tk_GOTO){ + outptr-=2; + i=(unsigned char)(output[outptr]^1); + GOTOdo(); + output[outptr-2]=i; + delta=(am32==0?-3:-5); + } + else{ + int otok2=tok2; + gotodo(); + if(output[ooutptr]==0xEB){ // + outptr=ooutptr-2; + op(output[outptr]^1); + op(output[ooutptr+1]+2); + delta=(am32==0?-3:-5); + } + else if(am32&&otok2==tk_number){ + outptr=ooutptr-2; + i=(unsigned char)((output[outptr]^1)+0x10); + op(0x0f); + op(i); + if(output[outptr]==0xE9)outdword(*(unsigned long *)&output[ooutptr+1]+1); + else outdword(*(unsigned short *)&output[ooutptr+2]); + delta=-1; + } + } + } + else{ // useor + if(tok==tk_goto)gotodo(); + else GOTOdo(); + if(output[ooutptr]==0xEB){ // + output[ooutptr-1]-=(am32==TRUE?3:1); + } + } + } + else{ + if(useor==FALSE){ + int ooutptr=outptr-2; + int otok=tok; + i=(unsigned char)(output[ooutptr]^1); + outptr--; + if(tok==tk_continue)i+=0x10; + else outptr--; + doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32))); + if(otok==tk_continue){ + output[ooutptr]=0x0f; + output[ooutptr+1]=i; + delta=-1; + } + else{ + output[ooutptr]=i; + delta=(am32==TRUE?-5:-3); + } + } + else{ + if(tok==tk_CONTINUE){ + output[outptr-1]-=(am32==TRUE?3:1); + } + doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32))); + } + } + for(i=0;i<*numcomp;i++){ +// if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]+=delta; +// else + if((icomp+i)->type==tk_andand){ + if(am32==FALSE)*(signed short *)&output[(icomp+i)->loc-2]+=delta; + else *(signed long *)&output[(icomp+i)->loc-4]+=delta; + } + } + if(tok==tk_else||tok==tk_ELSE){ + notunreach=TRUE; + nexttok(); + docommand(); + } + free(icomp); + return NULL; + } + } +endp: + if(type!=tk_for){ + startblock(); + if(rcompr==zerocompr)warcompneqconst(); + if(tok==tk_openbrace){ + if(rcompr==zerocompr){ + cha=cha2; + inptr=inptr2; + SkipBlock(); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + } + else{ +#ifdef OPTVARCONST + if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){ + Const2VarRec(comconst); + } +#endif + doblock(); + nexttok(); + } + } + else{ + if(rcompr==zerocompr){ + do{ + nexttok(); + }while(tok!=tk_semicolon&&tok!=tk_eof); + } + else{ +#ifdef OPTVARCONST + if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){ + Const2VarRec(comconst); + } +#endif + docommand(); + } + } + endblock(); + RestoreStack(); + } + if(bakreg)*bakreg=bakregstat; + if(changereg)*changereg=changeregstat; + return icomp; +} + +void opt_if_else_stop(unsigned int newptr) +{ +unsigned int ooutptr,ooutptrdata; +unsigned char instr; + dbgact++; + ooutptr=outptr; + ooutptrdata=outptrdata; + outptr=newptr; + instr=output[outptr]; + docommand(); + if(output[newptr]==0xEB){ + signed char ofs=output[newptr+1]; + if(output[newptr-1]==0x0F&&instr>=0x80&&instr<0x90){ + ofs--; + if(am32)ofs-=(signed char)2; + } + if(am32)*(long *)&output[newptr+1]=ofs; + else*(short *)&output[newptr+1]=ofs; + } + if(am32&&output[newptr]==0x66&&output[newptr+1]==0xE9){ + signed short ofs=(signed short)(*(short *)&output[newptr+2]-1); + *(long *)&output[newptr+1]=ofs; + } + output[newptr]=instr; + outptr=ooutptr; + outptrdata=ooutptrdata; + dbgact--; +} + +void doif() +{ +unsigned int startloc,elseline,numcomp=0,ifline; +ICOMP *icomp; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; +unsigned int oaddESP=addESP; + ifline=linenumber; +#ifdef OPTVARCONST +LVIC comconst; + comconst.rec=NULL; + icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat,&comconst); +#else + icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat); +#endif +// i=CheckStopBlock(); + /*-----------------19.08.99 22:35------------------- + else if + else if else + --------------------------------------------------*/ + if(icomp!=NULL){ + elseline=linenumber; +unsigned long temp; +unsigned int j=0; +unsigned int otok=tok; +unsigned int oinptr=inptr2; +unsigned char ocha=cha2; +unsigned int oline=linenumber; + if(tok==tk_else||tok==tk_ELSE){ + if(dbg)AddLine(); + j=(am32==FALSE?3:5); + if(tok2==tk_goto||tok2==tk_break||tok2==tk_continue||// + tok2==tk_RETURN||tok2==tk_return||tok2==tk_GOTO||tok2==tk_BREAK||tok2==tk_CONTINUE){ + nexttok(); + switch(tok){ + case tk_GOTO: otok=tk_goto; break; + case tk_BREAK: otok=tk_break; break; + case tk_CONTINUE: otok=tk_continue; break; + case tk_return: + case tk_RETURN: + if(tok2==tk_semicolon||(tok2==tk_openbracket&& + ScanTok3()==tk_closebracket)){ + startblock(); + otok=tk_return; + break; + } + tok=otok; // + inptr2=oinptr; + cha2=ocha; + linenumber=oline; + goto nooptim; + default:otok=tok; break; + } + oinptr=inptr2; + ocha=cha2; + oline=linenumber; + for(unsigned int i=0;itype!=tk_oror){ + notunreach=TRUE; + tok=otok; + inptr2=oinptr; + cha2=ocha; + linenumber=oline; + opt_if_else_stop((icomp+i)->loc-j); + } + } + if(otok==tk_return)endblock(); + if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline); + free(icomp); + retproc=FALSE; + lastcommand=tk_if; + return; + } +nooptim: + if(tok==tk_ELSE)j=2; + } + notunreach=TRUE; + for(unsigned int i=0;itype!=tk_oror){ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr+j-(icomp+i)->loc); + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr+j-(icomp+i)->loc); + } + } + if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline); + switch(lastcommand){ + case tk_return: + case tk_RETURN: + case tk_goto: + case tk_GOTO: + case tk_break: + case tk_BREAK: + case tk_continue: + case tk_CONTINUE: + addESP=oaddESP; + break; + } + if(retproc)CopyRegStat(bakregstat); + else{ + switch(lastcommand){ + case tk_return: + case tk_RETURN: + case tk_goto: + case tk_GOTO: + case tk_break: + case tk_BREAK: + case tk_continue: + case tk_CONTINUE: + CopyRegStat(bakregstat); + break; + default: + CompareRegStat(changeregstat); + break; + } + } +// printf("lastcommand=%d\n",lastcommand); +// CompareRegStat(changeregstat); + if(tok==tk_else/*&&i==FALSE*/){ + addESP=oaddESP; + RestoreStack(); + CopyRegStat(bakregstat); + jumploc0(); + startloc=outptr; + getoperand(); +#ifdef OPTVARCONST + if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){ + Const2VarRec(&comconst); + } +#endif + startblock(); + if(tok==tk_return||tok==tk_RETURN){ + if(dbg)AddLine(); + doreturn(tok); + } + else docommand(); + endblock(); + RestoreStack(); + temp=outptr-startloc; + if(temp<=127)warningjmp(mesELSE,elseline); + if(am32==FALSE)*(unsigned short *)&output[startloc-2]=(unsigned short)temp; + else *(unsigned long *)&output[startloc-4]=temp; + CompareRegStat(changeregstat); + } + else if(tok==tk_ELSE/*&&i==FALSE*/){ + addESP=oaddESP; + RestoreStack(); + CopyRegStat(bakregstat); + outword(0x00EB); + startloc=outptr; + getoperand(); +#ifdef OPTVARCONST + if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){ + Const2VarRec(&comconst); + } +#endif + startblock(); + if(tok==tk_return||tok==tk_RETURN){ + if(dbg)AddLine(); + doreturn(tok); + } + else docommand(); + endblock(); + RestoreStack(); + temp=outptr-startloc; + if(temp>127)jumperror(elseline,mesELSE); + output[startloc-1]=(unsigned char)temp; + CompareRegStat(changeregstat); + } +/* else{ + if(i!=FALSE&&(tok==tk_else||tok==tk_ELSE))nexttok(); + }*/ + free(icomp); + CopyRegStat(changeregstat); + } + FreeStat(bakregstat); + FreeStat(changeregstat); + retproc=FALSE; + lastcommand=tk_if; +} + +#ifdef OPTVARCONST +ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst) +#else +ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg) +#endif +{ +unsigned int ifline; +ICOMP *icomp; +unsigned int i=0; +int j=0; +int ptok=tk_oror; +int rcompr; +int useor=FALSE; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; + if(am32!=FALSE)j=2; + icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); // + ifline=linenumber; + do{ +#ifdef OPTVARCONST + if((rcompr=constructcompare(1,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1; +#else + if((rcompr=constructcompare(1,outptr))==voidcompr||rcompr==zerocompr)i=1; +#endif + (icomp+*numcomp)->use_cxz=rcompr&0xFC; + if(i){ + if(rcompr==voidcompr&&ptok==tk_andand){ + i=0; + ptok=tok; + } + continue; + } + op(0x00); + (icomp+*numcomp)->loc=outptr; + (icomp+*numcomp)->type=tok; + (*numcomp)++; + if(*numcomp==MAXIF){ + ManyLogicCompare(); + free(icomp); + return NULL; + } + ptok=tok; +/* if(tok==tk_andand&&bakregstat==NULL){ + bakregstat=BakRegStat(); + changeregstat=BakRegStat(); + }*/ + }while(tok==tk_oror||tok==tk_andand); + if(tok==tk_closebracket)nexttok(); + for(i=0;i<*numcomp;i++){ + if(outptr-(icomp+i)->loc>127)CompareOr(); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + if((icomp+i)->type==tk_oror){ +#ifdef OPTVARCONST + if(comconst)comconst->rec=NULL; +#endif + output[(icomp+i)->loc-2]=(unsigned char)(output[(icomp+i)->loc-2]^1); + clearregstat(); + useor=TRUE; + } + } + if(bakregstat==NULL){ + bakregstat=BakRegStat(); + changeregstat=BakRegStat(); + } + if(type==tk_IF&&rcompr!=zerocompr){ + if(rcompr==voidcompr)warcompeqconst(); + if(tok==tk_return||tok==tk_RETURN){ + if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){ + if(insertmode||(!optimizespeed)){ + if(tok==tk_RETURN)goto merge_if; + else if(chip>2&&(insertmode||(paramsize&& + (current_proc_type&f_typeproc)!=tp_cdecl)))goto merge_if2; + } + } + startblock(); + doreturn(tok); + endblock(); + for(unsigned int i=0;i<*numcomp;i++){ + if((icomp+i)->type!=tk_oror){ + if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + } + if(tok==tk_else||tok==tk_ELSE){ + notunreach=TRUE; + getoperand(); + docommand(); + } + free(icomp); + return NULL; + } + if(tok==tk_BREAK||tok==tk_CONTINUE||tok==tk_GOTO){ +merge_if: + int otok=tok; + for(i=0;i<*numcomp;i++){ + unsigned char oldcode; + if(((icomp+i)->type==tk_oror)||((i+1)==*numcomp)){ + outptr=(icomp+i)->loc-2; + oldcode=output[outptr]; + if(tok==tk_BREAK)MakeBreak(BREAK_SHORT); + else if(tok==tk_RETURN){ + AddRetList(outptr+1,ifline,tk_RETURN); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + } + else if(tok==tk_GOTO){ + if((i+1)!=*numcomp){ + int optr,ocha,oline; + optr=inptr2; + ocha=cha2; + oline=linenum2; + GOTOdo(); + if(outptr!=(icomp+i)->loc)jumperror(oline,"GOTO"); + inptr2=optr; + cha2=(unsigned char)ocha; + linenum2=oline; + tok=tk_GOTO; + } + else{ + getoperand(); + CheckIP(); + if(tok==tk_number||tok==tk_interruptproc||tok==tk_proc){ + long hnumber; + if(tok==tk_number)hnumber=doconstdwordmath(); + else{ + hnumber=itok.number; + nexttok(); + } + long loc=hnumber-outptr-2; + if(loc>-129&&loc<128){ + op((unsigned char)(oldcode^1)); + op(loc); + } + else{ + loc-=3; + outptr++; + op(am32==0?3:5); + op(0xE9); + if(am32==FALSE)outword(loc); + else{ + loc-=2; + outdword(loc); + } + } + seminext(); + break; + } + else if(GOTO())nexttok(); + seminext(); + } + } + else MakeContinue(CONTINUE_SHORT); + if((i+1)==*numcomp)oldcode^=1; + output[outptr-2]=oldcode; + } + } + if(tok==tk_RETURN&&tok2==tk_openbracket){ + nexttok(); + nexttok(); + } + if(otok!=tk_GOTO&&rcompr!=voidcompr)nextseminext(); + + if(tok==tk_else||tok==tk_ELSE){ + notunreach=TRUE; + getoperand(); + docommand(); + } + free(icomp); + return NULL; + } + if((tok==tk_break||tok==tk_continue||tok==tk_goto)&&chip>2){ +merge_if2: + +// printf("%s (%u) %s %s tok=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,itok.name,string,tok); + + if(*numcomp==1&&(!(tok==tk_goto&&(tok2==tk_reg||tok2==tk_reg32)))){ + outptr-=2; + i=(output[outptr]^1)+0x10; + op(0x0F); + } + if(tok==tk_break)doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32)); + else if(tok==tk_return){ + AddRetList(outptr+1,ifline,tk_return); + if(tok2==tk_openbracket){ + nexttok(); + nexttok(); + } + nextseminext(); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + } + else if(tok==tk_goto){ + nexttok(); + CheckIP(); + if((tok==tk_number&&*numcomp==1)||tok==tk_interruptproc||tok==tk_proc){ + if(tok==tk_proc&&tok2==tk_openbracket)doanyproc(TRUE); + else{ + long hnumber; + if(tok==tk_number)hnumber=doconstdwordmath(); + else{ + hnumber=itok.number; + nexttok(); + } + long loc=hnumber-outptr-2; + if(loc>-130&&loc<127){ + outptr--; + op((unsigned char)(i-0x10)); + op(loc+1); + seminext(); + goto c1; + } + else{ + loc--; + op(0xE9); + if(am32==FALSE)outword(loc); + else{ + loc-=2; + outdword(loc); + } + } + } + } + else{ + if(tok==tk_reg||tok==tk_reg32){ + i=outptr; + if(gotol(0))nexttok(); + i=outptr-i; + output[outptr-i-1]=(unsigned char)i; + goto c1; + } + if(gotol(0))nexttok(); + } + seminext(); + } + else doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32)); + if(*numcomp==1)output[outptr-3-j]=(unsigned char)i; +c1: + if(cpu<3)cpu=3; + if(tok==tk_else||tok==tk_ELSE){ + notunreach=TRUE; + getoperand(); + docommand(); + } + if(*numcomp!=1){ + for(unsigned int i=0;i<*numcomp;i++){ + if((icomp+i)->type!=tk_oror){ + if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + } + } + free(icomp); + return NULL; + } + } + if((icomp+(*numcomp-1))->use_cxz==cxnzcompr){ + outptr-=4; + outword(0xE3); + (icomp+(*numcomp-1))->loc=outptr; + for(i=(*numcomp-1);i!=0;i--){ + if((icomp+i-1)->type==tk_oror)output[(icomp+i-1)->loc-1]-=(unsigned char)2; + } + } + if(type!=tk_FOR){ + startblock(); + if(rcompr==zerocompr)warcompneqconst(); + if(tok==tk_openbrace){ + if(rcompr==zerocompr){ + cha=cha2; + inptr=inptr2; + SkipBlock(); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + } + else{ +#ifdef OPTVARCONST + if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst); +#endif + doblock(); + nexttok(); + } + } + else{ + if(rcompr==zerocompr){ + do{ + nexttok(); + }while(tok!=tk_semicolon&&tok!=tk_eof); + } + else{ +#ifdef OPTVARCONST + if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst); +#endif + docommand(); + } + } + endblock(); + RestoreStack(); + } + if(bakreg)*bakreg=bakregstat; + if(changereg)*changereg=changeregstat; + return icomp; +} + +void dobigif() +{ +unsigned int ifline,numcomp=0,j=0; +ICOMP *icomp; +int ic; +unsigned int oaddESP=addESP; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; + ifline=linenumber; +#ifdef OPTVARCONST +LVIC comconst; + comconst.rec=NULL; + icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat,&comconst); +#else + icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat); +#endif + if(icomp!=NULL){ + unsigned int elseline; + elseline=linenumber; + if(tok==tk_else)j=(am32==FALSE?3:5); + else if(tok==tk_ELSE)j=2; + notunreach=TRUE; + if(dbg)AddLine(); + for(unsigned int i=0;itype!=tk_oror){ + if((outptr+j-(icomp+i)->loc)>127)jumperror(ifline,mesIF); + output[(icomp+i)->loc-1]=(unsigned char)(outptr+j-(icomp+i)->loc); + } + } + switch(lastcommand){ + case tk_return: + case tk_RETURN: + case tk_goto: + case tk_GOTO: + case tk_break: + case tk_BREAK: + case tk_continue: + case tk_CONTINUE: + addESP=oaddESP; + break; + } + if(retproc)CopyRegStat(bakregstat); + else{ + switch(lastcommand){ + case tk_return: + case tk_RETURN: + case tk_goto: + case tk_GOTO: + case tk_break: + case tk_BREAK: + case tk_continue: + case tk_CONTINUE: + CopyRegStat(bakregstat); + break; + default: + CompareRegStat(changeregstat); + break; + } +// CompareRegStat(changeregstat); + } + if(tok==tk_else/*&&i==FALSE*/){ + addESP=oaddESP; + RestoreStack(); + CopyRegStat(bakregstat); + jumploc0(); + ic = outptr; + getoperand(); +#ifdef OPTVARCONST + if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst); +#endif + startblock(); + if(tok==tk_return||tok==tk_RETURN){ + if(dbg)AddLine(); + doreturn(tok); + } + else docommand(); + endblock(); + RestoreStack(); + if((outptr-ic)<=127)warningjmp(mesELSE,elseline); + if(am32==FALSE)*(unsigned short *)&output[ic-2]=(unsigned short)(outptr-ic); + else *(unsigned long *)&output[ic-4]=(unsigned long)(outptr-ic); + CompareRegStat(changeregstat); + } + else if(tok==tk_ELSE/*&&ic==FALSE*/){ + addESP=oaddESP; + RestoreStack(); + CopyRegStat(bakregstat); + outword(0x00EB); + ic=outptr; + getoperand(); +#ifdef OPTVARCONST + if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst); +#endif + startblock(); + if(tok==tk_return||tok==tk_RETURN){ + if(dbg)AddLine(); + doreturn(tok); + } + else docommand(); + endblock(); + RestoreStack(); + if((outptr-ic)>127)jumperror(elseline,mesELSE); + output[ic-1]=(unsigned char)(outptr-ic); + CompareRegStat(changeregstat); + } + free(icomp); + CopyRegStat(changeregstat); + } + FreeStat(bakregstat); + FreeStat(changeregstat); + retproc=FALSE; + lastcommand=tk_IF; +} + +void JXorJMP() +{ + if(chip<3){ + op(0xE9); + } + else{ + unsigned char i; + outptr-=2; + i=(unsigned char)((output[outptr]^1)+0x10); + op(0x0F); op(i); + if(cpu<3)cpu=3; + } +} + +void dowhile(unsigned int typeb) +{ +unsigned int ifline,conloc,numcomp=0; +ICOMP *icomp; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; + uptdbr(); + if(AlignCycle)AlignCD(CS,aligncycle); + conloc=outptr; + ifline=linenumber; + if(typeb==tk_while) +#ifdef OPTVARCONST + icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); +#else + icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat); +#endif + else +#ifdef OPTVARCONST + icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); +#else + icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat); +#endif + SetContinueLabel(); + jumploc(conloc); + if(icomp!=NULL){ + if(typeb==tk_WHILE){ + for(unsigned int i=0;itype!=tk_oror){ + if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesWHILE); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + } + } + else{ + for(unsigned int i=0;itype!=tk_oror){ + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); + } + } + if((outptr-icomp->loc)<=127)warningjmp(mesWHILE,ifline); + } + free(icomp); + } + if(retproc){ + if(bakregstat)CopyRegStat(bakregstat); + } + else if(changeregstat)CompareRegStat(changeregstat); + if(changeregstat)CopyRegStat(changeregstat); + SetBreakLabel(); + if(usebr[curbr]!=0)clearregstat(); + FreeStat(bakregstat); + FreeStat(changeregstat); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + lastcommand=tk_do; +} + +void dowhilefast(unsigned int typeb) +{ +unsigned int numcomp=0; +unsigned int startloc,i; +ICOMP *icomp; +ITOK oitok,ostructadr; +SINFO ostr; +unsigned int oldinptr; +int otok,otok2; +char *ostring,*obufrm; +int blinenum,olinenum,oinptr; +char *ostartline,*bstartline; +char ocha,bcha; +int jmptocompr=0; +int rcompr; +unsigned char *oinput; +unsigned int oaddESP=addESP; + ocha=cha2; + oinptr=inptr2; + olinenum=linenumber; + ostartline=startline; + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + do{ + nexttok(); + if(tok2==tk_openbracket)nexttok(); + if(tok2==tk_closebracket){ + nexttok(); + jmptocompr=1; + break; + } + if(tok2==tk_number){ + nexttok(); + if(tok2==tk_closebracket){ + if(itok.number!=0)jmptocompr=1; + else jmptocompr=2; + nexttok(); + break; + } + } + nexttok(); // + cha=cha2; + inptr=inptr2; + SkipParam(); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + if(typeb==tk_while&&tok==tk_oror&&optimizespeed==0){ + cha2=ocha; + inptr2=oinptr; + linenumber=linenum2=olinenum; + startline=ostartline; + dowhile(typeb); + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + return; + } + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + }while(tok==tk_andand||tok==tk_oror); + while(tok==tk_closebracket)nexttok(); + if(!jmptocompr){ + if(typeb==tk_WHILE)outword(0x00EB); // JMP SHORT + else jumploc0(); + } + i=outptr; + if(AlignCycle)AlignCD(CS,aligncycle); + startloc=outptr; + uptdbr(); + if(tok!=tk_openbrace){ + if(jmptocompr==2){ + do{ + nexttok(); + }while(tok!=tk_semicolon&&tok!=tk_eof); + } + else docommand(); + } + else{ + if(jmptocompr==2){ + cha=cha2; + inptr=inptr2; + SkipBlock(); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + } + else{ + startblock(); + doblock(); + nexttok(); + endblock(); + } + } + RestoreStack(); + if(!jmptocompr){ + if(typeb==tk_WHILE){ + if(i!=outptr){ + if((outptr-i)>127)jumperror(olinenum,mesWHILE); + output[i-1]=(unsigned char)(outptr-i); + } + else{ + if(dbg&1)KillLastLine(); + outptr-=2; + startloc-=2; + } + } + else{ + if(i!=outptr){ + if((outptr-i)<=127)warningjmp(mesWHILE,olinenum); + if(am32) *(unsigned long *)&output[i-4]=(unsigned long)(outptr-i); + else *(unsigned short *)&output[i-2]=(unsigned short)(outptr-i); + } + else{ + i=3; + if(am32)i+=2; + if(dbg){ + KillLastLine(); + KillLastLine(); + } + outptr-=i; + startloc-=i; + } + } + } + SetContinueLabel(); + clearregstat(); //06.09.04 21:56 +#ifdef OPTVARCONST + ClearLVIC(); +#endif + icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); // +// oitok2=itok2; + + ostring=BackString((char *)string); + oldinptr=inptr2; + oinput=input; + bcha=cha2; + otok=tok; + otok2=tok2; + oitok=itok; + ostructadr=structadr; + ostr=strinf; + strinf.bufstr=NULL; + obufrm=bufrm; + int oldendinptr=endinptr; +COM_MOD *tempcurmod=cur_mod; + if(cur_mod)BackMod(); + + bufrm=NULL; + blinenum=linenum2; + inptr2=oinptr; + cha2=ocha; + linenumber=linenum2=olinenum; + bstartline=startline; + startline=ostartline; + + if(dbg)AddLine(); + int ptok=tk_oror; + do{ + i=0; +#ifdef OPTVARCONST + if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1; +#else + if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1; +#endif + if(i){ + if(ptok==tk_andand){ +// i=0; + ptok=tok; + } + continue; + } + if((rcompr&1)){; + op(0x03); + if(tok!=tk_andand){ + JXorJMP(); + if(am32==FALSE)outword(startloc-(outptr+2)); + else outdword(startloc-(outptr+4)); + } + } + else{ + op(startloc-(outptr+1)); /* the small jump */ + if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1); + } + (icomp+numcomp)->loc=outptr; + (icomp+numcomp)->type=tok; + numcomp++; + if(numcomp==MAXIF){ + ManyLogicCompare(); + break; + } + ptok=tok; + }while(tok==tk_oror||tok==tk_andand); + if(jmptocompr==1)jumploc(startloc); + + startline=bstartline; + strinf=ostr; + inptr2=oldinptr; + input=oinput; + endinptr=oldendinptr; + cha2=bcha; + tok=otok; + itok=oitok; + structadr=ostructadr; + bufrm=obufrm; + tok2=otok2; + cur_mod=tempcurmod; + strcpy((char *)string,ostring); + free(ostring); + linenumber=linenum2=blinenum; + itok2=oitok; + + for(i=0;itype==tk_andand){ + if(outptr-(icomp+i)->loc>127)CompareOr(); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + } + if(rcompr==cxzcompr){ + outptr-=4; + op(0xE3); + op(startloc-outptr-1); + for(i=(numcomp-1);i!=0;i--){ + if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2; + } + } + SetBreakLabel(); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + free(icomp); + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + lastcommand=tk_do; +} + +void dodo() +{ +unsigned int startloc,numcomp=0,i=0; +ICOMP *icomp; +int ptok=tk_oror; +int rcompr; +unsigned int oaddESP=addESP; + nexttok(); + if(AlignCycle)AlignCD(CS,aligncycle); + startloc=outptr; + uptdbr(); + if(dbg&1)KillLastLine(); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + docommand(); + SetContinueLabel(); + if(dbg)AddLine(); + if(tok!=tk_while)preerror("'while' expected following 'do'"); + icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); // + do{ +#ifdef OPTVARCONST + if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1; +#else + if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1; +#endif + if(i){ + if(ptok==tk_andand){ + i=0; + ptok=tok; + } + continue; + } + if((rcompr&1)){; + op(0x03); + if(tok!=tk_andand){ + JXorJMP(); + if(am32==FALSE)outword(startloc-(outptr+2)); + else outdword(startloc-(outptr+4)); + } + } + else{ + op(startloc-(outptr+1)); /* the small jump */ + if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1); + } + (icomp+numcomp)->loc=outptr; + (icomp+numcomp)->type=tok; + numcomp++; + if(numcomp==MAXIF){ + ManyLogicCompare(); + goto end; + } + ptok=tok; + }while(tok==tk_oror||tok==tk_andand); + if(i)jumploc(startloc); + if(tok==tk_closebracket)nexttok(); + for(i=0;itype==tk_andand){ + if(outptr-(icomp+i)->loc>127)CompareOr(); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + } + if(rcompr==cxzcompr){ + outptr-=4; + op(0xE3); + op(startloc-outptr-1); + for(i=(numcomp-1);i!=0;i--){ + if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2; + } + } + seminext(); + SetBreakLabel(); + if(usebr[curbr]!=0||useco[curco]!=0)clearregstat(); +end: +#ifdef OPTVARCONST + ClearLVIC(); +#endif + free(icomp); + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + lastcommand=tk_do; +} + +void dofor(unsigned int typeb) +{ +unsigned int ifline,conloc,blinenum,numcomp=0; +unsigned char bcha; +unsigned char COMPARE=FALSE,modif=FALSE; +int i; +unsigned char *buf; +unsigned int oaddESP=addESP; +ICOMP *icomp=NULL; +REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; + ifline=linenumber; +// printf("start for, curco=%u curbr=%u\n",curco,curbr); + uptdbr(); + nexttok(); + i=inptr2; + bcha=cha2; + expecting(tk_openbracket); // + if(tok!=tk_semicolon){ // + for(;;){ // + AddBackBuf(i,bcha); + if(tok==tk_semicolon)break; + if(tok!=tk_camma){ + expecting(tk_semicolon); + break; + } + i=inptr2; + bcha=cha2; + nexttok(); + } + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + CharToBackBuf('}'); + CharToBackBuf(0); + RunBackText(); // + } + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + bcha=cha2; + i=inptr2; + nexttok(); + if(AlignCycle)AlignCD(CS,aligncycle); + conloc=outptr; // + + if(tok!=tk_semicolon){ // + if(tok!=tk_openbracket){ // ( + CharToBackBuf('('); // + COMPARE=TRUE; // + } + AddBackBuf(i,bcha); // + if(tok!=tk_semicolon)expected(';'); + SizeBackBuf--; + if(COMPARE)CharToBackBuf(')'); // , + CharToBackBuf(0); + int oendinptr=endinptr; + endinptr=SizeBackBuf-1;//strlen(BackTextBlock); + i=inptr2; + buf=input; + bcha=cha2; + input=(unsigned char *)BackTextBlock; + SizeBackBuf=0; + inptr2=1; + cha2='('; + if(typeb==tk_for) +#ifdef OPTVARCONST + icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); +#else + icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat); +#endif + else +#ifdef OPTVARCONST + icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); +#else + icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat); +#endif + free(input); + input=buf; + inptr2=i; + cha2=bcha; + endinptr=oendinptr; + COMPARE=TRUE; + nexttok(); + } + else{ + i=inptr2; + bcha=cha2; + nexttok(); + } + + if(tok!=tk_closebracket){ // + modif=TRUE; + while(tok!=tk_closebracket){ + AddBackBuf(i,bcha); + if(cha==')'||cha==26){ + CharToBackBuf(';'); + nextchar(); + cha2=cha; + inptr2=inptr; + break; + } + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + i=inptr2; + bcha=cha2; + nexttok(); + } + CharToBackBuf('}'); + CharToBackBuf(0); + buf=(unsigned char *)REALLOC(BackTextBlock,SizeBackBuf); + SizeBackBuf=0; + } + + blinenum=linenumber; + nexttok(); +/////////////////// + if(tok==tk_openbrace){ + if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){ + warcompneqconst(); + cha=cha2; + inptr=inptr2; + SkipBlock(); + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + nexttok(); + } + else{ + startblock(); + doblock(); + nexttok(); + endblock(); + } + } + else{ + if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){ + warcompneqconst(); + do{ + nexttok(); + }while(tok!=tk_semicolon&&tok!=tk_eof); + } + else docommand(); + } + + RestoreStack(); + SetContinueLabel(); +// puts((char *)string2); +// printf("end for, curco=%u curbr=%u\n",curco,curbr); + if(modif){ + unsigned int oldlinenum=linenum2; + ITOK oitok; + oitok=itok2; + BackTextBlock=(char *)buf; + linenum2=blinenum; + RunBackText(); + linenumber=linenum2=oldlinenum; + itok2=oitok; + } + + if(COMPARE==FALSE||(COMPARE&&(icomp+numcomp)->use_cxz!=zerocompr)){ + if(COMPARE&&(icomp+numcomp)->use_cxz==voidcompr)warcompeqconst(); + jumploc(conloc);//JMP + } + + if(COMPARE){ + for(unsigned int i=0;itype!=tk_oror){ + if(typeb==tk_FOR){ + if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesFOR); + output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); + } + else{ + if((outptr-(icomp+i)->loc)<=127)warningjmp(mesFOR,ifline); + if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); + else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); + } + } + } + free(icomp); + } + if(retproc){ + if(bakregstat)CopyRegStat(bakregstat); + } + else if(changeregstat)CompareRegStat(changeregstat); + if(changeregstat)CopyRegStat(changeregstat); + SetBreakLabel(); + if(usebr[curbr]!=0||useco[curco]!=0)clearregstat(); + FreeStat(bakregstat); + FreeStat(changeregstat); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + lastcommand=tk_for; +} + +void decit(int dectok,ITOK *detok,char *&decbuf,SINFO *dstr) +// outputs code to decrement the given variable one. +{ +int vop=0,i=0,razr=r16; + switch(dectok){ + case tk_dwordvar: + case tk_longvar: + CheckAllMassiv(decbuf,4,dstr,detok); + op66(r32); + if(cpu<3)cpu=3; + vop=1; + goto l2; + case tk_wordvar: + case tk_intvar: vop=1; + op66(r16); + i=1; + case tk_bytevar: + case tk_charvar: + i++; + CheckAllMassiv(decbuf,i,dstr,detok); + if(vop!=0)op66(r16); +l2: + outseg(detok,2); + op(0xFE + vop); + op(0x08+detok->rm); + outaddress(detok); + break; + case tk_reg32: + if(cpu<3)cpu=3; + razr=r32; + case tk_reg: + op66(razr); + op(0x48+detok->number); + break; + case tk_beg: + op(0xFE); + op(0xC8+detok->number); + break; + default: + preerror(invaliddecrem); + break; + } +} + +void uptdbr(/*int usesw*/) +{ + listbr[curbr]=numbr; // + usebr[curbr]=0; + curbr++; // + numbr++; // +// if(!usesw){ + useco[curco]=0; + curco++; +// } + if(curbr==MAXIN)preerror("to many inside bloks"); +} + +void doloop(unsigned int typeb) // both short and long loops +{ +unsigned int startloc,startloc2; +int looptok; +ITOK lootok; +char *loopbuf; +signed char delta; +SINFO lstr; +int j=0,sline=linenumber; +unsigned int oaddESP=addESP; + nexttok(); +// printf("tok=%u name=%s bufrm=%s\n",tok,itok.name,bufrm); + expecting(tk_openbracket); + looptok=tok; + lootok=itok; + loopbuf=bufrm; + bufrm=NULL; + lstr=strinf; + strinf.bufstr=NULL; +// printf("bufrm=%s strinf=%s\n",loopbuf,lstr.bufstr); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + uptdbr(); + if(dbg&1)KillLastLine(); + if((toktk_dwordvar)&&tok!=tk_reg&&tok!=tk_reg32 + &&tok!=tk_beg&&tok!=tk_closebracket) + preerror(invaliddecrem); + if(tok!=tk_closebracket){ + if(typeb!=tk_loop){ + if(dbg)AddLine(); + int vop=tok==tk_reg?r16:r32; + if(typeb==tk_LOOPNZ&&((tok==tk_reg&&itok.number==CX)|| + (tok==tk_reg32&&itok.number==ECX))&&(!(optimizespeed&&chip>3&&chip<7))){ + op67(vop); + outword(0xE3); + } + else{ + if(tok==tk_reg||tok==tk_reg32||tok==tk_beg){ + if(tok==tk_beg)op(0x84); + else{ + op66(vop); + op(0x85); + } + op(0xc0+(unsigned int)itok.number*9); + } + else{ + ITOK htok2; + htok2.number=0; + htok2.rm=(am32==FALSE?rm_d16:rm_d32); + htok2.segm=DS; + htok2.post=0; + htok2.sib=(am32==FALSE?CODE16:CODE32); + htok2.flag=0; + int razr=r_undef; + switch(tok){ + case tk_longvar: + case tk_dwordvar: + razr=2; + case tk_intvar: + case tk_wordvar: + razr++; + case tk_charvar: + case tk_bytevar: + razr++; + } + outcmp(0,tok,&itok,bufrm,&strinf,tk_number,&htok2,loopbuf,&lstr,razr); + } + if(typeb==tk_LOOPNZ)outword(0x74); + else{ + if(chip<3){ + outword(0x0375); // JNZ past jump up + op(0xE9); + } + else{ + outword(0x840F); + } + outword(0); + if(am32!=FALSE)outword(0); + } + } + } + nexttok(); // + } + expecting(tk_closebracket); + startloc2=outptr; + if(AlignCycle)AlignCD(CS,aligncycle); + startloc=outptr; + docommand(); + RestoreStack(); + SetContinueLabel(); + if(looptok!=tk_closebracket){ + if(((outptr-startloc)<=(127-3))&&(chip<3||optimizespeed==0)&& + ((looptok==tk_reg&&lootok.number==CX)||(looptok==tk_reg32&&lootok.number==ECX))){ + delta=(char)(startloc-(outptr+2)); + if(op67(looptok==tk_reg?r16:r32)!=FALSE)delta--; + op(0xE2); + op(delta); /* LOOP 'delta' */ + } + else{ + decit(looptok,&lootok,loopbuf,&lstr); + if((outptr-startloc)>(unsigned int)(127-2-j)){ /* long jump */ + if(chip<3){ + outword(0x0374); // JZ past jump up + op(0xE9); + } /* JMP top of loop */ + else{ + outword(0x850F); + if(cpu<3)cpu=3; + } + if(am32==FALSE)outword(startloc-(outptr+2)); + else outdword(startloc-(outptr+4)); + } + else{ + op(0x75); // short jump + op(startloc-(outptr+1)); + } /* JNZ 'delta' */ + } + } + else jumploc(startloc);//JMP + if(typeb!=tk_loop){ + looptok=outptr-startloc2; + if(typeb==tk_LOOPNZ){ + if(looptok>127)jumperror(sline,mesLOOPNZ); + output[startloc2-1]=(unsigned char)looptok; + } + else{ + if(looptok<=127)warningjmp(mesLOOPNZ,sline); + if(am32==FALSE)*(unsigned short *)&output[startloc2-2]=(unsigned short)looptok; + else *(unsigned long *)&output[startloc2-4]=(unsigned long)looptok; + } + } + SetBreakLabel(); + if(usebr[curbr]!=0||useco[curco]!=0||typeb!=tk_loop)clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + if(ESPloc&&am32&&oaddESP!=addESP)warESP(); + lastcommand=tk_loop; +} + +void GetNameLabel(int type,int num) +{ + sprintf((char *)string2,type==tk_break?"BREAK%04X":"CONTINUE%04X",listbr[num]); +} + +void SetBreakLabel() +{ + curbr--; + if(usebr[curbr]!=0){ + GetNameLabel(tk_break,curbr); + updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start); +// clearregstat(); + } +} + +void SetContinueLabel() +{ + curco--; + if(useco[curco]!=0){ + GetNameLabel(tk_continue,curco); + updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start); + } +} + +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ + +void SaveDataVal(unsigned int ssize,unsigned long long val) +{ + switch(ssize){ + case 1: opd(val); break; + case 2: outwordd(val); break; + case 4: outdwordd(val); break; + case 8: outqwordd(val); break; + } +} + +long AddVarString() +{ +long loop=0; +int term; + do{ + term=itok.flag; + for(int i=0;i0xFFFFL)tobigpost(); + else postsize=longpostsize; + } +} + +void labelindata() +{ +//idrec *varrec; + FindOff((unsigned char *)itok.name,DS); + tok=tk_number; + itok.number=outptrdata; + itok.segm=DS; + string[0]=0; + if(FixUp)itok.flag=f_reloc; + /*varrec=*/addtotree(itok.name); + /*varrec->count=*/FindOff((unsigned char *)itok.name,DS); + nexttok(); + nexttok(); +} + +void globalvar() /* both initialized and unitialized combined */ +{ +long size,loop,i,elements,ssize; +char done=0,typev; +char var_name[IDLENGTH]; +int type=itok.rm,typebak; // +unsigned int flag,fflag=itok.flag,dynamic; +unsigned int npointr=itok.npointr; +int count; +idrec *varrec; + size=typesize(type); // + if(FixUp)fflag|=f_reloc; + typebak=type; + while(tok!=tk_eof&&done==0){ + int nnpointr=0; + typev=variable; + ssize=size; + flag=fflag; + type=typebak; +// printf("type=%d\n",type); + if(tok==tk_far){ + flag|=f_far; + nexttok(); + } + while(tok==tk_mult){ // + npointr++; + nexttok(); + } + if(tok==tk_openbracket){ + nexttok(); + while(tok==tk_mult){ // + nnpointr++; + nexttok(); + } + } + if(npointr){ + if((flag&f_far)!=0||am32!=FALSE)ssize=4; + else ssize=2; + typev=pointer; + type=am32==FALSE?tk_word:tk_dword; + } +// printf("tok=%d %s\n",tok,itok.name); + switch(tok){ + case tk_id: + case tk_ID: + if(tok2==tk_openbracket||nnpointr){ + if(npointr)type=am32==FALSE?tk_word:tk_dword; + declare_procedure(flag,type,nnpointr); + break; + } + strcpy(var_name,itok.name); // + elements=1; + nexttok(); + if(tok==tk_openblock){ //[ + nexttok(); + if(tok==tk_closeblock){// + elements=0; + nexttok(); + } + else{ + CheckMinusNum(); + if(tok!=tk_number){ + numexpected(); + nexttok(); + } + else{ + elements=doconstlongmath(); // + expecting(tk_closeblock); + } + } + } + if(type==tk_void){ + preerror("type 'void' not use for declare variables"); + break; + } + dynamic=FALSE; + if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){ //= + if((flag&f_extern))preerror("extern variable do not initialize at declare"); + i=tok; + itok.type=tp_gvar;// 11.07.05 21:56 tp_ucnovn; + SetNewTok(type,typev); + if(useStartup==TRUE&&i!=tk_assign&&SaveStartUp(size*elements,var_name)!=FALSE){ + if(elements==0)ZeroMassiv(); // + tok=i; + break; + } + if(alignword&&ssize&&(!dynamic_flag))alignersize+=AlignCD(DS,ssize); + itok.number=dynamic_flag==0?outptrdata:0; + itok.segm=(comfile==file_rom&&modelmem==TINY?CS:DS); + itok.flag=flag; +// itok.post=dynamic; + itok.size=elements*ssize; + itok.rm=(am32==FALSE?rm_d16:rm_d32); + itok.npointr=(unsigned short)npointr; + + varrec=addtotree(var_name); + if((count=FindOff((unsigned char *)var_name,DS))==0){ + if(dynamic_flag)dynamic=DYNAMIC_VAR; + } + else if(dynamic_flag)dynamic=USED_DIN_VAR; + if(i!=tk_assign){ + if(elements==0)ZeroMassiv(); + else if(notpost==TRUE){ + for(loop=0;looprecsize=loop; + datasize+=loop; + } + tok=i; + break; + } + if(dynamic){ + varrec->sbuf=dynamic_var(); + varrec->recpost=dynamic; + } + else{ + loop=initglobalvar(type,elements,ssize,typev); + varrec->recsize=loop; + datasize+=loop; + } + varrec->count=count; + } + else{ + if(elements==0){ + ZeroMassiv(); + break; + } + if(CheckUseAsUndef((unsigned char *)var_name)==0&&dynamic_flag)dynamic=TRUE; + switch(tok){ // + default: expected(';'); + case tk_semicolon: done=1;// ; + case tk_camma: //, post global type + itok.type=tp_postvar;//11.07.05 21:57 tp_ucnovn; + SetNewTok(type,typev); + if((flag&f_extern)==0&&useStartup==TRUE&&dynamic==0){ + if(SaveStartUp(ssize*elements,var_name)!=FALSE){ + nexttok(); + break; + } + } + if((flag&f_extern)==0&&alignword&&dynamic==0){ // + if(ssize==2){ + if(postsize%2==1)postsize++; + } + else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4); + } + count=FindOff((unsigned char *)var_name,VARPOST); + itok.post=dynamic+1; + itok.segm=DS; + loop=elements*ssize; + itok.number=(flag&f_extern)==0?postsize:externnum++; + itok.flag=flag; + itok.size=loop; + itok.rm=(am32==FALSE?rm_d16:rm_d32); + itok.npointr=(unsigned short)npointr; + varrec=addtotree(var_name); + varrec->count=count; + if((flag&f_extern)==0)AddPostData(loop); + nexttok(); + break; + } + } + break; + case tk_undefproc: + if(tok2==tk_openbracket||nnpointr){ + if(npointr)type=am32==FALSE?tk_word:tk_dword; + declare_procedure(flag,type,nnpointr); + break; + } + case tk_proc: + case tk_floatvar: + case tk_dwordvar: + case tk_longvar: + case tk_charvar: + case tk_intvar: + case tk_bytevar: + case tk_pointer: + case tk_wordvar: idalreadydefined(); nexttok(); break; + default: expected(';'); + case tk_semicolon: done=1; + case tk_camma: nexttok(); break; + } + npointr=0; + } + dopoststrings(); +} + +void SetNewTok(int type,int typev) +{ + switch(typev){ + case variable: + if(type>=tk_char&&type<=tk_double)tok=type+(tk_charvar-tk_char); + break; + case pointer: +// if(type>=tk_void&&type<=tk_float){ + tok=tk_pointer; + itok.type=(unsigned short)type; +// } + break; + } +} + +int SaveStartUp(int size,char *var_name) +{ +int i=0; + if((startStartup+size)<=endStartup){ + if(alignword){ // + if(size==2){ + if(startStartup%2==1)i=1; + } + else if(size==4&&startStartup%4!=0)i=4-(startStartup%4); + } + if((startStartup+size+i)<=endStartup){ + startStartup+=i; + itok.number=startStartup; + itok.segm=DS; + itok.flag=0; + itok.post=0; + itok.rm=(am32==FALSE?rm_d16:rm_d32); + itok.type=tp_ucnovn; + addtotree(var_name); + startStartup+=size; + return TRUE; + } + } + return FALSE; +} + +/* ======= ======== */ + +void setuprm() +{ + itok.rm=returntype=(itok.rm==tokens?am32==FALSE?tk_word:tk_dword:itok.rm); + if(itok.npointr)itok.rm=returntype=(am32==FALSE?tk_word:tk_dword); +} + +void eaxToFloat(int reg=AX) +{ +int next=1; + CheckMinusNum(); + if(itok2.type==tp_opperand){ // + doeaxfloatmath(tk_reg32,reg); + next=0; + } + else{ + switch(tok){ + case tk_number: + if(itok.rm==tk_double)itok.fnumber=itok.dnumber; + else if(itok.rm!=tk_float){ + float temp=itok.number; + *(float *)&itok.number=temp; + } + op66(r32); + op(0xb8+reg); // MOV EAX,# + outdword(itok.number); + break; + case tk_floatvar: + if(reg==AX&&itok.rm==rm_d16&&itok.sib==CODE16){ + op66(r32); + outseg(&itok,1); + op(0xA1); + outword((unsigned int)itok.number); + } + else{ + CheckAllMassiv(bufrm,4,&strinf); + op66(r32); + outseg(&itok,2); + op(0x8B); + op(itok.rm+reg*8); + outaddress(&itok); + } + break; + default: + if(doeaxfloatmath(tk_reg32,reg)!=tk_reg32&®!=AX){ + if(!am32)Leave(); + op66(r32); + op(0x89); + op(0xc0+reg); + } + next=0; + } + } + if(next)nexttok(); +} + +void CalcRegPar(int reg,int def,char **ofsstr) +{ +char signflag=0; +int razr; +unsigned char oinline=useinline; + useinline=0; +// if(*ofsstr)puts(*ofsstr); + if(tok!=tk_camma){ + if(tok==tk_openbracket){ + nexttok(); + if(tok>=tk_char&&tok<=tk_double)def=tok; + nexttok(); + expectingoperand(tk_closebracket); + } + if(tok>=tk_char&&tok<=tk_double){ + def=tok; + getoperand(); + } + if(tok==tk_string){ + op(0xB8+reg); + if(am32==FALSE)outword(addpoststring()); + else outdword(addpoststring()); + nexttok(); + razr=(am32==FALSE?r16:r32); + } + else if(tok==tk_floatvar)eaxToFloat(reg); + else{ + switch(def){ + case tk_int: signflag=1; + case tk_word: + if(reg==AX)do_e_axmath(signflag,r16,ofsstr); + else getintoreg(reg,r16,signflag,ofsstr); + razr=r16; + break; + case tk_char: signflag=1; + case tk_byte: + if(reg==AX)doalmath(signflag,ofsstr); + else{ + getintobeg(reg,ofsstr); + dobegmath(reg); + } + razr=r8; + break; + case tk_long: signflag=1; + case tk_dword: + if(reg==AX)do_e_axmath(signflag,r32,ofsstr); + else getintoreg(reg,r32,signflag,ofsstr); + razr=r32; + break; + case tk_float: + eaxToFloat(reg); + razr=r32; + break; + case tk_qword: + getintoreg64(reg); + doregmath64(reg); + razr=r64; + break; + case tokens: + razr=(am32==FALSE?r16:r32); + if(reg==AX)do_e_axmath(0,razr,ofsstr); + else getintoreg(reg,razr,signflag,ofsstr); + break; + } + } + AddRegistr(razr,reg); +// printf("%08X\n",reg); + } + useinline=oinline; +} + +int GetTypeParam(char c) +{ + switch(c){ + case 'B': return tk_byte; + case 'W': return tk_word; + case 'D': return tk_dword; + case 'C': return tk_char; + case 'I': return tk_int; + case 'L': return tk_long; + case 'F': return tk_float; + case 'A': return tk_multipoint; + case 'Q': return tk_qword; + case 'E': return tk_double; + case 'S': return tk_fpust; + case 'T': return tk_struct; + case 'U': return tokens; + default: + extraparam(); +// printf("%c\n",c); + return 0; + } +} + +void doregparams() +{ +int i=0; +char *ofsstr=NULL; +int razr; +int retreg; + ClearRegister(); + if(tok!=tk_openbracket)expected('('); + while(tok2==tk_camma){ + nexttok(); + i++; + } + ofsstr=GetLecsem(tk_camma,tk_closebracket); + getoperand(); + if(tok!=tk_closebracket){ + if(strlen(param)!=0){ + int def; + char *oparam=BackString(param); + for(;;){ + while(tok==tk_camma){ + if(ofsstr)free(ofsstr); + ofsstr=GetLecsem(tk_camma,tk_closebracket); + getoperand(); + } + if((def=GetTypeParam(oparam[i++]))==0){ + nexttok(); + break; + } + if(def==tk_qword){ + int c1,c2; + c1=oparam[i++]-0x30; + c2=oparam[i++]-0x30; + retreg=c1|(c2*256); +// printf("%08X\n",retreg); + } + else retreg=oparam[i++]-0x30; + if(ofsstr){ + if((razr=getrazr(def))!=r64){ + int retr; + if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){ + GetEndLex(tk_camma,tk_closebracket); + if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr); + nexttok(); + goto endparam; + } + } + } + if(def==tk_fpust)float2stack(retreg); + else CalcRegPar(retreg,def,&ofsstr); +endparam: + if(ofsstr&&razr!=r64){ + IDZToReg(ofsstr,retreg,razr); + free(ofsstr); + ofsstr=NULL; + } + if(tok!=tk_camma){ + if(tok!=tk_closebracket)expected(')'); + if(oparam[i]!=0)missingpar(); + break; + } + } + free(oparam); + } + else{ +char regpar[6]={AX,BX,CX,DX,DI,SI}; + for(;i<6;i++){ + if(tok==tk_camma){ + if(ofsstr)free(ofsstr); + ofsstr=GetLecsem(tk_camma,tk_closebracket); + getoperand(); + if(tok==tk_camma)continue; + } + retreg=regpar[i]; + if(ofsstr&&tok!=tk_camma){ + razr=(am32==FALSE?r16:r32); + int retr; + if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){ + GetEndLex(tk_camma,tk_closebracket); + if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr); + nexttok(); + goto endparam1; + } + } + CalcRegPar(retreg,tokens,&ofsstr); +endparam1: + if(ofsstr){ + IDZToReg(ofsstr,retreg,razr); + free(ofsstr); + ofsstr=NULL; + } + if(tok!=tk_camma){ + if(tok!=tk_closebracket)expected(')'); + break; + } + } + } + setzeroflag=FALSE; + } + if(ofsstr)free(ofsstr); +} + +int CheckUses() +{ +int i; +int regs=0; +int bracket=FALSE; + memset((SAVEREG *)psavereg,0,sizeof(SAVEREG)); + if(tok==tk_openbracket){ + if(stricmp(itok2.name,"uses")==0){ + bracket=TRUE; + nexttok(); + } + else return 0; + } + if(stricmp(itok.name,"uses")==0){ + nexttok(); + while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){ + i=r32; + switch(tok){ + case tk_beg: + if(itok.number>3)itok.number-=4; + i=(am32+1)*2; + break; + case tk_reg: + if(!am32)i=r16; + break; + } + regs=regs|(1<reg[itok.number]=i; + i=1; + if((am32&&i==r16)||(am32==0&&i==r32))i=2; + psavereg->size+=i; + nexttok(); + if(tok==tk_camma)nexttok(); + } + if(strcmp(itok.name,"allregs")==0){ + psavereg->size=1; + psavereg->all=1; + regs=dEAX|dEBX|dECX|dEDX|dEBP|dEDI|dESI; + nexttok(); + } + } + if(bracket)expecting(tk_closebracket); + return regs; +} + +void Enter() +{ + if(ESPloc==FALSE||am32==FALSE){ + op(0x55); //push bp + outword(0xe589);//mov bp,sp + } +} + +void setproc(int defflag) +{ +char *bstring; +unsigned char oinline,ooptimizespeed; +ITOK otok; +unsigned int i; +int regs=0; +unsigned char oESPloc=ESPloc; +int startline=linenumber; +unsigned int oregidx; + + clearregstat(); + addESP=inlineflag=0; + oinline=useinline; + ooptimizespeed=optimizespeed; + oregidx=*(unsigned int *)&idxregs; + current_proc_type=itok.flag; + + if(itok.flag&f_extern)notexternfun(); //new 18.04.07 12:20 +// printf("%s tok=%d flag=%08X\n",itok.name,tok,itok.flag); + + tok=lastcommand=tk_proc; + itok.number=outptr; + if(itok.segmcount=i; + } + bstring=BackString((char *)string); + otok=itok; + if(strcmp(mesmain,otok.name)==0){ + if(startuptomain==TRUE&&comfile==file_com)doprestuff(); + if(numdomain!=0){ + for(i=0;iloc=outptr+1; + callloc0(); /* produce CALL [#] */ + break; + case tk_declare: + tok=tk_undefproc; + updatetree(); + case tk_undefproc: + addacall(itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR))); + callloc0(); /* produce CALL [#] */ + break; + case tk_proc: + if(itok.flag&f_far)op(0x0e); //push cs + if(itok.segmbaza; + for(i=0;inumoper;i++){ + if((bazael+i)->tok==tk_baseclass)CallDestructor((structteg *)(bazael+i)->rec); + } + } + i=numreturn; + setreturn(); + if(inlineflag==0&&retproc==FALSE&&(i||(lastcommand!=tk_goto&&lastcommand!=tk_GOTO)))leaveproc(); + endblock(); + initBP=0; + strcpy((char *)string,bstring); + itok=otok; + tok=tk_proc; + itok.size=outptr-procedure_start; + itok.rec->recpost=regs; +// printf("reg=%08X set=%s\n",regs,itok.name); +#ifdef OPTVARCONST + if(inlineflag)itok.flag|=f_useidx; +#endif + updatetree(); + if(mapfile)mapfun(startline); + i=linenumber; + linenumber=startline; + killlocals(); + linenumber=i; + free(bstring); + optimizespeed=ooptimizespeed; + useinline=oinline; + *(unsigned int *)&idxregs=oregidx; + if(searchteg)searchteg=NULL; + blockproc=FALSE; + ESPloc=oESPloc; + nexttok(); +} + +void insertproc(/*int sizepar*/) +{ +unsigned char oinline,ooptimizespeed; +struct treelocalrec *otlr; +struct structteg *olteglist; +//struct idrec *olstructlist; +struct idrec *rec; +unsigned int oparamsize; +unsigned int olocalsize; +unsigned char oinsertmode; +unsigned int onumblocks; // +unsigned int osizestack; +RETLIST *olistreturn; +unsigned int onumreturn; +int oinlineflag; +SAVEREG *osavr; +unsigned int oaddESP=addESP; + addESP=0; + clearregstat(); + osavr=psavereg; + psavereg=(SAVEREG*)MALLOC(sizeof(SAVEREG)); + oinsertmode=insertmode; + insertmode=TRUE; // + oinline=useinline; + ooptimizespeed=optimizespeed; + current_proc_type=itok.flag; + rec=itok.rec; + otlr=tlr; + olteglist=ltegtree; +// olstructlist=lstructlist; + oinlineflag=inlineflag; + osizestack=sizestack; + sizestack=0; + tlr=NULL; + ltegtree=NULL; +// lstructlist=0; + oparamsize=paramsize; + olocalsize=localsize; + onumblocks=numblocks; + olistreturn=listreturn; + onumreturn=numreturn; + paramsize=0; + localsize=0; + numblocks=0; // + listreturn=NULL; + numreturn=0; + inlineflag=0; + nextexpecting2(tk_openbracket); + if(tok!=tk_closebracket){ + if((current_proc_type&f_typeproc)!=tp_fastcall)declareparams(); + else declareparamreg(); + } + CorrectParamVar(); + nexttok(); + if(tok==tk_inline){ + nexttok(); + inlineflag=1; + expecting(tk_openbrace); + } + else{ + if((current_proc_type&f_typeproc)!=tp_fastcall&¶msize>0)Enter(); // PUSH BP MOV BP,SP + rec->recpost|=CheckUses(); + if(tok!=tk_openbrace)declarelocals(0); + expecting(tk_openbrace); + declarelocals(1); + } + retproc=FALSE; +#ifdef OPTVARCONST + ClearLVIC(); +#endif + startblock(); + doblock2(); + sizestack=osizestack; // do proc + setreturn(); + endblock(); + RestoreSaveReg(); + if(inlineflag==0&&(localsize||paramsize)&&(ESPloc==FALSE||am32==FALSE))Leave(); + killlocals(/*0*/); + optimizespeed=ooptimizespeed; + useinline=oinline; + paramsize=oparamsize; + localsize=olocalsize; + tlr=otlr; + ltegtree=olteglist; +// lstructlist=olstructlist; + insertmode=oinsertmode; + numblocks=onumblocks; + listreturn=olistreturn; + numreturn=onumreturn; + inlineflag=oinlineflag; + free(psavereg); + psavereg=osavr; + addESP=oaddESP; +// nexttok(); +// printf("tok=%d\n",tok); +} + +void AddTypeVar(int type,int pos) +{ + switch(type){ + case tk_char: + param[pos]='C'; + break; + case tk_byte: + param[pos]='B'; + break; + case tk_int: + param[pos]='I'; + break; + case tk_word: + param[pos]='W'; + break; + case tk_long: + param[pos]='L'; + break; + case tk_dword: + param[pos]='D'; + break; + case tk_float: + param[pos]='F'; + break; + case tk_qword: + param[pos]='Q'; + break; + case tk_double: + param[pos]='E'; + break; + + } +} + +void declareparamreg() /* declare procedure parameters */ +{ +int i=0,num=1; +unsigned char j=0; + do{ + if(tok>=tk_char&&tok<=tk_double){ + AddTypeVar(tok,i++); + nexttok(); + j=1; + } + else{ + switch(tok){ + case tk_beg: + if(j==0)param[i++]='B'; + param[i++]=(char)(itok.number+0x30); + j=0; + break; + case tk_reg: + if(j==0)param[i++]='W'; + param[i++]=(char)(itok.number+0x30); + j=0; + break; + case tk_reg32: + if(j==0)param[i++]='D'; + param[i++]=(char)(itok.number+0x30); + j=0; + break; + case tk_reg64: + param[i++]='Q'; + param[i++]=(char)((itok.number&255)+0x30); + param[i++]=(char)((itok.number/256)+0x30); + j=0; + break; + case tk_fpust: + param[i++]='S'; + param[i++]=(char)(itok.number+0x30); + j=0; + break; + case tk_closebracket: + if(j==0)goto endproc; + default: edpip(num); + } + nexttok(); + if(tok==tk_camma){ + if(j!=0){ + edpip(num); + param[i++]='0'; + j=0; + } + nexttok(); + } + } + num++; + }while(tok!=tk_closebracket); +endproc: + if(j!=0){ + edpip(num-1); + param[i++]='0'; + } + param[i]=0; +} + +void AddMultiPoint(int pos) +{ + param[pos]='A'; + nexttok(); + if(tok!=tk_closebracket)SwTok(tk_closebracket); +} + +void declareparamstack() /* declare procedure parameters */ +{ +int i=0,num=1; +unsigned char j=0; +/* + 1 - + 2 - + 3 - + 4 - + 5 - + 6 - void + */ +int typevar=tk_multipoint; +structteg *tteg=NULL; +int size; + do{ + if(tok==tk_struct)nexttok(); + if(tok>=tk_char&&tok<=tk_double){ + if(j>3||j==1)edpip(num); + j=1; + typevar=tok; + nexttok(); + } + else if((tteg=FindTeg(TRUE))!=NULL){ + size=Align(tteg->size,(am32+1)*2); +// printf("%s size=%u\n",itok.name,size); + j=1; + typevar=tk_struct; + nexttok(); + } + while(tok==tk_mult){ + param[i++]='*'; + nexttok(); + } + if(tok==tk_camma){ + if(j==1){ + if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); + else AddTypeVar(typevar,i++); + } + else if(j!=5)edpip(num); + j=2; + num++; + } + else if(tok==tk_semicolon){ + if(j==1){ + if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); + else AddTypeVar(typevar,i++); + } + else if(j!=5)edpip(num); + j=3; + num++; + } + else if(tok==tk_multipoint){ + AddMultiPoint(i++); + break; + } + else if(tok==tk_closebracket){ + if(j==0)param[i++]='A'; + else if(j==1){ + if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); + else AddTypeVar(typevar,i++); + } + else if(j<4)edpip(num); + break; + } + else if(tok==tk_void){ + if(j!=0)edpip(num); + param[i++]='V'; + j=6; + } + else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){ + if(j==1){ + if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); + else AddTypeVar(typevar,i++); + } + else if(j<4){ + switch(tok){ + case tk_beg: param[i++]='B'; break; + case tk_reg: param[i++]='W'; break; + case tk_reg32: param[i++]='D'; break; + case tk_fpust: param[i++]='S'; break; + case tk_reg64: + param[i++]='Q'; + param[i++]=(char)((itok.number&255)+0x30); + itok.number/=256; + break; + } + } + else edpip(num); + param[i++]=(char)(itok.number+0x30); + j=5; + } + else{ + if(j==1||j==2){ + if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); + else AddTypeVar(typevar,i++); + } + else edpip(num); + j=5; + } + nexttok(); + }while(tok!=tk_eof); + param[i]=0; +// puts(param); +} + +void CorrectParamVar() +{ +unsigned int addnum; +int fspin; +struct localrec *ptr; + if(paramsize==0)return; + if(insertmode)addnum=0; //ret-address + else addnum=2; + if(ESPloc==FALSE||am32==FALSE)addnum+=2; //EBP + if((current_proc_type&f_far))addnum+=2;// move over seg on stack + if(am32)addnum*=2; + if((current_proc_type&f_typeproc)==tp_cdecl||(current_proc_type&f_typeproc)==tp_stdcall)fspin=FALSE; + else fspin=TRUE; +treelocalrec *ntlr=tlr; + while(ntlr&&ntlr->level>1)ntlr=ntlr->next; + for(ptr=ntlr->lrec;;ptr=ptr->rec.next){ + if(ptr->rec.type==tp_paramvar){ + if(fspin)ptr->rec.recnumber=paramsize-ptr->rec.recnumber-Align(ptr->rec.recsize,am32==FALSE?2:4); + ptr->rec.recnumber+=addnum; + } + if(ptr->rec.next==NULL)break; + } +} + +void declareparams() /* declare procedure parameters */ +{ +int paramtok,sparamtok,i=0,type; +char flag=33; +int numpointr; +localrec *lrec; +structteg *tteg=NULL,*nteg; + do{ + if(flag!=33)nexttok(); + flag=1; + if(tok==tk_multipoint){ + AddMultiPoint(i++); + break; + } + if(tok==tk_void){ + param[i++]='V'; + nexttok(); + if(tok!=tk_closebracket)SwTok(tk_closebracket); + break; + } + if(tok>=tk_char&&tok<=tk_double){ + type=tok; + SetNewTok(tok,variable); + paramtok=tok; + } + else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust)flag=3; + else{ + if(tok==tk_struct)nexttok(); + if((tteg=FindTeg(TRUE))!=NULL)paramtok=tk_struct; + else{ + datatype_expected(); + flag=0; + nexttok(); + } + } + if(flag){ + do{ + numpointr=0; + skipfind=TRUE; + if(flag!=3)nexttok(); + while(tok==tk_mult){ + nexttok(); + numpointr++; + param[i++]='*'; + } + if(tok==tk_id||tok==tk_ID){ // define + skipfind=FALSE; + int otok=tok; + searchtree(&ptok,&otok,string); + if(otok>=tk_char&&otok<=tk_double){ + tok=otok; + itok=ptok; + } + skipfind=TRUE; + } + if(tok==tk_struct){ + nexttok(); + if((tteg=FindTeg(TRUE))!=NULL){ + paramtok=tk_struct; + nexttok(); + } + else{ + edpip(); + nexttok(); + goto endparam1; + } + } + else { + if((nteg=FindTeg(TRUE))!=NULL){ + tteg=nteg; + paramtok=tk_struct; + nexttok(); + } + else{ + if(tok>=tk_char&&tok<=tk_double){ + type=tok; + SetNewTok(tok,variable); + paramtok=tok; + nexttok(); + while(tok==tk_mult){ + nexttok(); + numpointr++; + param[i++]='*'; + } + flag=2; + } + skipfind=FALSE; + if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){ + if(flag==2)AddTypeVar(type,i++); + else{ + switch(tok){ + case tk_beg: param[i++]='B'; break; + case tk_reg: param[i++]='W'; break; + case tk_reg32: param[i++]='D'; break; + case tk_fpust: param[i++]='S'; break; + case tk_reg64: + param[i++]='Q'; + param[i++]=(char)((itok.number&255)+0x30); + itok.number/=256; + break; + } + } + param[i++]=(unsigned char)(itok.number+0x30); + flag=1; + goto endparam1; + } + } + } + sparamtok=paramtok; + if(tok==tk_multipoint){ + AddMultiPoint(i++); + break; + } + if(tok!=tk_ID&&tok!=tk_id){ + idalreadydefined(); + break; + } + int lsize; + if(am32)lsize=4; + else{ + lsize=2; + if(sparamtok>=tk_longvar&&sparamtok<=tk_floatvar&&numpointr==0) + lsize+=2;//add 2 more bytes + } + if((sparamtok==tk_qwordvar||sparamtok==tk_doublevar)&&numpointr==0)lsize=8; + AddTypeVar(type,i++); + if(sparamtok==tk_struct){ +//idrec *newrec,*trec; + lsize=Align(tteg->size,(am32+1)*2); + i+=sprintf(¶m[i],"T%u",lsize); +// newrec=(struct idrec *)MALLOC(sizeof(struct idrec)); +// if(lstructlist==NULL)lstructlist=newrec; +// else{ +// trec=lstructlist; +// while(trec->left!=NULL)trec=trec->left; +// trec->left=newrec; +// } +// newrec->right=newrec->left=NULL; + lrec=addlocalvar(itok.name,tk_structvar,paramsize); + lrec->rec.newid=(char *)tteg; + lrec->rec.flag=tteg->flag; + lrec->rec.recrm=1; + lrec->rec.recpost=LOCAL; + goto endparam; + } + lrec=addlocalvar(itok.name,sparamtok,paramsize); + lrec->rec.npointr=(unsigned short)numpointr; +endparam: + lrec->rec.type=tp_paramvar; + lrec->rec.recsize=lsize; + paramsize+=lsize; +endparam1: + nexttok(); + }while(tok==tk_camma); + } + }while(tok==tk_semicolon); + param[i]=0; +// puts(param); +} + +void CharToBackBuf(char c) +{ + if(SizeBackBuf==0){ + MaxSizeBackBuf=STRLEN; + BackTextBlock=(char *)MALLOC(STRLEN); + } + else if(SizeBackBuf==MaxSizeBackBuf){ + MaxSizeBackBuf+=STRLEN; + BackTextBlock=(char *)REALLOC(BackTextBlock,MaxSizeBackBuf); + } + BackTextBlock[SizeBackBuf++]=c; +} + +void AddBackBuf(int oinptr,char ocha) +// +{ +int numblock=0; +unsigned char save; +char bcha; + inptr=oinptr; + cha=ocha; + for(;;){ + save=TRUE; + switch(cha){ + case '(': + case '{': + case '[': + numblock++; + break; + case ')': + case '}': + case ']': + numblock--; + if(numblock<0)return; + break; + case ',': + if(numblock>0)break; + tok=tk_camma; + goto endp; + case ';': + case 26: + tok=tk_semicolon; +endp: + CharToBackBuf(';'); + nextchar(); + inptr2=inptr; + cha2=cha; + return; + case '/': // + nextchar(); + if(cha=='*'){ + do{ + nextchar(); + if(cha=='*'){ + nextchar(); + if(cha=='/'){ + save=FALSE; + break; + } + } + }while(cha!=26); + } + else if(cha=='/'){ + do{ + nextchar(); + }while(cha!=13&&cha!=26); + } + else CharToBackBuf('/'); + break; + case '"': + case '\'': + bcha=cha; + do{ + CharToBackBuf(cha); + nextchar(); + if(cha=='\\'){ + CharToBackBuf(cha); + nextchar(); + CharToBackBuf(cha); + nextchar(); + } + }while(cha!=bcha); + break; + } + if(save)CharToBackBuf(cha); + nextchar(); + } +} + +void RunBackText() +{ +ITOK oitok,ostructadr; +SINFO ostr; +unsigned char *oldinput; +unsigned int oldinptr,oldendinptr; +unsigned char bcha; +int otok,otok2; +char *ostartline; +char *ostring,*obufrm; +COM_MOD *ocurmod; + ostring=BackString((char *)string); + oldinput=input; // + oldinptr=inptr2; + ostructadr=structadr; + bcha=cha2; + oldendinptr=endinptr; + otok=tok; + otok2=tok2; + oitok=itok; + ostr=strinf; + strinf.bufstr=NULL; + obufrm=bufrm; + bufrm=NULL; + + ocurmod=cur_mod; + cur_mod=NULL; + + input=(unsigned char *)BackTextBlock; + inptr2=1; + cha2=input[0]; + tok=tk_openbrace; + SizeBackBuf=0; + ostartline=startline; + startline=(char*)input; + endinptr=strlen((char *)input); + endinput=startline+endinptr; + + doblock(); + + endoffile=0; + startline=ostartline; + strinf=ostr; + free(input); + input=oldinput; + inptr2=oldinptr; + cha2=bcha; + endinptr=oldendinptr; + tok=otok; + itok=oitok; + if(bufrm)free(bufrm); + bufrm=obufrm; + tok2=otok2; + strcpy((char *)string,ostring); + if(strinf.bufstr)free(strinf.bufstr); + structadr=ostructadr; + free(ostring); + + cur_mod=ocurmod; +} + +int PushLocInit(int ofs) +{ +ITOK oitok,ostructadr,wtok; +SINFO ostr; +unsigned char *oldinput; +unsigned int oldinptr,oldendinptr; +unsigned char bcha; +int otok,otok2; +char *ostartline; +char *ostring,*obufrm; +int retcode=FALSE; +// if(bufrm)puts(bufrm); + ostring=BackString((char *)string); + oldinput=input; // + oldinptr=inptr2; + ostructadr=structadr; + bcha=cha2; + oldendinptr=endinptr; + otok=tok; + otok2=tok2; + oitok=itok; + ostr=strinf; + strinf.bufstr=NULL; + obufrm=bufrm; + bufrm=NULL; + input=(unsigned char *)BackTextBlock; + inptr2=ofs; + ostartline=startline; + cha2=input[inptr2++]; + endinptr=strlen((char *)input); + startline=(char *)input+ofs; + endinput=startline+endinptr; + nexttok(); + wtok=itok; + nexttok(); + nexttok(); + if((retcode=Push(&wtok))!=FALSE){ + retcode=TRUE; + for(inptr2=ofs;;inptr2++){ + cha2=input[inptr2]; + input[inptr2]=' '; + if(cha2==';'||cha2==0)break; + } + } + endoffile=0; + startline=ostartline; + strinf=ostr; + input=oldinput; + inptr2=oldinptr; + cha2=bcha; + endinptr=oldendinptr; + tok=otok; + itok=oitok; + if(bufrm)free(bufrm); + bufrm=obufrm; + tok2=otok2; + strcpy((char *)string,ostring); + if(strinf.bufstr)free(strinf.bufstr); + structadr=ostructadr; + free(ostring); + return retcode; +} + +int pushinit(int localline,unsigned int ofs) +{ +int oline=linenumber; +COM_MOD *bcur_mod; +int retcode; + linenum2=localline; + bcur_mod=cur_mod; + cur_mod=NULL; + retcode=PushLocInit(ofs); + cur_mod=bcur_mod; + linenumber=linenum2=oline; + return retcode; +} + +int PossiblePush() +{ +int retcode=FALSE; + nexttok(); + switch(tok){ + case tk_dwordvar: + case tk_longvar: + case tk_reg32: + if(am32==FALSE)break; + case tk_postnumber: + case tk_string: + case tk_intvar: + case tk_wordvar: + case tk_reg: + if(tok2==tk_semicolon||tok2==tk_camma)retcode=TRUE; + break; + case tk_undefofs: + tok=tk_number; + goto chnum; + case tk_minus: + if(tok2!=tk_number)break; + nexttok(); + case tk_number: +chnum: + doconstlongmath(); + if(tok==tk_semicolon||tok==tk_camma)retcode=TRUE; + break; + } + +//// New 20.07.07 22:01 + if(bufrm){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } +//////////////////////////// + + return retcode; +} + +#define MAXLOCVAR 128 + +void declarelocals(int mode,int finline) /* declare locals */ +/*-----------------01.06.02 15:12------------------- +mode = 0 if local vars prior { +mode = 1 if local vars after { +--------------------------------------------------*/ +{ +unsigned int size,ssize,localtok; +int binptr; +int flag=0; +char bcha; +int slocaltok; +int numpointr,type; +unsigned int loop; +static int localline; +static int numinit; +static int maxlocvar; +static LILV *lilv=NULL; +static int headerinit; + if(localsize==0)localline=0; + if(lilv==NULL){ + numinit=0; + lilv=(LILV *)MALLOC(sizeof(LILV)*MAXLOCVAR); + maxlocvar=MAXLOCVAR; + if(paramsize&&(!finline))headerinit=TRUE; + else headerinit=FALSE; + } + dynamic_flag=0; + do{ + while(tok==tk_semicolon)nexttok(); + if(tok==tk_static){ + flag|=f_static; + nexttok(); + } + size=0; + switch(tok){ + case tk_union: + loop=dounion(0,flag); + goto locstruct; + case tk_struct: + loop=LocalStruct(flag,&localline); +locstruct: + (lilv+numinit)->size=-loop; + break; + case tk_int: localtok=tk_intvar; size=2; break; + case tk_word: localtok=tk_wordvar; size=2; break; + case tk_char: localtok=tk_charvar; size=1; break; + case tk_byte: localtok=tk_bytevar; size=1; break; + case tk_long: localtok=tk_longvar; size=4; break; + case tk_dword: localtok=tk_dwordvar; size=4; break; + case tk_float: localtok=tk_floatvar; size=4; break; + case tk_qword: localtok=tk_qwordvar; size=8; break; + case tk_double: localtok=tk_doublevar; size=8; break; + default: + if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_pointer||tok==tk_proc + ||tok==tk_declare||tok==tk_undefproc||tok==tk_structvar|| + (FindTeg(FALSE)==NULL&&FindTeg(TRUE)==NULL)){ + if(mode==0){ + (lilv+numinit)->size=0; + datatype_expected(); + nexttok(); + } + else{ + if(localsize){ + if(!finline){ + numpointr=0; + if(SizeBackBuf){ + BackTextBlock[SizeBackBuf]=0; + for(type=numinit-1,numpointr=0;type>=0;type--){// . + if((lilv+type)->size<=0)break; + numpointr+=(lilv+type)->size; + } + type++; // + ssize=type; + } + size=localsize; + if(lilv->size<=0&&optimizespeed==0&&chip>1){ + size-=numpointr; + if(headerinit)outptr-=3; /* remove PUSH BP and MOV BP,SP */ + op(0xC8); /* ENTER */ + outword(size); /* # of locals */ + op(0x00); /* level = 0 */ + flag=0; + type=0; + headerinit=TRUE; + size=numpointr; + } + else{ + if(headerinit==FALSE){ + Enter(); + headerinit=TRUE; + } + flag=1; + } + if(SizeBackBuf){ + if(lilv->size>0){ // + for(loop=0;loopsize,BackTextBlock); + if((lilv+loop)->size<=0)break; + if(pushinit(localline,(lilv+loop)->ofs)==FALSE)break; + (lilv+loop)->rec->fuse|=INITVAR; + size-=Align((lilv+loop)->size,(am32==FALSE?2:4)); + type--; + } + } + if(size){ + binptr=size-numpointr; + if(binptr){ + if(!optimizespeed&&type<3&&(type*(am32+1)*2)>=binptr)for(;type!=0;type--)op(0x50+ECX); + else{ + if(binptr<128){ + outword(0xEC83); + op(binptr); + } + else{ + outword(0xEC81); + if(am32==FALSE)outword(binptr); + else outdword((unsigned long)binptr); + } + } + } + if(numpointr){ + for(;ssizesize,BackTextBlock); + if(pushinit(localline,(lilv+ssize)->ofs)==FALSE)break; + (lilv+ssize)->rec->fuse|=INITVAR; + } + } + } + } + else if(flag){ + if(localsize<128){ + outword(0xEC83); + op(localsize); + } + else{ + outword(0xEC81); + if(am32==FALSE)outword(localsize); + else outdword((unsigned long)localsize); + } + } + } + else{ //finline + if(SizeBackBuf!=0){ + free(BackTextBlock); + SizeBackBuf=0; + } + } + } + if(psavereg->size){ + if(psavereg->all){ + op(0x60); + addESP+=am32==FALSE?16:32; + } + else{ + for(int i=0;i<8;i++){ + if(psavereg->reg[i]){ + op66(psavereg->reg[i]); + op(0x50+i); + addESP+=am32==FALSE?2:4; + + } + } + } + if(ESPloc&&am32&&(itok.type==tp_localvar||itok.type==tp_paramvar))itok.number+=addESP; + } +// printf("numinit=%d firstinit=%d\n%s\n",numinit,firstinit,BackTextBlock); + if(SizeBackBuf!=0){ + CharToBackBuf('}'); + CharToBackBuf(0); + int oline=linenumber; + linenum2=localline; + COM_MOD *bcur_mod; + bcur_mod=cur_mod; + cur_mod=NULL; + RunBackText(); + cur_mod=bcur_mod; + linenumber=linenum2=oline; + } + if(lilv){ + free(lilv); + lilv=NULL; + } + return; + } + } + else{ + loop=LocalStruct(flag,&localline); + (lilv+numinit)->size=-loop; + } + break; + } + if(size!=0){ + do{ + binptr=inptr2; + bcha=cha2; + skipfind=TRUE; // + nexttok(); + if(tok==tk_static){ + flag|=f_static; + binptr=inptr2; + bcha=cha2; + nexttok(); + } + slocaltok=localtok; + ssize=size; + numpointr=0; + type=tp_localvar; + while(tok==tk_mult){ + binptr=inptr2; + bcha=cha2; + nexttok(); + numpointr++; + } + if(tok!=tk_ID&&tok!=tk_id)idalreadydefined(); + else{ + long numcopyvar; + numcopyvar=1; + localrec *lrec=addlocalvar(itok.name,slocaltok,(flag&f_static)==0?localsize:postsize); + loop=ssize; + if(numpointr)loop=am32==TRUE?4:2; + skipfind=FALSE; // + if(tok2==tk_openblock){//[ + nexttok(); + nexttok(); + CheckMinusNum(); + if(tok!=tk_number){ + numexpected(); + nexttok(); + } + else numcopyvar=doconstlongmath(); + loop=numcopyvar*ssize; + if(tok!=tk_closeblock)expected(']'); + } + lrec->rec.recsize=loop; + if(!mode){ + nexttok(); + } + if(flag&f_static){ + if(tok==tk_assign||(mode&&tok2==tk_assign)){ + if(mode)nexttok(); + if(numpointr){ + type=tk_char+slocaltok-tk_charvar; + slocaltok=tk_pointer; + } + lrec->rec.rectok=slocaltok; + lrec->rec.recnumber=0; + lrec->rec.recpost=DYNAMIC_VAR; + lrec->rec.line=linenumber; + lrec->rec.file=currentfileinfo; + lrec->rec.count=0; +// lptr->rec.type=(unsigned short)type; + lrec->rec.npointr=(unsigned short)numpointr; + lrec->rec.sbuf=dynamic_var(); + lrec->rec.recsib=type; + lrec->rec.type=tp_gvar; + +// if(strcmp(lrec->rec.recid,"nnil")==0)crec=&lrec->rec; + + } + else{ + lrec->rec.type=tp_postvar; + AddPostData(loop); + if(mode)nexttok(); + } + } + else{ + lrec->rec.type=tp_localvar; + lrec->rec.npointr=(unsigned short)numpointr; + localsize+=loop; + if(mode)nexttok(); + (lilv+numinit)->size=-loop; + if(tok==tk_assign){ + if(localline==0)localline=linenumber; + if(numcopyvar!=1){ + int i=binptr; + while(input[i]!='[')i++; + i++; + input[i]='0'; + i++; + for ( int j=1;j!=0;i++){ + switch(input[i]){ + case '[': + j++; + break; + case ']': + j--; + break; + } + if(j!=0)input[i]= ' '; + } + } + else{ + switch(slocaltok){ + case tk_floatvar: + case tk_doublevar: + case tk_qwordvar: +// (lilv+numinit)->ofs=-1; + break; + default: + if(PossiblePush()){ + (lilv+numinit)->size=loop; + (lilv+numinit)->rec=lrec; + } + break; + } + } + (lilv+numinit)->ofs=SizeBackBuf; + AddBackBuf(binptr,bcha); +// if(bufrm)puts(bufrm); + } + numinit++; + if(numinit==maxlocvar){ + maxlocvar+=MAXLOCVAR; + lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV)); + } + lrec->rec.recnumber=-lrec->rec.recnumber-Align(loop,(am32==FALSE?2:4)); + } + } + if(localsize)localsize=Align(localsize,(am32==FALSE?2:4)); + }while(tok==tk_camma); + seminext(); + } + else{ + numinit++; + if(numinit==maxlocvar){ + maxlocvar+=MAXLOCVAR; + lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV)); + } + } + flag=0; +// printf("tok=%d %s\n",tok,BackTextBlock); + }while(tok!=tk_openbrace&&tok!=tk_eof); +} + +int CheckDeclareProc() +{ +unsigned int i=inptr2-1; + while(input[i]!='('){ + i++; + if(i>=endinptr){ + unexpectedeof(); + break; + } + } +lab1: + i++; + for(int j=1;j!=0;i++){ + char c=input[i]; + if(c=='(')j++; + else if(c==')')j--; + if(i>=endinptr){ + unexpectedeof(); + break; + } + } + for(;;i++){ + if(input[i]=='(')goto lab1; + if(input[i]>' ')break; + if(i>=endinptr){ + unexpectedeof(); + break; + } + } + + for(;;i++){ + if(input[i]==';'||input[i]==',')return TRUE; // + if(input[i]>' ')break; + if(i>=endinptr){ + unexpectedeof(); + break; + } + } + return FALSE; +} + +void IsUses(idrec *rec) +{ +int i; + if(tok==tk_openbracket&&stricmp(itok2.name,"uses")==0){ + nexttok(); + i=0; + nexttok(); + while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){ + if(tok==tk_beg&&itok.number>3)itok.number-=4; + i=i|(1<recpost=0xFF^i; + expecting(tk_closebracket); + } +} + +void declare_procedure(int oflag,int orm,int npointr) +{ +int i,next=TRUE,j; +char pname[IDLENGTH]; +idrec *rec; + strcpy(pname,itok.name); + param[0]=0; + nexttok(); + if(npointr)expecting(tk_closebracket); + expecting(tk_openbracket); + if((oflag&f_typeproc)==tp_fastcall)declareparamreg(); + else declareparamstack(); + if(tok2==tk_assign)nexttok(); + itok.post=1; + if(npointr){ + itok.segm=DS; + itok.type=tk_proc; + itok.sib=am32==FALSE?rm_d16:rm_d32; + i=2; + if(am32||(oflag&f_far))i=4; + if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){ //= + if((oflag&f_extern))preerror("extern variable do not initialize at declare"); + if(alignword&&(!dynamic_flag))alignersize+=AlignCD(DS,i); + FindOff((unsigned char *)pname,DS); + itok.number=outptrdata; + if(tok!=tk_assign){ + if(dbg&2)AddDataLine(i); + outword(0); + if(i==4)outword(0); + } + else{ + ITOK oitok; + oitok=itok; + initglobalvar(tk_word,1,i,variable); + itok=oitok; + next=FALSE; + } + itok.post=0; + datasize+=i; + } + else{ + if((oflag&f_extern)==0){ + itok.number=postsize; + AddPostData(i); + } + else itok.number=externnum++; + } + j=tok; + tok=tk_pointer; + } + else{ + tok=tk_declare; + itok.type=tp_declare; + itok.number=(oflag&f_extern)!=0?externnum++:secondcallnum++; + itok.segm=NOT_DYNAMIC; + itok.post=0; + } + itok.npointr=(unsigned short)npointr; + itok.rm=orm; + itok.flag=oflag; + if(itok.rm==tokens)itok.rm=(am32==0?tk_word:tk_dword); +// printf("rm=%d %s\n",itok.rm,itok.name); + strcpy((char *)string,param); + rec=addtotree(pname); + if(next)nexttok(); + else tok=j; + IsUses(rec); +} + +void define_procedure() +{ + if(dynamic_flag)dynamic_proc(); + else{ + itok.segm=NOT_DYNAMIC; + if(AlignProc!=FALSE)AlignCD(CS,alignproc); + procedure_start=outptr; + if(dbg)AddLine(); +// itok.flag&=~f_static; 26.08.05 00:09 + setproc((tok==tk_id||tok==tk_ID)?0:1); + dopoststrings(); + } +} + +void interruptproc() +{ +char *bstring; +ITOK otok; + inlineflag=0; + procedure_start=outptr; + returntype=tk_void; + current_proc_type=f_interrupt; + localsize=paramsize=0; + nexttok(); +// FindOff((unsigned char *)itok.name,CS); + itok.number=outptr; + itok.segm=NOT_DYNAMIC; + itok.post=0; + itok.rm=tk_void; + itok.flag=0; + if(tok==tk_ID||tok==tk_id){ + tok=tk_interruptproc; + itok.type=tp_ucnovn; + addtotree((char *)string); + } + else if(tok==tk_undefproc){ + tok=tk_interruptproc; + long hold=updatetree(); + updatecall((unsigned int)hold,(unsigned int)outptr,0); + } + else idalreadydefined(); + itok.rec->count=FindOff((unsigned char *)itok.name,CS); + bstring=BackString((char *)string); + otok=itok; + nextexpecting2(tk_openbracket); + expecting(tk_closebracket); + if(tok==tk_inline){ + inlineflag=1; + nexttok(); + } + else if(tok!=tk_openbrace)declarelocals(0); + expecting(tk_openbrace); + declarelocals(1); + startblock(); + doblock2(); /* do proc */ + endblock(); + if(retproc==FALSE){ + if(inlineflag==0)leaveproc(); + else if(localsize>0)Leave(); + } + initBP=0; + strcpy((char *)string,bstring); + itok=otok; + tok=tk_interruptproc; + itok.size=outptr-procedure_start; + updatetree(); + free(bstring); + killlocals(); + nexttok(); + dopoststrings(); +} + +int skipstring(int pos,unsigned char term) +{ +unsigned char c; + do{ + pos++; + c=input[pos]; + if(c==0x5C){ + pos++; + continue; +// c=input[pos+1]; + } + }while(c!=term); + return pos; +} + +int skipcomment(int pos) +{ + if(input[pos+1]=='*'){ + pos+=2; + for(;;pos++){ + if(input[pos]==13){ + linenumber++; + } + else if(input[pos]=='*'){ + pos++; + if(input[pos]=='/')break; + } + if((unsigned int)pos>=endinptr){ + unexpectedeof(); + break; + } + } + } + else if(input[pos+1]=='/'){ + pos+=2; + for(;;pos++){ + if(input[pos]==13){ + linenumber++; + break; + } + if(input[pos]==10)break; + } + } + return pos; +} + +int swapparam() +{ +int i,ns,j,lastofs; +int linep,linebak; +char c,ochar; +unsigned char *bufpar; +int numpar=0; +unsigned char *oldinput; +paraminfo *pi; + if(tok!=tk_openbracket){ + expected('('); + do{ + nexttok(); + }while(tok2!=tk_semicolon&&tok!=tk_eof); + return 0; + } + pi=(paraminfo *)MALLOC(128*sizeof(paraminfo)); + do{ + inptr2--; + }while(input[inptr2]!='('); + inptr2++; + pi->ofspar=inptr2; + pi->type[0]=0; + linep=linenumber; + for(i=inptr2,ns=1;ns>0;i++){ // + switch(input[i]){ + case '(': ns++; break; + case ')': ns--; break; + case ',': + if(ns==1){ + if(numpar==127)preerror("To many parametrs in function"); + numpar++; + (pi+numpar)->ofspar=i+1; + (pi+numpar)->type[0]=0; + } + break; + case '/': + i=skipcomment(i); + break; + case '"': + case 0x27: + i=skipstring(i,input[i]); + break; + case 13: + linenumber++; + break; + } + if((unsigned int)i>=endinptr){ + unexpectedeof(); + break; + } + } + for(j=0,ns=0;param[j]!=0;j++,ns++){// + lastofs=0; + ochar=c=param[j]; + (pi+ns)->type[0]=c; + while(c=='*'){ + j++; + ochar=c=param[j]; + (pi+ns)->type[++lastofs]=c; + } + if(c=='A'){ + if(ns){ + while(ns<=numpar){ + (pi+ns)->type[0]='U'; + (pi+ns)->type[1]=0; + ns++; + } + break; + } + } + if(ochar=='T'){ + do{ + j++; + lastofs++; + c=param[j]; + (pi+ns)->type[lastofs]=c; + }while(isdigit(c)); + (pi+ns)->type[lastofs]=0; + j--; + continue; + } + c=param[j+1]; + if(c>='0'&&c<='7'){ + (pi+ns)->type[1]=c; + j++; + lastofs++; + if(ochar=='Q'){ + (pi+ns)->type[2]=param[j+1]; + j++; + lastofs++; + } + } + (pi+ns)->type[++lastofs]=0; + } + ns--; + for(j=0;ns>=0;ns--){ + lastofs=0; + c=(pi+ns)->type[lastofs++]; + while(c!=0){ + param[j++]=c; + c=(pi+ns)->type[lastofs++]; + } + } + param[j]=0; +// puts(param); +// if(crec)printf("start0 swapparams num=%08X\n",crec->recnumber); + bufpar=(unsigned char *)MALLOC(i-inptr2+2); +// printf("crec=%08X size=%d bufpar=%08X size=%d\n",crec,sizeof(idrec),bufpar,i-inptr2+2); + inptr2=i; + ochar=input[inptr2]; + inptr2++; + i--; + lastofs=0; + for(;;){ + j=(pi+numpar)->ofspar;//[numpar]; + for(ns=0;(j+ns)!=i;ns++){ + bufpar[lastofs++]=input[j+ns]; + } + i=j-1; + numpar--; + if(numpar<0)break; + bufpar[lastofs++]=','; + } + bufpar[lastofs++]=')'; + *(short *)&bufpar[lastofs++]=';'; + free(pi); + oldinput=input; // +// puts((char *)(input+inptr)); +// printf("cur_mod=%08X input=%08X\n",cur_mod,input); + ns=inptr2; + j=endinptr; + input=bufpar; +// puts((char *)bufpar); + inptr2=1; + cha2=input[0]; + endinptr=lastofs; + tok=tk_openbracket; + if(bufrm!=NULL){ + free(bufrm); + bufrm=NULL; + } + if(strinf.bufstr!=NULL){ + free(strinf.bufstr); + strinf.bufstr=NULL; + } + linebak=linenumber; + linenumber=linep; + i=doparams(); + endoffile=0; + input=oldinput; + inptr2=ns; + cha2=ochar; + endinptr=j; + linenumber=linebak; +// printf("cur_mod=%08X input=%08X\n",cur_mod,input); + free(bufpar); +// puts((char *)input); + return i; +} + +int getrazr(int type) +{ + switch(type){ + case tk_char: + case tk_byte: + return r8; + case tk_word: + case tk_int: + return r16; + case tk_long: + case tk_dword: + case tk_float: + return r32; + case tk_qword: + case tk_double: + return r64; + } + if(am32)return r32; + return r16; +} + +int doparams() /* do stack procedure parameter pushing */ +{ +char done=0,next; +int vartype; +int stackpar=0; +int i; +int jj=0; +char *bparam; // +int ip=-1; // +char *ofsstr=NULL; +int useAX=FALSE; +int retreg=AX; +unsigned char oaddstack=addstack; +unsigned char oinline=useinline; + useinline=0; +int structsize; +struct idrec *ptrs; + addstack=FALSE; + if(am32!=FALSE)jj=2; + bparam=BackString(param); + if(param[0]!=0)ip=0; + ofsstr=GetLecsem(tk_camma,tk_closebracket); + expectingoperand(tk_openbracket); + ClearRegister(); + if(tok!=tk_closebracket){ + while(tok!=tk_eof&&done==0){ + useAX=FALSE; + retreg=AX; + i=0; + next=1; + if(ip!=-1){ + if(bparam[ip]=='*'){ + while(bparam[ip]=='*')ip++; + ip++; + vartype=(am32==FALSE?tk_word:tk_dword); + } + else{ + if((vartype=GetTypeParam(bparam[ip++]))==0)ip=-1; + else{ + int c=bparam[ip]; + if(vartype==tk_struct){ + structsize=0; + while(isdigit(c)){ + c-='0'; + structsize=structsize*10+c; + ip++; + c=param[ip]; + } + } + else if(c>='0'&&c<='7'){ + ip++; + c-=0x30; + if(vartype==tk_fpust)float2stack(c); + else{ + if(vartype==tk_qword){ + c|=(bparam[ip]-0x30)*256; + ip++; + } + CalcRegPar(c,vartype,&ofsstr); + } + goto endparam; + } + } + } + if(vartype==tk_multipoint){ + vartype=tokens; + ip--; + } + } + if(tok==tk_string){ + if(chip<2||(optimizespeed&&(chip==5||chip==6))){ + op(0xB8); + if(am32!=FALSE)outdword(addpoststring()); + else outword(addpoststring()); // MOV AX,imm16 + op(0x50); + useAX=TRUE; + ClearReg(EAX); // + } /* PUSH AX */ + else{ + op(0x68); /* PUSH imm16 */ + if(am32!=FALSE)outdword(addpoststring()); + else outword(addpoststring()); + if(cpu<2)cpu=2; + } + stackpar+=2+jj; + addESP+=2+jj; + nexttok(); + } + else{ + if(tok>=tk_char&&tok<=tk_double){ + vartype=tok; + getoperand(); + } + else if(tok==tk_openbracket){ + nexttok(); + if(tok>=tk_char&&tok<=tk_double)vartype=tok; + nexttok(); + expectingoperand(tk_closebracket); + } + else{ + if(ip==-1||vartype==tokens){ + switch(tok){ + case tk_longvar: vartype=tk_long; break; + case tk_floatvar: vartype=tk_float; break; + case tk_dwordvar: vartype=tk_dword; break; + case tk_doublevar: vartype=tk_double; break; + case tk_qwordvar: vartype=tk_qword; break; + case tk_number: + vartype=(itok.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword)); + break; + case tk_reg32: vartype=tk_dword; break; + case tk_reg64: vartype=tk_qword; break; + case tk_minus: + if(tok2==tk_number){ + vartype=itok2.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword); + break; + } + default: vartype=(am32==FALSE?tk_word:tk_dword); break; + } + } + } + if(tok==tk_minus&&tok2==tk_number&&vartype!=tk_float){ // + nexttok(); + itok.lnumber=-itok.lnumber; + } + int razr; + if(ofsstr){ + razr=getrazr(vartype); + int retr; + if((retr=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ +// printf("reg=%d\n",retr); + GetEndLex(tk_camma,tk_closebracket); + if(razr==r8)razr=am32==0?r16:r32; + if(retr==SKIPREG)retreg=AX; + else retreg=retr; + op66(razr); + op(0x50+retreg); + useAX=TRUE; + stackpar+=razr; + addESP+=razr; + goto endparam1; + } +// printf("reg=%d\n",retr); + } + razr=r32; + if(itok2.type==tp_opperand||tok==tk_minus){ // + switch(vartype){ + case tk_struct: + i=structsize/((am32+1)*2); + do_e_axmath(0,r32,&ofsstr); + ClearReg(AX); + if(am32){ + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=4; + outword(0x70FF); + op(itok.number); + } + outword(0x30FF); + } + else{ + ClearReg(BX); + warningreg(regs[1][BX]); + outword(0xC389); + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=2; + outword(0x77FF); + op(itok.number); + } + outword(0x37FF); + } + stackpar+=structsize; + addESP+=structsize; + break; + case tk_char: i=1; + case tk_byte: + stackpar+=jj; + doalmath((char)i,&ofsstr); + addESP+=2+jj; + break; + case tk_int: i=1; + case tk_word: + if(am32==FALSE)razr=r16; + stackpar+=jj; + goto blokl; + case tk_long: i=1; + case tk_dword: + if(cpu<3)cpu=3; + stackpar+=2; +blokl: + if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))&&(tok==tk_number + ||tok==tk_undefofs||tok==tk_postnumber)){ + int otok=tok; + ITOK oitok=itok; + tok=tk_number; + if(OnlyNumber(i)){ + op66(razr); + if(otok==tk_number&&(postnumflag&f_reloc)==0&&short_ok(itok.number,razr==r16?FALSE:TRUE)!=0){ + op(0x6A); // PUSH 8 extend to 32 bit + op((unsigned int)itok.number); + } + else{ + op(0x68); // PUSH const + if(otok==tk_undefofs)AddUndefOff(0,oitok.name); + else if(otok==tk_postnumber)(oitok.flag&f_extern)==0?setwordpost(&oitok):setwordext(&oitok.number); + else if((postnumflag&f_reloc)!=0)AddReloc(); + if(razr==r16)outword(itok.number); + else outdword(itok.number); + } + addESP+=razr==r16?2:4; + goto nopush; + } + tok=otok; + } + do_e_axmath(i,razr,&ofsstr); + addESP+=razr==r16?2:4; + op66(razr); + break; + case tk_double: + if(doeaxfloatmath(tk_stackstart,0,4)!=tk_stackstart){ + op66(r32); + op(0x50+EDX); // PUSH EDX + op66(r32); + op(0x50); //push eax + useAX=TRUE; + } + if(cpu<3)cpu=3; + stackpar+=6; + addESP+=8; + goto nopush; + case tk_float: + if(doeaxfloatmath(tk_stackstart)!=tk_stackstart){ + op66(r32); + if(!am32){ + op(0x89); // mov ssdword[bp+2]=eax + op(0x46); + op(2); + Leave(); + } + else{ + op(0x50); //push eax + useAX=TRUE; + } + } + if(cpu<3)cpu=3; + stackpar+=2; + addESP+=4; + goto nopush; + case tk_qwordvar: + i=EAX|(EDX*256); + getintoreg64(i); + doregmath64(i); + op66(r32); + op(0x50+EDX); // PUSH EDX + op66(r32); + next=0; + if(cpu<3)cpu=3; + stackpar+=6; + addESP+=8; + break; + default: goto deflt; + } + op(0x50);/* PUSH AX or EAX */ + useAX=TRUE; +nopush: + stackpar+=2; + } + else{ // +// next=1; +// printf("vartype=%d\n",vartype); + if(vartype==tk_struct){ +// printf("tok=%d %s\n",tok,itok.name); + i=structsize/((am32+1)*2); + switch(tok){ + case tk_structvar: + ptrs=itok.rec; + if(ptrs->recpost==LOCAL){ + if(ESPloc&&am32){ + itok.rm=rm_mod10|rm_sib; + itok.sib=0x24; + itok.number+=addESP; + } + else{ + itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); + } + itok.segm=SS; + itok.post=0; + compressoffset(&itok); + } + else{ + itok.segm=DS; + itok.rm=(am32==FALSE?rm_d16:rm_d32); // + itok.post=ptrs->recpost; + if(i>1&&am32){ + outseg(&itok,1); + op(0xB8); + outaddress(&itok); + ClearReg(AX); + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=4; + outword(0x70FF); + op(itok.number); + } + outword(0x30FF); + break; + } + } + itok.sib=(am32==FALSE?CODE16:CODE32); + itok.flag=ptrs->flag; + itok.number+=structsize; + for(;i>0;i--){ + itok.number-=(am32+1)*2; + outseg(&itok,2); + op(0xFF); // PUSH [dword] + op(0x30+itok.rm); + outaddress(&itok); + } + break; + case tk_rmnumber: + itok.number+=structsize; + for(;i>0;i--){ + itok.number-=(am32+1)*2; + outseg(&itok,2); + op(0xFF); // PUSH [dword] + op(0x30+itok.rm); + outaddress(&itok); + } + break; + case tk_undefofs: + itok.rm=(am32==FALSE?rm_d16:rm_d32); // + case tk_postnumber: + if(i>1&&am32){ + if(tok!=tk_undefofs)outseg(&itok,1); + op(0xB8); + if(tok==tk_undefofs){ + AddUndefOff(0,(char *)string); + outdword(itok.number); + } + else outaddress(&itok); + ClearReg(AX); + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=4; + outword(0x70FF); + op(itok.number); + } + outword(0x30FF); + break; + } + itok.number+=structsize; + for(;i>0;i--){ + itok.number-=(am32+1)*2; + if(tok!=tk_undefofs)outseg(&itok,2); + op(0xFF); // PUSH [dword] + op(0x30+itok.rm); + if(tok==tk_undefofs){ + AddUndefOff(0,(char *)string); + outdword(itok.number); + } + else outaddress(&itok); + } + break; + case tk_reg32: + i--; + itok.rm=structsize; + for(;i>0;i--){ + itok.rm-=4; + op(0xFF); + op(0x70+itok.number); + op(itok.rm); + } + op(0xFF); + op(0x30+itok.number); + break; + default: +// preerror("for parametr function required structure"); + do_e_axmath(0,r32,&ofsstr); + ClearReg(AX); + if(am32){ + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=4; + outword(0x70FF); + op(itok.number); + } + outword(0x30FF); + } + else{ + ClearReg(BX); + warningreg(regs[1][BX]); + outword(0xC389); + i--; + itok.number=structsize; + for(;i>0;i--){ + itok.number-=2; + outword(0x77FF); + op(itok.number); + } + outword(0x37FF); + } + break; + } + stackpar+=structsize; + addESP+=structsize; + } + else if(vartype=2/*&&(!(optimizespeed&&(chip==5||chip==6)))*/){ //28.03.07 19:04 + if((itok.flag&f_reloc)==0&&short_ok(itok.number)){ + op(0x6A); /* PUSH const */ + op((unsigned int)itok.number); + } + else{ + op(0x68); /* PUSH const */ + if((itok.flag&f_reloc)!=0)AddReloc(); + if(am32==FALSE)outword((unsigned int)itok.number); + else outdword(itok.number); + } + if(cpu<2)cpu=2; + } + else{ + MovRegNum(r16,itok.flag&f_reloc,itok.number,EAX); + op(0x50); + } + break; + case tk_apioffset: + op(0x68); // PUSH const + AddApiToPost(itok.number); + break; + case tk_postnumber: + case tk_undefofs: + if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))){ + op(0x68); // PUSH const + if(tok==tk_undefofs)AddUndefOff(0,(char *)string); + else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(am32==FALSE)outword((unsigned int)itok.number); + else outdword(itok.number); + break; + } + default: +deflt: +//if(tok==tk_new)puts("monovar default"); + switch(vartype){ + case tk_int: i=1; + case tk_word: do_e_axmath(i,r16,&ofsstr); break; + case tk_char: i=1; + case tk_byte: doalmath((char)i,&ofsstr); break; + default: beep(); break; + } + op(0x50); /* PUSH AX */ + useAX=TRUE; + next=0; + break; + } + stackpar+=2+jj; + addESP+=2+jj; + } + else if(vartype>32; + for(i=0;i<2;i++){ + op66(r32); + if((i==0||(itok.flag&f_reloc)==0)&&short_ok(itok.number,TRUE)!=0){ + op(0x6A); // PUSH 8 extend to 32 bit + op((unsigned int)itok.number); + } + else{ + op(0x68); // PUSH const + if(i==1&&(itok.flag&f_reloc)!=0)AddReloc(); + outdword(itok.number); + } + if(i==1)break; + itok.number=lnumber; + } + break; + case tk_postnumber: + case tk_undefofs: + op66(r32); + outword(0x6A); // PUSH 8 extend to 32 bit + op66(r32); + op(0x68); // PUSH const + if(tok==tk_undefofs)AddUndefOff(0,(char *)string); + else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + outdword(itok.number); + break; + default: + if(vartype==tk_double)doeaxfloatmath(tk_stackstart,0,4); + else{ + op66(r32); + outword(0x6A); + do_e_axmath(0,r32,&ofsstr); + op66(r32); + op(0x50); // PUSH EAX + useAX=TRUE; + } + next=0; + break; + } + stackpar+=8; + addESP+=8; + if(cpu<3)cpu=3; + } +endparam1: + if(next)nexttok(); + + } + } +endparam: + if(ofsstr){ + if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype)); + free(ofsstr); + ofsstr=NULL; + } + if(tok==tk_camma){ + ofsstr=GetLecsem(tk_camma,tk_closebracket); + getoperand(); + } + else if(tok==tk_closebracket)done=1; + else{ + expected(')'); + done=1; + } + } + } + if(ofsstr){ + if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype)); + free(ofsstr); + } + if(ip!=-1&&bparam[ip]!=0&&bparam[ip]!='A'&&bparam[ip]!='V')missingpar(); + free(bparam); + setzeroflag=FALSE; + addstack=oaddstack; + useinline=oinline; + return stackpar; +} + +void CheckDir() +{ + do{ + switch(itok.number){ + case d_ifdef: + case d_ifndef: + case d_endif: + case d_else: + case d_if: + case d_elif: + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + directive(); + inptr=inptr2; + cha=cha2; + break; + default: + FastTok(0); + break; + } + if(tok==tk_eof)break; + }while(tok==tk_question); +} + +char *dynamic_var() +{ +int start,size; +char *bstring; +int use_extract=FALSE; + +#define TBUFSIZE 2048 +#define MTBUFSIZE TBUFSIZE-IDLENGTH +int curbsize; +COM_MOD *ocur_mod; + bstring=(char *)MALLOC(TBUFSIZE); + curbsize=TBUFSIZE; + size=0; + if(tok2==tk_extract)use_extract=TRUE; + do{ + start=inptr2-1; + ocur_mod=cur_mod; + if(size>(curbsize-IDLENGTH)){ + curbsize+=TBUFSIZE; + bstring=(char *)REALLOC(bstring,curbsize); + } + nexttok(); + if(tok==tk_openbrace){ + bstring[size]='{'; + size++; + do{ + start=inptr2-1; + ocur_mod=cur_mod; + if(size>(curbsize-IDLENGTH)){ + curbsize+=TBUFSIZE; + bstring=(char *)REALLOC(bstring,curbsize); + } + nexttok(); + if(tok==tk_number){ + switch(itok.rm){ + case tk_double: + case tk_float: + sprintf(itok.name,"%e",itok.dnumber); + break; + case tk_qword: + sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number); + break; + default: + sprintf(itok.name,"0x%X",itok.number); + break; + } + } + if(itok.name[0]!=0){ + strcpy(bstring+size,itok.name); + size+=strlen(itok.name); + } + else{ + if(cur_mod!=ocur_mod){ + start=inptr2-2; + if(start<0)start=0; + } + strncpy(bstring+size,(char *)(input+start),inptr2-1-start); + size+=inptr2-1-start; + } + }while(tok!=tk_closebrace&&tok!=tk_eof); + if(tok!=tk_eof)continue; + } + if(tok==tk_number){ + switch(itok.rm){ + case tk_double: + case tk_float: + sprintf(itok.name,"%e",itok.dnumber); + break; + case tk_qword: + sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number); + break; + default: + sprintf(itok.name,"0x%X",itok.number); + break; + } + } + if(itok.name[0]!=0){ + strcpy(bstring+size,itok.name); + size+=strlen(itok.name); + } + else{ + if(cur_mod!=ocur_mod){ + start=inptr2-2; + if(start<0)start=0; + } + strncpy(bstring+size,(char *)(input+start),inptr2-1-start); + size+=inptr2-1-start; + } + if(tok==tk_eof){ + unexpectedeof(); + return NULL; + } + if(tok==tk_camma&&use_extract==FALSE)break; + }while(tok!=tk_semicolon); +// size++; + bstring[size]=0; + return bstring; +} + +int SkipBlock() +{ + for(int i=1;i!=0;){ + FastTok(0); + if(tok==tk_question)CheckDir(); + switch(tok){ + case tk_eof: unexpectedeof(); return FALSE; + case tk_openbrace: i++; break; + case tk_closebrace: i--; break; + } + } + return TRUE; +} + +int SkipParam() +{ + for(int i=1;i!=0;){ + FastTok(0); + if(tok==tk_question)CheckDir(); + switch(tok){ + case tk_openbracket: i++; break; + case tk_closebracket: i--; break; + case tk_eof: unexpectedeof(); return FALSE; + } + } + return TRUE; +} + +int SkipLocalVar() +{ + while(tok!=tk_openbrace&&tok!=tk_eof){ + if(tok==tk_question){ + CheckDir(); + continue; + } + if(tok==tk_id&&(strcmp(itok.name,"struct")==0||strcmp(itok.name,"union")==0)){ + do{ + FastTok(0); + if(tok==tk_eof){ + unexpectedeof(); + return FALSE; + } + }while(tok!=tk_semicolon&&tok!=tk_openbrace); + if(tok==tk_openbrace){ + FastTok(0); + if(!SkipBlock())return FALSE; + } + } + FastTok(1); + } + return TRUE; +} + +SAVEPAR *SRparam(int save,SAVEPAR *par) //save or restore global param compiler +{ + if(save){ + par=(SAVEPAR *)MALLOC(sizeof(SAVEPAR)); + par->ooptimizespeed=optimizespeed; + par->owarning= warning; + par->odbg= dbg; + par->odosstring= dosstring; + par->ouseinline= useinline; + par->oam32= am32; + par->oalignword= alignword; + par->oAlignCycle= AlignCycle; + par->oidasm= idasm; // + par->ooptnumber= optnumber; + par->odivexpand= divexpand; + par->ooptstr= optstr; // + par->ochip= chip; + par->oaligncycle= aligncycle; + par->ouselea= uselea; + par->oregoverstack= regoverstack; + return par; + } + if(par){ + optimizespeed=par->ooptimizespeed; + warning= par->owarning; + dbg= par->odbg; + dosstring= par->odosstring; + useinline= par->ouseinline; + am32= par->oam32; + alignword= par->oalignword; + AlignCycle= par->oAlignCycle; + idasm= par->oidasm; // + optnumber= par->ooptnumber; + divexpand= par->odivexpand; + optstr= par->ooptstr; // + chip= par->ochip; + aligncycle= par->oaligncycle; + uselea = par->ouselea; + regoverstack= par->oregoverstack; + free(par); + } + return NULL; +} + +void dynamic_proc() +{ +int dtok,start,size,line; +ITOK otok; +char *bstring; +idrec *ptr; +_PROCINFO_ *pinfo; + if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); + dtok=tok; + otok=itok; + line=linenum2; + switch(tok){ + case tk_id: + case tk_ID: + string[0]=0; + case tk_undefproc: + case tk_declare: + break; + default: idalreadydefined(); break; + } + if(itok.flag&f_export)preerror("'_export' not use in dynamic functions"); + bstring=BackString((char *)string); + start=inptr2-1; + pinfo=(_PROCINFO_ *)MALLOC(sizeof(_PROCINFO_)); + if(itok.flag&f_classproc)pinfo->classteg=searchteg; + else pinfo->classteg=NULL; + pinfo->warn=warning; + pinfo->speed=optimizespeed; + pinfo->lst=(dbg&2)>>1; + pinfo->typestring=dosstring; + pinfo->inlinest=useinline; + pinfo->code32=am32; + pinfo->align=alignword; + pinfo->acycle=AlignCycle; + pinfo->idasm=idasm; + pinfo->opnum=optnumber; + pinfo->de=divexpand; + pinfo->ostring=optstr; + pinfo->chip=chip; + pinfo->sizeacycle=aligncycle; + pinfo->uselea=uselea; + pinfo->regoverstack=regoverstack; + nexttok(); + if(dtok==tk_id||dtok==tk_ID){ + param[0]=0; + if(tok2!=tk_closebracket&&(otok.flag&f_typeproc)==tp_fastcall){ + nexttok(); // + declareparamreg(); + free(bstring); + bstring=BackString((char *)param); + nexttok(); + inptr=inptr2; + cha=cha2; + linenumber=linenum2; + } + } + else{ + inptr=inptr2; + cha=cha2; + if(!SkipParam()){ + free(bstring); + return; + } + FastTok(1); + } + if(tok==tk_semicolon)preerror("error declare dynamic function"); + if((!SkipLocalVar())||(!SkipBlock())){ + free(bstring); + return; + } + size=inptr-start+1; + inptr2=inptr; + cha2=cha; + linenum2=linenumber; + linenumber=line; + itok=otok; + strcpy((char *)string,bstring); + free(bstring); + bstring=(char *)MALLOC(size+1); + strncpy(bstring,(char *)(input+start),size); + bstring[size-1]=';'; + bstring[size]=0; + +// printf("tok=%d %s\n%s\n",dtok,itok.name,bstring); + itok.size=0; + tok=tk_proc; + itok.segm=DYNAMIC; + if(dtok==tk_id||dtok==tk_ID){ + int i; + itok.number=secondcallnum++; + itok.type=tp_ucnovn; + if((i=FindUseName(itok.name))!=0)itok.segm=DYNAMIC_USED; + ptr=addtotree(itok.name); + if(i){ + ptr->count=i; + ptr=itok.rec; + AddDynamicList(ptr); + } + } + else{ + if(dtok==tk_undefproc)itok.segm=DYNAMIC_USED; + updatetree(); + ptr=itok.rec; + //11.08.04 23:38 + strcpy(ptr->recid,itok.name); + + if(dtok==tk_undefproc&&(itok.flag&f_classproc))AddDynamicList(ptr); + } + ptr->line=linenumber; + ptr->file=currentfileinfo; + pinfo->buf=bstring; + ptr->pinfo=pinfo; +// ptr->sbuf=bstring; +// linenumber=linenum2; + if(searchteg)searchteg=NULL; + nexttok(); +} + +/* ======= procedure handling ends here ======== */ + +int macros(int expectedreturn) +{ +int dynamicindex,actualreturn; +ITOK otok; +int orettype; +unsigned int oproctype; +int otok2; +unsigned int typep; +int snum=0; + actualreturn=(am32==FALSE?tk_word:tk_dword); + switch(tok){ + case tk_ID: + case tk_id: + dynamicindex=NOT_DYNAMIC; + break; + case tk_proc: + case tk_undefproc: + case tk_declare: + dynamicindex=itok.segm; + actualreturn=itok.rm; + break; + default: + idalreadydefined(); + return expectedreturn; + } + typep=itok.flag; + otok=itok; + if(tok==tk_ID)param[0]=0; + else strcpy(param,(char *)string); + nexttok(); + orettype=returntype; + returntype=actualreturn; //01.08.04 14:45 + oproctype=current_proc_type; + if(dynamicindex==NOT_DYNAMIC)doregparams(); + else{ + switch(typep&f_typeproc){ + case tp_cdecl: + case tp_stdcall: + snum=swapparam(); + break; + case tp_pascal: + snum=doparams(); + break; + case tp_fastcall: + doregparams(); + break; + } + } + itok=otok; + otok2=tok2; + if(dynamicindex==NOT_DYNAMIC){ + if((actualreturn=includeit(0))==-1){ + char holdstr[IDLENGTH+16]; + sprintf(holdstr,"unknown macro '%s'",itok.name); + preerror(holdstr); + } + } + else insert_dynamic(TRUE); + if(actualreturn!=tk_void&&expectedreturn!=tk_ID)convert_returnvalue(expectedreturn,actualreturn); + returntype=orettype; + current_proc_type=oproctype; + if(snum!=0){ + if(typep&f_retproc)warningdestroyflags(); + CorrectStack(snum); + } + tok2=otok2; + return actualreturn; +} + +int updatecall(unsigned int which,unsigned int where,unsigned int top) +/* update output with newly defined location, but only for addresses after + and including top. return the number of addresses updated. + which - + where - */ +{ +unsigned int count=0; +long hold; +int updates=0; + while(counttype>=CALL_SHORT&&(postbuf+count)->type<=CONTINUE_32)&& + (postbuf+count)->num==which&&(postbuf+count)->loc>=top){ + hold=(long)where-(long)(postbuf+count)->loc; + if((postbuf+count)->type>=CALL_NEAR&&(postbuf+count)->type<=CONTINUE_NEAR){ //NEAR + hold-=2; + *(unsigned short *)&output[(postbuf+count)->loc]=(unsigned short)hold; + } + else if((postbuf+count)->type>=CALL_32&&(postbuf+count)->type<=CONTINUE_32){//32-BIT + hold-=4; + *(unsigned long *)&output[(postbuf+count)->loc]=(unsigned long)hold; + } + else{ //SHORT + hold--; // CALL_SHORT + if(short_ok(hold))output[(postbuf+count)->loc]=(unsigned char)hold; + else{ + if((postbuf+count)->type==BREAK_SHORT)preerror3("BREAK distance too large, use break",(postbuf+count)->line); + else if((postbuf+count)->type==CONTINUE_SHORT)preerror3("CONTINUE distance too large, use continue",(postbuf+count)->line); + else preerror3(shorterr,(postbuf+count)->line,(postbuf+count)->file); + } + } + if(hold<127){ + if((postbuf+count)->type==JMP_NEAR||(postbuf+count)->type==JMP_32)warningjmp("GOTO",(postbuf+count)->line,(postbuf+count)->file); + if((postbuf+count)->type==BREAK_NEAR||(postbuf+count)->type==BREAK_32)warningjmp("BREAK",(postbuf+count)->line); + if((postbuf+count)->type==CONTINUE_NEAR||(postbuf+count)->type==CONTINUE_32)warningjmp("CONTINUE",(postbuf+count)->line); + } + killpost(count); + updates++; + } + else count++; + } + if(updates==1&&hold==0)return -1; + return(updates); +} + +void define_locallabel() +{ + FindOff(string,CS); + updatecall((unsigned int)updatelocalvar((char *)string,tk_number,outptr),outptr,procedure_start); + nextexpecting2(tk_colon); + RestoreStack(); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif +} + +void addacall(unsigned int idnum,unsigned char callkind) +{ + CheckPosts(); + (postbuf+posts)->num=idnum; + (postbuf+posts)->loc=outptr+1; + (postbuf+posts)->type=callkind; + (postbuf+posts)->line=(unsigned short)linenumber; + (postbuf+posts)->file=(unsigned short)currentfileinfo; + posts++; +} + +unsigned int dofrom() // returns number of bytes read from FROM file +{ +int filehandle; +long filesize; + if(tok!=tk_string){ + stringexpected(); + return(0); + } + filehandle=open((char *)string3,O_BINARY|O_RDONLY); + if(filehandle==-1){ + unableopenfile((char *)string3); + return(0); + } + if((filesize=getfilelen(filehandle))==-1L){ + preerror("Unable to determine FROM file size"); + close(filehandle); + return(0); + } + if(am32==FALSE&&filesize>=0xFFFFL){ + preerror("FROM file too large"); + close(filehandle); + return(0); + } + LoadData(filesize,filehandle); + return filesize; +} + +unsigned int doextract() // returns number of bytes EXTRACTed +{ +unsigned int sizetoread; +int filehandle; +long filesize,startpos; + if(tok!=tk_string){ + stringexpected(); + return(0); + } + filehandle=open((char *)string3,O_BINARY|O_RDONLY); + if(filehandle==-1){ + unableopenfile((char *)string3); + return(0); + } + nexttok(); + expecting(tk_camma); + if(tok!=tk_number){ + numexpected(); + return(0); + } + startpos=doconstlongmath(); + expecting(tk_camma); + if(tok!=tk_number){ + numexpected(); + return(0); + } + sizetoread=doconstlongmath(); + if((filesize=getfilelen(filehandle))==-1L){ + preerror("Unable to determine EXTRACT file size"); + close(filehandle); + return(0); + } + if(filesize<=startpos){ + preerror("EXTRACT offset exceeds the length of the file"); + close(filehandle); + return(0); + } + if(sizetoread==0)sizetoread=filesize-startpos; + if(am32==FALSE&&sizetoread>=0xFFFFL){ + preerror("Block to EXTRACT exceeds 64K"); + close(filehandle); + return(0); + } + lseek(filehandle,startpos,0); // error checking required on this + LoadData(sizetoread,filehandle); + return sizetoread; +} + +void LoadData(unsigned int size,int filehandle) +{ + if(splitdata){ + while(((unsigned long)size+(unsigned long)outptrdata)>=outdatasize){ + if(CheckDataSize()==0)break; + } + if((unsigned int)read(filehandle,outputdata+outptrdata,size)!=size)errorreadingfile((char *)string3); + outptrdata+=size; + } + else{ + while(((unsigned long)size+(unsigned long)outptr)>=outptrsize){ + if(CheckCodeSize()==0)break; + } + if((unsigned int)read(filehandle,output+outptr,size)!=size)errorreadingfile((char *)string3); + outptr+=size; + outptrdata=outptr; + } + close(filehandle); +} + +void op66(int ctok) +{ + if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){ + if(cpu<3)cpu=3; + op(0x66); + } +} + +int op67(int ctok) +{ + if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){ + if(cpu<3)cpu=3; + op(0x67); + return TRUE; + } + return FALSE; +} + +void outseg(ITOK *outtok,unsigned int locadd) +{ +int rmm1; + rmm1=outtok->rm&7; + if(outtok->sib!=CODE16){ + if(am32==FALSE)op(0x67); + if(rmm1==4)locadd++; + } + else if(am32!=FALSE)op(0x67); + switch(outtok->segm){ + case ES: op(0x26); break; + case CS: op(0x2E); break; + case FS: op(0x64); + if(cpu<3)cpu=3; + break; + case GS: op(0x65); + if(cpu<3)cpu=3; + break; + case SS: + if(outtok->sib==CODE16){ + if(rmm1!=2&&rmm1!=3&&!(rmm1==6&&outtok->rm!=6))op(0x36); + } + else{ + if(rmm1==4){ + rmm1=outtok->sib&7; + if(rmm1!=4){ + if(rmm1==5){ + if(outtok->rm==4)op(0x36); + break; + } + op(0x36); + } + } + else if(rmm1==5){ + if(outtok->rm==5)op(0x36); + else break; + } + else op(0x36); + } + break; + case DS: + if(outtok->sib==CODE16){ + if(rmm1==2||rmm1==3||(rmm1==6&&outtok->rm!=6))op(0x3E); + } + else{ + if(rmm1==4){ + rmm1=outtok->sib&7; + if(rmm1==4||(rmm1==5&&outtok->rm!=4))op(0x3e); + } + else if(rmm1==5&&outtok->rm!=5)op(0x3e); + } + } + CheckPosts(); + if(outtok->post!=0&&outtok->post!=UNDEF_OFSET){ + if((outtok->flag&f_extern)){ + (postbuf+posts)->type=EXT_VAR; + (postbuf+posts)->num=outtok->number&0xFFFF; + outtok->number>>=16; + } + else if(outtok->post==USED_DIN_VAR){ + (postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32); +// printf("Add tok=%d %08X sib=%d %s\n",outtok->rec->rectok,outtok->rec->right,outtok->rec->recsib,outtok->rec->recid); + if(outtok->rec->rectok==tk_structvar&&outtok->rec->recsib==tp_gvar){ + (postbuf+posts)->num=(int)outtok->rec;//02.09.05 17:10 ->right; + } + else (postbuf+posts)->num=(int)outtok->rec; + } +// else if((outtok->flag&f_dataseg))(postbuf+posts)->type=(unsigned short)(am32==0?DATABLOCK_VAR:DATABLOCK_VAR32); + else (postbuf+posts)->type=(unsigned short)(am32==0?POST_VAR:POST_VAR32); + (postbuf+posts)->loc=outptr+locadd; + posts++; + } + else if(outtok->flag&f_reloc){ + (postbuf+posts)->type=(unsigned short)(am32==0?FIX_VAR:FIX_VAR32); + (postbuf+posts)->loc=outptr+locadd; + posts++; + } +} + +int addpoststring(int segm,int len,int term) /* add a string to the post queue */ +{ +int i; +int returnvalue; + if((returnvalue=FindDublString(segm,len,term))!=-1)return returnvalue; + CheckPosts(); + (postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32); + (postbuf+posts)->loc=(segm==CS?outptr:outptrdata); + (postbuf+posts)->num=segm; + posts++; + returnvalue=poststrptr; + if((int)(len+poststrptr+1)>=sbufstr){ + sbufstr+=SIZEBUF; + bufstr=(char *)REALLOC(bufstr,sbufstr); + } + for(i=0;itype=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32); + (postbuf+posts)->loc=(segm==CS?outptr:outptrdata); + (postbuf+posts)->num=segm; + posts++; + return outs.ofs+j; + } + } + prevstr=nextstr; + nextstr=outs.next; + } + outs.next=(void *)MALLOC(sizeof(STRING_LIST)+len); + memcpy(outs.next,&ins,sizeof(STRING_LIST)); + if(len!=0)memcpy((char *)outs.next+sizeof(STRING_LIST),&string,len); + if(prevstr!=NULL)memcpy(prevstr,&outs,sizeof(STRING_LIST)); + else liststring=outs.next; + return -1; +} + +void killpost(unsigned int poz) +{ + posts--; + memcpy((postinfo *)(postbuf+poz),(postinfo *)(postbuf+posts),sizeof(postinfo)); +} + +void dopoststrings() +{ +unsigned int addvalue,i; + if(poststrptr==0)return; + if(splitdata){ + addvalue=outptrdata; + if((outptrdata+poststrptr)>=outdatasize)CheckDataSize(); + } + else{ + addvalue=outptr; + if((outptr+poststrptr)>=outptrsize)CheckCodeSize(); + } + datasize+=poststrptr; + if(dbg&2)AddDataNullLine(3); + memcpy(&outputdata[outptrdata],bufstr,poststrptr); + outptrdata+=poststrptr; + if(!splitdata)outptr=outptrdata; + for(i=0;inum; + if((postbuf+i)->type==POST_STRING){ + if(segm==CS)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)addvalue; + else *(unsigned short *)&outputdata[(postbuf+i)->loc]+=(unsigned short)addvalue; + if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR; + else if(FixUp==FALSE)killpost(i--); + else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR:FIX_CODE); + } + else if((postbuf+i)->type==POST_STRING32){ + if(segm==CS)*(unsigned int *)&output[(postbuf+i)->loc]+=addvalue; + else *(unsigned int *)&outputdata[(postbuf+i)->loc]+=addvalue; + if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR32; + else if(FixUp==FALSE)killpost(i--); + else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR32:FIX_CODE32); + } + } + poststrptr=0; /* reset the poststrptr */ +STRING_LIST ins; + void *nextstr=liststring; + while(nextstr!=NULL){ + memcpy(&ins,nextstr,sizeof(STRING_LIST)); + if(ins.plase!=0){ + ins.plase=0; + ins.ofs+=addvalue; + memcpy(nextstr,&ins,sizeof(STRING_LIST)); + } + nextstr=ins.next; + } + if(dbg&2)AddCodeNullLine(); +} + +void insertcode() // force code procedure at specified location +{ + nexttok(); + testInitVar(FALSE); + if((itok.flag&f_extern)!=0){ + notexternfun(); + return; + } + int tproc=itok.flag&f_typeproc; + setuprm(); + switch(tok){ + case tk_undefproc: + case tk_declare: + tok=tk_proc; + itok.number=outptr; + updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0); + if(tproc==tp_fastcall){ + if(includeit(1)==-1)thisundefined(itok.name); + } + else if(includeproc()==-1)thisundefined(itok.name); + break; + case tk_id: + case tk_ID: + tok=tk_proc; + itok.number=outptr; + string[0]=0; + itok.type=tp_ucnovn; + addtotree(itok.name); + if(tproc==tp_fastcall){ + if(includeit(1)==-1)thisundefined(itok.name); + } + else if(includeproc()==-1)thisundefined(itok.name); + break; + case tk_proc: + if(itok.segmstlist=staticlist; + oendinptr=endinptr; + endoffile=0; + ostartline=startline; + idrec *ptr=itok.rec; + pinfo=ptr->pinfo; + input=(unsigned char *)pinfo->buf; + inptr2=1; + startline=(char *)input; + cha2=input[0]; + endinptr=strlen((char *)input); + endinput=startline+endinptr; + linenumber=linenum2=ptr->line; + currentfileinfo=ptr->file; + staticlist=(startfileinfo+currentfileinfo)->stlist; + par=SRparam(TRUE,NULL); + warning=pinfo->warn; + optimizespeed=pinfo->speed; + dosstring=pinfo->typestring; + useinline=pinfo->inlinest; + am32=pinfo->code32; + alignword=pinfo->align; + AlignCycle=pinfo->acycle; + idasm=pinfo->idasm; + optnumber=pinfo->opnum; + divexpand=pinfo->de; + optstr=pinfo->ostring; + chip=pinfo->chip; + aligncycle=pinfo->sizeacycle; + uselea=pinfo->uselea; + regoverstack=pinfo->regoverstack; + if(pinfo->classteg!=NULL){ + /*if((itok.flag&f_static)==0)*/searchteg=(structteg *)pinfo->classteg; + insert=0; + } + if(pinfo->lst)dbg|=2; + else dbg&=0xFD; +// puts(itok.name); + if(!insert){ + procedure_start=outptr; + if(dbg){ + if(dbg&2){ + char m1[130]; + //11.08.04 23:39 +// if(searchteg)sprintf(m1,"%s::%s()",searchteg->name,itok.name); +// else sprintf(m1,"%s()",itok.name); + sprintf(m1,"%s()",itok.name); + + AddCodeNullLine(m1); + } + else AddLine(); + } + if(AlignProc)AlignCD(CS,alignproc); +// puts((char *)input); + if(pinfo->classteg==NULL)itok.flag&=~f_static; + setproc(1); + dopoststrings(); + } + else insertproc(); + input=oinput; + inptr2=oinptr; + cha2=ocha; + linenum2=oline; +// printf("cur_mod=%08X\n",cur_mod); + (startfileinfo+currentfileinfo)->stlist=staticlist; + currentfileinfo=ofile; + staticlist=(startfileinfo+currentfileinfo)->stlist; + endinptr=oendinptr; + endoffile=0; + startline=ostartline; + SRparam(FALSE,par); + if(oinsert)searchteg=osearchteg; + else searchteg=NULL; +// if(insert)nexttok(); +// printf("tok=%d %08X\n",tok,cur_mod); +} + +idrec *addtotree(char *keystring)// +{ +struct idrec *ptr,*newptr; +int cmpresult; +// + newptr=(struct idrec *)MALLOC(sizeof(struct idrec)); + ptr=(itok.flag&f_static)!=0?staticlist:treestart; // + if(ptr==NULL)((itok.flag&f_static)!=0?staticlist:treestart)=newptr;// + else{ // + while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)|| + (cmpresult>0&&ptr->right!=NULL))ptr=(cmpresult<0?ptr->left:ptr->right); + (cmpresult<0?ptr->left:ptr->right)=newptr; + } + strcpy(newptr->recid,keystring);// + newptr->newid=NULL; + if(string[0]!=0)newptr->newid=BackString((char *)string); + newptr->rectok=tok; + newptr->recnumber=itok.number; + newptr->recsegm=itok.segm; + newptr->recrm=itok.rm; + newptr->recpost=itok.post; + newptr->flag=itok.flag; + newptr->recsize=itok.size; + newptr->left=newptr->right=NULL; + newptr->sbuf=NULL; + newptr->recsib=itok.sib; + newptr->line=linenumber; + newptr->file=currentfileinfo; + newptr->count=0; + newptr->type=itok.type; + newptr->npointr=itok.npointr; + itok.rec=newptr; + return newptr; +} + +long updatetree() // returns the old number value +{ +struct idrec *ptr; +long hold; + ptr=itok.rec; + if(ptr==0)internalerror("address record not found when update tree"); + if(ptr->newid)free(ptr->newid); + ptr->newid=NULL; + if(string[0]!=0)ptr->newid=BackString((char *)string); + ptr->rectok=tok; + hold=ptr->recnumber; + ptr->recnumber=itok.number; + ptr->recsegm=itok.segm; + ptr->recrm=itok.rm; + ptr->flag=itok.flag; + ptr->recsize=itok.size; + ptr->recsib=itok.sib; + return hold; +} + +/* --------------- local variable handling starts here ----------------- */ + +unsigned int updatelocalvar(char *str,int tok4,unsigned int num) +{ +struct localrec *ptr; +unsigned int retvalue; +treelocalrec *ntlr=tlr; + while(ntlr&&ntlr->level>1)ntlr=ntlr->next; + for(ptr=ntlr->lrec;;ptr=ptr->rec.next){ + if(strcmp(ptr->rec.recid,str)==0){ + retvalue=ptr->rec.recnumber; + ptr->rec.rectok=tok4; + ptr->rec.recnumber=num; + break; + } + if(ptr->rec.next==NULL)break; + } + return(retvalue); +} + +localrec * addlocalvar(char *str,int tok4,unsigned int num,int addmain) +{ +localrec *ptr,*newptr; +localrec *uptr; +treelocalrec *ntlr; + if(addmain){ + ntlr=tlr; + while(ntlr&&ntlr->level>1)ntlr=ntlr->next; + uptr=ntlr->lrec; + } + else uptr=tlr->lrec; + newptr=(struct localrec *)MALLOC(sizeof(struct localrec)); + + if(uptr==NULL){ + if(addmain)ntlr->lrec=newptr; + else tlr->lrec=newptr; + } + else{ + ptr=uptr; + while(ptr->rec.next!=NULL)ptr=ptr->rec.next; + ptr->rec.next=newptr; + } + strcpy(newptr->rec.recid,str); + newptr->rec.rectok=tok4; + newptr->rec.recnumber=num; + newptr->rec.next=NULL; + newptr->rec.right=NULL; + newptr->rec.recsize=0; + newptr->fuse=NOTINITVAR; + newptr->rec.type=tp_ucnovn; + newptr->rec.flag=0; + newptr->rec.npointr=0; + newptr->rec.recpost=LOCAL; + newptr->li.count=0; + newptr->li.start=linenumber; + return newptr; +} + +void KillTegList(structteg *tteg) +{ + if(tteg){ + KillTegList(tteg->left); + KillTegList(tteg->right); + if(tteg->baza)free(tteg->baza); + free(tteg); + } +} + +void killlocals(/*int endp*/) +/* Clear and free the local linked list, check for any unresolved local +jump labels. */ +{ +/* if(endp){ + dopoststrings(); + for(int i=0;itype,(postbuf+i)->num); + if((postbuf+i)->type==DIN_VAR||(postbuf+i)->type==DIN_VAR32){ + idrec *ptr=(idrec *)(postbuf+i)->num; +// printf("sib=%d num=%08X %s\n",ptr->recsib,ptr->recnumber,ptr->recid); + if(ptr->recsib!=tp_gvar)continue; + puts("recsib=tp_gvar"); + if(ptr->recpost==USED_DIN_VAR){ +unsigned int otok,otok2; +ITOK oitok; + oitok=itok; + otok=tok; + otok2=tok2; + setdindata(ptr,i); + itok=oitok; + tok=otok; + tok2=otok2; + } + else{ + if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber); + else *(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber; + } + if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32); + else killpost(i--); + } + } + dopoststrings(); + } + */ +treelocalrec *ftlr,*ftlr1; +struct localrec *ptr, *ptr1; + for(ftlr=btlr;ftlr!=NULL;){ + ftlr1=ftlr; + for(ptr=ftlr->lrec;ptr!=NULL;){ + ptr1=ptr; + if(ptr->rec.rectok==tk_locallabel){ /* check for unresolved labels */ +char holdstr[32+IDLENGTH]; + sprintf(holdstr,"local jump label '%s' unresolved",ptr1->rec.recid); + preerror(holdstr); + } +// printf("type=%d post=%08X %s\n",ptr->rec.type,ptr->rec.recpost,ptr->rec.recid); + if(ptr->rec.rectok==tk_structvar){ + if(ptr->rec.count==0){ + warningnotused(ptr->rec.recid,5); + if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf); + } + } + else if(ptr->fuserec.type==tp_localvar||ptr->rec.type==tp_postvar||ptr->rec.type==tp_gvar)warningnotused(ptr->rec.recid,3); + else if(ptr->rec.type==tp_paramvar)warningnotused(ptr->rec.recid,4); + if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf); + } + ptr=ptr->rec.next; + if(ptr1->rec.recpost!=USED_DIN_VAR)free(ptr1); + } + ftlr=ftlr->next; + free(ftlr1); + } + btlr=NULL; + paramsize=0; + localsize=0; + KillTegList(ltegtree); + ltegtree=NULL; +} + +/* ================ input procedures start ================= */ +int loadinputfile(char *inpfile) // +{ +unsigned long size; +int filehandle; + if((filehandle=open(inpfile,O_BINARY|O_RDONLY))==-1)return -2; + if((size=getfilelen(filehandle))==0){ + badinfile(inpfile); + close(filehandle); + return(-1); + } + if(totalmodule==0){ + startfileinfo=(struct FILEINFO *)MALLOC(sizeof(FILEINFO)); + totalmodule=1; + currentfileinfo=0; + } + else{ // + for(currentfileinfo=0;currentfileinfofilename)==0)break; + } + if(currentfileinfo!=totalmodule){ + if(crif!=FALSE)return 1; + goto cont_load; + } + totalmodule++; + startfileinfo=(struct FILEINFO *)REALLOC(startfileinfo,sizeof(FILEINFO)*(totalmodule)); + } + + (startfileinfo+currentfileinfo)->stlist=NULL; + (startfileinfo+currentfileinfo)->filename=(char *)MALLOC(strlen(inpfile)+1); + strcpy((startfileinfo+currentfileinfo)->filename,inpfile); + (startfileinfo+currentfileinfo)->numdline=0; + //GetFileTime(filehandle,&(startfileinfo+currentfileinfo)->time); // bug +// getftime(filehandle,&(startfileinfo+currentfileinfo)->time); +cont_load: + staticlist=(startfileinfo+currentfileinfo)->stlist; + input=(unsigned char *)MALLOC(size+1); + printf("%08lX %s %lu\n",input,inpfile,size); + if((endinptr=read(filehandle,input,size))!=size){ +printf("%d\n",endinptr); + + errorreadingfile(inpfile); + close(filehandle); + return(-1); + } + close(filehandle); + return(0); +} + +void notnegit(int notneg) +/* produce NOT .. or NEG .. */ +{ +int wordadd=0,i=0; + getoperand(); + switch(tok){ + case tk_reg: wordadd=1; op66(r16); + ClearReg(itok.number); + case tk_beg: + if(optimizespeed&&(chip==5||chip==6)){ + if(wordadd==0&&itok.number==AL)outword(0xFF34); + else{ + if(wordadd)op(0x83); + else op(0x80); + op(0xF0+itok.number); + op(0xFF); + } + if(notneg){ + if(wordadd){ + op66(r16); + op(0x40+itok.number); + } + else{ + op(0xFE); + op(0xC0+itok.number); + } + } + } + else{ + op(0xF6+wordadd); + op(0xD0+notneg+itok.number); + } + if(wordadd==0)ClearReg(itok.number&3); + break; + case tk_wordvar: + case tk_intvar: wordadd=1; + i=1; + case tk_bytevar: + case tk_charvar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + if(wordadd)op66(r16); + outseg(&itok,2); + if((!notneg)&&optimizespeed&&(chip==5||chip==6)){ + op(wordadd!=0?0x83:0x80); + op(0x30+itok.rm); + outaddress(&itok); + op(0xFF); + } + else{ + op(0xF6+wordadd); + op(0x10+notneg+itok.rm); + outaddress(&itok); + } + KillVar(itok.name); + break; + case tk_reg32: + op66(r32); + if(optimizespeed&&(chip==5||chip==6)){ + op(0x83); + outword(0xFFF0+itok.number); + if(notneg){ + op66(r32); + op(0x40+itok.number); + } + } + else{ + op(0xF7); + op(0xD0+notneg+itok.number); + } + if(cpu<3)cpu=3; + ClearReg(itok.number); + break; + case tk_reg64: + int r1,r2; + r1=itok.number&255; + r2=itok.number/256; + op66(r32); + op(0xF7); + op(0xD0+notneg+r2); // NEG reg + op66(r32); + op(0xF7); + op(0xD0+notneg+r1); // NEG reg + op66(r32); + op(0x83); + op(0xD8+r2); + op(0); + ClearReg(r1); + ClearReg(r2); + break; + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf); + op66(r32); + outseg(&itok,2); + if((!notneg)&&optimizespeed&&(chip==5||chip==6)){ + op(0x83); + op(0x30+itok.rm); + outaddress(&itok); + op(0xFF); + } + else{ + op(0xF7); + op(0x10+notneg+itok.rm); + outaddress(&itok); + } + if(cpu<3)cpu=3; + KillVar(itok.name); + break; + case tk_qword: + itok.number+=4; + compressoffset(&itok); + for(i=0;i<2;i++){ + CheckAllMassiv(bufrm,8,&strinf); + op66(r32); + outseg(&itok,2); + op(0xF7); + op(0x10+notneg+itok.rm); + outaddress(&itok); + if(i==1)break; + itok.number-=4; + compressoffset(&itok); + } + itok.number-=4; + compressoffset(&itok); + CheckAllMassiv(bufrm,8,&strinf); + op66(r32); + outseg(&itok,2); + op(0x83); op(0x18+itok.rm); + outaddress(&itok); + op(0); + KillVar(itok.name); + if(cpu<3)cpu=3; + break; + case tk_doublevar: + i=4; + case tk_floatvar: + if(notneg!=8)illegalfloat(); + CheckAllMassiv(bufrm,4+i,&strinf); + outseg(&itok,2); //fld var + op(0xd9+i); + op(itok.rm); + outaddress(&itok); + outword(0xe0d9); //fchs + outseg(&itok,2);//fstp var + op(0xd9+i); + op(itok.rm+0x18); + outaddress(&itok); + fwait3(); + break; + default: varexpected(0); + } +} + +void setreturn() +{ + if(numreturn){ +unsigned int pos,dist; +//int j=0; +//restart: + for(int i=0;iuse)continue; + pos=(listreturn+i)->loc; + dist=outptr-pos; + if((listreturn+i)->type==tk_RETURN){ + dist--; +// if(dist){ + if(dist>127/*&&i>=j*/)jumperror((listreturn+i)->line,mesRETURN); + output[pos]=(unsigned char)dist; +/* } + else{ + outptr-=2; + j=i; + (listreturn+i)->use=FALSE; + goto restart; + }*/ + } + else{ + dist-=(am32==0?2:4); +// if(dist){ + if(dist<128/*&&i>=j*/)warningjmp(mesRETURN,(listreturn+i)->line,currentfileinfo); + if(am32)*(unsigned long *)&output[pos]=dist; + else*(unsigned short *)&output[pos]=(unsigned short)dist; +/* } + else{ + outptr-=3; + if(am32)outptr-=2; + j=i; + (listreturn+i)->use=FALSE; + goto restart; + }*/ + } + } + free(listreturn); + listreturn=NULL; + numreturn=0; + } +} + +void RestoreSaveReg() +{ + if(psavereg->all){ + op(0x61); + addESP-=am32==FALSE?16:32; + } + else{ + for(int i=7;i>=0;i--){ + if(psavereg->reg[i]){ + op66(psavereg->reg[i]); + op(0x58+i); + addESP-=am32==FALSE?2:4; + } + } + } +} + +void AddRetList(int pos,int line,int type) +{ + if(numreturn==0)listreturn=(RETLIST *)MALLOC(sizeof(RETLIST)); + else listreturn=(RETLIST *)REALLOC(listreturn,sizeof(RETLIST)*(numreturn+1)); + (listreturn+numreturn)->loc=pos; + (listreturn+numreturn)->line=line; + (listreturn+numreturn)->type=type; +// (listreturn+numreturn)->use=TRUE; + if(type==tk_return)jumploc0(); + else outword(0x00EB); // JMP SHORT + numreturn++; +} + +void RetProc() +{ + if((current_proc_type&f_far)){ + if((current_proc_type&f_typeproc)==tp_cdecl)retf(); + else{ + if(paramsize==0)retf(); /* RETF */ + else{ + op(0xCA); + outword(paramsize); + } + } + } + else{ + if((current_proc_type&f_typeproc)==tp_cdecl)ret(); + else if(current_proc_type==f_interrupt)op(0xCF);//interrupt procedure IRET + else{ + if(paramsize==0)ret(); /* RET */ + else{ + op(0xC2); + outword(paramsize); + } + } + } +} + +void doreturn(int typer) /* do return(...); */ +{ +char sign=0; +int line=linenumber; +char *ofsstr=NULL; +int i; +unsigned int oaddESP=addESP; + if(tok2==tk_openbracket)nexttok(); + if((ofsstr=GetLecsem(tk_closebracket,tk_semicolon))){ + int retreg; + int razr=getrazr(returntype); + if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ + GetEndLex(tk_closebracket,tk_semicolon); + if(razr==r16)tok=tk_reg; + else if(razr==r32)tok=tk_reg32; + else tok=tk_beg; + itok.number=retreg==SKIPREG?AX:retreg; + goto nn1; + } + } + getoperand(); + if(tok!=tk_closebracket&&tok!=tk_semicolon){ +nn1: + switch(returntype){ + case tk_int: sign=1; + case tk_word: do_e_axmath(sign,r16,&ofsstr); break; + case tk_char: sign=1; + case tk_byte: doalmath(sign,&ofsstr); break; + case tk_long: sign=1; + case tk_dword: do_e_axmath(sign,r32,&ofsstr); break; + case tk_qword: + getintoreg64(EAX|(EDX*256)); + if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare)doregmath64(EAX|(EDX*256)); + break; + case tk_void: retvoid(); nexttok(); break; + case tk_double: +/* if(tok2==tk_closebracket)doregmath64(EAX|(EDX*256)); + else doeaxfloatmath(tk_reg64); + break;*/ + case tk_fpust: + doeaxfloatmath(tk_fpust); + break; + case tk_float: + if(itok2.type==tp_stopper&&(tok==tk_floatvar||tok==tk_number)){ + if(tok==tk_floatvar){ + tok=tk_dwordvar; + do_e_axmath(0,r32,&ofsstr); + } + else doeaxfloatmath(tk_reg32,0,0); + } + else{ + doeaxfloatmath(tk_stackstart,0,0); + op66(r32); + op(0x58); //pop eax + } + break; +// default: +// printf("returntype=%d\n",returntype); + } + } + if(tok==tk_closebracket)nexttok(); + seminext(); + if(ofsstr)free(ofsstr); + clearregstat(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + if(typer!=tokens){ + i=(am32==0?2:4); + if(typer==tk_RETURN)i=1; + if(paramsize||localsize)i--; + if(insertmode||((!optimizespeed)&¶msize&& + (current_proc_type&f_typeproc)!=tp_cdecl)||psavereg->size>i){ + if(numblocks>1){ // return goto + AddRetList(outptr+1,line,typer); + retproc=TRUE; + return; + } + else{ + setreturn(); + if(insertmode)return; + } + } + } + if(numblocks==1)setreturn(); //06.09.04 22:20 + if(!inlineflag)leaveproc(); + else{ + AutoDestructor(); + RestoreStack(); + RestoreSaveReg(); + RetProc(); + } + retproc=TRUE; + if(numblocks>1||(numblocks==1&&tok!=tk_closebrace))addESP=oaddESP; +} + +int IsSaveReg() +{ + if(psavereg->all)return TRUE; + for(int i=7;i>=0;i--){ + if(psavereg->reg[i])return TRUE; + } + return FALSE; +} + +void leaveproc() +{ + AutoDestructor(); + RestoreStack(); + RestoreSaveReg(); + if(ESPloc==FALSE||am32==FALSE){ + if(localsize)Leave(); + else if(paramsize)op(0x5D); /* POP BP */ + else if(initBP)Leave(); + } + else if(localsize){ + if(short_ok(localsize,TRUE)){ + outword(0xC483); + op(localsize); + } + else{ + outword(0xC481); + outdword(localsize); + } + } + RetProc(); +} + +DLLLIST *FindDLL() +{ +DLLLIST *newdll; + if(listdll!=NULL){ // DLL + for(newdll=listdll;stricmp(newdll->name,(char *)string)!=0;newdll=newdll->next){ + if(newdll->next==NULL){ // + newdll->next=(DLLLIST *)MALLOC(sizeof(DLLLIST));// + newdll=newdll->next; + newdll->next=NULL; + newdll->num=0; + newdll->list=NULL; + strcpy(newdll->name,(char *)string); + break; + } + } + } + else{ + listdll=newdll=(DLLLIST *)MALLOC(sizeof(DLLLIST)); + newdll->next=NULL; + newdll->num=0; + newdll->list=NULL; + strcpy(newdll->name,(char *)string); + } + return newdll; +} + +void declareextern() +{ +int next; + nexttok(); + if(comfile==file_w32&&strcmp(itok.name,"WINAPI")==0){ + nexttok(); + if(tok!=tk_string)stringexpected(); + DLLLIST *newdll; + newdll=FindDLL(); + nextexpecting2(tk_openbrace); // + APIPROC *listapi=newdll->list; + returntype=tk_declare; + do{ + if(tok==tk_enum)doenum(); + else if(tok==tk_struct)InitStruct(); + else{ + next=TRUE; + if(testInitVar(FALSE)!=FALSE)preerror("Error declare WINAPI"); + if(itok.rm==tokens)itok.rm=tk_dword; + if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); + ITOK hitok=itok; + int htok=tok; + param[0]=0; + hitok.sib=hitok.size=-1; + if(tok2==tk_period){ + nexttok(); + if(tok2==tk_number){ + nexttok(); + hitok.sib=itok.number; + } + } + if(tok2==tk_at){ + nexttok(); + if(tok2==tk_number){ + nexttok(); + hitok.size=itok.number; + } + } + else{ + nextexpecting2(tk_openbracket); + if((hitok.flag&f_typeproc)==tp_fastcall)declareparamreg(); + else declareparamstack(); + } + if(htok==tk_id||htok==tk_ID){ + tok=tk_apiproc; + itok=hitok; + itok.number=secondcallnum++; + itok.segm=NOT_DYNAMIC; + itok.post=dEBX|dEDI|dESI; //05.09.04 01:36 + strcpy((char *)string,param); + itok.type=tp_ucnovn; + if(newdll->num==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC)); // + else listapi=(APIPROC *)REALLOC(listapi,sizeof(APIPROC)*(newdll->num+1)); + (listapi+newdll->num)->recapi=addtotree(itok.name); + if(tok2==tk_openbracket){ + next=0; + nexttok(); + IsUses((listapi+newdll->num)->recapi); + } + newdll->num++; + } + else warningdefined(hitok.name); + if(next)nexttok(); + seminext(); + } + }while(tok!=tk_closebrace); + returntype=tokens; + newdll->list=listapi; + nexttok(); + } + else{ + itok.flag=f_extern; + switch(tok){ + case tk_far: + case tk_cdecl: + case tk_pascal: + case tk_stdcall: + case tk_fastcall: + case tk_declare: + case tk_undefproc: + case tk_ID: + case tk_id: + case tk_float: + case tk_long: + case tk_dword: + case tk_word: + case tk_byte: + case tk_char: + case tk_int: + case tk_void: + int j; + if((j=testInitVar())==FALSE)define_procedure(); + else if(j==TRUE)globalvar(); + break; + case tk_struct: InitStruct(); break; + default: preerror("Error declare extern"); + } + if((!fobj)&&(!sobj))preerror("extern using only for compilation obj files"); + } +} + +int testInitVar(int checkaldef) +{ +unsigned int ffar=0; +unsigned int fexport=0; +unsigned int tproc=0; +unsigned int fretproc=0; +int rettype=tokens; +unsigned int flag=itok.flag; +unsigned int npointr=0; + if(fstatic){ + flag|=f_static; + fstatic=FALSE; + } + if(tok==tk_inline){ + flag=f_inline; + nexttok(); + } + for(;;){ + if(tok==tk_far)ffar=f_far; + else if(tok==tk_export)fexport=f_export; + else if(tok>=tk_pascal&&tok<=tk_fastcall)tproc=tok; + else if((tok>=tk_void&&tok<=tk_double)||tok==tk_fpust){ + if(rettype!=tokens)unknowntype(); + rettype=tok; + } + else if(tok==tk_id){ + if(CheckDef())continue; + if(tok2==tk_dblcolon)goto classdecl; + if(tproc==0)tproc=(comfile==file_w32?tp_stdcall:tp_pascal); // + else tproc=(tproc-tk_pascal)*2; + break; + } + else if(tok==tk_ID){ + if(CheckDef())continue; + if(tok2==tk_dblcolon){ +classdecl: + itok.flag=(unsigned int)(flag|ffar|fexport|fretproc|f_classproc); + itok.rm=rettype; + itok.npointr=(unsigned short)npointr; + doclassproc(tproc); + return 2; + } + if(tproc==0)tproc=tp_fastcall; // + else tproc=(tproc-tk_pascal)*2; + break; + } + else if(tok==tk_undefproc||tok==tk_declare/*||tok==tk_apiproc*/){ + + flag|=itok.flag; //new 18.04.07 12:19 + + if(tproc==0){ + if(CidOrID()==tk_ID)tproc=tp_fastcall; + else tproc=(comfile==file_w32?tp_stdcall:tp_pascal); + } + else tproc=(tproc-tk_pascal)*2; // 17.09.05 17:06 + if((flag&f_extern)!=0||tproc!=(itok.flag&f_typeproc)|| + ffar!=(itok.flag&f_far)||(unsigned short)npointr!=itok.npointr|| + ((flag&f_static)&&(itok.flag&f_static)==0)){ + if(strcmp(itok.name,"main")){ + if(rettype==itok.rm||(rettype==tokens&&(itok.rm==(am32==0?tk_word:tk_dword))))break; +// printf("rm=%d rmnew=%d\n",itok.rm,rettype); + if(checkaldef)redeclare(itok.name); + } + } + break; + } + else if(tok==tk_proc||tok==tk_apiproc){ + if(checkaldef)idalreadydefined(); + break; + } + else if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_structvar||tok==tk_pointer){ + idalreadydefined(); + return 2; + } + else if(tok==tk_mult){ + do{ + npointr++; + nexttok(); + }while(tok==tk_mult); + if(rettype==tokens)rettype=am32==FALSE?tk_word:tk_dword; + continue; + } + else if(tok==tk_openbracket){ + if(tok2!=tk_mult){ + unuseableinput(); + return 2; + } + if(tproc!=0)tproc=(tproc-tk_pascal)*2; + itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc); + itok.rm=rettype; + itok.npointr=(unsigned short)npointr; + return TRUE; + } + else if((tok>=tk_overflowflag&&tok<=tk_notzeroflag)||tok==tk_minusflag|| + tok==tk_plusflag)fretproc=(tok-tk_overflowflag+1)*256; + else if(tok==tk_static)flag|=f_static; + else if(tok==tk_fpust)rettype=tk_fpust; + else{ + unuseableinput(); + return 2; + } + nexttok(); + } + itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc); + itok.rm=rettype; + itok.npointr=(unsigned short)npointr; + if(returntype==tk_declare&& + (tok2==tk_openbracket||tok2==tk_at||tok2==tk_period))return FALSE; + if(tok2==tk_openbracket)return CheckDeclareProc(); + if(rettype==tokens){ + thisundefined(itok.name);//02.09.04 20:55 was unuseableinput(); + return 2; + } + return TRUE; +/*-----------------23.12.01 02:11------------------- + rerurn: + FALSE - , + TRUE - + 2 - - . + --------------------------------------------------*/ +} + +int CidOrID() +{ +unsigned char cha; +unsigned char *string4=(unsigned char *)itok.name; + for(;;){ + cha=*string4; + if(cha>='a'&&cha<='z')return tk_id; + if(cha==0)break; + string4++; + } + return tk_ID; +} + +void unpackteg(structteg *tteg) +{ +int i; +elementteg *bazael; +structteg *newteg; +int ssize,count; +idrec *newrec,*ptr; + if(alignword){ // + if(am32==0){ + if(postsize%2==1)postsize++; + } + else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4); + } + bazael=tteg->baza; + string[0]=0; + for(i=0;inumoper;i++){ +// printf("tok=%d %s\n",(bazael+i)->tok,(bazael+i)->name); + switch((bazael+i)->tok){ + case tk_floatvar: + case tk_longvar: + case tk_dwordvar: + case tk_wordvar: + case tk_bytevar: + case tk_charvar: + case tk_intvar: + case tk_doublevar: + case tk_qwordvar: + ssize=GetVarSize((bazael+i)->tok); // + itok.type=tp_ucnovn; + tok=(bazael+i)->tok; + count=FindOff((unsigned char *)(bazael+i)->name,VARPOST); + itok.post=1; + itok.segm=DS; + itok.number=postsize; + itok.flag=tteg->flag; + itok.size=(bazael+i)->numel*ssize; + itok.rm=(am32==FALSE?rm_d16:rm_d32); + itok.npointr=0; + newrec=addtotree((bazael+i)->name); + newrec->count=count; + break; + case tk_struct: + case tk_structvar: + strcpy(itok.name,(bazael+i)->name); + newteg=(structteg *)(bazael+i)->nteg; + newrec=(struct idrec *)MALLOC(sizeof(struct idrec)); + ptr=((tteg->flag&f_static)==0?treestart:staticlist); // + if(ptr==NULL)((tteg->flag&f_static)==0?treestart:staticlist)=newrec;// + else{ // + while(((ssize=strcmp(ptr->recid,itok.name))<0&&ptr->left!=NULL)||(ssize>0&&ptr->right!=NULL)){ + ptr=(ssize<0?ptr->left:ptr->right); + } + (ssize<0?ptr->left:ptr->right)=newrec; // + } + newrec->recsib=0; + strcpy(newrec->recid,itok.name);// + newrec->newid=(char *)newteg; + newrec->left=NULL; + newrec->right=NULL; + newrec->rectok=tk_structvar; + newrec->flag=tteg->flag|newteg->flag; + newrec->line=linenumber; + newrec->file=currentfileinfo; + if(FixUp)newrec->flag|=f_reloc; + newrec->recrm=(bazael+i)->numel; + newrec->recsize=(bazael+i)->numel*newteg->size; + newrec->recpost=1; + count=FindOff((unsigned char *)newrec->recid,VARPOST); + newrec->count=count; + break; + default: + declareanonim(); + break; + } + } + AddPostData(tteg->size); +} + +void unpackteg2(structteg *tteg) +{ +int i; +elementteg *bazael; +structteg *newteg; +//idrec *newrec,*trec; +localrec *lrec; + bazael=tteg->baza; + string[0]=0; + for(i=0;inumoper;i++){ + switch((bazael+i)->tok){ + case tk_floatvar: + case tk_longvar: + case tk_dwordvar: + case tk_wordvar: + case tk_bytevar: + case tk_charvar: + case tk_intvar: + case tk_doublevar: + case tk_qwordvar: + lrec=addlocalvar((bazael+i)->name,(bazael+i)->tok,localsize); + lrec->rec.recsize=(bazael+i)->numel*GetVarSize((bazael+i)->tok); + lrec->rec.type=tp_localvar; + lrec->rec.npointr=0; + lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4)); + break; + case tk_struct: + case tk_structvar: + newteg=(structteg *)(bazael+i)->nteg; + lrec=addlocalvar((bazael+i)->name,tk_structvar,localsize); + lrec->rec.newid=(char *)tteg; + lrec->rec.flag=tteg->flag; + lrec->rec.type=tp_localvar; + lrec->rec.recrm=(bazael+i)->numel; + lrec->rec.recsize=(bazael+i)->numel*newteg->size; + lrec->rec.recpost=LOCAL; + lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4)); + break; + default: + declareanonim(); + break; + } + } + localsize+=tteg->size; + localsize=Align(localsize,(am32==FALSE?2:4)); +} + +unsigned long dounion(int Global,int flag) +{ +structteg *tteg; +int noname=FALSE; + nexttok(); + if(tok==tk_openbrace)noname=TRUE; + else if((tok!=tk_id&&tok!=tk_ID)||FindTeg(Global)||(Global==FALSE&&FindTeg(TRUE))){ + idalreadydefined(); + SkipBlock2(); + return 0; + } + if((tteg=CreatTeg(Global,TRUE,noname))!=NULL){ + if(tok==tk_semicolon){ + if(noname==TRUE){ + if(Global)unpackteg(tteg); + else unpackteg2(tteg); + if(tteg->baza)free(tteg->baza); + free(tteg); + } + nexttok(); + } + else{ + if(Global)InitStruct2(flag,tteg); + else return LocalStruct2(flag,0,0,0,tteg); + } + } + else declareunion(); + return 0; +} + +char *BackString(char *str) +{ + char *retbuf=(char *)MALLOC(strlen(str)+1); + strcpy(retbuf,str); + return retbuf; +} + + +void GetFileTime(int fd,struct ftime *buf) +{ +/* +struct stat sb; +struct tm *tblock; + fstat(fd,&sb); + tblock=localtime(&sb.st_atime); + buf->ft_tsec=tblock->tm_sec; + buf->ft_min=tblock->tm_min; + buf->ft_hour=tblock->tm_hour; + buf->ft_day=tblock->tm_mday; + buf->ft_month=tblock->tm_mon; + buf->ft_year=tblock->tm_year-80;*/ +} + +void CheckPosts() +{ + if(posts==maxposts){ + maxposts+=MAXPOSTS; + postbuf=(postinfo *)REALLOC(postbuf,maxposts*sizeof(postinfo)); + } +} + +void CheckRealizable() +{ + switch(tok){ + case tk_case: + case tk_CASE: + case tk_default: + case tk_closebrace: + return; + } + if(tok2==tk_colon)return; + if(notunreach){ + notunreach=FALSE; + return; + } + warningunreach(); +// preerror("Unreachable code"); +} + +void AddRegistr(int razr,int reg) +{ + if(razr==r8&®>3)reg-=4; + if(razr==r64){ + stat_reg[reg&255]=1; + stat_reg[reg/256]=1; + } + else stat_reg[reg]=1; +} + +void ClearRegister() +{ + for(int i=0;i<8;i++)stat_reg[i]=0; +} + +int GetRegister(int mode) +{ +int reg=SI; + if(am32!=FALSE||mode){ + if(stat_reg[AX]==0)reg=AX; + else if(stat_reg[SI]==0)reg=SI; + else if(stat_reg[DI]==0)reg=DI; + else if(stat_reg[BX]==0)reg=BX; + else if(stat_reg[CX]==0)reg=CX; + else if(stat_reg[DX]==0)reg=DX; + } + else{ + if(stat_reg[SI]==0)reg=SI; + else if(stat_reg[DI]==0)reg=DI; + else if(stat_reg[BX]==0)reg=BX; + } + return reg; +} + +void RegAddNum(int reg) +{ + if((!structadr.post)&&optnumadd(structadr.number,reg,am32==FALSE?r16:r32,0)!=FALSE)return; + if(reg==AX)op(5); + else{ + op(0x81); + op(0xC0+reg); + } + if(structadr.post)setwordpost(&structadr); + if(am32)outdword(structadr.number); + else outword(structadr.number); +} + +void RestoreStack() +{ + if(addstack&&sizestack){ + if(short_ok(sizestack,am32)){ + outword(0xC483); + op(sizestack); + } + else{ + outword(0xC481); + if(am32==FALSE)outword(sizestack); + else outdword(sizestack); + } +// printf("%s(%d)> Restore %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,sizestack); + addESP-=sizestack; + sizestack=0; + } +} + +void startblock() +{ +treelocalrec *nrec; + numblocks++; +// printf("start block %d\n",numblocks); + nrec=(treelocalrec*)MALLOC(sizeof(treelocalrec)); + nrec->level=numblocks; + nrec->lrec=NULL; + nrec->addesp=addESP; + nrec->next=tlr; + tlr=nrec; +} + +void endblock() +{ +treelocalrec *orec; +// printf("end block %d\n",numblocks); + orec=tlr; + tlr=tlr->next; + if(tlr)numblocks=tlr->level; + else numblocks=0; + if(orec->lrec==NULL){ + free(orec); + return; + } + orec->endline=linenumber; + orec->next=btlr; + btlr=orec; +// if(addESP!=orec->addesp)??? +} +/* end of TOKC.C */ diff --git a/programs/develop/cmm/toke.cpp b/programs/develop/cmm/toke.cpp new file mode 100644 index 0000000000..99878e22dd --- /dev/null +++ b/programs/develop/cmm/toke.cpp @@ -0,0 +1,4937 @@ +#define _TOKE_ + +#include +#include +#include "tok.h" + + +unsigned char gotoendif=FALSE; + +unsigned char atex=FALSE; + +unsigned char usedirectiv=TRUE; // ࠡ⪠ ४⨢ + +unsigned char parsecommandline = 0; // parse command line flag + +unsigned char sdp_mode=FALSE; //० ਭ㤨⥫쭮 㧪 ᪨ 楤 + +unsigned int startexit; + +extern int maxerrors; // number of errors to stop at + +unsigned int postnumflag; //䫠 ᫥ 䨪 ᫥ + +int calcnumber=FALSE; + + + +char mesmain[]="main"; + +char *macroname[]={"inp","inportb","inport","inportd","outp","outportb", + + "outport","outportd","sqrt","cos","sin","atan2", + + "tan","log","log10","exp","atan","fabs",NULL}; + +enum{m_ib,m_ibt,m_iw,m_id,m_ob,m_obt,m_ow,m_od,m_sqrt,m_cos,m_sin,m_atan2, + + m_tan,m_log,m_log10,m_exp,m_atan,m_fabs,m_end}; + + + +int FindProcLib(int); + +int RetAtExit(); + +int ConvRetCode(int i); + +int CompConst(int firstval); + +int dirmode; + + + +#define NUMIFDEF 32 //ᨬ쭠 ४⨢ ifdef/ifndef + +int endifcount=-1; // depth count of ?if + +char ujo[]="Unknown #jumptomain option"; + +char toelse[]="#else use once in #if"; + +char ido[]="Unknown #inline option"; + +unsigned char startuptomain=FALSE; + +unsigned char dosstring=FALSE; + +unsigned char useelse[NUMIFDEF]; //䫠 ᯮ짮 ४⨢ else + +unsigned char jumptomain = CALL_NEAR; // jump to the main() + +unsigned char resizemem = 1; // set owned memory block to 64K + +unsigned char fargc=FALSE; + +unsigned int startptrdata = 0x100; // data start address + +unsigned int resizesizeaddress; /* location of resize memory size descr. */ + +unsigned int stackstartaddress; /* location of SP assignment */ + + + +/*-----------------18.09.98 23:20------------------- + + SYS + +--------------------------------------------------*/ + +char sysname[8]="NO_NAME"; + +int sysatr=0x2000; + +int sysstack=0; + +int sysnumcom=0; + +int syscom; + +//६ 樨 rom-bios + +int unsigned romsize=0; + +int dataromstart,dataromsize; + +int dataseg=0x70; + + + +unsigned int numdomain=0; //᫮ 楤 ᪠ main + +char *domain; // 楤 ᪠ main + + + +int ifdefconst(); + +void CheckNumIF(); + +void KillVarOfTree(idrec **treestart); + +void IncludeFile(char *fileincl,int tfind); + + + +char *pragmalist[]={"option","line","startup","resource","pack","debug","indexregs",""}; + +enum{p_op,p_li,p_st,p_re,p_pa,p_db,p_idx,p_end}; + +int strpackdef=1; + +int strpackcur=1; + +struct STACKALIGN { + + STACKALIGN *prev; + + int size; + + char id[IDLENGTH]; + +}; + +#ifdef DEBUGMODE + +int debug=FALSE; + +#endif + + + +STACKALIGN *stackalign=NULL; + +/* -------------- constant math procedures start --------------- */ + + + +int calcqwordnumber(unsigned long long *retnum,unsigned long long number,int operand) + +{ + +unsigned long long value; + + value=*retnum; + + switch(operand){ + + case tk_minus: value-=number; break; + + case tk_plus: value+=number; break; + + case tk_xor: value^=number; break; + + case tk_and: value&=number; break; + + case tk_or: value|=number; break; + + case tk_mod: value%=number; break; + + case tk_div: value/=number; break; + + case tk_mult: value*=number; break; + + case tk_rr: value>>=number; break; + + case tk_ll: value<<=number; break; + + case tk_xorminus: value^=-number; break; + + case tk_andminus: value&=-number; break; + + case tk_orminus: value|=-number; break; + + case tk_modminus: value%=-number; break; + + case tk_divminus: value/=-number; break; + + case tk_multminus: value*=-number; break; + + case tk_rrminus: value>>=-number; break; + + case tk_llminus: value<<=-number; break; + + default: return FALSE; + + } + + *retnum=value; + + return TRUE; + +} + + + +unsigned long long doconstqwordmath() + +{ + +unsigned long long value; + +unsigned int htok; + +int fundef; //䫠 ᯮ짮 + + CheckMinusNum(); + + if(tok!=tk_number){ + + numexpected(); + + return(0); + + } + + if(itok.rm==tk_float)value=*(float *)&itok.number; + + else if(itok.rm==tk_double)value=*(double *)&itok.lnumber; + + else value=itok.lnumber; + + fundef=itok.rm; + + postnumflag=itok.flag; + +// usedirectiv=TRUE; + + calcnumber=TRUE; + + while(itok2.type==tp_opperand){ + + if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break; + + nexttok(); + + htok=tok; + + if(tok2!=tk_number){ + + if(tok2!=tk_dollar&&tok2!=tk_not){ + + calcnumber=FALSE; + + return(value); + + } + + nexttok(); + + if(tok!=tk_number){ + + calcnumber=FALSE; + + return(value); + + } + + } + + else nexttok(); + + if(itok.rm==tk_float)itok.number=*(float *)&itok.number; + + else if(itok.rm==tk_double)itok.lnumber=*(double *)&itok.lnumber; + + if(calcqwordnumber(&value,itok.lnumber,htok)==FALSE)beep(); + + postnumflag^=itok.flag; + + } + + nexttok(); + + calcnumber=FALSE; + + return(value); + +} + + + +int calcdwordnumber(unsigned long *retnum,unsigned long number,int operand) + +{ + +unsigned long value; + + value=*retnum; + + switch(operand){ + + case tk_minus: value-=number; break; + + case tk_plus: value+=number; break; + + case tk_xor: value^=number; break; + + case tk_and: value&=number; break; + + case tk_or: value|=number; break; + + case tk_mod: value%=number; break; + + case tk_div: value/=number; break; + + case tk_mult: value*=number; break; + + case tk_rr: value>>=number; break; + + case tk_ll: value<<=number; break; + + case tk_xorminus: value^=-number; break; + + case tk_andminus: value&=-number; break; + + case tk_orminus: value|=-number; break; + + case tk_modminus: value%=-number; break; + + case tk_divminus: value/=-number; break; + + case tk_multminus: value*=-number; break; + + case tk_rrminus: value>>=-number; break; + + case tk_llminus: value<<=-number; break; + + default: return FALSE; + + } + + *retnum=value; + + return TRUE; + +} + + + +unsigned long doconstdwordmath() + +{ + +unsigned long value; + +unsigned int htok; + +int fundef; //䫠 ᯮ짮 + + CheckMinusNum(); + + if(tok!=tk_number){ + + numexpected(); + + return(0); + + } + + if(itok.rm==tk_float)value=*(float *)&itok.number; + + else value=itok.number; + + fundef=itok.rm; + + postnumflag=itok.flag; + +// usedirectiv=TRUE; + + calcnumber=TRUE; + + while(itok2.type==tp_opperand){ + + if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break; + + nexttok(); + + htok=tok; + + if(tok2!=tk_number){ + + if(tok2!=tk_dollar&&tok2!=tk_not){ + + calcnumber=FALSE; + + return(value); + + } + + nexttok(); + + if(tok!=tk_number){ + + calcnumber=FALSE; + + return(value); + + } + + } + + else nexttok(); + + if(itok.rm==tk_float)itok.number=*(float *)&itok.number; + + if(itok.rm==tk_double)itok.number=*(double *)&itok.lnumber; + + if(calcdwordnumber(&value,itok.number,htok)==FALSE)beep(); + + postnumflag^=itok.flag; + + } + + nexttok(); + + calcnumber=FALSE; + + return(value); + +} + + + +int calclongnumber(long *retnum,long number,int operand) + +{ + +long value; + + value=*retnum; + + switch(operand){ + + case tk_minus: value-=number; break; + + case tk_plus: value+=number; break; + + case tk_xor: value^=number; break; + + case tk_and: value&=number; break; + + case tk_or: value|=number; break; + + case tk_mod: value%=number; break; + + case tk_div: value/=number; break; + + case tk_mult: value*=number; break; + + case tk_rr: value>>=number; break; + + case tk_ll: value<<=number; break; + + case tk_xorminus: value^=-number; break; + + case tk_andminus: value&=-number; break; + + case tk_orminus: value|=-number; break; + + case tk_modminus: value%=-number; break; + + case tk_divminus: value/=-number; break; + + case tk_multminus: value*=-number; break; + + case tk_rrminus: value>>=-number; break; + + case tk_llminus: value<<=-number; break; + + default: return FALSE; + + } + + *retnum=value; + + return TRUE; + +} + + + +signed long doconstlongmath() + +//᫨ ࠦ + +{ + +long value; + +unsigned int htok; + +int fundef; //䫠 ᯮ짮 + + CheckMinusNum(); + + if(tok!=tk_number){ + + numexpected(); + + return(0); + + } + + fundef=itok.rm; + + if(itok.rm==tk_float)value=*(float *)&itok.number; + + else value=itok.number; + +// value=itok.number; + + postnumflag=itok.flag; + +// usedirectiv=TRUE; + + calcnumber=TRUE; + + while(itok2.type==tp_opperand){ // ࠭ + + if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break; + + nexttok(); + +// printf("tok=%d tok2=%d\n",tok,tok2); + + htok=tok; + + if(tok2!=tk_number){ + + if(tok2!=tk_dollar&&tok2!=tk_not){ + + calcnumber=FALSE; + + return(value); + + } + + nexttok(); + + if(tok!=tk_number){ + + calcnumber=FALSE; + + return(value); + + } + + } + + else nexttok(); + + if(itok.rm==tk_float)itok.number=*(float *)&itok.number; + + if(itok.rm==tk_double)itok.number=*(double *)&itok.lnumber; + + if(calclongnumber(&value,itok.number,htok)==FALSE)beep(); + + postnumflag^=itok.flag; + + } + + nexttok(); + + calcnumber=FALSE; + + return(value); + +} + + + +int calcfloatnumber(float *retnum,float number,int operand) + +{ + +float value; + + value=*retnum; + + switch(operand){ + + case tk_minus: value-=number; break; + + case tk_plus: value+=number; break; + + case tk_div: value/=number; break; + + case tk_mult: value*=number; break; + + case tk_divminus: value/=-number; break; + + case tk_multminus: value*=-number; break; + + default: return FALSE; + + } + + *retnum=value; + + return TRUE; + +} + + + +long doconstfloatmath() + +//᫨ ࠦ + +{ + +float value; + + postnumflag=0; + + CheckMinusNum(); + + if(tok!=tk_number){ + + numexpected(); + + return(0); + + } + + if(itok.rm==tk_double)*(float *)&itok.number=itok.dnumber; + + else if(itok.rm!=tk_float){ + + float temp=itok.number; + + *(float *)&itok.number=temp; + + } + + value=itok.fnumber; + +// usedirectiv=TRUE; + + calcnumber=TRUE; + + while(itok2.type==tp_opperand){ // ࠭ + + nexttok(); + + if(tok2!=tk_number){ + + calcnumber=FALSE; + + return *(long *) &value;// ⢨ + + } + + if(itok2.rm==tk_double)*(float *)&itok2.number=itok2.dnumber; + + else if(itok2.rm!=tk_float)*(float *)&itok2.number=itok2.number; + + itok2.rm=tk_float; + + if(calcfloatnumber(&value,itok2.fnumber,tok)==FALSE)beep(); + + nexttok(); + + } + + nexttok(); + + calcnumber=FALSE; + + return *(long *) &value; + +} + + + +int calcdoublenumber(double *retnum,double number,int operand) + +{ + +double value; + + value=*retnum; + + switch(operand){ + + case tk_minus: value-=number; break; + + case tk_plus: value+=number; break; + + case tk_div: value/=number; break; + + case tk_mult: value*=number; break; + + case tk_divminus: value/=-number; break; + + case tk_multminus: value*=-number; break; + + default: return FALSE; + + } + + *retnum=value; + + return TRUE; + +} + + + +long long doconstdoublemath() + +//᫨ ࠦ + +{ + +double value; + + postnumflag=0; + + CheckMinusNum(); + + if(tok!=tk_number){ + + numexpected(); + + return(0); + + } + + if(itok.rm==tk_float){ + + itok.dnumber=*(float *)&itok.number; + + itok.rm=tk_double; + + } + + else if(itok.rm!=tk_double){ + + itok.dnumber=itok.lnumber; + + } + + value=itok.dnumber; + +// usedirectiv=TRUE; + + calcnumber=TRUE; + + while(itok2.type==tp_opperand){ // ࠭ + + nexttok(); + + if(tok2!=tk_number){ + + calcnumber=FALSE; + + return *(long long *) &value;// ⢨ + + } + + if(itok2.rm==tk_float)itok2.dnumber=*(float *)&itok2.number; + + else if(itok2.rm!=tk_double)itok2.dnumber=itok2.lnumber;; + + itok2.rm=tk_double; + + if(calcdoublenumber(&value,itok2.dnumber,tok)==FALSE)beep(); + + nexttok(); + + } + + nexttok(); + + calcnumber=FALSE; + + return *(long long *) &value; + +} + + + +/* ================= simple syntax procedures start =================== */ + + + +void nextseminext() + +{ + + nexttok(); + + seminext(); + +} + + + +void seminext() + +{ + + if(tok!=tk_semicolon)expected(';'); + + else nexttok(); + +} + + + +void beep() /* beep for any internal errors */ + +{ + + printf("\a"); + +} + + + +int expecting(int want) + +/* compares current token with want token. If different, issues error + + message and returns 1, else advances to next token and returns 0 */ + +{ + + if(want!=tok){ + + SwTok(want); + + return(1); + + } + + nexttok(); + + return(0); + +} + + + +void expectingoperand(int want) + +/* compares current token with want token. If different, issues error + + message and returns 1, else advances to next token and returns 0 */ + +{ + + if(want!=tok)SwTok(want); + + else getoperand(); + +} + + + +void SwTok(int want) + +{ + + switch(want){ + + case tk_closebracket: expected(')'); break; + + case tk_openbracket: expected('('); break; + + case tk_semicolon: expected(';'); break; + + case tk_colon: expected(':'); break; + + case tk_openblock: expected('['); break; + + case tk_closeblock: expected(']'); break; + + case tk_openbrace: expected('{'); break; + + case tk_closebrace: expected('}'); break; + + case tk_camma: expected(','); break; + + default: preerror("expecting a different token"); break; + + } + +} + + + +/*-----------------03.07.99 22:48------------------- + + ७ 楤 + + --------------------------------------------------*/ + +void outprocedure(unsigned char *array,unsigned int length) + +{ + + if((outptr+length)>=outptrsize)CheckCodeSize(); + + memcpy(output+outptr,array,length); + + outptr+=length; + + if(splitdata==0)outptrdata=outptr; + +} + + + +#define MMBANER 11 + +unsigned char aabaner[]={ + + 0x53,0x50,0x48,0x49,0x4E,0x58,0x43,0x2d,0x2d,ver1,ver2}; // SPHINXC--ver + + + +#define MMEXP 18 + +unsigned char aaEXP[]={ + + 0xD9,0xE8, // fld1 + + 0xD9,0xEA, //fldl2e + + 0xD8,0xCA, //fmul st, st(2) + + 0xDD,0xD2, //fst st(2) + + 0xD9,0xF8, //fprem + + 0xD9,0xF0, //f2xm1 + + 0xDE,0xC1, //faddp st(1), st + + 0xD9,0xFD, //fscale + + 0xDD,0xD9 }; //fstp st(1) + + + +void CallExitProcess() + +//맮 楤 ExitProcess + +{ + + tok=tk_id; + + searchvar("ExitProcess"); + + if(FastCallApi==TRUE){ + + outword(0x15FF); + + AddApiToPost(itok.number); + + } + + else{ + + addacall((unsigned int)itok.number,(unsigned char)CALL_32); + + callloc0(); /* produce CALL [#] */ + + } + +} + + + +int includeit(int type) + +{ + +int i=0; + + itok.post=1; + + if(strcmp("ABORT",itok.name)==0){ + + RestoreStack(); + + clearregstat(); + +#ifdef OPTVARCONST + + ClearLVIC(); + +#endif + + type=0; + + if(type==1&&dbg&2)AddCodeNullLine("ABORT()"); + + if(comfile==file_w32)outword(0xC031); //xor eax,eax + + if(atex==TRUE)i=RetAtExit(); + + if(i==0){ + + if(comfile==file_exe)outdword(0x21CD4CB4); + + else if(comfile==file_w32){ + + if(jumptomain!=CALL_NONE)jumploc(startexit); + + else{ + + op(0x50); + + CallExitProcess(); + + } + + } + + else outword(0x20CD); + + } + + retproc=TRUE; + + } + + else if(strcmp("ATEXIT",itok.name)==0){ + + if(type&&AlignProc)AlignCD(CS,alignproc); + + if(atex==FALSE)preerror("?atexit must be set for ATEXIT"); + + if(type==1&&dbg&2)AddCodeNullLine("ATEXIT()"); + + searchvar("__atexitproc"); + + itok2=itok; + + searchvar("__numatexit"); + + if(am32){ + + op(0x51); //push ecx + + outword(0x0D8B); //mov ecx,numatex + + if(itok.post)setwordpost(&itok); + + outdword(itok.number); + + outdword(0x7310F983); + + outdword(0x8D04890F); //cmp ecx,10 jnb bp mov [numatexit+4+ECX*4]=EAX + + if(itok2.post)setwordpost(&itok2); + + outdword(itok2.number); + + outword(0x05FF); //inc numatexit + + if(itok.post)setwordpost(&itok); + + outdword(itok.number); + + outword(0xC031); //xor eax,eax + + //bp: + + op(0x59); //pop ECX + + } + + else{ + + outword(0x368B); + + if(itok.post)setwordpost(&itok); + + outword(itok.number); + + op(0x83); + + outdword(0x0C7310FE); //cmp si,10 jnb + + outdword(0x8489F601); //si+=si + + if(itok2.post)setwordpost(&itok2); + + outword(itok2.number); + + outword(0x06FF); + + if(itok.post)setwordpost(&itok); + + outword(itok.number); + + outword(0xC031); + + } + + } + + else if(strcmp("EXIT",itok.name)==0){ + + RestoreStack(); + + clearregstat(); + +#ifdef OPTVARCONST + + ClearLVIC(); + +#endif + + type=0; + + if(dbg&2)AddCodeNullLine("EXIT()"); + + if(atex==TRUE)i=RetAtExit(); + + if(i==0){ + + if(comfile==file_w32){ + + if(jumptomain!=CALL_NONE)jumploc(startexit); + + else{ + + op(0x50); + + CallExitProcess(); + + } + + } + + else if(comfile==file_meos){ + + outdword(0xCDFFC883); + + op(0x40); + + } + + else outdword(0x21CD4CB4); + + } + + retproc=TRUE; + + } + + else return ConvRetCode(FindProcLib(type)); + + if(type==1)ret(); /* if it is a REG Proc not a MACRO */ + + return (am32==FALSE?tk_word:tk_dword); + +} + + + +int ConvRetCode(int i) + +{ + + switch(i){ + + case 0: return tk_void; + + case 1: return tk_char; + + case 2: return tk_byte; + + case 3: return tk_int; + + case 4: return tk_word; + + case 5: return tk_long; + + case 6: return tk_dword; + + case 7: return tk_float; + + default: return -1; + + } + +} + + + +int RetAtExit() + +{ + + if(comfile==file_exe||fobj!=FALSE||comfile==file_w32||comfile==file_meos){ + + jumploc(startexit); + + return 1; + + } + + else callloc(startexit); + + return 0; + +} + + + +int includeproc() + +{ + + return ConvRetCode(FindProcLib(1)); + +} + + + +/*-----------------18.01.99 22:42------------------- + + ய楤 + + --------------------------------------------------*/ + +int CheckMacros() + +{ + +int m,app=0,s32=0; + +unsigned int num; + +char *ofsstr=NULL; + +int razr; + + for(m=0;m=outptrsize)CheckCodeSize(); + + lseek(lhandl,ofs+sizeof(_HLIB_)+hlib.info[index].ofs,SEEK_SET); + + size=hlib.info[index].size; + + if(type!=1)size--; + + else if(dbg&2){ + + sprintf(m1,"%s()",itok.name); + + AddCodeNullLine(m1); + + } + + if(read(lhandl,output+outptr,size)!=size)break; + + outptr+=size; + + if(splitdata==0)outptrdata=outptr; + + if(cpudos1){ + + dos1=hlib.dosr[1]; + + dos2=hlib.dosr[0]; + + } + + else if(hlib.dosr[1]==dos1&&hlib.dosr[0]>dos2)dos2=hlib.dosr[0]; + + } + + clearregstat(); + +#ifdef OPTVARCONST + + ClearLVIC(); + +#endif + + return hlib.rettype; + + } + + ofs+=sizeof(_HLIB_)+hlib.size; + + lseek(lhandl,ofs,SEEK_SET); + + } + + return -1; + +} + + + +void addconsttotree(char *keystring,long long constvalue,int type) + +//⠢ ⠭ ॢ + +{ + +struct idrec *ptr,*newptr; + +int cmpresult; + + newptr=(struct idrec *)MALLOC(sizeof(struct idrec));// ⠭ + + ptr=definestart; + + if(ptr==NULL)definestart=newptr; + + else{ + + while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)||(cmpresult>0&&ptr->right!=NULL)){ + + if(cmpresult<0)ptr=ptr->left; + + else if(cmpresult>0)ptr=ptr->right; + + } + + if(cmpresult<0)ptr->left=newptr; + + else if(cmpresult>0)ptr->right=newptr; + + else{ + + free(newptr); + + if(ptr->newid){ + + free(ptr->newid); + + ptr->newid=NULL; + + } + + if(ptr->sbuf){ + + free(ptr->sbuf); + + ptr->sbuf=NULL; + + } + + ptr->recnumber=constvalue; + + ptr->recrm=type; + + ptr->rectok=tk_number; + + ptr->recsegm=DS; + + ptr->recpost=0; + + ptr->flag=0; + + ptr->recsize=0; + + return; + + } + + } + + strcpy(newptr->recid,keystring); + + newptr->newid=NULL; + + newptr->rectok=tk_number; + + newptr->reclnumber=constvalue; + + newptr->recsegm=DS; + + newptr->recrm=type; + + newptr->recpost=0; + + newptr->flag=0; + + newptr->recsize=0; + + newptr->left=NULL; + + newptr->right=NULL; + +// newptr->count=1; + +} + + + +void addtodefine(char *keystring)// ப ॢ define + +{ + +struct idrec *ptr,*newptr,*left=NULL,*right=NULL; + +int cmpresult; + +//뤥 + + newptr=(struct idrec *)MALLOC(sizeof(struct idrec)); + + ptr=definestart; //砫 ॢ + + if(ptr==NULL)definestart=newptr; + + else{ // ப ॢ + + while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)|| + + (cmpresult>0&&ptr->right!=NULL)){ + + if(cmpresult<0)ptr=ptr->left; + + else if(cmpresult>0)ptr=ptr->right; + + } + + if(cmpresult<0)ptr->left=newptr; //ப + + else if(cmpresult>0)ptr->right=newptr; + + else{ + + free(newptr); + + newptr=ptr; + + left=ptr->left; + + right=ptr->right; + + if(newptr->newid)free(newptr->newid); + + if(newptr->sbuf)free(newptr->sbuf); + + } + + } + + strcpy(newptr->recid,keystring);//᪮ + + newptr->newid=NULL; + + if(tok==tk_string){ + + newptr->newid=(char *)MALLOC(itok.number); + + memcpy(newptr->newid,string,itok.number); + + if(itok.rm==1)newptr->sbuf=BackString((char *)string3); + + } + + else{ + + if(string[0]!=0)newptr->newid=BackString((char *)string); + + newptr->sbuf=NULL; + + } + + newptr->rectok=tok; + + newptr->recnumber=itok.number; + + newptr->recsegm=itok.segm; + + newptr->recrm=itok.rm; + + newptr->recpost=itok.post; + + newptr->flag=itok.flag; + + newptr->recsize=itok.size; + + newptr->left=left; + + newptr->right=right; + + newptr->recsib=itok.sib; + + newptr->line=linenumber; + + newptr->file=currentfileinfo; + + newptr->count=0; + + newptr->type=itok.type; + + newptr->npointr=itok.npointr; + + itok.rec=newptr; + +} + + + +unsigned char get_directive_value() //return the 0 or 1 value for directive + +{ + + nexttok(); + + if(tok==tk_number){ + + if(doconstlongmath())return(1);//᫨ 祭 㫥 1 + + return(0); + + } + + numexpected(); + + nexttok(); + + return(0); + +} + + + +int GetStringAsIt() + +{ + +int tstr; + + if(tok2==tk_string){ + + nexttok(); + + tstr=1; + + } + + else{ + + inptr=inptr2; + + cha=cha2; + + whitespace(); + + if(cha=='<'){ + + tstr=0; + + for(int i=0;i'){ + + string3[i]=0; + + break; + + } + + if(cha==13||cha==26)goto errstr; + + string3[i]=cha; + + } + + nextchar(); + + } + + else{ + +errstr: + + stringexpected(); + + tstr=-1; + + } + + inptr2=inptr; + + linenum2=linenumber; + + cha2=cha; + + } + + return tstr; + +} + + + +void InitDefineConst() + +{ + + addconsttotree("TRUE",TRUE); + + addconsttotree("FALSE",FALSE); + + addconsttotree("__SECOND__",timeptr.tm_sec); + + addconsttotree("__MINUTE__",timeptr.tm_min); + + addconsttotree("__HOUR__",timeptr.tm_hour); + + addconsttotree("__DAY__",timeptr.tm_mday); + + addconsttotree("__MONTH__",timeptr.tm_mon); + + addconsttotree("__YEAR__",timeptr.tm_year+1900); + + addconsttotree("__WEEKDAY__",timeptr.tm_wday); + + addconsttotree("__VER1__",ver1); + + addconsttotree("__VER2__",ver2); + + tok=tk_string; + + itok.flag=zero_term; + + itok.rm=0; + + strcpy((char *)string,(char *)compilerstr); + + itok.number=strlen((char *)string); + + addtodefine("__COMPILER__"); + + strcpy((char *)string,asctime(&timeptr)); + + itok.number=strlen((char *)string)-1; + + string[itok.number]=0; + + addtodefine("__DATESTR__"); + + DateToStr((char *)string); + + itok.number=11; + + addtodefine("__DATE__"); + + sprintf((char *)string,"%02d:%02d:%02d",timeptr.tm_hour,timeptr.tm_min,timeptr.tm_sec); + + itok.number=8; + + addtodefine("__TIME__"); + + strcpy((char *)string,"struct"); + + tok=tk_struct; + + itok.number=6; + + addtodefine("class"); + +} + + + +char *AddTextToBuf(char *buf,int *size,int start,int add) + +{ + +int addsize; + + addsize=(add==0?itok.number-1:inptr)-start; + + *size+=addsize; + + if(!buf){ + + buf=(char *)MALLOC(*size+1+add); + + buf[0]=0; + + } + + else buf=(char *)REALLOC(buf,*size+1+add); + +// printf("size=%d %s\n",*size+1+add,(char *)(input+start)); + + strncat(buf,(char *)(input+start),addsize); + + buf[*size]=0; + + return buf; + +} + + + +void AddMacro(char *name,int numpar,char *paramstr) + +{ + +int start,size; + +char *bstring=NULL; + +idrec *ptr; + + start=inptr-1; + + size=0; + + do{ + + FastTok(2); + + if(tok==tk_comment1){ + + inptr=itok.number; + + cha=input[itok.number-1]; + + break; + + } + + if(tok==tk_comment2){ + + bstring=AddTextToBuf(bstring,&size,start,0); + + start=inptr-1; + + } + + }while(tok!=tk_endline&&tok!=tk_eof); + + bstring=AddTextToBuf(bstring,&size,start,1); + + strbtrim(bstring); + + size=strlen(bstring); + + bstring[size]=0x20; + + bstring[size+1]=0; + + inptr2=inptr; + + cha2=cha; + + linenum2=linenumber; + + tok=tk_macro; + + itok.size=numpar; + + string[0]=0; + +/* int i; + + for(i=0,size=0;inewid=paramstr; + + ptr->sbuf=bstring; + + ptr->line=linenumber-1; + +} + + + +void GetMacro(char *name) + +{ + +int size,nsize,numpar=0; + +char *paramstr; + + inptr=inptr2; + + cha=cha2; + + FastTok(0); + + FastTok(1); + + size=0; + + while(tok!=tk_closebracket&&tok!=tk_eof){ + + if(tok!=tk_id)varexpected(numpar+1); + + nsize=strlen(itok.name)+1; + + if(size==0)paramstr=(char *)MALLOC(nsize); + + else paramstr=(char *)REALLOC(paramstr,size+nsize); + + strcpy(paramstr+size,itok.name); + + size+=nsize; + + numpar++; + + FastTok(0); + + if(tok!=tk_closebracket){ + + if(tok!=tk_camma)expected(','); + + FastTok(1); + + } + + } + + if(tok==tk_eof)unexpectedeof(); + + AddMacro(name,numpar,paramstr); + +} + + + +int pushpop(int i) + +{ + +STACKALIGN *newpar; + + switch(i){ + + case 1: + + newpar=(STACKALIGN *)MALLOC(sizeof(STACKALIGN)); + + newpar->prev=stackalign; + + newpar->size=strpackcur; + + newpar->id[0]=0; + + stackalign=newpar; + + return TRUE; + + case 2: + + newpar=stackalign->prev; + + free(stackalign); + + stackalign=newpar; + + + + strpackcur=(stackalign!=NULL?stackalign->size:strpackdef); + + return TRUE; + + } + + return FALSE; + +} + + + +void doifdef(int intok) + +{ + +int defcond; + +int curcond; + +int bracket; + +int notflag; + +int next; + +int locrez,endrez,lastoper; + +int stopscan; + +unsigned int i; + +int oscanlexmode; + + dirmode=dm_if; + +/* string3[0]=cha2; + + int j=1; + + for(i=inptr2;input[i]>13;i++,j++)string3[j]=input[i]; + + string3[j]=0; + + printf("%s (%u) %s %s",(startfileinfo+currentfileinfo)->filename,linenumber,itok.name,string3); + + */ + + defcond=intok; + + if(intok==d_if||intok==d_elif)defcond=d_ifdef; + + curcond=defcond; + + oscanlexmode=scanlexmode; + + bracket=0; + + lastoper=tk_oror; + + endrez=0; + + stopscan=FALSE; + + do{ + + scanlexmode=DEFLEX; + + nexttok(); + + notflag=FALSE; + + next=TRUE; + + while(tok==tk_openbracket){ + + nexttok(); + + bracket++; + + } + + if(tok==tk_not){ + + notflag=TRUE; + + nexttok(); + + } + + if(tok==tk_id&&strcmp("defined",itok.name)==0){ + + nexttok(); + + curcond=(notflag==FALSE?d_ifdef:d_ifndef); + + } + + while(tok==tk_openbracket){ + + nexttok(); + + bracket++; + + } + +// printf("tok=%d type2=%d\n",tok,itok2.type); + + if(tok==tk_number){ + + locrez=1; + + if(itok2.type==tp_opperand){ + + i=doconstdwordmath(); + + next=0; + + if(itok.type==tp_compare)locrez=CompConst(i); + + } + + else if(itok2.type==tp_compare){ + + i=itok.number; + + nexttok(); + + locrez=CompConst(i); + + } + + } + + else if((locrez=ifdefconst())==2){ + + if(tok==tk_id||tok==tk_ID){ + + if(FindTeg(TRUE))locrez=1; + + else locrez=0; + + } + + else locrez=1; + + } + + if(curcond==d_ifndef)locrez^=1; + + if(stopscan==FALSE){ + + if(lastoper==tk_oror)endrez|=locrez; + + else{ + + endrez&=locrez; + + if(endrez==FALSE)stopscan=TRUE; + + } + + } + +// printf("lastoper=%d endrez=%d locrez=%d\n",lastoper,endrez,locrez); + + if(next)nexttok(); + + while(tok==tk_closebracket){ + + nexttok(); + + bracket--; + + } + + if(tok==tk_endline||tok2==tk_endline){ + + scanlexmode=oscanlexmode; + +// retoldscanmode(oscanlexmode); + + dirmode=dm_other; + + nexttok(); + + break; + + } + + if(tok==tk_oror||tok==tk_andand)lastoper=tok; + + else{ + + preerror("bad token in 'ifdef/ifndef/if'"); + +// printf("tok=%d\n",tok); + + } + + }while(tok!=tk_eof&&tok!=tk_endline); + + dirmode=dm_other; + + scanlexmode=oscanlexmode; + +// retoldscanmode(oscanlexmode); + + if(bracket>0)preerror("missing ')'"); + + else if(bracket<0)preerror("extra ')'"); + + gotoendif=1^endrez; + + if(intok!=d_elif){ + + endifcount++; + + CheckNumIF(); + + useelse[endifcount]=1; + + } + +// printf(" %s endifcount=%d\n",endrez==0?"FALSE":"TRUE",endifcount); + +} + + + +void InitIdxRegs() + +{ + +unsigned char lreg[8]; + +int i,j; + + for(i=0;i<8;i++)lreg[i]=0; + + nexttok(); + +// printf("tok=%d %s\n",tok,itok.name); + + for(i=0;tok==tk_reg32||tok==tk_reg||tok==tk_beg;i++){ + + if(i<4){ + + if(tok==tk_beg&&itok.number>3)itok.number-=4; + + idxregs[i]=itok.number; + + if(lreg[itok.number])preerror("expected unique register for \"pragma indexregs\""); + + lreg[itok.number]=1; + + } + + nexttok(); + + if(tok==tk_camma)nexttok(); + + } + + lreg[ESP]=lreg[EBP]=1; + + for(;i<4;i++){ + + if(lreg[idxregs[i]]==0)lreg[idxregs[i]]=1; + + else{ + + for(j=7;j>=0;j--){ + + if(lreg[j]==0){ + + lreg[j]=1; + + idxregs[i]=j; + + break; + + } + + } + + } + + } + +} + + + +void directive() + +{ + +unsigned char next=1; + +char holdid[IDLENGTH]; + +long longhold,longhold2; + +long long llhold; + +unsigned int i; + +int oscanlexmode; + + holdid[0]=DS; + + usedirectiv=TRUE; + + dirmode=dm_other; + + switch(itok.number){ + + case d_alignc: + + holdid[0]=CS; + + case d_align: //ᯮ짮 ⠢ ᫨ + + if(notdoneprestuff==TRUE)doprestuff(); //砫 + + i=2; + + nexttok(); + + next=0; + + if(tok==tk_number){ + + i=doconstlongmath(); + + if(i<2)i=2; + + } + + i=AlignCD(holdid[0],i); + + if(holdid[0]==DS)alignersize+=i; + + break; + + case d_aligner://祭 ⠢ + + nexttok(); + + if(tok==tk_number){ + + aligner=(unsigned char)doconstlongmath();//᫨ 祭 + + next=0; + + } + + else numexpected(); + + break; + + case d_alignw://ࠢ ᮢ + + alignword=get_directive_value(); + + next=0; + + break; + +// case d_beep: beep(); break; + + case d_code: optimizespeed=0; break; + + case d_ctrl: + + killctrlc=get_directive_value(); + + next=0; + + break; + + case d_define: + + dirmode=dm_def0; + + oscanlexmode=scanlexmode; + + scanlexmode=DEFLEX2; + + nexttok(); + + scanlexmode=DEFLEX; + + dirmode=dm_def; + + strcpy(holdid,itok.name); + +// printf("1 line=%d\n",linenumber); + +// printf("tok=%d %s\n",tok,itok.name); + + if(tok==tk_id||tok==tk_ID){ + + if(cha2=='('){ + + GetMacro(holdid); + + } + + else{ + + longhold=inptr2; + + longhold2=cha2; + + nexttok(); + +// printf("2 line=%d\n",linenumber); + + i=tk_dword; + + if((tok==tk_float||tok==tk_double||tok==tk_qword)&&(tok2==tk_minus||tok2==tk_number)){ + + i=tok; + + nexttok(); + + } + +// printf("tok=%d tok2=%d %s %s\n",tok,tok2,itok.name,string); + + if(tok!=tk_endline&&tok!=tk_minus&&tok!=tk_number&&tok2!=tk_endline&&tok2!=tk_semicolon){ + + inptr=longhold; + + cha=longhold2; + + AddMacro(holdid,0,NULL); + + } + + else{ + + switch(tok){ + + case tk_structvar: + + struct idrec *ptrs,*ptrsnew; + + ptrs=itok.rec; + + addtodefine(holdid); + + ptrsnew=itok.rec; + + if(ptrsnew->newid)free(ptrsnew->newid); + + ptrsnew->newid=ptrs->newid; + + break; + + case tk_eof: unexpectedeof(); break; + + case tk_string: + +// printf("tok=%d tok2=%d %s %s\n",tok,tok2,itok.name,string); + + if(cha2==13&&itok.name[0]==0){ + + cha2=input[inptr2]; + + inptr2++; + + } + + goto endef; + + case tk_minus: + + if(tok2==tk_number){ + + if(i==tk_dword&&(itok2.rm==tk_float||itok2.rm==tk_double|| + + itok2.rm==tk_qword))i=itok2.rm; + + case tk_number: + + if(i==tk_dword&&(itok.rm==tk_float||itok.rm==tk_double||itok.rm==tk_qword))i=itok.rm; + + switch(i){ + + case tk_float: + + llhold=doconstfloatmath(); + + break; + + case tk_double: + + llhold=doconstdoublemath(); + + break; + + case tk_qword: + + llhold=doconstqwordmath(); + + break; + + default: + + llhold=doconstdwordmath(); + + break; + + } + + itok.flag=(unsigned char)postnumflag; + + addconsttotree(holdid,llhold,i); + + next=0; + + break; + + } + + case tk_proc: + + case tk_apiproc: + + case tk_declare: + + case tk_undefproc: + + tok=tk_id; + + strcpy((char *)string,itok.name); + + default: + +endef: + + if(itok.type!=tp_modif)itok.type=tp_ucnovn; + + addtodefine(holdid); break; + + } + + } + + } + + } + + else idalreadydefined(); + +// retoldscanmode(oscanlexmode); + + scanlexmode=oscanlexmode; + + if(tok==tk_endline){ + +// nextchar(); + + nexttok(); + + next=0; + + } + +// printf("3 line=%d cha=%02X\n",linenumber,cha2); + + break; + + case d_DOS: + + nexttok(); + + if(tok==tk_number){ + + longhold=doconstlongmath(); + + longhold2=dos1*256+dos2; + + if(longhold>longhold2){ + + dos1=(unsigned char)(longhold/256); + + dos2=(unsigned char)(longhold%256); + + } + + next=0; + + } + + else numexpected(); + + break; + + case d_endif: + + if(endifcount==-1) preerror("?endif without preceeding ?if"); + + else endifcount--; + +// printf("%s (%u) endif: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount); + + break; + + case d_ifdef: + + case d_if: + + case d_ifndef: + + doifdef(itok.number); + + if(gotoendif==0)useelse[endifcount]|=2; + + next=0; + + break; + + case d_incl: + + i=GetStringAsIt(); + + usedirectiv=FALSE; + + if((int)i!=-1){ + + char *a; + + if((a=strrchr((char *)string3,'.'))!=NULL){ + + if(stricmp(a,".obj")==0){ + + AddNameObj((char *)string3,i,0); + + break; + + } + + if(stricmp(a,".lib")==0){ + + AddNameObj((char *)string3,i,1); + + break; + + } + + } + +// puts((char *)string3); + + IncludeFile((char *)string3,i); + + } + + break; + + case d_jump: + + nexttok(); + + if(tok==tk_number){ + + jumptomain=CALL_NEAR; + + if((unsigned int)itok.number==0){ + + jumptomain=CALL_NONE; + + header=0; + + } + + } + + else if(stricmp(itok.name,"NONE")==0){ + + jumptomain=CALL_NONE; + + header=0; + + } + + else if(stricmp(itok.name,"SHORT")==0)jumptomain=CALL_SHORT; + + else if(stricmp(itok.name,"NEAR")==0)jumptomain=CALL_NEAR; + + else preerror(ujo); + + break; + + case d_error: + + nexttok(); + + if(tok==tk_number){ + + maxerrors=doconstlongmath(); + + next=0; + + } + + else numexpected(); + + break; + + case d_command: + + parsecommandline=get_directive_value(); + + next=0; + + break; + + case d_argc: + + parsecommandline=fargc=get_directive_value(); + + next=0; + + break; + + case d_print: + + nexttok(); + + i=0; + + if(strcmp(itok.name,"error")==0){ + + i=1; + + nexttok(); + + } + + switch(tok){ + + case tk_string: + + printf("%s",string); + + break; + + case tk_number: + + printf("\n%u",itok.number); + + break; + + default: preerror("unsupported token for #print"); break; + + } + + if(i)exit(e_preprocess); + + break; + + case d_prnex: + + nexttok(); + + if(tok==tk_number)printf("%X",itok.number); + + else numexpected(); + + break; + + case d_random: + + if(notdoneprestuff==TRUE)doprestuff(); + + op(rand()); + + break; + + case d_resize: + + resizemem=get_directive_value(); + + next=0; + + break; + + case d_resmes: + + nexttok(); + + if(tok==tk_string){ + + itok.flag=dos_term; + + addtotree("__RESIZEMESSAGE"); + + addconsttotree("__resizemessage",TRUE); + + } + + else stringexpected(); + + break; + + case d_speed: optimizespeed=1; break; + + case d_stack: + + nexttok(); + + if(tok==tk_number){ + + longhold=doconstlongmath(); + + if(am32==FALSE&&(longhold>0xFEFF||longhold<0))preerror("invalid size for stack"); + + else{ + + if(comfile!=file_sys)stacksize=longhold; + + else sysstack=longhold; + + } + + next=0; + + } + + else numexpected(); + + break; + + case d_start: + + nexttok(); + + if(comfile==file_com){ + + if(tok==tk_number){ + + startptrdata=startptr=doconstlongmath(); + + if(startStartup!=0x100)startStartup=startptr; + + } + + else{ + + numexpected(); + + nexttok(); + + } + + next=0; + + } + + else OnlyComFile(); + + break; + + case d_8086: case d_8088: chip=0; break; + + case d_80186: chip=1; break; + + case d_80286: chip=2; break; + + case d_80386: chip=3; break; + + case d_80486: chip=4; break; + + case d_80586: chip=5; break; + + case d_80686: chip=6; break; + + case d_80786: chip=7; break; + + case d_atr: + + nexttok(); + + if(tok==tk_number){ + + sysatr=doconstlongmath(); + + next=0; + + } + + else numexpected(); + + break; + + case d_name: + + nexttok(); + + if(tok==tk_string){ + + int i; + + for(i=0;i<8&&string[i]!=0;i++)sysname[i]=string[i]; + + for(;i<8;i++)sysname[i]=' '; + + } + + else stringexpected(); + + break; + + case d_com: //ᯨ᮪ SYS + + listcom=(LISTCOM *)MALLOC(sizeof(LISTCOM)*MAXSYSCOM); + + do{ + + nexttok(); + + if(tok==tk_id||tok==tk_ID){ + + strncpy((listcom+sysnumcom)->name,(char *)string,32); + + (listcom+sysnumcom)->name[32]=0; + + sysnumcom++; + + } + + else{ + + idalreadydefined(); + + break; + + } + + nexttok(); + + if(tok==tk_semicolon)break; + + if(tok!=tk_camma){ + + expected(','); + + break; + + } + + }while(sysnumcom<=MAXSYSCOM); + + if(sysnumcom>MAXSYSCOM)preerror("to many commands"); + + else if(sysnumcom!=0&&sysnumcom!=MAXSYSCOM)listcom=(LISTCOM *)REALLOC(listcom,sysnumcom*sizeof(LISTCOM)); + + break; + + case d_sdp: //㧨 ᪨ 楤 + + next=notdoneprestuff; + + sdp_mode=TRUE; + + usedirectiv=FALSE; + + docalls(); + + sdp_mode=FALSE; + + notdoneprestuff=next; + + next=1; + + break; + + case d_warning: + + warning=get_directive_value(); + + next=0; + + break; + + case d_ip: + + if( GetStringAsIt()!=-1)IncludePath((char *)string3); + + break; + + case d_us: //ᯮ짮 STARTUP + + if(comfile==file_com)useStartup=TRUE; + + break; + + case d_suv: // 砫 ᯮ짮 樠஢ ६ + + nexttok(); + + if(comfile==file_com){ + + if(tok==tk_number)startStartup=doconstlongmath(); + + else{ + + numexpected(); + + nexttok(); + + } + + next=0; + + } + + else OnlyComFile(); + + break; + + case d_iav: //樠஢ ६ + + notpost=get_directive_value(); + + next=0; + + break; + + case d_atex: //堭 ATEXIT + + atex=TRUE; + + break; + + case d_dseg: //ᥣ rom-bios + + nexttok(); + + if(tok==tk_number){ + + dataseg=doconstlongmath(); + + next=0; + + } + + else numexpected(); + + break; + + case d_rsize: //ࠧ rom-bios + + nexttok(); + + if(tok==tk_number){ + + romsize=doconstlongmath(); + + next=0; + + } + + else numexpected(); + + break; + + case d_mdr: //७ + + splitdata=modelmem=get_directive_value(); + + next=0; + + break; + + case d_am32: //32 ⭠ + + nexttok(); + + if(tok!=tk_number)numexpected(); + + else am32=(unsigned char)(itok.number==0?FALSE:TRUE); + + break; + + case d_undef: //undef + + oscanlexmode=scanlexmode; + + scanlexmode=DEFLEX2; + + nexttok(); + + scanlexmode=oscanlexmode; + +// retoldscanmode(oscanlexmode); + + if(tok==tk_string){ + + strcpy(itok.name,(char *)string); + + KillVarOfTree(&treestart); + + } + + else KillVarOfTree(&definestart); + + break; + + case d_stm: //startuptomain + + startuptomain=TRUE; + + break; + + case d_ib: //imagebase + + nexttok(); + + ImageBase=doconstlongmath(); + + next=0; + + break; + + case d_fut: //fixuptable + + FixUpTable=get_directive_value(); + + next=0; + + break; + + case d_fca: //fastcallapi + + FastCallApi=get_directive_value(); + + next=0; + + break; + + case d_dstr: + + dosstring=get_directive_value(); + + next=0; + + break; + + case d_cv: + + int v1,v2; + + v1=v2=0; + + cha=cha2; + + inptr=inptr2; + + linenumber=linenum2; + + whitespace(); //ய ᨬ + + while(isdigit(cha)){ + + v1=v1*10+(cha-'0'); + + nextchar(); + + } + + if(cha!='.')expected('.'); + + nextchar(); + + i=0; + + while(isdigit(cha)){ + + v2=v2*10+(cha-'0'); + + nextchar(); + + i++; + + } + + while(i<3){ + + v2=v2*10; + + i++; + + } + + cha2=cha; + + inptr2=inptr; + + linenum2=linenumber; + + if(v1>=ver1){ + + if(v1==ver1&&v2<=ver2)break; + + } + + sprintf((char *)string,"needed compiler version %0u.%03u or best",v1,v2); + + preerror((char *)string); + + break; + + case d_else: + + if(endifcount==-1) preerror("#else without preceeding #if"); + + else if((useelse[endifcount]&1)==0)preerror(toelse); + + else useelse[endifcount]&=0xFE; + + if(gotoendif==1) gotoendif=0; + + else gotoendif=1; + + break; + + case d_elif: + + if(endifcount==-1) preerror("#elif without preceeding #if"); + + doifdef(d_elif); + + next=0; + + gotoendif=1; + + break; + + case d_wmb: //ନ஢ win + + WinMonoBlock=get_directive_value(); + + next=0; + + break; + + case d_pragma: + + char *ptr; + + inptr=inptr2; + + cha=cha2; + + FastTok(1); + +// printf("%c %s\n",cha,itok.name); + + i=0; + + while(cha!=13&&cha!=26){ + + if(cha=='/'){ + + if(input[inptr]=='/'){ + + while(cha!=13&&cha!=26)nextchar(); + + break; + + } + + if(input[inptr]=='*'){ + + while(cha!=26){ + + nextchar(); + + if(cha=='*'&&input[inptr]=='/'){ + + nextchar(); + + nextchar(); + + break; + + } + + if(cha==13)linenumber++; + + } + + break; + + } + + } + + string[i++]=cha; + + nextchar(); + + } + + cha2=cha; + + inptr2=inptr; + + linenum2=linenumber; + + string[i]=0; + + strbtrim((char *)string); + +// printf("%s %s\n",itok.name,string); + + if(strlen((char *)string))ptr=BackString((char *)string); + + else ptr=NULL; + + for(i=0;ifilename,linenumber,ptr==NULL?"":ptr); + + break; + + case p_st: + + i=0; + + char c; + + do{ + + c=ptr[i++]; + + }while(isalnum(c)||c=='_'); + + ptr[i]=0; + + if(numdomain==0)domain=(char *)MALLOC(IDLENGTH); + + else domain=(char *)REALLOC(domain,IDLENGTH*(numdomain+1)); + + strcpy(domain+numdomain*IDLENGTH,ptr); + + numdomain++; + + break; + + case p_re: + + if(strcmp(ptr,"start")==0){ + + scanlexmode=RESLEX; + + input_res(); + + } + + else if(strcmp(ptr,"end")==0) + + scanlexmode=STDLEX; + +// retoldscanmode(STDLEX); + + else preerror("for '#pragma resource' used only 'start' or 'end'"); + + break; + + case p_db: + +#ifdef DEBUGMODE + + if(strcmp(ptr,"start")==0){ + + debug=TRUE; + + } + + else if(strcmp(ptr,"end")==0)debug=FALSE; + + else unknownpragma("debug"); + +#endif + + break; + + case p_pa: + +// printf("ptr=%08X input=%08X tok=%d\n",ptr,input,tok); + + SetNewStr(ptr); + + displaytokerrors=1; + + FastTok(1); + + if(tok!=tk_openbracket){ + + expected('('); + + break; + + } + + FastTok(1); + + if(tok==tk_closebracket)strpackcur=strpackdef; + + i=0; + + STACKALIGN *newpar; + + while(tok!=tk_closebracket&&tok!=tk_eof){ + + switch(tok){ + + case tk_number: + + if(caselong(itok.number)==NUMNUM){ + + preerror("bad align size"); + + break; + + } + + if(pushpop(i))i=3; + + strpackcur=itok.number; + + break; + + case tk_id: + + if(strcmp(itok.name,"push")==0){ + + if(i)unknownpragma("pack(push)"); + + i=1; + + } + + else if(strcmp(itok.name,"pop")==0){ + + if(i)unknownpragma("pack(pop)"); + + i=2; + + } + + else if(strcmp(itok.name,"show")==0){ + + printf("%s (%u) Current packing alignment for structure = %d\n",(startfileinfo+currentfileinfo)->filename,linenumber,strpackcur); + + i=3; + + } + + else{ + + switch(i){ + + case 0: + + unknownpragma("pack"); + + break; + + case 1: + + newpar=(STACKALIGN *)MALLOC(sizeof(STACKALIGN)); + + newpar->prev=stackalign; + + newpar->size=strpackcur; + + strcpy(newpar->id,itok.name); + + stackalign=newpar; + + i=3; + + break; + + case 2: + + while(stackalign!=NULL&&strcmp(itok.name,stackalign->id)!=0){ + + newpar=stackalign->prev; + + free(stackalign); + + stackalign=newpar; + + } + + if(stackalign==NULL){ + + strpackcur=strpackdef; + + warpragmapackpop(); + + break; + + } + + newpar=stackalign->prev; + + free(stackalign); + + stackalign=newpar; + + strpackcur=(stackalign==NULL?strpackdef:stackalign->size); + + i=3; + + break; + + default: + + unknownpragma("pack"); + + break; + + } + + } + + } + + FastTok(1); + + if(tok==tk_camma)FastTok(1); + + } + + pushpop(i); + +// printf("ptr=%08X input=%08X tok=%d\n",ptr,input,tok); + + inptr2=inptr; + + cha2=cha; + + while(ptr==(char*)input)nexttok(); + + next=0; + + break; + + case p_idx: + + SetNewStr(ptr); + + inptr2=1; + + InitIdxRegs(); + + next=0; + + break; + + default: + + unknownpragma(""); + + break; + + } + + if(ptr)free(ptr); + + break; + + case d_inline: + + nexttok(); + + if(tok==tk_number){ + + if(itok.number>=0&&itok.number<=2)useinline=itok.number; + + else preerror(ido); + + } + + else if(strcmp(itok.name,"AUTO")==0)useinline=2; + + else preerror(ido); + + break; + + default: + + preerror("compiler directive expected"); + + } + + if(next)nexttok(); + + while(gotoendif){ + + if(tok==tk_question){ + + if(itok.number==d_endif){ + + gotoendif--; + + endifcount--; + +// printf("%s (%u) endif shadow: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount); + + } + + else if(itok.number==d_ifdef||itok.number==d_ifndef||itok.number==d_if){ + + gotoendif++; + + endifcount++; + +// printf("%s (%u) if shadow: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount); + + CheckNumIF(); + + useelse[endifcount]=1; + + } + + else if(itok.number==d_else){ + + if((useelse[endifcount]&1)==0)preerror(toelse); + + else useelse[endifcount]&=0xFE; + + if(gotoendif==1&&useelse[endifcount]==0){ + + gotoendif=0; + + useelse[endifcount]|=2; + + } + + } + + else if(itok.number==d_elif){ + + if(gotoendif==1){ + + doifdef(d_elif); + + if(gotoendif==0){ + + if((useelse[endifcount]&2)==0){ + + useelse[endifcount]|=2; + + break; + + } + + gotoendif=1; + + } + + } + + } + + } + + else if(tok==tk_eof){ + + unexpectedeof(); + + break; + + } + + if(gotoendif)FindDirectiv(); + + else{ + + nexttok(); + + break; + + } + + } + + usedirectiv=FALSE; + + dirmode=dm_none; + +} + + + +void doenum() + +{ + +long counter=0; + +unsigned char next; + +char holdid[IDLENGTH]; + + nexttok(); + + if(tok!=tk_openbrace){ + + if(tok2!=tk_openbrace)expected('{'); + + nexttok(); + + } + + do{ + + next=1; + + nexttok(); + + switch(tok){ + + case tk_ID: + + case tk_id: + + strcpy(holdid,(char *)string); + + if(tok2==tk_assign){ + + nexttok(); + + nexttok(); + + CheckMinusNum(); + + if(tok==tk_number){ + + counter=doconstlongmath(); + + next=0; + + postnumflag=0; + + } + + else numexpected(); + + } + + addconsttotree(holdid,counter); + + counter++; + + break; + + case tk_closebrace: + + next=0; + + break; + + default: + + idalreadydefined(); + + break; + + } + + if(next)nexttok(); + + }while(tok==tk_camma); + + if(tok!=tk_closebrace)expected('}'); + + nextseminext(); + +} + + + +int CompConst(int firstval) + +{ + + int otok=tok; + + nexttok(); + + if(tok!=tk_number)unknowncompop(); + + switch(otok){ + + case tk_equalto: + + if(firstval==itok.number)return TRUE; + + break; + + case tk_notequal: + + if(firstval!=itok.number)return TRUE; + + break; + + case tk_greater: + + if(firstval>itok.number)return TRUE; + + break; + + case tk_less: + + if(firstval=itok.number)return TRUE; + + break; + + case tk_lessequal: + + if(firstval<=itok.number)return TRUE; + + break; + + default: unknowncompop(); + + } + + return FALSE; + +} + + + +int ifdefconst() + +{ + + if(optimizespeed==TRUE){ + + if(strcmp((char *)string,"speed")==0)return TRUE; + + } + + else if(strcmp((char *)string,"codesize")==0)return TRUE; + + if(strcmp((char *)string,"cpu")==0){ + + nexttok(); + + return CompConst(chip); + + } + + if(itok2.type==tp_compare){ + +// unknowncompop(); + + nexttok(); + + nexttok(); + + return FALSE; + + } + + if(comfile==file_w32&&strcmp((char *)string,"_WIN32")==0)return TRUE; + + if(*(short *)&string[0]==0x5F5F){ + + if(comfile==file_w32){ + + if(strcmp((char *)string+2,"TLS__")==0)return TRUE; + + if(dllflag&&strcmp((char *)string+2,"DLL__")==0)return TRUE; + + else{ + + if(wconsole&&strcmp((char *)string+2,"CONSOLE__")==0)return TRUE; + + else if(strcmp((char *)string+2,"WIN32__")==0)return TRUE; + + } + + } + + if(am32){ + + if(strcmp((char *)string+2,"FLAT__")==0)return TRUE; + + } + + else{ + + if(strcmp((char *)string+2,"MSDOS__")==0)return TRUE; + + if(modelmem==TINY&&strcmp((char *)string+2,"TINY__")==0)return TRUE; + + if(modelmem==SMALL&&strcmp((char *)string+2,"SMALL__")==0)return TRUE; + + } + + if(comfile==file_d32&&strcmp((char *)string+2,"DOS32__")==0)return TRUE; + + if(comfile==file_com&&strcmp((char *)string+2,"COM__")==0)return TRUE; + + if(comfile==file_sys&&strcmp((char *)string+2,"SYS__")==0)return TRUE; + + if(comfile==file_rom&&strcmp((char *)string+2,"ROM__")==0)return TRUE; + + if(comfile==file_bin&&strcmp((char *)string+2,"BIN32__")==0)return TRUE; + + if(comfile==file_meos&&strcmp((char *)string+2,"MEOS__")==0)return TRUE; + + if((sobj||fobj)&&strcmp((char *)string+2,"OBJ__")==0)return TRUE; + + if(comfile==file_exe){ + + if(modelmem==TINY){ + + if(strcmp((char *)string+2,"TEXE__")==0)return TRUE; + + } + + else if(strcmp((char *)string+2,"EXE__")==0)return TRUE; + + } + + } + + return 2; + +} + + + +void CheckNumIF() + +{ + + if(endifcount>=NUMIFDEF)preerror("#ifdef/#ifndef - too large enclosure"); + +} + + + +static int firstincl=FALSE; + + + +void IncludeFile(char *fileincl,int tfind) + +{ + +unsigned char *holdinput; + +unsigned int holdinptr,holdendinptr,holdlinenum; + +unsigned char holdwarning; + +unsigned char holdcha,holdendoffile; + +int ofileinfo; + +char *ostartline; + +int oscanlexmode=scanlexmode; + +int opostnumflag; + +COM_MOD *ocurmod=cur_mod; + + + +int oendifcount; + + + + oendifcount=endifcount; + + cur_mod=NULL; + + if(!firstincl){ + + firstincl=TRUE; + + if((dbg&1)&&am32==FALSE){ + + holdcha=dbgact; + + dbgact=0; + + AddLine(); + + dbgact=holdcha; + + } + + } + + scanlexmode=STDLEX; + + opostnumflag=postnumflag; + + holdinput=input; // ६ + + holdinptr=inptr2; + + holdcha=cha2; + + holdlinenum=linenum2; + + holdendinptr=endinptr; + + holdendoffile=endoffile; + + holdwarning=warning; + + ostartline=startline; + + ofileinfo=currentfileinfo; + + (startfileinfo+currentfileinfo)->stlist=staticlist; + + compilefile(fileincl,tfind);//⪮஢ + + if(endifcount!=oendifcount){ + + sprintf((char *)string2,"num if prior %d after %d",oendifcount,endifcount); + + preerror((char *)string2); + + } + +// (startfileinfo+currentfileinfo)->staticlist=staticlist; + + currentfileinfo=ofileinfo; + + staticlist=(startfileinfo+currentfileinfo)->stlist; + + warning=holdwarning; + + endoffile=holdendoffile;//⠭ ६ + + endinptr=holdendinptr; + + input=holdinput; + + inptr2=holdinptr; + + cha2=holdcha; + + linenumber=linenum2=holdlinenum; + + startline=ostartline; + +// retoldscanmode(oscanlexmode); + + scanlexmode=oscanlexmode; + + postnumflag=opostnumflag; + + cur_mod=ocurmod; + +} + + + +/*-----------------31.05.99 21:39------------------- + + প startup + + --------------------------------------------------*/ + + + +int startlabl(char *namelab) + +{ + +//ITOK btok; + +//int bb; + +// if(searchtree(&btok,&bb,(unsigned char *)namelab)==FALSE)thisundefined(namelab); + + searchvar(namelab); + + return itok.number; + +} + + + +void searchvar(char *name,int err) + +{ + + strcpy((char *)string,name); + + if(searchtree(&itok,&tok,string)==FALSE&&err)thisundefined(name); + +} + + + +void doprestuff() //樠 砫쭮 , like resize mem, jump to main... + +{ + +ITOK oitok; + +int otok,otok2; + +unsigned int addresshold; + +unsigned char ojmp; + +char *bstring; + +int odbg=dbg; + +//࠭ ࠬ + +// if(FixUp==TRUE||comfile==file_w32)optnumber=FALSE; + + oitok=itok; + + bstring=BackString((char *)string); + + otok=tok; + + ojmp=0xff; + + otok2=tok2; + +// printf("tok=%d inptr=%d\n",tok,inptr); + + if(notdoneprestuff==TRUE){ + + if(splitdata)startptrdata=0; + + if(comfile!=file_w32||(dbg&2))dbgact=0; + + } + + if(startuptomain==TRUE&&comfile==file_com){ + + if(notdoneprestuff==TRUE){ + + outptr=startptr; + + outptrdata=startptrdata; + + if(jumptomain!=CALL_NONE){ + + tok=tk_ID; + + strcpy(itok.name,mesmain); + + tobedefined(jumptomain==CALL_NEAR?JMP_NEAR:CALL_SHORT,tk_void); /* put main on the to be defined stack */ + + if(jumptomain==CALL_NEAR )jumploc0(); + + else outword(0x00EB); // JMP short + + } + + endStartup=outptr; + + notdoneprestuff=FALSE; + + goto endp; + + } + + else{ + + header=0; //⮡ 뫮 ୮ sphinx + + ojmp=jumptomain; + + jumptomain=CALL_NONE; + + startuptomain=FALSE; + + } + + } + + else if(comsymbios==FALSE){ + + outptr=startptr; + + outptrdata=startptrdata; + + } + + notdoneprestuff=FALSE; + + if(comfile==file_meos)outptrdata=outptr=startptr+sizeof(MEOSheader); + + if(sobj){ + + outptrdata=outptr=startptrdata=startptr=0; + + goto endp; + + } + + itok.post=1; + + itok.segm=DS; + + itok.number=0; + + itok.flag=0; + + itok.size=0; + + itok.rm=(am32==FALSE?rm_d16:rm_d32); + + tok=(am32==0?tk_wordvar:tk_dwordvar); + + string[0]=0; + + addtotree("__startpostvar"); + + itok.rec->count=1; + + if(comfile==file_bin)goto endp; + + else ImageBase=Align(ImageBase,0x10000); + + if(jumptomain==CALL_NONE){ + + if(comfile==file_w32||comfile==file_exe||comfile==file_meos)goto endp; + + if(comfile==file_com&&fargc==0&&parsecommandline==0&&atex==0&&use_env==0 + + &&clearpost==0&&resizemem==0&&killctrlc==0)goto endp; + + } + + if(comfile==file_sys){ + + addconsttotree("__SYSATRIB",sysatr); + + tok=tk_string; + + itok.number=8; + + itok.flag=zero_term; + + strncpy((char *)string,sysname,8); + + addtotree("__SYSNAME"); + + if(sysstack!=0){ + + addconsttotree("__SYSSTACK",sysstack); + + } + + if(sysnumcom==0)preerror("list command expected"); + + else addconsttotree("__SYSNUMCOM",sysnumcom); + + } + + else if(comfile==file_rom){ + + resizemem=0; + + addconsttotree("__ROMSIZE",romsize); + + addconsttotree("__DATASEG",dataseg); + + if(modelmem!=SMALL){ + + free(outputdata); + + outputdata=output; + + } + + } + + else if(comsymbios==TRUE){ + + addresshold=outptr; + + addconsttotree("__STARTPTR",startptr); + + addconsttotree("__STARTVALW",*(unsigned short *)&output[startptr]); + + addconsttotree("__STARTVALB",output[startptr+2]); + + } + + if(comfile==file_w32&&wbss)clearpost=FALSE; + + if(resizemem)addconsttotree("__resizemem",TRUE); + + if(killctrlc)addconsttotree("__ctrl_c",TRUE); + + if(parsecommandline)addconsttotree("__parsecommandline",TRUE); + + if(atex)addconsttotree("__atexit",TRUE); + + if(fargc)addconsttotree("__argc",TRUE); + + if(use_env)addconsttotree("__environ",TRUE); + + if(clearpost)addconsttotree("__clearpost",TRUE); + + if(comfile==file_d32){ + + if(useDOS4GW)addconsttotree("__useDOS4GW",TRUE); + + if(dpmistub&&(!usestub)){ + + addconsttotree("__DPMIonly",TRUE); + + resizemem=TRUE; + + jumptomain=CALL_NEAR; + + } + + } + + if(jumptomain==CALL_SHORT)addconsttotree("__shortjmp",TRUE); + + else if(jumptomain==CALL_NONE)addconsttotree("__nonejmptomain",TRUE); + + + + if(dbg){ + + if(am32==FALSE){ + + if(firstincl==FALSE){ + + firstincl=TRUE; + + AddLine(); + + } + + dbg=0; + + } + + } + + IncludeFile(namestartupfile,0); + + dbg=odbg; + + + + if((dbg&1)&&outptr==startptr)KillLastLine(); + + + + if(atex||(comfile==file_w32&&(!dllflag))){ + + startexit=startlabl("__startexit"); + + if(ojmp==0xff)endStartup=startexit; + + } + + else if(ojmp==0xff)endStartup=outptr; + + if(sobj==FALSE&&fobj==FALSE&& //new 18.04.07 23:52 + + comfile==file_com){ + + if(resizemem){ + + resizesizeaddress=startlabl("__stackseg"); + + stackstartaddress=startlabl("__stackval"); + + } + + } + + else if(comfile==file_sys){ + + syscom=startlabl("__listcom"); + + } + + else if(comfile==file_rom){ + + if(modelmem==SMALL){ + + stackstartaddress=startlabl("__stackstart"); + + dataromstart=startlabl("__startdata"); + + dataromsize=startlabl("__sizedata"); + + } + + else{ + + useStartup=TRUE; + + endStartup=0xfff0; + + startStartup=0; + + } + + } + + if(comsymbios==TRUE){ + + output[startptr]=0xE9; + + addresshold=addresshold-(startptr+3); /* inital */ + + *(unsigned short *)&output[startptr+1]=(unsigned short)addresshold; + + } + + if(ojmp!=0xff)jumptomain=ojmp; + +endp: + + if(header){ + + outprocedure(aabaner,MMBANER); + + alignersize+=MMBANER; + + } + + itok=oitok; + + tok=otok; + + tok2=otok2; + + strcpy((char *)string,bstring); + + free(bstring); + + if(strcmp(itok.name,mesmain)==0)searchtree(&itok,&tok,(unsigned char *)&string); + + if((comfile!=file_d32||dpmistub)&&stubfile!=NULL){ + + free(stubfile); + + stubfile=NULL; + + } + + dbgact=0; + +} + + + +void KillVarOfTree(idrec **treestart) + +{ + +struct idrec *ptr,*leftptr,*rightptr,*prev; + +int cmpresult,ocmpresult=0; + + ptr=*treestart; // + + while(ptr!=NULL&&(cmpresult=strcmp(ptr->recid,itok.name))!=0){ + + prev=ptr; //த⥫ + + ocmpresult=cmpresult; //१ । ࠢ - ࠢ ⢨ + + if(cmpresult<0)ptr=ptr->left; + + else ptr=ptr->right; + + } + + if(ptr!=NULL){ // ꥪ 㤠 + + if(ptr->newid)free(ptr->newid); //㤠 . + + leftptr=ptr->left; // + + rightptr=ptr->right;//㣮 + + if(leftptr==NULL&&rightptr==NULL){ //᫨ ⥩ + + if(ocmpresult<0)prev->left=NULL; // த⥫ ⠫ ⮩ + + else if(ocmpresult>0)prev->right=NULL; + + else *treestart=NULL; //㤠 ७ ⢥ + + } + + else if(leftptr==NULL){ // ࠢ + + if(ocmpresult<0)prev->left=rightptr; //। 㪮 த⥫ + + else if(ocmpresult>0)prev->right=rightptr; + + else *treestart=rightptr; //㤠 ७ ࠢ ⪮ + + } + + else if(rightptr==NULL){ //⮦ ᫨ ᫥ + + if(ocmpresult<0)prev->left=leftptr; + + else if(ocmpresult>0)prev->right=leftptr; + + else *treestart=leftptr; //㤠 ७ ⪮ + + } + + else{ //᫨ ॡ + + struct idrec *ostptr,*ptrf; + + if(ocmpresult<0){ //᫨ ᫥ + + prev->left=leftptr; //। ॡ + + ostptr=rightptr; //ࠢ + + } + + else if(ocmpresult>0){ //᫨ ࠢ + + prev->right=rightptr; //। ࠢ ॡ + + ostptr=leftptr; // + + } + + else{ //᫨ த⥫ + + *treestart=rightptr; // 㣠 ⠭ + + ostptr=leftptr; //㣮 + + } + + ptrf=*treestart; //砫 ॢ + + while(((cmpresult=strcmp(ptrf->recid,ostptr->recid))<0&&ptrf->left!=NULL)|| + + (cmpresult>0&&ptrf->right!=NULL)){ + + if(cmpresult<0)ptrf=ptrf->left; + + else ptrf=ptrf->right; + + } + + if(cmpresult<0)ptrf->left=ostptr; //ப + + else ptrf->right=ostptr; + + } + + if(ptr->newid)free(ptr->newid); + + if(ptr->sbuf)free(ptr->sbuf); + + free(ptr); + + } + +} + +/* end of TOKE.C */ + diff --git a/programs/develop/cmm/tokr.cpp b/programs/develop/cmm/tokr.cpp new file mode 100644 index 0000000000..ed8c65db54 --- /dev/null +++ b/programs/develop/cmm/tokr.cpp @@ -0,0 +1,6135 @@ +#define _TOKR_ + +#include "tok.h" + +char useasm=FALSE; +char asmparam=FALSE; +#include "asmnemon.h" + +void asmtwo1(int basecode); // used for ADD ADC SUB SBB CMP AND OR XOR. +void asmregmem(int out1,int out2); // used for LEA LDS LES LFS LGS LSS. +void Scanbit(int basecode); +void CheckBit(int code); +void asmone1(int basecode); // used for INC and DEC. +void asmone2(int basecode); // used for NEG NOT MUL IMUL DIV IDIV. +void asmshortjump(int shortcode,int nearcode); +void lar_lsl(int code); +unsigned char tabldeckr(int code); +void protectinstr(int code,int code2); +void doasmmov(); // do MOV +void asmextend(int basecode); // procedure MOVSX and MOVZX +void movd(); +void movq(); +void packMMX(int code,int code1,int code2); +void asmshift(int basecode); // used for ROL ROR RCL RCR SHL SAL SHR SAR. +void Shxd(int code); +void FpuType1(unsigned int addrm); +void FpuType2(unsigned int addrm,unsigned int addrm2); +void FpuType3(unsigned int opcode,unsigned int addrm); +void FpuType4(unsigned int opcode,unsigned int addrm); +void FpuType5(unsigned int opcode,unsigned int addrm); +void FpuType6(unsigned int opcode,unsigned int addrm); +void FpuType7(unsigned int addrm); +void FpuType8(unsigned int opcode,unsigned int addrm); +void addlocaljump(int callkind); +unsigned long SaveNumber(int type,int tok4,char *name); +void cmov(int num); +void mmxiii(int type); +void prefetch(int code, int type); +void pextrw(); +void pinsrw(); +void pshufw(); +void xmminstr(int type,int sec,int op1=tk_xmmreg,int op2=tk_xmmreg); +void xmm3instr(int type,int sec); +void xmm2xmm(int code,int code2=0,int type=tk_xmmreg); +void movxmm(int code,int code2,int addc=1); +void movxmm2(int code,int code2=0); +void movxmm3(int code,int code2=0,int type=tk_xmmreg); +void movxmm4(int code,int code2); +void shiftxmm(int rm); //rxmm,i8 +void DDDW(int faradd); +void AADM(int code); + +extern void shortjumperror(); +extern void invalidfarjumpitem(); +extern void invalidfarcallitem(); +extern void bytedxexpected(); +extern void axalexpected(); +extern void clornumberexpected(); +extern void reg32regexpected(int type); +extern void begexpected(int type); +extern void regexpected(int type); +extern void invalidoperand(int type); +extern void mmxregexpected(int type=0); +extern void mmxregordwordexpected(int type); +extern void mmxormem(int type); +extern void reg32orword(int type); +extern void xmmregorvarexpected(int type); +extern void xmmregexpected(int type); +extern void fpustakexpected(int type); +extern void fpuvarexpected(int type); + +void doasm(int nexta) +{ +unsigned char possiblecpu=0,next=1; +int htok; +ITOK hstok; +char *hbuf; +SINFO hstr; +unsigned int i=0; +int razr=r16; +unsigned long hnumber; +int faradd=0; + if(nexta==FALSE){ + useasm=TRUE; + nexttok(); + useasm=FALSE; + } + if(tok==tk_idasm){ + htok=itok.rm; + goto sw_asm; + } + if(tok==tk_ID||tok==tk_id||tok==tk_undefproc){ + if(tok2==tk_colon){ //⪠ + if(tok==tk_undefproc)doanyundefproc(); + else doid((char)(tok==tk_ID?1:0),tk_void); + return; + } + strupr((char *)string); + htok=FastSearch((unsigned char *)asmMnem,ofsmnem,0,(char *)string); +sw_asm: + asmparam=TRUE; + switch(htok){ + case a_add: //ADD + case a_or: //OR + case a_adc: //ADC + case a_sbb: //SBB + case a_and: //AND + case a_sub: //SUB + case a_xor: //XOR + case a_cmp: //CMP + asmtwo1(htok*8); + next=0; + break; + case a_not: //NOT + case a_neg: //NEG + case a_mul: //MUL + case a_div: //DIV + case a_idiv: //IDIV + asmone2((htok-a_not)*8+16); + break; + case a_rol: //ROL + case a_ror: //ROR + case a_rcl: //RCL + case a_rcr: //RCR + case a_shl: //SHL + case a_shr: //SHR + case a_sar: //SAR + asmshift((htok-a_rol)*8); + next=0; + break; + case a_btc: //BTC + case a_btr: //BTR + case a_bts: //BTS + case a_bt: //BT + CheckBit((htok-a_bt)*8); + next=0; + break; + case a_dec: //DEC + case a_inc: //INC + asmone1((htok-a_inc)*8); + break; + case a_shrd: //SHRD + case a_shld: //SHLD + Shxd((htok-a_shld)*8+0xa4); + next=0; + break; + case a_aaa: + ClearReg(AX); + op(0x37); //AAA + break; + case a_aad: + ClearReg(AX); + AADM(0xD5); //AAD + break; + case a_aam: + ClearReg(AX); + AADM(0xD4); //AAM + break; + case a_aas: + ClearReg(AX); + op(0x3F); //AAS + break; + case a_adrsiz: + op(0x67); + possiblecpu=3; + break; + case a_arpl: //ARPL + nexttok(); + htok=tok; + hstok=itok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + if(tok!=tk_reg)regexpected(2); + switch(htok){ + case tk_intvar: + case tk_wordvar: +#ifdef OPTVARCONST + ClearVarByNum(&hstok); +#endif + CheckAllMassiv(hbuf,2,&hstr,&hstok); + KillVar(hstok.name); + outseg(&hstok,2); + op(0x63); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + break; + case tk_reg: + ClearReg(hstok.number); + op(0x63); + op(192+(unsigned int)itok.number*8+hstok.number); + break; + default: wordvalexpected(); + } + possiblecpu=2; + break; + case a_bound: //BOUND + asmregmem(0x62,0); + possiblecpu=2; + break; + case a_lea: + asmregmem(0x8D,0); //LEA + break; + case a_lds: //LDS + case a_les: //LES + asmregmem(htok-a_les+0xC4,0); + break; + case a_lss: //LSS + asmregmem(0xF,0xB2); + possiblecpu=3; + break; + case a_lgs: //LGS + case a_lfs: //LFS + asmregmem(0xF,htok-a_lfs+0xB4); + possiblecpu=3; + break; + case a_bswap: //BSWAP + nexttok(); + ClearReg(itok.number); + if(tok==tk_reg32||tok==tk_reg){ + op66(tok==tk_reg?r16:r32); + op(0x0F); + op(0xC8+(unsigned int)itok.number); + } + else preerror("Expecting 32 bit Register for BSWAP"); + possiblecpu=4; + break; + case a_bsf: //BSF + case a_bsr: //BSR + Scanbit(htok-a_bsf+0xbc); + break; + case a_call: //CALL + nexttok(); + htok=0; + if(tok==tk_ID||tok==tk_id){ + if(stricmp("FAR",(char *)string)==0){ + nexttok(); + faradd=8; + htok=1; + } + else if(stricmp("NEAR",(char *)string)==0){ + nexttok(); + htok=1; + } + } + else if(tok==tk_far){ + nexttok(); + faradd=8; + htok=1; + } +// printf("call %d\n",tok); + switch(tok){ + case tk_proc: + if(faradd==0){ + if(itok.segm==DYNAMIC){ + itok.segm=DYNAMIC_USED; + updatetree(); + } + int flag=itok.flag; + if(itok.segm255)bytedxexpected(); + op(hnumber); + next = 0; + } + else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xED); + else bytedxexpected(); + } + else if(tok==tk_beg&&(unsigned int)itok.number==AL){ + nexttok(); + expecting(tk_camma); + if(tok==tk_number){ + op(0xE4); + asmparam=FALSE; + if((hnumber=doconstdwordmath())>255)bytedxexpected(); + op(hnumber); + next=0; + } + else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xEC); + else bytedxexpected(); + } + else axalexpected(); + break; + case a_insb: //INSB + ClearReg(AX); + ClearReg(DI); + op(0x6C); + possiblecpu=2; + break; + case a_insw: //INSW + op66(r16); + possiblecpu=2; + goto insd; + break; + case a_insd: //INSD + op66(r32); + possiblecpu=3; +insd: + op(0x6D); + ClearReg(AX); + ClearReg(DI); + break; + case a_int: //INT + clearregstat(); + nexttok(); + if(tok==tk_number){ + asmparam=FALSE; + htok=doconstlongmath(); + if(htok==3)op(0xCC); + else{ + op(0xCD); + op(htok); + } + next=0; + } + else numexpected(); + break; + case a_into: + op(0xCE); //INTO + break; + case a_invd: //INVD + outword(0x080F); + possiblecpu=4; + break; + case a_invlpg: //INVLPG + nexttok(); + switch(tok){ + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf); + goto invlgp; + case tk_intvar: + case tk_wordvar: + CheckAllMassiv(bufrm,2,&strinf); +invlgp: + outseg(&itok,3); + outword(0x010F); + op(itok.rm+0x38); + outaddress(&itok); + break; + + case tk_undefofs: + strcpy(hstok.name,itok.name); + tok=tk_number; + case tk_number: + hnumber=doconstdwordmath(); + outword(0x010f); + op((am32==FALSE?rm_d16:rm_d32)+0x38); + if(postnumflag&f_reloc)AddReloc(); + if(htok==tk_undefofs)AddUndefOff(2,hstok.name); + if(am32)outdword(hnumber); + else outword(hnumber); + next=0; + break; + case tk_postnumber: + outword(0x010F); + op((am32==FALSE?rm_d16:rm_d32)+0x38); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(am32==FALSE)outword(itok.number); //뫮 0 + outdword(itok.number); + break; + + default: + varexpected(0); break; + } + possiblecpu=4; + break; + case a_iret: +#ifdef OPTVARCONST + ClearLVIC(); +#endif + RestoreStack(); + clearregstat(); + op66(r16); + op(0xCF); //IRET + break; + case a_iretd: +#ifdef OPTVARCONST + ClearLVIC(); +#endif + RestoreStack(); + clearregstat(); + op66(r32); + op(0xCF); //IRETD + break; + case a_jo: + case a_jno: + case a_jc: + case a_jnc: + case a_jz: + case a_jnz: + case a_jna: + case a_ja: + case a_js: + case a_jns: + case a_jp: + case a_jnp: + case a_jl: + case a_jnl: + case a_jng: + case a_jg: + RestoreStack(); + asmshortjump((htok-a_jo)+0x70,(htok-a_jo)+0x80); + next=0; + break; + case a_jecxz: //JECXZ + RestoreStack(); + op67(r32); + asmshortjump(0xE3,0); + next=0; + break; + case a_jcxz: //JCXZ + RestoreStack(); + op67(r16); + asmshortjump(0xE3,0); + next=0; + break; + case a_jmp: //JMP + RestoreStack(); + nexttok(); + faradd=0; + lastcommand=tk_goto; + if(stricmp("FAR",itok.name)==0){ + nexttok(); + faradd=8; + } + else if(stricmp("NEAR",itok.name)==0)nexttok(); + else if(stricmp("SHORT",itok.name)==0){ // case insensitive + nexttok(); + next=(unsigned char)GOTO(); + break; + } + next=gotol(faradd); + break; + case a_lahf: + ClearReg(AX); + op(0x9F); //LAHF + break; + case a_lar: //LAR + case a_lsl: //LSL + lar_lsl(htok-a_lar+2); + break; + case a_leave: //LEAVE + RestoreStack(); + op(0xC9); + ClearReg(BP); + possiblecpu = 2; + break; + case a_lmsw: + protectinstr(1,0x30); //LMSW + break; + case a_loadall: // LOADALL 80286 only + outword(0x050F); + possiblecpu=2; + break; + case a_lodsb: + ClearReg(SI); + ClearReg(AX); + op(0xAC); //LODSB + break; + case a_lodsw: + op66(r16); + ClearReg(SI); + ClearReg(AX); + op(0xAD); //LODSW + break; + case a_lodsd: + op66(r32); + ClearReg(SI); + ClearReg(AX); + op(0xAD); + possiblecpu =3; //LODSD + break; + case a_lock: + op(0xF0); //LOCK + break; + case a_loop: + ConstToReg(0,CX,(am32+1)*2); + op67(r16); + asmshortjump(0xE2,0); + next=0; + break; + case a_loopd: + ConstToReg(0,CX,r32); + possiblecpu=3; + op67(r32); + asmshortjump(0xE2,0); + next=0; + break; + case a_loopz: //LOOPE LOOPZ + ClearReg(CX); + asmshortjump(0xE1,0); + next=0; + break; + case a_loopnz: //LOOPNZ LOOPNE + ClearReg(CX); + asmshortjump(0xE0,0); + next=0; + break; + case a_ltr: + protectinstr(0,0x18); //LTR + break; + case a_str: + protectinstr(0,0x08); //STR + break; + case a_lgdt: + next=tabldeckr(0x10); + break; + case a_lidt: //LIDT + next=tabldeckr(0x18); + break; + case a_lldt: + protectinstr(0,0x10); //LLDT + break; + case a_mov: + doasmmov(); + next=0; + break; + case a_movsb: + movsb(); //MOVSB + break; + case a_movsd: + if(ScanTok3()==tk_camma&&(tok2==tk_xmmreg||(tok2>=tk_charvar&&tok2255)bytedxexpected(); + expecting2(tk_camma); + if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){ + op66(tok==tk_reg?r16:r32); + if(tok==tk_reg32)possiblecpu=3; + op(0xE7); op(hnumber); + } + else if(tok==tk_beg&&(unsigned int)itok.number==AL){ + op(0xE6); op(hnumber); + } + else axalexpected(); + } + else if(tok==tk_reg&&(unsigned int)itok.number==DX){ + nextexpecting2(tk_camma); + if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){ + op66(tok==tk_reg?r16:r32); + if(tok==tk_reg32)possiblecpu=3; + op(0xEF); + } + else if(tok==tk_beg&&(unsigned int)itok.number==AL)op(0xEE); + else axalexpected(); + } + else bytedxexpected(); + break; + case a_outsb: //OUTSB + ClearReg(SI); + op(0x6E); + possiblecpu=2; + break; + case a_outsw: //OUTSW + ClearReg(SI); + op66(r16); + op(0x6F); + possiblecpu=2; + break; + case a_outsd: //OUTSD + ClearReg(SI); + op66(r32); + op(0x6F); + possiblecpu=3; + break; + case a_pop: //POP + RestoreStack(); + do{ + possiblecpu=0; + asmparam=TRUE; + nexttok(); + razr=r16; + switch(tok){ + case tk_reg32: + possiblecpu=3; + razr=r32; + case tk_reg: + ClearReg(itok.number); + op66(razr); + op(0x58+(unsigned int)itok.number); break; + case tk_dwordvar: + tok--; + case tk_longvar: + CheckAllMassiv(bufrm,4,&strinf); + possiblecpu=3; + razr=r32; + goto pop; + case tk_wordvar: + tok--; + case tk_intvar: + CheckAllMassiv(bufrm,2,&strinf); +pop: +#ifdef OPTVARCONST + ClearVarByNum(&itok); +#endif + KillVar(itok.name); + op66(razr); + outseg(&itok,2); + op(0x8F); op(itok.rm); + outaddress(&itok); + break; + case tk_seg: + if(itok.number!=CS){ + PopSeg((unsigned int)itok.number); + break; + } + default: + preerror("Invalid operand for POP"); + break; + } + if(cpu3?hstok.number-4:hstok.number); + switch(tok){ + case tk_minus: + if(tok2!=tk_number){ + bytevalexpected(2); + break; + } + case tk_number: + asmparam=FALSE; + holdnumber2=doconstlongmath(); + next=0; + if(hstok.number==AL)op(4+basecode); + else{ + op(128); + op(128+64+hstok.number+basecode); + } + op(holdnumber2); + break; + case tk_beg: + op(2+basecode); + op(128+64+(unsigned int)itok.number+hstok.number*8); + break; + case tk_bytevar: + case tk_charvar: + CheckAllMassiv(bufrm,1,&strinf); + outseg(&itok,2); + op(2+basecode); + op(itok.rm+hstok.number*8); + outaddress(&itok); + break; + default: bytevalexpected(2); break; + } + break; + case tk_dwordvar: + case tk_longvar: + typet=r32; + if(cpu<3)cpu=3; + case tk_intvar: + case tk_wordvar: + if((basecode/8)!=a_cmp)KillVar(hstok.name); + CheckAllMassiv(hbuf,typet,&hstr,&hstok); + op66(typet); + outseg(&hstok,2); + switch(tok){ + case tk_undefofs: + strcpy(hstok.name,itok.name); + tok=tk_number; + goto vnum; + case tk_minus: + if(tok2!=tk_number)goto erval; + case tk_number: +vnum: + asmparam=FALSE; + holdnumber2=doconstlongmath(); +#ifdef OPTVARCONST + if(i==tk_number&&(postnumflag&f_reloc)==0){ + initconst=UpdVarConst(&hstok,holdnumber2,tk_dword,operand); + } +#endif + next=0; + if(i!=tk_undefofs&&(postnumflag&f_reloc)==0&&short_ok(holdnumber2,typet/2-1)){ + op(128+2+1); + op(hstok.rm+basecode); + outaddress(&hstok); + op(holdnumber2); + } + else{ + op(128+1); + op(hstok.rm+basecode); + outaddress(&hstok); + if((postnumflag&f_reloc)!=0)AddReloc(); + if(i==tk_undefofs)AddUndefOff(2,hstok.name); + if(typet==r16)outword(holdnumber2); + else outdword(holdnumber2); + } + break; + case tk_postnumber: + if(typet==r32)goto erval; + op(128+1); + op(hstok.rm+basecode); + outaddress(&hstok); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(typet==r16)outword(itok.number); + else outdword(itok.number); + break; + case tk_reg32: + if(typet==r16)goto erval; + case tk_reg: + op(1+basecode); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + break; + default: +erval: + if(typet==r16)wordvalexpected(); + else dwordvalexpected(); + break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&hstok); +#endif + + break; + case tk_bytevar: + case tk_charvar: + if((basecode/8)!=a_cmp)KillVar(hstok.name); + CheckAllMassiv(hbuf,1,&hstr,&hstok); + switch(tok){ + case tk_minus: + if(tok2!=tk_number){ + bytevalexpected(2); + break; + } + case tk_number: + asmparam=FALSE; + holdnumber2=doconstlongmath(); +#ifdef OPTVARCONST + if((postnumflag&f_reloc)==0){ + initconst=UpdVarConst(&hstok,holdnumber2,tk_byte,operand); + } +#endif + next=0; + outseg(&hstok,2); + op(128); + op(hstok.rm+basecode); + outaddress(&hstok); + op(holdnumber2); + break; + case tk_beg: + outseg(&hstok,2); + op(basecode); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + break; + default: bytevalexpected(2); break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&hstok); +#endif + break; + default: varexpected(1); break; + } + if(next)nexttok(); +} + +int GOTO() +{ +unsigned char next=1; + CheckIP(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + clearregstat(); + switch(tok){ + case tk_proc: + case tk_interruptproc: + if(itok.segm!=NOT_DYNAMIC){ + idrec *ptr=itok.rec; + itok.segm=ptr->recsegm=DYNAMIC_USED; + itok.rm=tok=tk_undefofs; //ᬥ饭 ⭮ ⪨ + goto undefproc; + } + jumploc(itok.number); // 楤 ࠭ + break; + case tk_number: + asmparam=FALSE; + jumploc(doconstlongmath());// + next=0; + break; + case tk_ID: + addlocaljump(CALL_SHORT); // + outword(0x00EB); // JMP SHORT + break; + case tk_id: + tobedefined(CALL_SHORT,tk_void);//  + outword(0x00EB); // JMP SHORT + break; + case tk_declare: + tok=tk_undefproc; + updatetree(); + case tk_locallabel: + case tk_undefproc: // +undefproc: + addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT)); + outword(0x00EB); // JMP SHORT + break; + default: shortjumperror(); break; + } + return next; +} + +unsigned char gotol(int faradd) +{ +unsigned char next=1; +unsigned long hnumber; +unsigned int i=0; + CheckIP(); +#ifdef OPTVARCONST + ClearLVIC(); +#endif + clearregstat(); + switch(tok){ + case tk_declare: + if(tok2!=tk_openbracket){ + tok=tk_undefproc; + updatetree(); + } + case tk_locallabel: + case tk_undefproc: + if(tok2==tk_openbracket){ + asmparam=FALSE; + if(doanyundefproc(TRUE)==tokens)next=0; + break; + } + if(faradd==0){ + addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32))); + jumploc0(); + } /* JMP num */ + else invalidfarjumpitem(); + break; + case tk_proc: + if(tok2==tk_openbracket){ + doanyproc(TRUE); + break; + } + if(itok.segm!=NOT_DYNAMIC){ + idrec *ptr=itok.rec; + itok.segm=ptr->recsegm=DYNAMIC_USED; + itok.rm=tok=tk_undefofs; //ᬥ饭 ⭮ ⪨ + if(faradd==0){ + addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32))); + jumploc0(); + break; + } /* JMP num */ + } + case tk_interruptproc: + if(faradd==0)jumploc(itok.number); + else invalidfarjumpitem(); + break; + case tk_apiproc: + asmparam=FALSE; + if(tok2==tk_openbracket){ + if(doanyundefproc(TRUE)==tokens)next=0; + } + else{ + if(FastCallApi==TRUE){ + outword(0x25ff); + AddApiToPost(itok.number); + } + else{ + addacall(itok.number,(unsigned char)CALL_32); + jumploc0(); + } + } + break; + case tk_minus: + if(tok2!=tk_number)goto err; + case tk_number: + asmparam=FALSE; + hnumber=doconstdwordmath(); + if(faradd==0)jumploc(hnumber); + else{ + op(0xEA); + expecting2(tk_colon); + int htok=tok; + char name[IDLENGTH]; + if(tok==tk_undefofs){ + tok=tk_number; + strcpy(name,itok.name); + } + unsigned long tempi=doconstdwordmath(); + if(postnumflag&f_reloc)AddReloc(); + if(htok==tk_undefofs)AddUndefOff(2,name); + if(am32==FALSE)outword((unsigned int)tempi); + else outdword(tempi); + outword((unsigned int)hnumber); + } + next=0; + break; /* JMP num */ + case tk_postnumber: + if(faradd==0){ + op(0xE9); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(am32==FALSE)outword((unsigned int)itok.number); + else outdword(itok.number); + } + else invalidfarjumpitem(); + break; + case tk_reg32: + op66(r32); + goto jmpreg; + case tk_reg: + op66(r16); +jmpreg: + if(faradd==0){ + op(0xFF); + op(0xE0+(unsigned int)itok.number); + } /* JMP reg */ + else invalidfarjumpitem(); + break; + case tk_ID: + if(faradd==0){ + addlocaljump(am32==FALSE?JMP_NEAR:JMP_32); + jumploc0(); + } /* JMP num */ + else invalidfarjumpitem(); + break; + case tk_id: + if(faradd==0){ + tobedefined(am32==FALSE?JMP_NEAR:JMP_32,tk_void); + jumploc0(); + } /* JMP num */ + else invalidfarjumpitem(); + break; + case tk_dwordvar: + case tk_longvar: + i=2; + case tk_intvar: + case tk_wordvar: + i+=2; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,2); + op(0xFF); op(0x20+itok.rm+(faradd==0?(i==4&&am32==0?8:0):8)); + outaddress(&itok); + break; + default: +err: + preerror("Invalid item for JMP"); + break; + } + return next; +} + +void asmregmem(int out1,int out2) // used for LEA LDS LES LFS LGS LSS. +{ +int holdreg; + nexttok(); + op66(tok==tk_reg?r16:r32); + if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1); + holdreg=(unsigned int)itok.number; + ClearReg(itok.number); + nextexpecting2(tk_camma); + switch(tok){ + case tk_intvar: + case tk_wordvar: + case tk_charvar: + case tk_bytevar: + case tk_longvar: + case tk_dwordvar: + break; + default: varexpected(2); + } + CheckAllMassiv(bufrm,2,&strinf); + if(out2==0)outseg(&itok,2); + else outseg(&itok,3); + op(out1); + if(out2!=0)op(out2); + op(itok.rm+holdreg*8); + outaddress(&itok); +} + +void Scanbit(int basecode) +{ +unsigned long hnumber; +int htok,typet=r16; + nexttok(); + hnumber=itok.number; + ClearReg(itok.number); + htok=tok; + nextexpecting2(tk_camma); + switch(htok){ + case tk_reg32: + typet=r32; + if(tok==tk_reg||tok==tk_wordvar||tok==tk_intvar)goto erval; + case tk_reg: + switch(tok){ + case tk_reg32: + if(typet==r16)goto erval; + case tk_reg: + op66(typet); + op(0xf); + op(basecode); + op(0xc0+(unsigned int)itok.number+hnumber*8); + break; + case tk_dwordvar: + case tk_longvar: + if(typet==r16)goto erval; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,typet,&strinf); + op66(typet); + outseg(&itok,3); + op(0xf); + op(basecode); + op(itok.rm+hnumber*8); + outaddress(&itok); + break; + default: +erval: + if(typet==r16)wordvalexpected(); + else dwordvalexpected(); + break; + } + break; + default: reg32regexpected(1); + } + if(cpu<3)cpu=3; +} + +void CheckBit(int code) +{ +unsigned long holdnumber2; +int htok; +ITOK hstok; +unsigned char next=1; +char *hbuf; +SINFO hstr; + nexttok(); + hstok=itok; + htok=tok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + switch(htok){ + case tk_reg32: + case tk_reg: + op66(htok==tk_reg?r16:r32); + if(code)ClearReg(hstok.number); + switch(tok){ + case tk_number: + asmparam=FALSE; + holdnumber2=doconstlongmath(); + next=0; + outword(0xba0f); + op(0xe0+code+hstok.number); + op(holdnumber2); + break; + case tk_reg32: + if(tok!=htok){ + dwordvalexpected(); + break; + } + case tk_reg: + if(tok!=htok)wordvalexpected(); + op(0xf); + op(0xa3+code); + op(0xc0+hstok.number+(unsigned int)itok.number*8); + break; + default: wordvalexpected(); break; + } + break; + case tk_intvar: + case tk_wordvar: + CheckAllMassiv(hbuf,2,&hstr,&hstok); + if(code)KillVar(hstok.name); + op66(r16); + switch(tok){ + case tk_number: +varc: + asmparam=FALSE; + holdnumber2=doconstlongmath(); + next=0; + outseg(&hstok,3); + outword(0xba0f); + op(hstok.rm+code+0x20); + outaddress(&hstok); + op(holdnumber2); + break; + case tk_reg: +varreg: + outseg(&hstok,3); + op(0xf); + op(0xa3+code); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + break; + default: wordvalexpected(); break; + } +#ifdef OPTVARCONST + if(code)ClearVarByNum(&hstok); +#endif + break; + case tk_dwordvar: + case tk_longvar: + CheckAllMassiv(hbuf,4,&hstr,&hstok); + if(code)KillVar(hstok.name); + op66(r32); + if(tok==tk_number)goto varc; + if(tok==tk_reg32)goto varreg; + dwordvalexpected(); + break; + default: varexpected(1); + } + if(cpu<3)cpu=3; + if(next)nexttok(); +} + +void asmone1(int basecode) // used for INC and DEC. +{ +int razr=r16; +#ifdef OPTVARCONST +int operand=GetOperand(basecode/8+a_inc); +#endif + nexttok(); + switch(tok){ + case tk_reg32: + if(cpu<3)cpu=3; + razr=r32; + case tk_reg: + ClearReg(itok.number); + op66(razr); + op(64+basecode+(unsigned int)itok.number); + break; + case tk_beg: + ClearReg(itok.number); + op(254); op(128+64+basecode+(unsigned int)itok.number); + break; + case tk_charvar: + case tk_bytevar: +#ifdef OPTVARCONST + UpdVarConst(&itok,1,tk_byte,operand); +#endif + CheckAllMassiv(bufrm,1,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(254); + op(itok.rm+basecode); + outaddress(&itok); + break; + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf); + if(cpu<3)cpu=3; + razr=r32; + goto dec; + case tk_intvar: + case tk_wordvar: + CheckAllMassiv(bufrm,2,&strinf); +dec: +#ifdef OPTVARCONST + UpdVarConst(&itok,1,tk_dword,operand); +#endif + KillVar(itok.name); + op66(razr); + outseg(&itok,2); + op(255); + op(itok.rm+basecode); + outaddress(&itok); + break; + default: varexpected(0); break; + } +} + +void asmone2(int basecode) // used for NEG NOT MUL IMUL DIV IDIV. +{ +int razr=r16; +#ifdef OPTVARCONST +int operand=GetOperand((basecode-16)/8+a_not); +#endif + nexttok(); + switch(tok){ + case tk_reg32: + if(cpu<3)cpu=3; + razr=r32; + case tk_reg: + ClearReg(itok.number); + op66(razr); + op(246+1); op(128+64+basecode+(unsigned int)itok.number); break; + case tk_beg: + ClearReg(itok.number); + op(246); op(128+64+basecode+(unsigned int)itok.number); break; + razr=r8; + case tk_charvar: + case tk_bytevar: +#ifdef OPTVARCONST + UpdVarConst(&itok,0,tk_dword,operand); +#endif + CheckAllMassiv(bufrm,1,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(246); + op(itok.rm+basecode); + outaddress(&itok); + razr=r8; + break; + case tk_longvar: + case tk_dwordvar: + CheckAllMassiv(bufrm,4,&strinf); + if(cpu<3)cpu=3; + razr=r32; + goto neg; + case tk_intvar: + case tk_wordvar: + CheckAllMassiv(bufrm,2,&strinf); +neg: +#ifdef OPTVARCONST + UpdVarConst(&itok,0,tk_dword,operand); +#endif + KillVar(itok.name); + op66(razr); + outseg(&itok,2); + op(247); + op(itok.rm+basecode); + outaddress(&itok); + break; + default: varexpected(0); break; + } + if(basecode!=16&&basecode!=24){ + ClearReg(AX); + if(razr!=r8)ClearReg(DX); + } +} + +void asmshortjump(int shortcode,int nearcode) +{ +unsigned char next=1,shortjump=1; +unsigned int address; +#ifdef OPTVARCONST + ClearLVIC(); +#endif + nexttok(); + if(stricmp("FAR",itok.name)==0){ // case insensitive + preerror("FAR jump not available for this instruction"); + nexttok(); + } + else if(stricmp("NEAR",itok.name)==0){ // case insensitive + shortjump=0; + nexttok(); + } + else if(stricmp("SHORT",itok.name)==0)nexttok(); // case insensitive + if(shortjump){ + CheckIP(); + switch(tok){ + case tk_proc: + *(unsigned int *)&itok.number-=outptr+2; + if(short_ok(itok.number)){ + op(shortcode); + op((unsigned int)itok.number); + } + else shortjumptoolarge(); + break; + case tk_number: + asmparam=FALSE; + address=doconstdwordmath()-(outptr+2); + if(short_ok(address)){ + op(shortcode); + op(address); + } + else shortjumptoolarge(); + next=0; + break; + case tk_ID: + addlocaljump(CALL_SHORT); + op(shortcode); op(0x00); /* JXX SHORT */ + break; + case tk_id: + tobedefined(CALL_SHORT,tk_void); + op(shortcode); op(0x00); /* JXX SHORT */ + break; + case tk_declare: + tok=tk_undefproc; + updatetree(); + case tk_locallabel: + case tk_undefproc: + addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT)); + op(shortcode); op(0x00); /* JXX SHORT */ + break; + default: shortjumperror(); break; + } + } + else if(nearcode!=0){ +unsigned long numlong; + asmparam=FALSE; + switch(tok){ + case tk_proc: + op(0xF); op(nearcode); + numlong=itok.number-outptr-2; + if(am32==FALSE)outword((unsigned int)numlong); + else outdword(numlong-2); + break; + case tk_number: + op(0xF); op(nearcode); + numlong=doconstdwordmath()-outptr-2; + if(am32==FALSE)outword((unsigned int)numlong); + else outdword(numlong-2); + next=0; + break; + case tk_undefofs: // ???? 32 ० + op(0xF); op(nearcode); + AddUndefOff(2,itok.name); + outword(-(int)(outptr-2)); + if(am32!=FALSE)outword(0x0000); + break; + case tk_postnumber: + op(0xF); op(nearcode); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + numlong=itok.number-outptr-2; + if(am32==FALSE)outword((unsigned int)numlong); + else outdword(numlong-2); + break; + case tk_ID: + op(0xF); // must go before tobedefined() + addlocaljump(am32==FALSE?CALL_NEAR:CALL_32); + op(nearcode); outword(0x0000); /* JXX NEAR */ + if(am32!=FALSE)outword(0x0000); + break; + case tk_id: + op(0xF); // must go before tobedefined() + tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void); + op(nearcode); outword(0x0000); /* JXX NEAR */ + if(am32!=FALSE)outword(0x0000); + break; + case tk_declare: + tok=tk_undefproc; + updatetree(); + case tk_locallabel: + case tk_undefproc: + op(0xF); // must go before addacall() + addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?CALL_NEAR:CALL_32))); + op(nearcode); outword(0x0000); /* JXX NEAR */ + if(am32!=FALSE)outword(0x0000); + break; + default: preerror("Invalid operand for NEAR jump"); break; + } + if(cpu<3)cpu=3; + } + else preerror("NEAR jump not available for this instruction"); + if(next)nexttok(); +} + +void lar_lsl(int code) +{ +unsigned char possiblecpu=0; +int razr=r16; + nexttok(); + if(tok!=tk_reg&&tok!=tk_reg32)reg32regexpected(1); + int htok=tok; + int hnumber=(unsigned int)itok.number; + ClearReg(itok.number); + nextexpecting2(tk_camma); + switch(tok){ + case tk_reg32: + if(htok==tk_reg)reg32expected(1); + possiblecpu=3; + razr=r32; + goto lar; + case tk_reg: + if(htok==tk_reg32)regexpected(1); + possiblecpu=2; +lar: + op66(razr); + op(0x0f); + op(code); + op(0xc0+(unsigned int)itok.number+hnumber*8); + break; + case tk_longvar: + case tk_dwordvar: + if(htok==tk_reg)reg32expected(1); + CheckAllMassiv(bufrm,4,&strinf); + possiblecpu=3; + razr=r32; + goto lar1; + case tk_intvar: + case tk_wordvar: + if(htok==tk_reg32)regexpected(1); + possiblecpu=2; + CheckAllMassiv(bufrm,2,&strinf); +lar1: + op66(razr); + outseg(&itok,3); + op(0x0f); + op(code); + op(itok.rm+hnumber*8); + outaddress(&itok); + break; + default: invalidoperand(2); break; + } + if(possiblecpu>cpu)cpu=possiblecpu; +} + +unsigned char tabldeckr(int code) +{ +unsigned int i=0; +int htok; +unsigned char next=1; +char name[IDLENGTH]; + nexttok(); + htok=tok; + KillVar(itok.name); + switch(tok){ + case tk_longvar: + case tk_dwordvar: + i=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,3); + outword(0x010f); + op(itok.rm+code); + outaddress(&itok); + break; + case tk_undefofs: + strcpy(name,itok.name); + tok=tk_number; + case tk_number: + i=doconstdwordmath(); + outword(0x010f); + op((am32==FALSE?rm_d16:rm_d32)+code); + if(postnumflag&f_reloc)AddReloc(); + if(htok==tk_undefofs)AddUndefOff(2,name); + if(am32)outdword(i); + else outword(i); + next=0; + break; + default: varexpected(0); + } + if(cpu<2)cpu=2; + return next; +} + +void protectinstr(int code,int code2) +{ +int i=0; + nexttok(); + switch(tok){ + case tk_longvar: + case tk_dwordvar: + i=2; + case tk_intvar: + case tk_wordvar: + i++; + case tk_charvar: + case tk_bytevar: + i++; +#ifdef OPTVARCONST + ClearVarByNum(&itok); +#endif + CheckAllMassiv(bufrm,i,&strinf); + KillVar(itok.name); + outseg(&itok,3); + op(0x0f); + op(code); + op(itok.rm+code2); + outaddress(&itok); + break; + case tk_reg32: + case tk_reg: + ClearReg(itok.number); + op(0x0f); + op(code); + op(0xc0+code2+(unsigned int)itok.number); + break; + default: wordvalexpected(); + } + if(cpu<2)cpu=2; +} + +void doasmmov() // do MOV +{ +unsigned char next=1,possiblecpu=0; +int htok,typet; +ITOK hstok; +char *hbuf; +SINFO hstr; +#ifdef OPTVARCONST +int initconst=FALSE; +#endif + nexttok(); + hstok=itok; + htok=tok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + typet=r16; +int i=tok; + switch(htok){ + case tk_reg32: + possiblecpu=3; + typet=r32; + case tk_reg: + switch(tok){ + case tk_debugreg: + ClearReg(hstok.number); + if(typet==r16)goto erreg; + outword(0x210F); + op(128+64+(unsigned int)itok.number*8+hstok.number); + possiblecpu=4; + if((unsigned int)itok.number<=DR3||(unsigned int)itok.number==DR6 + ||(unsigned int)itok.number==DR7)possiblecpu=3; + break; + case tk_controlreg: + ClearReg(hstok.number); + if(typet==r16)goto erreg; + outword(0x200F); + op(128+64+(unsigned int)itok.number*8+hstok.number); + possiblecpu=4; + if((unsigned int)itok.number<=CR3)possiblecpu=3; + break; + case tk_testreg: + ClearReg(hstok.number); + if(typet==r16)goto erreg; + outword(0x240F); + op(128+64+(unsigned int)itok.number*8+hstok.number); + possiblecpu=4; + if((unsigned int)itok.number==TR6||(unsigned int)itok.number==TR7)possiblecpu=3; + break; + case tk_reg32: + if(typet==r16)goto erreg; + case tk_reg: + RegToReg(hstok.number,itok.number,typet); + op66(typet); + op(0x89); + op(128+64+(unsigned int)itok.number*8+hstok.number); + break; + case tk_undefofs: + strcpy(hstok.name,itok.name); + tok=tk_number; + goto wnum; + case tk_minus: + if(tok2!=tk_number){ + wordvalexpected(); + break; + } + case tk_number: +wnum: + op66(typet); + op(0xB8+hstok.number); + ClearReg(hstok.number); + asmparam=FALSE; + SaveNumber(typet,i,hstok.name); + next=0; + break; + case tk_postnumber: + ClearReg(hstok.number); + op66(typet); + op(0xB8+hstok.number); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(typet==r32)outdword(itok.number); + else outword((unsigned int)itok.number); + break; + case tk_dwordvar: + case tk_longvar: + if(typet==r16)goto erreg; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,typet,&strinf); + IDZToReg(itok.name,hstok.number,typet); + op66(typet); + if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ + outseg(&itok,1); + op(0xA1); + } + else{ + outseg(&itok,2); + op(0x8B); + op(itok.rm+hstok.number*8); + } + outaddress(&itok); + break; + case tk_seg: + if(typet==r32)goto erreg; + IDZToReg(itok.name,hstok.number,typet); + op66(r16); + op(0x8C); + op(128+64+(unsigned int)itok.number*8+hstok.number); + if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)possiblecpu=3; + break; + default: +erreg: + invalidoperand(2); break; + } + break; + case tk_beg: + ClearReg(hstok.number%4); + switch(tok){ + case tk_beg: + op(0x88); + op(128+64+(unsigned int)itok.number*8+hstok.number); + break; + case tk_number: + op(0xB0+hstok.number); + asmparam=FALSE; + op((int)doconstlongmath()); + next=0; + break; + case tk_bytevar: + case tk_charvar: + CheckAllMassiv(bufrm,1,&strinf); + if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ + outseg(&itok,1); + op(0xA0); + } + else{ + outseg(&itok,2); + op(0x8A); + op(itok.rm+hstok.number*8); + } + outaddress(&itok); + break; + default: invalidoperand(2); break; + } + break; + case tk_seg: + if(hstok.number==CS){ + invalidoperand(1); break; + } + switch(tok){ + case tk_reg: + op66(r16); + op(0x8E); + op(128+64+hstok.number*8+(unsigned int)itok.number); + if(hstok.number==FS||hstok.number==GS)possiblecpu=3; + break; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,2,&strinf); + op66(r16); + outseg(&itok,2); + op(0x8E); + op(itok.rm+hstok.number*8); + outaddress(&itok); + if(hstok.number==FS||hstok.number==GS)possiblecpu=3; + break; + default: invalidoperand(2); break; + } + break; + case tk_dwordvar: + case tk_longvar: + possiblecpu=3; + typet=r32; + case tk_wordvar: + case tk_intvar: + KillVar(itok.name); + CheckAllMassiv(hbuf,typet,&hstr,&hstok); + op66(typet); + switch(tok){ + case tk_reg32: + if(typet==r16)goto ervar; + case tk_reg: + /*if((tok==tk_reg||tok==tk_reg32)&&hbuf==NULL&&hstr.bufstr==NULL)*/ + AddRegVar(itok.number,typet,&hstok); + if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){ + outseg(&hstok,1); + op(0xA3); + outaddress(&hstok); + } + else{ + outseg(&hstok,2); + op(0x89); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + } + break; + case tk_undefofs: + strcpy(hstok.name,itok.name); + tok=tk_number; + goto vnum; + case tk_minus: + if(tok2!=tk_number){ + wordvalexpected(); + break; + } + case tk_number: +vnum: + outseg(&hstok,2); + op(0xC7); + op(hstok.rm); + outaddress(&hstok); + asmparam=FALSE; +#ifdef OPTVARCONST + unsigned long t; + t=SaveNumber(typet,i,hstok.name); + if(typet==r16)t&=0xffff; + else t&=0xffffffff; + if((i==tk_number||i==tk_minus)&&(postnumflag&f_reloc)){ + Const2Var(&hstok,t,tk_dword); + initconst=TRUE; + } +#else + SaveNumber(typet,i,hstok.name); +#endif + next=0; + break; + case tk_postnumber: + outseg(&hstok,2); + op(0xC7); + op(hstok.rm); + outaddress(&hstok); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + if(typet==r16)outword((unsigned int)itok.number); + else outdword(itok.number); + break; + case tk_seg: + outseg(&hstok,2); + if(typet==r32)goto ervar; + op(0x8C); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + if(hstok.number==FS||hstok.number==GS)possiblecpu=3; + break; + default: +ervar: + invalidoperand(2); break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&hstok); +#endif + break; + case tk_charvar: + case tk_bytevar: + KillVar(itok.name); + CheckAllMassiv(hbuf,1,&hstr,&hstok); + switch(tok){ + case tk_beg: + /*if(tok==tk_beg&&hbuf==NULL&&hstr.bufstr==NULL)*/ + AddRegVar(itok.number,r8,&hstok); + if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){ + outseg(&hstok,1); + op(0xA2); + outaddress(&hstok); + } + else{ + outseg(&hstok,2); + op(0x88); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + } + break; + case tk_number: + outseg(&hstok,2); + op(0xC6); + op(hstok.rm); + outaddress(&hstok); + asmparam=FALSE; +#ifdef OPTVARCONST + long t; + t=doconstlongmath()&0xff; + op(t); + if((postnumflag&f_reloc)){ + initconst=TRUE; + Const2Var(&hstok,t,tk_byte); + } +#else + op((int)doconstlongmath()); +#endif + next=0; + break; + default: invalidoperand(2); break; + } +#ifdef OPTVARCONST + if(initconst==FALSE)ClearVarByNum(&hstok); +#endif + break; + case tk_debugreg: + if(tok==tk_reg32){ + outword(0x230F); + op(128+64+hstok.number*8+(unsigned int)itok.number); + possiblecpu=4; + if(hstok.number<=DR3||hstok.number==DR6||hstok.number==DR7)possiblecpu=3; + } + else invalidoperand(2); + break; + case tk_controlreg: + if(tok==tk_reg32){ + outword(0x220F); + op(128+64+hstok.number*8+(unsigned int)itok.number); + possiblecpu=4; + if(hstok.number<=CR3)possiblecpu=3; + } + else invalidoperand(2); + break; + case tk_testreg: + if(tok==tk_reg32){ + outword(0x260F); + op(128+64+hstok.number*8+(unsigned int)itok.number); + possiblecpu=4; + if(hstok.number==TR6||hstok.number==TR7)possiblecpu=3; + } + else invalidoperand(2); + break; + default: invalidoperand(1); break; + } + asmparam=FALSE; + if(possiblecpu>cpu)cpu=possiblecpu; + if(next)nexttok(); +} + +void asmextend(int basecode) // procedure MOVSX and MOVZX +{ +int regnum; +int razr=r16; + nexttok(); + if(tok==tk_reg32)razr=r32; + if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1); + regnum=(unsigned int)itok.number*8; + ClearReg(itok.number); + nextexpecting2(tk_camma); + switch(tok){ + case tk_reg: + op66(razr); + op(0xF); op(basecode|1); + op(128+64+regnum+(unsigned int)itok.number); + break; + case tk_beg: + op66(razr); + op(0xF); op(basecode); + op(128+64+regnum+(unsigned int)itok.number); + break; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,2,&strinf); + op66(razr); + outseg(&itok,3); + op(0xF); op(basecode|1); + op(itok.rm+regnum); + outaddress(&itok); + break; + case tk_bytevar: + case tk_charvar: + CheckAllMassiv(bufrm,1,&strinf); + op66(razr); + outseg(&itok,3); + op(0xF); op(basecode); + op(itok.rm+regnum); + outaddress(&itok); + break; + default: varexpected(2); break; + } + if(cpu<3)cpu=3; +} + +void movd() +{ +ITOK hstok; +int htok; +char *hbuf; +SINFO hstr; +int i=0; + nexttok(); + hstok=itok; + htok=tok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + if(tok==tk_xmmreg)i++; + switch(htok){ + case tk_reg32: + ClearReg(hstok.number); + if(tok==tk_mmxreg||i){ //MOVD EAX,MM0 + if(i)op(0x66); + outword(0x7E0F); + op(0xc0+hstok.number+(unsigned int)itok.number*8); + } + else mmxregexpected(2); + break; + case tk_dwordvar: + case tk_longvar: + if(tok==tk_mmxreg||i){ //MOVD mem,MM0 +#ifdef OPTVARCONST + ClearVarByNum(&hstok); +#endif + CheckAllMassiv(hbuf,4,&hstr,&hstok); + KillVar(hstok.name); + outseg(&hstok,i==0?3:4); + if(i)op(0x66); + outword(0x7E0F); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + } + else mmxregexpected(2); + break; + case tk_xmmreg: + i++; + case tk_mmxreg: + switch(tok){ + case tk_reg32: //MOVD MM0,EAX + if(i)op(0x66); + outword(0x6E0F); + op(0xc0+hstok.number*8+(unsigned int)itok.number); + break; + case tk_dwordvar: //MOVD MMO,mem + case tk_longvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,i==0?3:4); + if(i)op(0x66); + outword(0x6E0F); + op(itok.rm+hstok.number*8); + outaddress(&itok); + break; + default: dwordvalexpected(); + } + break; + default: mmxregordwordexpected(1); + } + if(cpu<6)cpu=6; + if(i&&cpu<9)cpu=9; +} + +void movq() +{ +int htok; +ITOK hstok; +char *hbuf; +SINFO hstr; +int i=1,xmm=0; + nexttok(); + hstok=itok; + htok=tok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + if(tok==tk_xmmreg)xmm++; + switch(htok){ + case tk_qwordvar: + case tk_doublevar: + i+=4; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i++; + case tk_charvar: + case tk_bytevar: + if(tok==tk_mmxreg||xmm){ //MOVQ mem,MM0 +#ifdef OPTVARCONST + ClearVarByNum(&hstok); +#endif + KillVar(hstok.name); + CheckAllMassiv(hbuf,i,&hstr,&hstok); + outseg(&hstok,xmm==0?3:4); + if(xmm){ + op(0x66); + outword(0xD60f); + } + else outword(0x7F0F); + op(hstok.rm+(unsigned int)itok.number*8); + outaddress(&hstok); + } + else mmxregexpected(2); + break; + case tk_mmxreg: + switch(tok){ + case tk_mmxreg: //MOVQ MM0,MM1 + outword(0x6F0F); + op(0xc0+hstok.number*8+(unsigned int)itok.number); + break; + case tk_qwordvar: + case tk_doublevar: + i+=4; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i++; + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,3); + outword(0x6F0F); + op(itok.rm+hstok.number*8); + outaddress(&itok); + break; + default: mmxregordwordexpected(2); + } + break; + case tk_xmmreg: + switch(tok){ + case tk_xmmreg: + op(0xF3); + outword(0x7e0F); + op(0xc0+hstok.number*8+(unsigned int)itok.number); + break; + case tk_qwordvar: + case tk_doublevar: + i+=4; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i++; + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,4); + op(0xF3); + outword(0x7E0F); + op(itok.rm+hstok.number*8); + outaddress(&itok); + xmm++; + break; + default: xmmregorvarexpected(2); + } + break; + default: mmxregordwordexpected(1); + } + if(cpu<6)cpu=6; + if(xmm&&cpu<9)cpu=9; +} + +void packMMX(int code,int code1,int code2) +{ +unsigned int hnumber; +int htok,next=TRUE; +int i=1; +int xmm=FALSE; + nexttok(); + hnumber=(unsigned int)itok.number; + htok=tok; + nextexpecting2(tk_camma); + if(htok==tk_xmmreg)xmm=TRUE; + else if(htok!=tk_mmxreg)mmxregexpected(1); + switch(tok){ + case tk_mmxreg: + if(xmm)xmmregexpected(2); + op(0x0f); + op(code); + op(0xc0+hnumber*8+(unsigned int)itok.number); + break; + case tk_xmmreg: + if(!xmm)mmxregexpected(2); + else op(0x66); + op(0x0f); + op(code); + op(0xc0+hnumber*8+(unsigned int)itok.number); + break; + case tk_number: + if(xmm)op(0x66); + op(0x0f); + op(code1); + op(code2+hnumber); + asmparam=FALSE; + op((unsigned int)doconstlongmath()); + next=FALSE; + break; + case tk_qwordvar: + i+=4; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i++; + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(bufrm,i,&strinf); + outseg(&itok,xmm==FALSE?3:4); + if(xmm)op(0x66); + op(0x0f); + op(code); + op(itok.rm+hnumber*8); + outaddress(&itok); + break; + default: + mmxregordwordexpected(2); + break; + } + if(cpu<6)cpu=6; + if(xmm&&cpu<9)cpu=9; + if(next==TRUE)nexttok(); +} + +void asmshift(int basecode) // used for ROL ROR RCL RCR SHL SAL SHR SAR. +{ +int htok,precode; +unsigned char holdbyte; +int usenumsh=TRUE; +ITOK hstok; +char *hbuf; +char next=1; +SINFO hstr; +int razr=r16; +#ifdef OPTVARCONST +int operand=GetOperand(basecode/8+a_rol); +#endif + nexttok(); + htok=tok; + hstok=itok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + if(tok==tk_beg&&(unsigned int)itok.number==CL){ + precode=0xD2; + usenumsh=FALSE; + } + else if(tok==tk_number){ + asmparam=FALSE; + holdbyte=(unsigned char)doconstlongmath(); + if(holdbyte==1){ + precode=0xD0; + usenumsh=FALSE; + } + else /*if(holdbyte!=0)*/{ + precode=0xC0; + if(cpu<2)cpu=2; + } + next=0; + } + else clornumberexpected(); +// if(precode!=0){ + switch(htok){ + case tk_reg32: + if(cpu<3)cpu=3; + razr=r32; + case tk_reg: + ClearReg(hstok.number); + op66(razr); + op(precode+1); op(128+64+basecode+hstok.number); + break; + case tk_beg: + ClearReg(hstok.number); + op(precode); op(128+64+basecode+hstok.number); + break; + case tk_charvar: + case tk_bytevar: +#ifdef OPTVARCONST + if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand); + else ClearVarByNum(&hstok); +#endif + CheckAllMassiv(hbuf,1,&hstr,&hstok); + KillVar(hstok.name); + outseg(&hstok,2); + op(precode); + op(hstok.rm+basecode); + outaddress(&hstok); + break; + case tk_dwordvar: + case tk_longvar: + CheckAllMassiv(hbuf,4,&hstr,&hstok); + if(cpu<3)cpu=3; + razr=r32; + goto rol; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(hbuf,2,&hstr,&hstok); +rol: +#ifdef OPTVARCONST + if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand); + else ClearVarByNum(&hstok); +#endif + KillVar(hstok.name); + op66(razr); + outseg(&hstok,2); + op(precode+1); + op(hstok.rm+basecode); + outaddress(&hstok); + break; + default: varexpected(1); break; + } + if(usenumsh)op(holdbyte); + if(next)nexttok(); +} + +void CheckCl(int code) +{ + op(0xf); + if(tok==tk_beg){ + if(itok.number==CL)code++; + else clornumberexpected(); + } + else if(tok!=tk_number)clornumberexpected(); + op(code); +} + +void Shxd(int code) +{ +unsigned int h2number; +int htok,h2tok; +ITOK hstok; +char *hbuf; +unsigned char next=1; +SINFO hstr; + nexttok(); + hstok=itok; + htok=tok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + nextexpecting2(tk_camma); + h2number=(unsigned int)itok.number; + ClearReg(itok.number); + h2tok=tok; + nextexpecting2(tk_camma); + switch(htok){ + case tk_reg: + if(h2tok==tk_reg){ + op66(r16); +regreg: + ClearReg(hstok.number); + CheckCl(code); + op(0xc0+hstok.number+(unsigned int)h2number*8); + if(tok==tk_number){ + asmparam=FALSE; + op(doconstlongmath()); + next=0; + } + } + else regexpected(2); + break; + case tk_reg32: + if(h2tok==tk_reg32){ + op66(r32); + goto regreg; + } + else reg32expected(2); + break; + case tk_intvar: + case tk_wordvar: + if(h2tok==tk_reg){ + CheckAllMassiv(hbuf,2,&hstr,&hstok); + op66(r16); +varreg: +#ifdef OPTVARCONST + ClearVarByNum(&hstok); +#endif + + KillVar(hstok.name); + outseg(&hstok,3); + CheckCl(code); + op(hstok.rm+h2number*8); + outaddress(&hstok); + if(tok==tk_number){ + asmparam=FALSE; + op(doconstlongmath()); + next=0; + } + } + else regexpected(2); + break; + case tk_dwordvar: + case tk_longvar: + if(h2tok==tk_reg32){ + CheckAllMassiv(hbuf,4,&hstr,&hstok); + op66(r32); + goto varreg; + } + else reg32expected(2); + break; + default: valueexpected(); + } + if(cpu<3)cpu=3; + if(next)nexttok(); +} + +void FpuType1(unsigned int addrm) +{ +int opcode=0xd8; +int oscan=scanlexmode; + scanlexmode=ASMLEX; + nexttok(); + retoldscanmode(oscan); + if(tok==tk_endline||tok==tk_semicolon){ + op(0xD8); + op(0xC1+addrm); + return; + } + if(tok==tk_double){ + opcode=0xdc; + nexttok(); + } + switch(tok){ + case tk_fpust: + op(0xD8); + op(0xC0+(unsigned int)itok.number+addrm); + break; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,2); + op(opcode); + op(itok.rm+addrm); + outaddress(&itok); + break; + case tk_doublevar: + CheckAllMassiv(bufrm,8,&strinf); + outseg(&itok,2); + op(0xDC); + op(itok.rm+addrm); + outaddress(&itok); + break; + default: fpuvarexpected(0); + } +} + +void FpuType2(unsigned int addrm,unsigned int addrm2) +{ +long hnum; +int opcode=0xd8; +int oscan=scanlexmode; + scanlexmode=ASMLEX; + nexttok(); + retoldscanmode(oscan); + if(tok==tk_endline||tok==tk_semicolon){ + op(0xDE); + op(0xC1+addrm); + return; + } + if(tok==tk_double){ + opcode=0xdc; + nexttok(); + } + switch(tok){ + case tk_fpust: + hnum=itok.number; + nextexpecting2(tk_camma); + if(hnum==0){ + if(tok==tk_fpust){ + op(0xD8); + op(0xC0+addrm2+(unsigned int)itok.number); + } + else fpustakexpected(2); + } + else{ + if(tok==tk_fpust){ + if(itok.number!=0)fpu0expected(); + op(0xDC); + op(0xC0+(unsigned int)hnum+addrm); + } + else fpustakexpected(2); + } + break; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + CheckAllMassiv(bufrm,4,&strinf); + outseg(&itok,2); + op(opcode); + op(addrm2+itok.rm); + outaddress(&itok); + break; + case tk_doublevar: + CheckAllMassiv(bufrm,8,&strinf); + outseg(&itok,2); + op(0xDC); + op(addrm2+itok.rm); + outaddress(&itok); + break; + default: fpuvarexpected(1); + } +} + +void FpuType3(unsigned int opcode,unsigned int addrm) +{ +int oscan=scanlexmode; + + scanlexmode=ASMLEX; + nexttok(); +// scanlexmode=oscan; + retoldscanmode(oscan); + if((tok==tk_endline||tok==tk_semicolon)&&opcode!=0xDD){ + op(opcode); + op(0xC1+addrm); + } + else if(tok==tk_fpust){ + op(opcode); + op(0xC0+(unsigned int)itok.number+addrm); + } + else fpustakexpected(1); + if(opcode==0xDE&&tok2==tk_camma){ + nexttok(); + nexttok(); + if(tok!=tk_fpust||itok.number!=0)fpu0expected(); + + } +} + +void FpuType4(unsigned int opcode,unsigned int addrm) +{ + nexttok(); + if(opcode==1&&(addrm==0x18||addrm==0)&&tok==tk_qwordvar){ + if(addrm==0)addrm=0x28; + else addrm=0x38; + CheckAllMassiv(bufrm,8,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(0xDF); + op(itok.rm+addrm); + outaddress(&itok); + return; + } + switch(tok){ + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,2,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(0xDE + opcode); + op(itok.rm+addrm); + outaddress(&itok); + break; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + CheckAllMassiv(bufrm,4,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(0xDA+opcode); + op(itok.rm+addrm); + outaddress(&itok); + break; + default: fpuvarexpected(0); + } +} + +void FpuType5(unsigned int opcode,unsigned int addrm) +{ +int opc=0xd9; +int i=4; + nexttok(); + if(tok==tk_qword||tok==tk_double){ + nexttok(); + tok=tk_qwordvar; + } + else if((strcmp(itok.name,"tbyte")==0||strcmp(itok.name,"ldouble")==0)&&addrm!=0x10){ + opc=0xdb; + i=10; + if(addrm==0)addrm=40; + else addrm=56; + nexttok(); + if(tok>=tk_charvar&&tok<=tk_wordvar)tok=tk_dwordvar; + } + switch(tok){ + case tk_fpust: + op(opcode); + op(0xC0+(unsigned int)itok.number+addrm); + break; + case tk_qwordvar: + case tk_doublevar: + opc=0xdd; + i=8; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + CheckAllMassiv(bufrm,i,&strinf); + if(opcode!=0xD9)KillVar(itok.name); + outseg(&itok,2); + op(opc); + op(itok.rm+addrm); + outaddress(&itok); + break; + default: fpuvarexpected(0); + } +} + +void FpuType6(unsigned int opcode,unsigned int addrm) +{ +int i=0; + nexttok(); + if(opcode==0xDF){ + if(tok==tk_qword){ + nexttok(); + tok=tk_qwordvar; + } + if(strcmp(itok.name,"tbyte")==0){ + i=2; + nexttok(); + tok=tk_qwordvar; + } + } + switch(tok){ + case tk_qwordvar: + if(opcode!=0xDF)wordvalexpected(); + i=+4; + case tk_longvar: + case tk_dwordvar: + case tk_floatvar: + i+=2; + case tk_wordvar: + case tk_intvar: + i+=2; + CheckAllMassiv(bufrm,i,&strinf); + KillVar(itok.name); + outseg(&itok,2); + op(opcode); + op(itok.rm+addrm); + outaddress(&itok); + break; + default: wordvalexpected(); + } +} + +void FpuType7(unsigned int addrm) +{ + nexttok(); + switch(tok){ + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(bufrm,2,&strinf); + if(addrm!=0x28)KillVar(itok.name); + outseg(&itok,2); + op(0xD9); + op(itok.rm+addrm); + outaddress(&itok); + break; + default: wordvalexpected(); + } +} + +void FpuType8(unsigned int opcode,unsigned int addrm) +{ + nexttok(); + if(tok==tk_fpust&&itok.number==0&&tok2==tk_camma){ + nexttok(); + nexttok(); + } + if(tok==tk_fpust){ + op(opcode); + op(0xC0+(unsigned int)itok.number+addrm); + if(cpu<7)cpu=7; + } + else fpustakexpected(1); +} + +/* ***************** start of some quick codes ****************** */ + +int short_ok(long thenumber,int reg32) +{ + if(reg32==TRUE){ + if(thenumber<=SHORTMAX&&thenumber>=SHORTMIN)return(1); + } + else{ + if((short)thenumber<=SHORTMAX&&(short)thenumber>=SHORTMIN)return(1); + } + return(0); +} + +void cbw() +{ + if(optimizespeed&&(chip==5||chip==6)){ + outdword(0xFCC0C488); //mov ah,al sar AH,7 + op(7); + } + else{ + op66(r16); + op(0x98); + } + ClearReg(AX); +} + +void stosb() +{ + op(0xAA); + ClearReg(DI); +} + +void stosw() +{ + op66(r16); + op(0xAB); + ClearReg(DI); +} + +void stosd() +{ + op66(r32); + op(0xAB); + if(cpu<3)cpu=3; + ClearReg(DI); +} + +void movsb() +{ + op(0xA4); + ClearReg(DI); + ClearReg(SI); +} + +void movsw() +{ + op66(r16); + op(0xA5); + ClearReg(DI); + ClearReg(SI); +} + +void movsd() +{ + op66(r32); + op(0xA5); + if(cpu<3)cpu=3; + ClearReg(DI); + ClearReg(SI); +} + +void pushds() /* produce PUSH DS */ +{ + RestoreStack(); + op(0x1E); +} + +void pushss() +{ + RestoreStack(); + op(0x16); /* PUSH SS */ +} + +void popes() /* produce POP ES */ +{ + RestoreStack(); + op(0x07); +} + +void ret() /* produce RET */ +{ + RestoreStack(); + op(0xC3); +} + +void retf() /* produce RETF */ +{ + RestoreStack(); + op(0xCB); +} + +void jumploc(long loc) /* produce JUMP # */ +{ + + loc=loc-outptr-3; + if(loc>-130&&loc<127){ + loc++; + op(0xEB); + op(loc); + if(loc==0)notunreach=TRUE; + } + else{ + if(am32==FALSE){ + op(0xE9); + outword(loc); + } + else{ + if(!optimizespeed&&(loc>126&&loc<65533)){ + outword(0xE966); + outword(loc-1); + } + else{ + op(0xE9); + outdword(loc-2); + } + } + } +} + +void callloc(long loc) /* produce CALL # */ +{ + loc=loc-outptr-3; + op(0xE8); + if(am32==FALSE) outword(loc); + else outdword(loc-2); +} + +void xorAHAH() /* produce XOR AH,AH */ +{ + outword(0xE430); + ConstToReg(0,AH,r8); +} + +void xorAXAX() /* produce XOR AX,AX */ +{ + op66(r16); + outword(0xC031); + ConstToReg(0,AX,r16); +} + +void xorEAXEAX() /* produce XOR EAX,EAX */ +{ + op66(r32); + outword(0xC031); + if(cpu<3)cpu=3; + ConstToReg(0,AX,r32); +} + +void ZeroReg(int reg, int razr) +{ + op66(razr); + op(0x31); + op(0xc0+9*reg); //xor reg,reg + ConstToReg(0,reg,razr); +} + +void fwait() +{ + op(0x9B); +} + +void cwdq(int razr) +{ + op66(razr); + if(optimizespeed&&(chip==5||chip==6)){ + outword(0xC289); //mov dx,ax + op66(razr); + outword(0xFAC1); //sar dx,15 + op(razr==r16?15:31); + } + else op(0x99); + ClearReg(DX); +} + +void nextexpecting2(int want) +{ + nexttok(); + expecting2(want); +} + +void expecting2(int want) +{ + if(want!=tok)SwTok(want); + nexttok(); +} + +void CheckIP() +{ + if(tok==tk_dollar){ + tok=tk_number; + itok.number=outptr; + } +} + +void jumploc0() +{ + op(0xE9); + outword(0); /* the large jump */ + if(am32!=FALSE)outword(0); +} + +void callloc0() +{ + op(0xE8); + outword(0); + if(am32!=FALSE)outword(0); +} + +void Leave() +{ + if((optimizespeed&&chip>3&&chip<7)||chip==0){ + outword(0xEC89); // MOV SP,BP + op(0x5D); + } + else op(0xC9); +} + +void tobedefined(int callkind,int expectedreturn) +{ +// strcpy(itok.name,(char *)string); + string[0]=0; + itok.flag=(unsigned char)(tok==tk_ID?tp_fastcall:(comfile==file_w32?tp_stdcall:tp_pascal)); + tok=tk_undefproc; + itok.number=secondcallnum; + itok.segm=NOT_DYNAMIC; + itok.rm=expectedreturn; + itok.post=0; + addtotree(itok.name); + addacall(secondcallnum++,(unsigned char)callkind); +} + +void addlocaljump(int callkind) +{ + addlocalvar((char *)string,tk_locallabel,secondcallnum,TRUE); + addacall(secondcallnum++,(char)callkind); +} + +unsigned long SaveNumber(int type,int tok4,char *name) +{ + unsigned long t=doconstdwordmath(); + if(tok4==tk_undefofs)AddUndefOff(0,name); + else if((postnumflag&f_reloc)!=0)AddReloc(); + if(type==r16)outword((unsigned int)t); + else outdword(t); + return t; +} + +void Swap2tok(int *tok4, ITOK *itok4, char **buf4, SINFO *strinf4, int *tok6, + ITOK *itok6, char **buf6, SINFO *strinf6) +{ +int htok; +ITOK hstok; +char *hbuf; +SINFO hstr; + htok=*tok4; + *tok4=*tok6; + *tok6=htok; + hstok=*itok4; + *itok4=*itok6; + *itok6=hstok; + hbuf=*buf4; + *buf4=*buf6; + *buf6=hbuf; + hstr=*strinf4; + *strinf4=*strinf6; + *strinf6=hstr; +} + +int iTest(int mode) +{ +int htok,i; +ITOK hstok; +char *hbuf; +SINFO hstr; +unsigned char possiblecpu=0,next=1; +unsigned long num; + asmparam=TRUE; + nexttok(); + htok=tok; + hstok=itok; + hbuf=bufrm; + bufrm=NULL; + hstr=strinf; + strinf.bufstr=NULL; + if(tok==tk_number)hstok.number=doconstlongmath(); + else nexttok(); + expecting2(tk_camma); + i=r16; +// printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n", +// tok,itok.number,bufrm,htok,hstok.number,hbuf); + if(htok==tk_number||htok==tk_postnumber)Swap2tok(&tok,&itok,&bufrm,&strinf, + &htok,&hstok,&hbuf,&hstr); +// printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n", +// tok,itok.number,bufrm,htok,hstok.number,hbuf); + switch(htok){ + case tk_reg32: + i=r32; + possiblecpu=3; + case tk_reg: + switch(tok){ + case tk_reg32: + if(i==r16){ + reg32expected(1); + return FALSE; + } + op66(i); + op(0x85); + op(128+64+(unsigned int)itok.number*8+hstok.number); + break; + case tk_reg: + if(i==r32){ + reg32expected(2); + return FALSE; + } + op66(i); + op(0x85); + op(128+64+(unsigned int)itok.number*8+hstok.number); + break; + case tk_number: + asmparam=FALSE; + num=doconstdwordmath(); + if(mode){ + if(num<256&&hstok.number<4)goto testal; + if(num<65536)i=r16; + } + op66(i); + if(hstok.number==AX)op(0xA9); + else{ + op(0xF7); + op(128+64+hstok.number); + } + if(i==r16)outword((unsigned int)num); + else outdword(num); + next=0; + break; + case tk_postnumber: + if(i==r32)return FALSE; + op66(r16); + if(hstok.number==AX)op(0xA9); + else{ + op(0xF7); + op(128+64+hstok.number); + } + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + outword(itok.number); //뫮 0 + break; + case tk_dwordvar: + case tk_longvar: + if(i==r16){ + reg32expected(1); + return FALSE; + } + CheckAllMassiv(bufrm,i,&strinf); + op66(i); + outseg(&itok,2); + op(0x85); + op(hstok.number*8+itok.rm); + outaddress(&itok); + break; + case tk_wordvar: + case tk_intvar: + if(i==r32){ + regexpected(1); + return FALSE; + } + CheckAllMassiv(bufrm,i,&strinf); + op66(i); + outseg(&itok,2); + op(0x85); + op(hstok.number*8+itok.rm); + outaddress(&itok); + break; + default: return FALSE; + } + break; + case tk_beg: + switch(tok){ + case tk_beg: + op(0x84); + op(128+64+(unsigned int)itok.number*8+hstok.number); + break; + case tk_number: + asmparam=FALSE; + num=doconstdwordmath(); +testal: + if(hstok.number==AL)op(0xA8); + else{ + op(0xF6); + op(128+64+hstok.number); + } + op(num); + next=0; + break; + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(bufrm,1,&strinf); + outseg(&itok,2); + op(0x84); + op(hstok.number*8+itok.rm); + outaddress(&itok); + break; + default: return FALSE; + } + break; + case tk_dwordvar: + case tk_longvar: + i=r32; + possiblecpu=3; + case tk_wordvar: + case tk_intvar: + CheckAllMassiv(hbuf,i,&hstr,&hstok); + switch(tok){ + case tk_reg32: + if(i==r16){ + regexpected(2); + return FALSE; + } + op66(i); + outseg(&hstok,2); + op(0x85); + op((unsigned int)itok.number*8+hstok.rm); + outaddress(&hstok); + break; + case tk_reg: + if(i==r32){ + reg32expected(2); + return FALSE; + } + op66(i); + outseg(&hstok,2); + op(0x85); + op((unsigned int)itok.number*8+hstok.rm); + outaddress(&hstok); + break; + case tk_number: + asmparam=FALSE; + num=doconstdwordmath(); + if(mode){ + if(num<256)goto testbyte; + if(num<65536)i=r16; + } + op66(i); + outseg(&hstok,2); + op(0xF7); + op(hstok.rm); + outaddress(&hstok); + if(i==r32)outdword(num); + else outword((unsigned int)num); + next=0; + break; + case tk_postnumber: + op66(i); + outseg(&hstok,2); + if(i==r32)return FALSE; + op(0xF7); + op(hstok.rm); + outaddress(&hstok); + (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); + outword((unsigned int)itok.number); + break; + default: return FALSE; + } + break; + case tk_charvar: + case tk_bytevar: + CheckAllMassiv(hbuf,1,&hstr,&hstok); + switch(tok){ + case tk_beg: + outseg(&hstok,2); + op(0x84); + op((unsigned int)itok.number*8+hstok.rm); + outaddress(&hstok); + break; + case tk_number: + asmparam=FALSE; + num=doconstdwordmath(); +testbyte: + outseg(&hstok,2); + op(0xF6); + op(hstok.rm); + outaddress(&hstok); + op(num); + next=0; + break; + default: return FALSE; + } + break; + default: return FALSE; + } + if(cpu