Visitar URL original
W27a #5: emitPrimitiveUnaryOp → C body + delegation stub · SonicField/cpython@19bc25e · GitHub
Skip to content

Commit 19bc25e

Browse files
committed
W27a python#5: emitPrimitiveUnaryOp → C body + delegation stub
PRIMITIVE_UNARY_OP (Static Python) opcode handler. Per W27a Step A scope final commit (5 of 5). C body: hir_builder_emit_primitive_unary_op_c (~50 lines). Inlines the PRIM_OP_* unary-op switch: - NEG_INT/INV_INT/NOT_INT: emit primitive_unary_op directly - NEG_DBL: special-case via load_const(-1.0) + double_multiply (no native double-negate primitive). hir_type_from_cdouble handles Type::fromCDouble C-side equivalent. PHX_PRIM_UOP_* values are in a SEPARATE namespace from binary/compare (per classloader.h:110-113 — unary uses 0..3, distinct from binary 0..23). Defined separately to avoid identifier collision. C primitives used: hir_c_create_primitive_unary_op + hir_c_create_load_const + hir_c_create_double_binary_op + hir_type_from_cdouble + hir_builder_temps_alloc_stack (all existing). C++ HIRBuilder::emitPrimitiveUnaryOp → 4-line delegation stub (passes current_func_ for AllocateRegister equivalent). Verification: cmake --build target jit/phoenix_jit clean (BUILD_EXIT=0). W27a CLOSURE: 5/5 emit-methods converted (PrimitiveBox/Unbox/BinaryOp/ Compare/UnaryOp). Pure-C++ count: 20 → 15 (5 delegation stubs added).
1 parent 55de520 commit 19bc25e

2 files changed

Lines changed: 54 additions & 32 deletions

File tree

‎Python/jit/hir/builder.cpp‎

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4098,41 +4098,14 @@ void HIRBuilder::emitPrimitiveCompare(
40984098
hir_builder_emit_primitive_compare_c(&tc, this, bc_instr.oparg());
40994099
}
41004100

4101+
extern "C" void hir_builder_emit_primitive_unary_op_c(
4102+
void *tc, void *func, void *builder, int oparg);
4103+
41014104
void HIRBuilder::emitPrimitiveUnaryOp(
41024105
TranslationContext& tc,
41034106
const jit::BytecodeInstruction& bc_instr) {
4104-
Register* value = static_cast<Register*>(phx_ptr_arr_pop(&tc.frame.stack));
4105-
Register* result = temps_.AllocateStack();
4106-
PrimitiveUnaryOpKind op;
4107-
switch (bc_instr.oparg()) {
4108-
case PRIM_OP_NEG_INT: {
4109-
op = PrimitiveUnaryOpKind::kNegateInt;
4110-
tc.emitPrimitiveUnaryOp(result, op, value);
4111-
break;
4112-
}
4113-
case PRIM_OP_INV_INT: {
4114-
op = PrimitiveUnaryOpKind::kInvertInt;
4115-
tc.emitPrimitiveUnaryOp(result, op, value);
4116-
break;
4117-
}
4118-
case PRIM_OP_NOT_INT: {
4119-
op = PrimitiveUnaryOpKind::kNotInt;
4120-
tc.emitPrimitiveUnaryOp(result, op, value);
4121-
break;
4122-
}
4123-
case PRIM_OP_NEG_DBL: {
4124-
// For doubles, there's no easy way to unary negate a value, so just
4125-
// multiply it by -1
4126-
auto tmp = temps_.AllocateStack();
4127-
tc.emitLoadConst(tmp, Type::fromCDouble(-1.0));
4128-
tc.emitDoubleBinaryOp(result, BinaryOpKind::kMultiply, tmp, value);
4129-
break;
4130-
}
4131-
default: {
4132-
JIT_ABORT("unsupported unary op");
4133-
}
4134-
}
4135-
phx_ptr_arr_push(&tc.frame.stack, result);
4107+
hir_builder_emit_primitive_unary_op_c(
4108+
&tc, current_func_, this, bc_instr.oparg());
41364109
}
41374110

41384111
extern "C" void hir_builder_emit_fast_len_c(void *tc, void *func, int oparg, int bc_offset);

‎Python/jit/hir/builder_emit_c.c‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3856,4 +3856,53 @@ void hir_builder_emit_primitive_compare_c(
38563856
phx_ptr_arr_push(&tc->frame.stack, result);
38573857
}
38583858

3859+
/* W27a #5: emitPrimitiveUnaryOp (PRIMITIVE_UNARY_OP opcode, Static Python).
3860+
* Mirrors C++ HIRBuilder::emitPrimitiveUnaryOp @ builder.cpp:4156.
3861+
*
3862+
* UnaryOp PRIM_OP_* values are in a SEPARATE namespace from binary/compare
3863+
* (per classloader.h:110-113). PRIM_OP_NEG_DBL handled specially via
3864+
* load_const(-1.0) + double_multiply since there is no native double-negate. */
3865+
#define PHX_PRIM_UOP_NEG_INT 0
3866+
#define PHX_PRIM_UOP_INV_INT 1
3867+
#define PHX_PRIM_UOP_NEG_DBL 2
3868+
#define PHX_PRIM_UOP_NOT_INT 3
3869+
3870+
void hir_builder_emit_primitive_unary_op_c(
3871+
PhxTranslationContext *tc,
3872+
void *func,
3873+
void *builder,
3874+
int oparg) {
3875+
void *value = phx_ptr_arr_pop(&tc->frame.stack);
3876+
void *result = hir_builder_temps_alloc_stack(builder);
3877+
3878+
switch (oparg) {
3879+
case PHX_PRIM_UOP_NEG_INT:
3880+
phx_tc_emit(tc, hir_c_create_primitive_unary_op(
3881+
result, HIR_PUOP_NegateInt, value));
3882+
break;
3883+
case PHX_PRIM_UOP_INV_INT:
3884+
phx_tc_emit(tc, hir_c_create_primitive_unary_op(
3885+
result, HIR_PUOP_InvertInt, value));
3886+
break;
3887+
case PHX_PRIM_UOP_NOT_INT:
3888+
phx_tc_emit(tc, hir_c_create_primitive_unary_op(
3889+
result, HIR_PUOP_NotInt, value));
3890+
break;
3891+
case PHX_PRIM_UOP_NEG_DBL: {
3892+
/* No native double-negate; emit load_const(-1.0) + multiply. */
3893+
void *tmp = hir_builder_temps_alloc_stack(builder);
3894+
HirType cdouble_neg1 = hir_type_from_cdouble(-1.0);
3895+
phx_tc_emit(tc, hir_c_create_load_const(tmp, cdouble_neg1));
3896+
phx_tc_emit(tc, hir_c_create_double_binary_op(
3897+
result, HIR_BOP_Multiply, tmp, value));
3898+
break;
3899+
}
3900+
default:
3901+
JIT_CHECK_C(0, "unsupported unary op %d", oparg);
3902+
return; /* unreachable */
3903+
}
3904+
phx_ptr_arr_push(&tc->frame.stack, result);
3905+
(void)func; /* func unused (no error path needs it) */
3906+
}
3907+
38593908

0 commit comments

Comments
 (0)