diff --git a/programs/develop/cmm/Makefile b/programs/develop/cmm/Makefile index b4667588d8..7e508b5226 100644 --- a/programs/develop/cmm/Makefile +++ b/programs/develop/cmm/Makefile @@ -1,111 +1,112 @@ -Compiler = kos32-gcc -Linker = kos32-ld - -SDK_DIR:= $(abspath ../../../contrib/sdk) - -Includes = -Id:\TEMP\mprog\kos\includes -I$(SDK_DIR)/sources/newlib/libc/include - -Compatib_Posix = -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp - -Compiler_Options = -c -fno-exceptions -D_KOS_ -U_Win32 -U_WIN32 -U__MINGW32__ \ - -mno-ms-bitfields -Wno-write-strings $(Includes) $(Compatib_Posix) - -Exe_file = cmm.kex - - -Path_Libs = -Ld:/TEMP/Dev-Cpp/lib/kos -L $(SDK_DIR)/lib -#-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 -Link_Libs = -static -S -nostdlib -T $(SDK_DIR)/sources/newlib/app-dynamic.lds \ - --image-base 0 -lgcc -ldll -lc.dll - -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 --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 $< - +# sudo apt-get install gcc-multilib g++-multilib + +Compiler = gcc + +Compiler_Options = -m32 -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) -m32 -o $(Exe_file) $(My_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/MakefileKolibriOS b/programs/develop/cmm/MakefileKolibriOS new file mode 100644 index 0000000000..e2a66371ca --- /dev/null +++ b/programs/develop/cmm/MakefileKolibriOS @@ -0,0 +1,111 @@ +Compiler = kos32-gcc +Linker = kos32-ld + +SDK_DIR:= $(abspath ../../../contrib/sdk) + +Includes = -Id:\TEMP\mprog\kos\includes -I$(SDK_DIR)/sources/newlib/libc/include + +Compatib_Posix = -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp + +Compiler_Options = -c -fno-exceptions -D_KOS_ -U_Win32 -U_WIN32 -U__MINGW32__ \ + -mno-ms-bitfields -Wno-write-strings $(Includes) $(Compatib_Posix) + +Exe_file = cmm.kex + + +Path_Libs = -Ld:/TEMP/Dev-Cpp/lib/kos -L $(SDK_DIR)/lib +#-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 +Link_Libs = -static -S -nostdlib -T $(SDK_DIR)/lib/app-dynamic.lds \ + --image-base 0 -lgcc -ldll -lc.dll + +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 --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/MakefileUnixWin b/programs/develop/cmm/MakefileUnixWin new file mode 100644 index 0000000000..42650a58c2 --- /dev/null +++ b/programs/develop/cmm/MakefileUnixWin @@ -0,0 +1,110 @@ +Compiler = gcc + +Compiler_Options = -c -m32 -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) -m32 -o $(Exe_file) $(My_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/asmnemon.h b/programs/develop/cmm/asmnemon.h index 03b5a75638..c3cdfb5032 100644 --- a/programs/develop/cmm/asmnemon.h +++ b/programs/develop/cmm/asmnemon.h @@ -1,620 +1 @@ -/* Этот файл сгенерирован программой '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' -}; +/* Этот файл сгенерирован программой 'FASTLIST.EXE' */ unsigned 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' }; \ No newline at end of file diff --git a/programs/develop/cmm/dirlist.h b/programs/develop/cmm/dirlist.h index f85f74c992..a7b548548d 100644 --- a/programs/develop/cmm/dirlist.h +++ b/programs/develop/cmm/dirlist.h @@ -1,94 +1 @@ -/* Этот файл сгенерирован программой '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' -}; +/* Этот файл сгенерирован программой 'FASTLIST.EXE' */ unsigned 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' }; \ No newline at end of file diff --git a/programs/develop/cmm/disasm.cpp b/programs/develop/cmm/disasm.cpp index 88d08810f8..19053dbcd0 100644 --- a/programs/develop/cmm/disasm.cpp +++ b/programs/develop/cmm/disasm.cpp @@ -706,7 +706,7 @@ char *second_f20f[]={ -char *second_660f[]={ +const char *second_660f[]={ // 0 @@ -1152,7 +1152,7 @@ void addr_to_hex(long addr, unsigned char splitup) { -static char buffer[12]; // fix by cppcheck +static char buffer[25]; WORD32 adr; @@ -1848,7 +1848,7 @@ void floating_point(int e1) int esc = e1*8 + REG(modrm()); - if(MOD(modrm())==3){ //2-Й БАЙТ>C0 + if(MOD(modrm())==3){ //2-\89 \81\80\89\92>C0 if (fspecial[esc]) { @@ -2572,7 +2572,7 @@ int c; getbyte(); - ua_str(second_660f[getbyte()]); + ua_str((char *)second_660f[getbyte()]); goto endp; diff --git a/programs/develop/cmm/id.h b/programs/develop/cmm/id.h index 94e12006bc..6622383f3f 100644 --- a/programs/develop/cmm/id.h +++ b/programs/develop/cmm/id.h @@ -1,136 +1 @@ -/* Этот файл сгенерирован программой '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' -}; +/* Этот файл сгенерирован программой 'FASTLIST.EXE' */ unsigned 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' }; \ No newline at end of file diff --git a/programs/develop/cmm/main.cpp b/programs/develop/cmm/main.cpp index cae1780d71..b1e7802107 100644 --- a/programs/develop/cmm/main.cpp +++ b/programs/develop/cmm/main.cpp @@ -34,9 +34,9 @@ char modelmem=TINY; char *stubfile=NULL; char *winstub=NULL; FILE *hout=NULL; -char *namestartupfile="startup.h--"; +const char *namestartupfile="startup.h--"; -char outext[4]="com"; +char outext[4]="kex"; short extflag=TRUE;//Ёрё°шЁхэшх ьюцэю яЁшётюшЄ№ //int scrsize; unsigned char gwarning=FALSE; @@ -78,73 +78,73 @@ unsigned char ESPloc=FALSE; int startupfile=-1; int alignproc=8,aligncycle=8; -char *usage[]={ +const 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", +"-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", +"-ORV replace variable on constant -OIR skip repeated initializing register", #else -" /OIR skip repeated initializing register", +" -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", +"-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", +"-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", +"-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", +"-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", +"-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[]={ +const char *dir[]={ "ME", "WORDS", "SYM", "LAI", "OBJ", "SOBJ", "J0", "J1", "J2", "C", "R", @@ -204,7 +204,7 @@ void compile(); void PrintInfo(char **str); void LoadIni(char *name); //void CheckNumStr(); -void ListId(int num,unsigned char *list,short *ofs); +void ListId(int num,unsigned char *list,unsigned short *ofs); void printmemsizes(); void print8item(char *str); void doposts(void); @@ -222,6 +222,27 @@ int MakePE(); int MakeObj(); void CheckUndefClassProc(); + +void ListId(int numfirstchar,unsigned char *list,unsigned short *ofs) +{ +char buf[40]; + for(int i=0;i4096)aligncycle=8; // fix by cppcheck + if(aligncycle<1&&aligncycle>4096)aligncycle=8; } break; case c_ws: //dos-stub for windows programs @@ -1254,25 +1268,7 @@ 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;irectok; if(tok==tk_structvar)datasize+=initstructvar((structteg *)ptr->newid,ptr->recrm); else{ -long type,ssize; -unsigned char typev; +long type = 0,ssize = 0; +unsigned char typev = 0; if(tok>=tk_charvar&&tok<=tk_doublevar){ type=tok-(tk_charvar-tk_char); typev=variable; @@ -1671,7 +1667,6 @@ unsigned char typev; if(am32==FALSE&&((itok.flag&f_far)==0))ssize=2; else ssize=4; } - else printf("unexpected condition\n"); // fix by cppcheck datasize+=initglobalvar(type,ptr->recsize/ssize,ssize,typev); } free(input); @@ -1689,10 +1684,7 @@ FILE *CreateOutPut(char *ext,char *mode) { char buf[256]; FILE *diskout; - if (comfile == file_meos) - sprintf(buf,"%s",rawfilename); - else - sprintf(buf,"%s.%s",rawfilename,ext); + sprintf(buf,"%s.%s",rawfilename,ext); if((diskout=fopen(buf,mode))==NULL){ ErrOpenFile(buf); exit(e_notcreateoutput); diff --git a/programs/develop/cmm/new_type.cpp b/programs/develop/cmm/new_type.cpp index b3dd730772..515a8a7b72 100644 --- a/programs/develop/cmm/new_type.cpp +++ b/programs/develop/cmm/new_type.cpp @@ -33,7 +33,7 @@ int usebracket=FALSE; if(usebracket){ while(tok==tk_mult){ nexttok(); - (*pointr)++; // fix by cppcheck + *pointr++; } if(tok!=tk_closebracket)expected(')'); else getoperand(reg); diff --git a/programs/develop/cmm/outpe.cpp b/programs/develop/cmm/outpe.cpp index 49260b3572..b99a11268f 100644 --- a/programs/develop/cmm/outpe.cpp +++ b/programs/develop/cmm/outpe.cpp @@ -1,1105 +1 @@ -#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 = 0,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; -} +#include "tok.h" #include "coff.h" #define _OUTPE_ /* ----------------------------------------------------------------------- Создание PE формата ------------------------------------------------------------------------ */ #define SIZESTUB 96 #define STRVERS 0x20 //смещение текста с номером версии unsigned 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=0,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((char *)(&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 = {0}; 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((char *)(&stub[STRVERS]),"%s%s",compilerstr,__DATE__); (objentry+curobj)->psize=strlen((char *)(&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; } \ No newline at end of file diff --git a/programs/develop/cmm/port.cpp b/programs/develop/cmm/port.cpp index 3d39d808f4..dda99b4909 100644 --- a/programs/develop/cmm/port.cpp +++ b/programs/develop/cmm/port.cpp @@ -99,7 +99,7 @@ int MultiByteToWideChar( int cchWideChar // size of buffer ) { - int i = 0; // fix by cppcheck + int i = 0; while ((lpMultiByteStr[i*2]!=0) && (lpMultiByteStr[i*2+1]!=0)) i++; return i/2; } @@ -147,7 +147,7 @@ int stat (const char* path, struct _stat* buf) char * getcwd (char *buffer, int size) { - volatile int len=0; // fix by cppcheck + int len=0; if (size==0){ if (buffer!=0) return 0; diff --git a/programs/develop/cmm/port.h b/programs/develop/cmm/port.h index 1a3ebf248f..c260e724ef 100644 --- a/programs/develop/cmm/port.h +++ b/programs/develop/cmm/port.h @@ -90,15 +90,12 @@ bool OemToCharA(char*, char*); bool CharToOemA(char*, char*); int MultiByteToWideChar(unsigned int,unsigned int,char*,int,wchar_t *,int); -#else - -int stricmp(const char*, const char*); -int strnicmp(const char*, const char*, int); - #endif char* strupr(char* s); char* strlwr(char* s); +int stricmp(const char*, const char*); +int strnicmp(const char*, const char*, int); #ifdef _PORT_CPP_ diff --git a/programs/develop/cmm/res.h b/programs/develop/cmm/res.h index 949410ff0f..faca10b30f 100644 --- a/programs/develop/cmm/res.h +++ b/programs/develop/cmm/res.h @@ -1,218 +1 @@ -#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; -}; +#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]={ (char *)"FILEVERSION",v_fv, (char *)"PRODUCTVERSION",v_pv, (char *)"FILEFLAGSMASK",v_ffm, (char *)"FILEFLAGS",v_ff, (char *)"FILEOS",v_fo, (char *)"FILETYPE",v_ft, (char *)"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; }; \ No newline at end of file diff --git a/programs/develop/cmm/resname.h b/programs/develop/cmm/resname.h index ebde790c20..4e6280f5b8 100644 --- a/programs/develop/cmm/resname.h +++ b/programs/develop/cmm/resname.h @@ -1,75 +1 @@ -/* Этот файл сгенерирован программой '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' -}; +/* Этот файл сгенерирован программой 'FASTLIST.EXE' */ unsigned 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' }; \ No newline at end of file diff --git a/programs/develop/cmm/struct.h b/programs/develop/cmm/struct.h index fa7dfedfbb..390243928b 100644 --- a/programs/develop/cmm/struct.h +++ b/programs/develop/cmm/struct.h @@ -278,7 +278,7 @@ typedef struct _PE_HEADER_ typedef struct _OBJECT_ENTRY_ { - char name[8]; + char name[16]; long vsize; long sectionRVA; long psize; @@ -414,7 +414,7 @@ struct paraminfo struct MEOSheader { - unsigned char sign[8]; + unsigned char sign[25]; unsigned long vers; unsigned long start; unsigned long size; diff --git a/programs/develop/cmm/tok.h b/programs/develop/cmm/tok.h index 2beb2e594b..ad3abcdd16 100644 --- a/programs/develop/cmm/tok.h +++ b/programs/develop/cmm/tok.h @@ -191,14 +191,14 @@ extern int tok,tok2; #if !defined (_TOKR_) extern char useasm; -extern short ofsmnem[]; +extern unsigned short ofsmnem[]; extern unsigned char asmMnem[]; extern char asmparam; #endif #if !defined (_TOKA_) extern unsigned char id[]; -extern short idofs[]; +extern unsigned short idofs[]; extern char id2[ID2S][9]; extern char regs[2][8][4]; extern char begs[8][3]; @@ -350,7 +350,7 @@ 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); +int FastSearch(unsigned char *list,short unsigned *ofs,int type,char *str); void FindDirectiv(); unsigned long long scannumber(int *rm); void FastTok(int mode,int *tok4=&tok,ITOK *itok4=&itok); @@ -462,7 +462,7 @@ 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=""); +void missingpar(char *name=(char *)""); int CheckCodeSize(); void CheckPosts(); int doanyundefproc(int jumpsend=FALSE); diff --git a/programs/develop/cmm/toka.cpp b/programs/develop/cmm/toka.cpp index ea4946bfec..37f025a850 100644 --- a/programs/develop/cmm/toka.cpp +++ b/programs/develop/cmm/toka.cpp @@ -663,7 +663,7 @@ int otok; void CheckReg(int idx,int base,int *reg1,int *reg2,int razr) { if(razr==r32){ - unsigned char lreg[8]; + unsigned char lreg[16]; int i; for(i=0;i<8;i++){ if(i==ESP||i==EBP)lreg[i]=1; @@ -675,7 +675,7 @@ void CheckReg(int idx,int base,int *reg1,int *reg2,int razr) } if(lreg[*reg1]==0)lreg[*reg1]=1; else{ - for(i=7;i>=0;i--){ // fix by cppcheck, side effect - enable EAX + for(i=8;i!=0;i--){ if(lreg[i]==0){ lreg[i]=1; *reg1=i; @@ -685,7 +685,7 @@ void CheckReg(int idx,int base,int *reg1,int *reg2,int razr) } // printf("\nreg1=%d",*reg1); if(lreg[*reg2]!=0){ - for(i=7;i>=0;i--){ // fix by cppcheck, side effect - enable EAX + for(i=8;i!=0;i--){ if(lreg[i]==0){ *reg2=i; break; @@ -4094,7 +4094,7 @@ int GetDirective(char *str) return i; } -int FastSearch(unsigned char *list,short *ofs,int type,char *str) +int FastSearch(unsigned char *list,short unsigned *ofs,int type,char *str) { if((strlen(str)-1)>0){ short offs=-1; diff --git a/programs/develop/cmm/tokb.cpp b/programs/develop/cmm/tokb.cpp index 513d84a04b..5efe7ffbc8 100644 --- a/programs/develop/cmm/tokb.cpp +++ b/programs/develop/cmm/tokb.cpp @@ -1,12194 +1 @@ -#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)) { //cppcheck - condition val>127||val<0xffffff80 always true, add diagnostic printf("suspicious instruction compilation\n"); 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); - ClearReg(AL); break; // fix by cppcheck - 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); bufrm=NULL; } - 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); bufrm=NULL; } -// 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); bufrm=NULL; } - 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>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=0; 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); bufrm=NULL; } 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); bufrm=NULL; } // 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); bufrm=NULL; } 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>16,itok.number); + sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number); break; default: sprintf(itok.name,"0x%X",itok.number); @@ -9976,7 +9976,7 @@ void unpackteg(structteg *tteg) int i; elementteg *bazael; structteg *newteg; -int ssize=4,count; // fix by cppcheck +int ssize=0,count; idrec *newrec,*ptr; if(alignword){ //т√Ёютэ Є№ эр ўхЄэ√щ рфЁхё if(am32==0){