void do_lds(jit_function_t func) { jit_value_t ldw = LOAD(LDWhich, jit_type_uint); jit_label_t label = jit_label_undefined; jit_insn_branch_if(func, jit_insn_eq(func, ldw, make_ubyte(35)), &label); jit_value_t raw = LOAD(_ReadAbsorbWhich, jit_type_ubyte); WGPR_VAL(ldw, LOAD(LDValue, jit_type_uint)); WRA(ldw, CAST(LOAD(LDAbsorb, jit_type_uint), jit_type_ubyte)); STORE(_ReadFudge, CAST(ldw, jit_type_ubyte)); STORE(_ReadAbsorbWhich, CAST(jit_insn_or(func, raw, jit_insn_and(func, ldw, make_uint(0x1F))), jit_type_ubyte)); jit_insn_label(func, &label); STORE(LDWhich, make_uint(35)); }
jit_value_t Match::Pattern::match(Compiler &c, jit_value_t v) const { jit_type_t args_types[2] = {LS_POINTER, LS_POINTER}; jit_type_t sig = jit_type_create_signature(jit_abi_cdecl, jit_type_sys_bool, args_types, 2, 1); if (interval) { jit_value_t ge = nullptr; if (begin) { auto b = begin->compile(c); if (begin->type.nature == Nature::VALUE) { ge = jit_insn_ge(c.F, v, b.v); } else { jit_value_t args[2] = { v, b.v }; ge = jit_insn_call_native(c.F, "", (void*) jit_greater_equal_, sig, args, 2, JIT_CALL_NOTHROW); c.insn_delete_temporary(b); } } jit_value_t lt = nullptr; if (end) { auto e = end->compile(c); if (end->type.nature == Nature::VALUE) { lt = jit_insn_lt(c.F, v, e.v); } else { jit_value_t args[2] = { v, e.v }; lt = jit_insn_call_native(c.F, "", (void*) jit_less_, sig, args, 2, JIT_CALL_NOTHROW); c.insn_delete_temporary(e); } } jit_type_free(sig); if (ge) { if (lt) { return jit_insn_and(c.F, ge, lt); } else { return ge; } } else { return lt; } } else { jit_value_t cond; auto p = begin->compile(c); if (begin->type.nature == Nature::VALUE) { cond = jit_insn_eq(c.F, v, p.v); } else { jit_value_t args[2] = { v, p.v }; cond = jit_insn_call_native(c.F, "", (void*) jit_equals_, sig, args, 2, JIT_CALL_NOTHROW); c.insn_delete_temporary(p); } jit_type_free(sig); return cond; } }
/* * Handle a binary opcode. */ static void JITCoder_Binary(ILCoder *coder, int opcode, ILEngineType type1, ILEngineType type2) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); ILJitValue result = 0; _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); switch(opcode) { case IL_OP_ADD: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_ADD_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_ADD_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_DIV: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_div(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_DIV_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_div(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_REM: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_rem(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_REM_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_rem(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_AND: { result = jit_insn_and(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_OR: { result = jit_insn_or(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_XOR: { result = jit_insn_xor(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; default: { return; } } _ILJitStackPushValue(jitCoder, result); }
static jit_value_t pj_jit_internal_op(jit_function_t function, jit_value_t *var_values, int nvars, pj_op_t *op) { jit_value_t tmp1, tmp2, rv; tmp1 = pj_jit_internal(function, var_values, nvars, op->op1); if (op->op2 != NULL) tmp2 = pj_jit_internal(function, var_values, nvars, op->op2); switch (op->optype) { case pj_unop_negate: rv = jit_insn_neg(function, tmp1); break; case pj_unop_sin: rv = jit_insn_sin(function, tmp1); break; case pj_unop_cos: rv = jit_insn_cos(function, tmp1); break; case pj_unop_abs: rv = jit_insn_abs(function, tmp1); break; case pj_unop_sqrt: rv = jit_insn_sqrt(function, tmp1); break; case pj_unop_log: rv = jit_insn_log(function, tmp1); break; case pj_unop_exp: rv = jit_insn_exp(function, tmp1); break; case pj_unop_not: rv = jit_insn_not(function, tmp1); break; case pj_unop_not_bool: rv = jit_insn_to_not_bool(function, tmp1); break; case pj_binop_add: rv = jit_insn_add(function, tmp1, tmp2); break; case pj_binop_subtract: rv = jit_insn_sub(function, tmp1, tmp2); break; case pj_binop_multiply: rv = jit_insn_mul(function, tmp1, tmp2); break; case pj_binop_divide: rv = jit_insn_div(function, tmp1, tmp2); break; case pj_binop_modulo: rv = jit_insn_rem(function, tmp1, tmp2); /* FIXME should this use jit_insn_rem_ieee? */ break; case pj_binop_atan2: rv = jit_insn_atan2(function, tmp1, tmp2); break; case pj_binop_left_shift: rv = jit_insn_shl(function, tmp1, tmp2); break; case pj_binop_right_shift: rv = jit_insn_shr(function, tmp1, tmp2); break; case pj_binop_and: rv = jit_insn_and(function, tmp1, tmp2); break; case pj_binop_or: rv = jit_insn_or(function, tmp1, tmp2); break; case pj_binop_xor: rv = jit_insn_xor(function, tmp1, tmp2); break; case pj_binop_eq: rv = jit_insn_eq(function, tmp1, tmp2); break; case pj_binop_ne: rv = jit_insn_ne(function, tmp1, tmp2); break; case pj_binop_lt: rv = jit_insn_lt(function, tmp1, tmp2); break; case pj_binop_le: rv = jit_insn_le(function, tmp1, tmp2); break; case pj_binop_gt: rv = jit_insn_gt(function, tmp1, tmp2); break; case pj_binop_ge: rv = jit_insn_ge(function, tmp1, tmp2); break; default: abort(); } return rv; }
virtual jit_value_t jit_compile(jit_function_t func) { jit_value_t v0 = m_first->jit_compile(func); jit_value_t v1 = m_second->jit_compile(func); return jit_insn_and(func, v0, v1); }
jit_value jit_function::insn_and (const jit_value& value1, const jit_value& value2) { value_wrap(jit_insn_and(func, value1.raw(), value2.raw())); }
jit_value operator&(const jit_value& value1, const jit_value& value2) { return jit_value(jit_insn_and(value_owner(value1, value2), value1.raw(), value2.raw())); }