JIT_OP_LADD: binary [lreg, imm] -> { jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; if(value1 != 0) { x86_alu_reg_imm(inst, X86_ADD, $1, value1); x86_alu_reg_imm(inst, X86_ADC, %1, value2); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_ADD, %1, value2); } } [lreg, local] -> { x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2+4); } [lreg, lreg] -> { x86_alu_reg_reg(inst, X86_ADD, $1, $2); x86_alu_reg_reg(inst, X86_ADC, %1, %2); } JIT_OP_LADD_OVF: binary [lreg, imm] -> { unsigned char *patch; jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; if(value1 != 0) { x86_alu_reg_imm(inst, X86_ADD, $1, value1); x86_alu_reg_imm(inst, X86_ADC, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_ADD, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } } [lreg, local] -> { unsigned char *patch; x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2+4); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } [lreg, lreg] -> { unsigned char *patch; x86_alu_reg_reg(inst, X86_ADD, $1, $2); x86_alu_reg_reg(inst, X86_ADC, %1, %2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } JIT_OP_LADD_OVF_UN: binary [lreg, imm] -> { unsigned char *patch; jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; if(value1 != 0) { x86_alu_reg_imm(inst, X86_ADD, $1, value1); x86_alu_reg_imm(inst, X86_ADC, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_ADD, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } } [lreg, local] -> { unsigned char *patch; x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2+4); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } [lreg, lreg] -> { unsigned char *patch; x86_alu_reg_reg(inst, X86_ADD, $1, $2); x86_alu_reg_reg(inst, X86_ADC, %1, %2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } JIT_OP_LSUB: binary [lreg, imm] -> { jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; if(value1 != 0) { x86_alu_reg_imm(inst, X86_SUB, $1, value1); x86_alu_reg_imm(inst, X86_SBB, %1, value2); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_SUB, %1, value2); } } [lreg, local] -> { x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2+4); } [lreg, lreg] -> { x86_alu_reg_reg(inst, X86_SUB, $1, $2); x86_alu_reg_reg(inst, X86_SBB, %1, %2); } JIT_OP_LSUB_OVF: binary [lreg, imm] -> { jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; unsigned char *patch; if(value1 != 0) { x86_alu_reg_imm(inst, X86_SUB, $1, value1); x86_alu_reg_imm(inst, X86_SBB, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_SUB, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } } [lreg, local] -> { unsigned char *patch; x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2+4); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } [lreg, lreg] -> { unsigned char *patch; x86_alu_reg_reg(inst, X86_SUB, $1, $2); x86_alu_reg_reg(inst, X86_SBB, %1, %2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } JIT_OP_LSUB_OVF_UN: binary [lreg, imm] -> { jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; unsigned char *patch; if(value1 != 0) { x86_alu_reg_imm(inst, X86_SUB, $1, value1); x86_alu_reg_imm(inst, X86_SBB, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } else if(value2 != 0) { x86_alu_reg_imm(inst, X86_SUB, %1, value2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } } [lreg, local] -> { unsigned char *patch; x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2); x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2+4); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } [lreg, lreg] -> { unsigned char *patch; x86_alu_reg_reg(inst, X86_SUB, $1, $2); x86_alu_reg_reg(inst, X86_SBB, %1, %2); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } JIT_OP_LMUL: binary [lreg, imm, scratch("?"), clobber("eax", "edx")] -> { jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; jit_long value_imm = ((jit_long *)($2))[0]; switch(value_imm) { case 0: { x86_clear_reg(inst, $1); x86_clear_reg(inst, %1); } break; case 1: break; case -1: { x86_not_reg(inst, $1); x86_not_reg(inst, %1); x86_alu_reg_imm(inst, X86_ADD, $1, 1); x86_alu_reg_imm(inst, X86_ADC, $1, 0); } break; default: { x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg_imm(inst, $3, $3, value2); x86_imul_reg_reg_imm(inst, %1, %1, value1); x86_alu_reg_reg(inst, X86_ADD, %1, $3); if(%1==X86_EDX || %1==X86_EAX) { x86_mov_reg_reg(inst, $3, %1, 4); } if($1==X86_EAX) { x86_mov_reg_imm(inst, X86_EDX, value1); x86_mul_reg(inst, X86_EDX, 0); } else { x86_mov_reg_imm(inst, X86_EAX, value1); x86_mul_reg(inst, $1, 0); } if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); } } break; } } [lreg, local, scratch("?"), clobber("eax", "edx")] -> { x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_membase(inst, $3, X86_EBP, $2 + 4); x86_imul_reg_membase(inst, %1, X86_EBP, $2); x86_alu_reg_reg(inst, X86_ADD, %1, $3); if(%1==X86_EDX || %1==X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_membase(inst, X86_EBP, $2, 0); if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } [lreg, lreg, scratch("?"), clobber("eax", "edx")] -> { x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg(inst, $3, %2); x86_imul_reg_reg(inst, %1, $2); x86_alu_reg_reg(inst, X86_ADD, %1, $3); if(%1==X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_reg(inst, $2, 0); if(%1==X86_EDX || %1 == X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } JIT_OP_LMUL_OVF: binary [lreg, imm, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; jit_long value_imm = ((jit_long *)($2))[0]; switch(value_imm) { case 0: { x86_clear_reg(inst, $1); x86_clear_reg(inst, %1); } break; case 1: break; case -1: { unsigned char *patch1, *patch2; x86_alu_reg_imm(inst, X86_CMP, $1, 0); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch1, inst); x86_patch(patch2, inst); x86_not_reg(inst, $1); x86_not_reg(inst, %1); x86_alu_reg_imm(inst, X86_ADD, $1, 1); x86_alu_reg_imm(inst, X86_ADC, %1, 0); } break; default: { x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg_imm(inst, $3, $3, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_reg_imm(inst, %1, %1, value1); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1==X86_EAX) { x86_mov_reg_reg(inst, $3, %1, 4); } if($1==X86_EAX) { x86_mov_reg_imm(inst, X86_EDX, value1); x86_mul_reg(inst, X86_EDX, 0); } else { x86_mov_reg_imm(inst, X86_EAX, value1); x86_mul_reg(inst, $1, 0); x86_mov_reg_reg(inst, $1, X86_EAX, 4); } if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } } break; } } [lreg, local, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_membase(inst, $3, X86_EBP, $2 + 4); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_membase(inst, %1, X86_EBP, $2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1==X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_membase(inst, X86_EBP, $2, 0); if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } [lreg, lreg, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg(inst, $3, %2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_reg(inst, %1, $2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_reg(inst, $2, 0); if(%1==X86_EDX || %1 == X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } JIT_OP_LMUL_OVF_UN: binary [lreg, imm, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; jit_long value_imm = ((jit_long *)($2))[0]; switch(value_imm) { case 0: { x86_clear_reg(inst, $1); x86_clear_reg(inst, %1); } break; case 1: break; default: { x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg_imm(inst, $3, $1, value2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_reg_imm(inst, %1, %1, value1); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1 == X86_EAX) { x86_mov_reg_reg(inst, $3, %1, 4); } if($1==X86_EAX) { x86_mov_reg_imm(inst, X86_EDX, value1); x86_mul_reg(inst, X86_EDX, 0); } else { x86_mov_reg_imm(inst, X86_EAX, value1); x86_mul_reg(inst, $1, 0); } if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } } } [lreg, local, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_membase(inst, $3, X86_EBP, $2+4); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_membase(inst, %1, X86_EBP, $2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1==X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_membase(inst, X86_EBP, $2, 0); if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } [lreg, lreg, scratch("?"), clobber("eax", "edx")] -> { unsigned char *patch; x86_mov_reg_reg(inst, $3, $1, 4); x86_imul_reg_reg(inst, $3, %2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_imul_reg_reg(inst, %1, $2); patch = inst; x86_branch8(inst, X86_CC_NO, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_alu_reg_reg(inst, X86_ADD, %1, $3); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); if(%1==X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4); x86_mul_reg(inst, $2, 0); if(%1==X86_EDX || %1==X86_EAX) { x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); x86_mov_reg_reg(inst, %1, $3, 4); } else { x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX); patch = inst; x86_branch8(inst, X86_CC_NC, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch, inst); } if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } JIT_OP_LDIV: binary [lreg, imm, clobber("eax", "ecx", "edx", "ebx")] -> { extern long long __divdi3(long long a, long long b); jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; jit_long value_imm = ((jit_long *)($2))[0]; switch(value_imm) { case 0: { inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); } break; case 1: break; case -1: { x86_not_reg(inst, $1); x86_not_reg(inst, %1); x86_alu_reg_imm(inst, X86_ADD, $1, 1); x86_alu_reg_imm(inst, X86_ADC, $1, 0); } break; default: { x86_push_imm(inst, value2); x86_push_imm(inst, value1); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_call_code(inst, __divdi3); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *)); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } break; } } [lreg, local, clobber("eax", "ecx", "edx", "ebx")] -> { extern long long __divdi3(long long a, long long b); unsigned char *patch1, *patch2, *patch3, *patch4; #ifndef JIT_USE_SIGNALS x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2+4, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); x86_patch(patch1, inst); x86_patch(patch2, inst); #endif x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_reg_imm(inst, X86_CMP, $1, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0xffffffff); patch3 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2+4, 0xffffffff); patch4 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch1, inst); x86_patch(patch2, inst); x86_patch(patch3, inst); x86_patch(patch4, inst); x86_push_membase(inst, X86_EBP, $2+4); x86_push_membase(inst, X86_EBP, $2); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_call_code(inst, __divdi3); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *)); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } [lreg, lreg, clobber("eax", "ecx", "edx", "ebx")] -> { extern long long __divdi3(long long a, long long b); unsigned char *patch1, *patch2, *patch3, *patch4; #ifndef JIT_USE_SIGNALS x86_alu_reg_imm(inst, X86_CMP, $2, 0); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); x86_alu_reg_imm(inst, X86_CMP, %2, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); x86_patch(patch1, inst); x86_patch(patch2, inst); #endif x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_reg_imm(inst, X86_CMP, $1, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_reg_imm(inst, X86_CMP, $2, 0xffffffff); patch3 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); x86_alu_reg_imm(inst, X86_CMP, %2, 0xffffffff); patch4 = inst; x86_branch8(inst, X86_CC_NE, 0, 1); inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW); x86_patch(patch1, inst); x86_patch(patch2, inst); x86_patch(patch3, inst); x86_patch(patch4, inst); x86_push_reg(inst, %2); x86_push_reg(inst, $2); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *)); x86_call_code(inst, __divdi3); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } JIT_OP_LDIV_UN: binary [lreg, imm, clobber("eax", "ecx", "edx", "ebx")] -> { extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c); jit_uint value1 = ((jit_uint *)($2))[0]; jit_uint value2 = ((jit_uint *)($2))[1]; jit_long value_imm = ((jit_long *)($2))[0]; switch(value_imm) { case 0: { inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); } break; case 1: break; default: { x86_push_imm(inst, 0); x86_push_imm(inst, 0); x86_push_imm(inst, value2); x86_push_imm(inst, value1); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_call_code(inst, __udivmoddi4); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *)); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } break; } } [lreg, local, clobber("eax", "ecx", "edx", "ebx")] -> { extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c); #ifndef JIT_USE_SIGNALS unsigned char *patch1, *patch2; x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2+4, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); x86_patch(patch1, inst); x86_patch(patch2, inst); #endif x86_push_imm(inst, 0); x86_push_imm(inst, 0); x86_push_membase(inst, X86_EBP, $2+4); x86_push_membase(inst, X86_EBP, $2); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_call_code(inst, __udivmoddi4); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *)); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); } [lreg, lreg, clobber("eax", "ecx", "edx", "ebx")] -> { extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c); #ifndef JIT_USE_SIGNALS unsigned char *patch1, *patch2; x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0); patch1 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2+4, 0); patch2 = inst; x86_branch8(inst, X86_CC_NE, 0, 0); inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO); x86_patch(patch1, inst); x86_patch(patch2, inst); #endif x86_push_imm(inst, 0); x86_push_imm(inst, 0); x86_push_reg(inst, %2); x86_push_reg(inst, $2); x86_push_reg(inst, %1); x86_push_reg(inst, $1); x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *)); x86_call_code(inst, __udivmoddi4); if(%1!=X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4); if($1!=X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4); }