diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index 204aabf4..f4136eb7 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -139,6 +139,26 @@ void Write_Error(JitWriter *jit, int error) IA32_Write_Jump32(jit, jmp, data->jit_return); } +void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg) +{ + CompData *data = (CompData *)jit->data; + + //test reg, reg + //jnz :continue + //divzero: (write error) + IA32_Test_Rm_Reg(jit, reg, reg, MOD_REG); + jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0); + if (!(data->inline_level & JIT_INLINE_ERRORCHECKS)) + { + //sub esp, 4 - correct stack for returning to non-inlined JIT + IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG); + } + Write_Error(jit, SP_ERR_DIVZERO); + //continue: + IA32_Send_Jump8_Here(jit, jmp); + +} + void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall) { CompData *data = (CompData *)jit->data; @@ -188,7 +208,7 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall) jitoffs_t jmp1 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0); IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_HEAP); jitoffs_t jmp2 = IA32_Jump_Cond_Imm8(jit, CC_B, 0); - IA32_Lea_DispRegReg(jit, REG_ECX, reg, REG_EDI); + IA32_Lea_Reg_DispRegMult(jit, REG_ECX, reg, REG_EDI, NOSCALE); IA32_Cmp_Rm_Reg(jit, REG_ECX, AMX_REG_STK, MOD_REG); jitoffs_t jmp3 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0); IA32_Send_Jump8_Here(jit, jmp1); @@ -201,24 +221,6 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall) } } -void Write_CheckMargin_Stack(JitWriter *jit) -{ - /* this is small, so we always inline it. - */ - //cmp ebp, [esi+stp] - //jle :continue - IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_STK, AMX_REG_INFO, AMX_INFO_STACKTOP); - jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_LE, 0); - if (!(((CompData *)jit->data)->inline_level & JIT_INLINE_ERRORCHECKS)) - { - //sub esp, 4 - correct stack for returning to non-inlined JIT - IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG); - } - Write_Error(jit, SP_ERR_STACKMIN); - //continue: - IA32_Send_Jump8_Here(jit, jmp); -} - void Macro_PushN_Addr(JitWriter *jit, int i) { //push eax diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index d740d41f..9a56da08 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -27,6 +27,11 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg, bool firstcall); */ void Write_CheckMargin_Stack(JitWriter *jit); +/** +* Checks for division by zero. +*/ +void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg); + /** * These are for writing the PushN opcodes. @@ -111,11 +116,11 @@ typedef enum OP_SHR_C_PRI, //DONE OP_SHR_C_ALT, //DONE OP_SMUL, //DONE - OP_SDIV, - OP_SDIV_ALT, + OP_SDIV, //DONE + OP_SDIV_ALT, //DONE OP_UMUL, //DONE - OP_UDIV, - OP_UDIV_ALT, + OP_UDIV, //DONE + OP_UDIV_ALT, //DONE OP_ADD, //DONE OP_SUB, //DONE OP_SUB_ALT, //DONE diff --git a/sourcepawn/vm/jit/x86/x86_macros.h b/sourcepawn/vm/jit/x86/x86_macros.h index dc86e62f..66e22138 100644 --- a/sourcepawn/vm/jit/x86/x86_macros.h +++ b/sourcepawn/vm/jit/x86/x86_macros.h @@ -517,13 +517,6 @@ inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit, jit->write_byte(val); } -inline void IA32_Lea_DispRegReg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t dispreg) -{ - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, dispreg, src_base)); -} - inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val) { /* :TODO: - why does this take in src_base? */