Index: vm_x86.c =================================================================== --- vm_x86.c (revision 1962) +++ vm_x86.c (working copy) @@ -249,6 +249,10 @@ return v; } +static int NextConstant4( void ) { + return (code[pc] | (code[pc+1]<<8) | (code[pc+2]<<16) | (code[pc+3]<<24)); +} + static int Constant1( void ) { int v; @@ -424,6 +428,7 @@ */ void VM_Compile( vm_t *vm, vmHeader_t *header ) { int op; + int op1; int maxLength; int v; int i; @@ -487,7 +492,8 @@ Emit4( Constant4() ); break; case OP_CONST: - if (code[pc+4] == OP_LOAD4) { + op1 = code[pc+4]; + if ( op1 == OP_LOAD4 ) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); @@ -497,7 +503,7 @@ instruction += 1; break; } - if (code[pc+4] == OP_LOAD2) { + if ( op1 == OP_LOAD2 ) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); @@ -507,7 +513,7 @@ instruction += 1; break; } - if (code[pc+4] == OP_LOAD1) { + if ( op1 == OP_LOAD1 ) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); @@ -517,7 +523,7 @@ instruction += 1; break; } - if (code[pc+4] == OP_STORE4) { + if ( op1 == OP_STORE4 ) { opt = EmitMovEBXEDI(vm, (vm->dataMask & ~3)); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); @@ -532,7 +538,7 @@ instruction += 1; break; } - if (code[pc+4] == OP_STORE2) { + if ( op1 == OP_STORE2 ) { opt = EmitMovEBXEDI(vm, (vm->dataMask & ~1)); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); @@ -547,7 +553,7 @@ instruction += 1; break; } - if (code[pc+4] == OP_STORE1) { + if ( op1 == OP_STORE1 ) { opt = EmitMovEBXEDI(vm, vm->dataMask); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); @@ -562,20 +568,93 @@ instruction += 1; break; } - if (code[pc+4] == OP_ADD) { + if ( op1 == OP_ADD ) { + v = NextConstant4(); + if ( v == 1 ) { + EmitString( "FF 07" ); // inc dword ptr [edi] + pc += 5; // OP_CONST + OP_ADD + instruction += 1; + break; + } EmitString( "81 07" ); // add dword ptr [edi], 0x1234567 Emit4( Constant4() ); pc++; // OP_ADD instruction += 1; break; } - if (code[pc+4] == OP_SUB) { + if ( op1 == OP_SUB ) { + v = NextConstant4(); + if ( v == 1 ) { + EmitString( "FF 0F" ); // dec dword ptr [edi] + pc += 5; // OP_CONST + OP_SUB + instruction += 1; + break; + } EmitString( "81 2F" ); // sub dword ptr [edi], 0x1234567 Emit4( Constant4() ); pc++; // OP_ADD instruction += 1; break; } + if ( op1 == OP_LSH ) { + v = NextConstant4(); + if ( v >=1 && v <= 31 ) { + EmitString( "C1 27" ); // shl dword ptr [edi], 0x12 + Emit1( v ); + pc += 5; // OP_CONST + OP_LSH + instruction += 1; + break; + } + } + if ( op1 == OP_RSHI ) { + v = NextConstant4(); + if ( v >=1 && v <= 31 ) { + EmitString( "C1 3F" ); // sar dword ptr [edi], 0x12 + Emit1( v ); + pc += 5; // OP_CONST + OP_RSHI + instruction += 1; + break; + } + } + if ( op1 == OP_RSHU ) { + v = NextConstant4(); + if ( v >=1 && v <= 31 ) { + EmitString( "C1 2F" ); // shr dword ptr [edi], 0x12 + Emit1( v ); + pc += 5; // OP_CONST + OP_RSHU + instruction += 1; + break; + } + } + if ( op1 == OP_BAND ) { + v = NextConstant4(); + // try to generate shorter version + if ( v >= 0 && v <= 127 ) { + EmitString( "83 27" ); // and dword ptr[edi], 0x7F + Emit1( v ); + } else { + EmitString( "81 27" ); // and dword ptr[edi], 0x7FFFF + Emit4( v ); + } + pc += 5; // OP_CONST + OP_BAND + instruction += 1; + break; + } + if ( op1 == OP_BOR ) { + v = NextConstant4(); + // try to generate shorter version + if ( v >= 0 && v <= 127 ) { + EmitString( "83 0F" ); // or dword ptr[edi], 0x7F + Emit1( v ); + } else { + EmitString( "81 0F" ); // or dword ptr[edi], 0x7FFFF + Emit4( v ); + } + pc += 5; // OP_CONST + OP_BOR + instruction += 1; + break; + } + EmitAddEDI4(vm); EmitString( "C7 07" ); // mov dword ptr [edi], 0x12345678 lastConst = Constant4();