From ab841035c03968f1cb471bd0656cb575bc781edd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 7 Oct 2025 14:20:36 -0700 Subject: [PATCH] preserve operand size info for shift operations, use along with typegroup to do correct sign preservation on shifts --- src/eval/eval_interpret.c | 149 +++++++++++++++++++++++--------------- src/eval/eval_ir.c | 42 ++++++----- src/eval/eval_ir.h | 4 +- src/eval/eval_types.c | 7 +- src/lib_rdi/rdi.c | 4 +- src/rdi/rdi.mdesk | 4 +- 6 files changed, 127 insertions(+), 83 deletions(-) diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index e667a429..12ce59a3 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -150,6 +150,10 @@ e_interpret(String8 bytecode) ptr = next_ptr; } + // rjf: unpack imm -> type group & arithmetic width + RDI_EvalTypeGroup type_group = (RDI_EvalTypeGroup)imm.u512.u8[0]; + U64 op_arithmetic_size = (U64)imm.u512.u8[1]; + // rjf: pop E_Value *svals = 0; { @@ -297,7 +301,7 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Abs: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.f32 = svals[0].f32; if(svals[0].f32 < 0) @@ -305,7 +309,7 @@ e_interpret(String8 bytecode) nval.f32 = -svals[0].f32; } } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.f64 = svals[0].f64; if(svals[0].f64 < 0) @@ -325,11 +329,11 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Neg: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.f32 = -svals[0].f32; } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.f64 = -svals[0].f64; } @@ -341,11 +345,11 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Add: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.f32 = svals[0].f32 + svals[1].f32; } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.f64 = svals[0].f64 + svals[1].f64; } @@ -357,11 +361,11 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Sub: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.f32 = svals[0].f32 - svals[1].f32; } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.f64 = svals[0].f64 - svals[1].f64; } @@ -373,11 +377,11 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Mul: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.f32 = svals[0].f32*svals[1].f32; } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.f64 = svals[0].f64*svals[1].f64; } @@ -389,7 +393,7 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Div: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { if(svals[1].f32 != 0.f) { @@ -401,7 +405,7 @@ e_interpret(String8 bytecode) goto done; } } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { if(svals[1].f64 != 0.) { @@ -413,8 +417,8 @@ e_interpret(String8 bytecode) goto done; } } - else if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { if(svals[1].u64 != 0) { @@ -435,8 +439,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Mod: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { if(svals[1].u64 != 0) { @@ -452,10 +456,27 @@ e_interpret(String8 bytecode) case RDI_EvalOp_LShift: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U) { - nval.u64 = svals[0].u64 << svals[1].u64; + switch(op_arithmetic_size) + { + default:{}break; + case 1:{nval.u8 = svals[0].u8 << svals[1].u8;}break; + case 2:{nval.u16 = svals[0].u16 << svals[1].u16;}break; + case 4:{nval.u32 = svals[0].u32 << svals[1].u32;}break; + case 8:{nval.u64 = svals[0].u64 << svals[1].u64;}break; + } + } + else if(type_group == RDI_EvalTypeGroup_S) + { + switch(op_arithmetic_size) + { + default:{}break; + case 1:{nval.s8 = svals[0].s8 << svals[1].s8;}break; + case 2:{nval.s16 = svals[0].s16 << svals[1].s16;}break; + case 4:{nval.s32 = svals[0].s32 << svals[1].s32;}break; + case 8:{nval.s64 = svals[0].s64 << svals[1].s64;}break; + } } else { @@ -466,13 +487,27 @@ e_interpret(String8 bytecode) case RDI_EvalOp_RShift: { - if(imm.u64 == RDI_EvalTypeGroup_U) + if(type_group == RDI_EvalTypeGroup_U) { - nval.u64 = svals[0].u64 >> svals[1].u64; + switch(op_arithmetic_size) + { + default:{}break; + case 1:{nval.u8 = svals[0].u8 >> svals[1].u8;}break; + case 2:{nval.u16 = svals[0].u16 >> svals[1].u16;}break; + case 4:{nval.u32 = svals[0].u32 >> svals[1].u32;}break; + case 8:{nval.u64 = svals[0].u64 >> svals[1].u64;}break; + } } - else if(imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_S) { - nval.u64 = svals[0].s64 >> svals[1].u64; + switch(op_arithmetic_size) + { + default:{}break; + case 1:{nval.s8 = svals[0].s8 >> svals[1].s8;}break; + case 2:{nval.s16 = svals[0].s16 >> svals[1].s16;}break; + case 4:{nval.s32 = svals[0].s32 >> svals[1].s32;}break; + case 8:{nval.s64 = svals[0].s64 >> svals[1].s64;}break; + } } else { @@ -483,8 +518,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_BitAnd: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = svals[0].u64&svals[1].u64; } @@ -497,8 +532,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_BitOr: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = svals[0].u64|svals[1].u64; } @@ -511,8 +546,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_BitXor: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = svals[0].u64^svals[1].u64; } @@ -525,8 +560,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_BitNot: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = ~svals[0].u64; } @@ -539,8 +574,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_LogAnd: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].u64 && svals[1].u64); } @@ -553,8 +588,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_LogOr: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].u64 || svals[1].u64); } @@ -567,8 +602,8 @@ e_interpret(String8 bytecode) case RDI_EvalOp_LogNot: { - if(imm.u64 == RDI_EvalTypeGroup_U || - imm.u64 == RDI_EvalTypeGroup_S) + if(type_group == RDI_EvalTypeGroup_U || + type_group == RDI_EvalTypeGroup_S) { nval.u64 = (!svals[0].u64); } @@ -593,19 +628,19 @@ e_interpret(String8 bytecode) case RDI_EvalOp_LsEq: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.u64 = (svals[0].f32 <= svals[1].f32); } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.u64 = (svals[0].f64 <= svals[1].f64); } - else if(imm.u64 == RDI_EvalTypeGroup_U) + else if(type_group == RDI_EvalTypeGroup_U) { nval.u64 = (svals[0].u64 <= svals[1].u64); } - else if(imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].s64 <= svals[1].s64); } @@ -618,19 +653,19 @@ e_interpret(String8 bytecode) case RDI_EvalOp_GrEq: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.u64 = (svals[0].f32 >= svals[1].f32); } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.u64 = (svals[0].f64 >= svals[1].f64); } - else if(imm.u64 == RDI_EvalTypeGroup_U) + else if(type_group == RDI_EvalTypeGroup_U) { nval.u64 = (svals[0].u64 >= svals[1].u64); } - else if(imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].s64 >= svals[1].s64); } @@ -643,19 +678,19 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Less: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.u64 = (svals[0].f32 < svals[1].f32); } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.u64 = (svals[0].f64 < svals[1].f64); } - else if(imm.u64 == RDI_EvalTypeGroup_U) + else if(type_group == RDI_EvalTypeGroup_U) { nval.u64 = (svals[0].u64 < svals[1].u64); } - else if(imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].s64 < svals[1].s64); } @@ -668,19 +703,19 @@ e_interpret(String8 bytecode) case RDI_EvalOp_Grtr: { - if(imm.u64 == RDI_EvalTypeGroup_F32) + if(type_group == RDI_EvalTypeGroup_F32) { nval.u64 = (svals[0].f32 > svals[1].f32); } - else if(imm.u64 == RDI_EvalTypeGroup_F64) + else if(type_group == RDI_EvalTypeGroup_F64) { nval.u64 = (svals[0].f64 > svals[1].f64); } - else if(imm.u64 == RDI_EvalTypeGroup_U) + else if(type_group == RDI_EvalTypeGroup_U) { nval.u64 = (svals[0].u64 > svals[1].u64); } - else if(imm.u64 == RDI_EvalTypeGroup_S) + else if(type_group == RDI_EvalTypeGroup_S) { nval.u64 = (svals[0].s64 > svals[1].s64); } @@ -841,22 +876,22 @@ e_interpret(String8 bytecode) case 8:{nval.u64 = bswap_u64(svals[0].u64);}break; } }break; - + case RDI_EvalOp_CallSiteValue: { NotImplemented; }break; - + case RDI_EvalOp_PartialValue: { NotImplemented; }break; - + case RDI_EvalOp_PartialValueBit: { NotImplemented; }break; - + case RDI_EvalOp_Swap: { // TODO: add support for pushing multiple values onto the stack diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index f38c2557..359a5b0d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -163,19 +163,20 @@ e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode } internal E_IRNode * -e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r) +e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, U64 operand_size, E_IRNode *l, E_IRNode *r) { E_IRNode *n = e_push_irnode(arena, op); - n->value.u64 = group; + n->value.u512.u8[0] = (U8)group; + n->value.u512.u8[1] = (U8)operand_size; e_irnode_push_child(n, l); e_irnode_push_child(n, r); return n; } internal E_IRNode * -e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r) +e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, U64 operand_size, E_IRNode *l, E_IRNode *r) { - E_IRNode *n = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, l, r); + E_IRNode *n = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, operand_size, l, r); return n; } @@ -314,8 +315,8 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type { valid_bits_mask |= (1ull<off)); - result = e_irtree_binary_op_u(arena, RDI_EvalOp_BitAnd, result, e_irtree_const_u(arena, valid_bits_mask)); + result = e_irtree_binary_op_u(arena, RDI_EvalOp_RShift, type->byte_size, result, e_irtree_const_u(arena, type->off)); + result = e_irtree_binary_op_u(arena, RDI_EvalOp_BitAnd, type->byte_size, result, e_irtree_const_u(arena, valid_bits_mask)); } } return result; @@ -475,7 +476,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) if(r_value != 0 && !r_is_constant_value) { E_IRNode *const_tree = e_irtree_const_u(arena, r_value); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, e_type_byte_size_from_key(new_tree_type), new_tree, const_tree); } else if(r_is_constant_value) { @@ -544,7 +545,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) if(direct_type_size > 1) { E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, 8, offset_tree, const_tree); } // rjf: ops to push stack value, push offset, + read from stack value @@ -562,7 +563,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) if(direct_type_size > 1) { E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, 8, offset_tree, const_tree); } // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) @@ -573,7 +574,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, 8, offset_tree, base_tree); if(mode != E_Mode_Null) { mode = E_Mode_Offset; @@ -1136,6 +1137,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + U64 l_type_size = e_type_byte_size_from_key(l_type); + U64 r_type_size = e_type_byte_size_from_key(r_type); + U64 op_operand_size = Max(l_type_size, r_type_size); // rjf: resolve complex types to simple arithmetic tyeps if(l_type_kind == E_TypeKind_Bitfield) @@ -1254,7 +1258,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); l_value_tree = e_irtree_convert_hi(arena, l_value_tree, l_type, l_type); r_value_tree = e_irtree_convert_hi(arena, r_value_tree, l_type, r_type); - E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, l_value_tree, r_value_tree); + E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, op_operand_size, l_value_tree, r_value_tree); result.root = new_tree; result.type_key = final_type_key; result.mode = E_Mode_Value; @@ -1267,10 +1271,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I // rjf: map l/r to ptr/int E_IRTreeAndType *ptr_tree = &l_tree; E_IRTreeAndType *int_tree = &r_tree; + U64 ptr_size = l_type_size; B32 ptr_is_decay = l_is_decay; if(ptr_arithmetic_mul_rptr) { ptr_tree = &r_tree; + ptr_size = r_type_size; int_tree = &l_tree; ptr_is_decay = r_is_decay; } @@ -1291,14 +1297,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I if(direct_type_size > 1) { E_IRNode *const_root = e_irtree_const_u(arena, direct_type_size); - int_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, int_root, const_root); + int_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, ptr_size, int_root, const_root); } E_TypeKey ptr_type = ptr_tree->type_key; if(ptr_is_decay) { ptr_type = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type, 1, 0); } - E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); + E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_size, ptr_root, int_root); result.root = new_root; result.type_key = ptr_type; result.mode = E_Mode_Value; @@ -1323,12 +1329,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I { r_root = e_irtree_resolve_to_value(arena, r_tree.mode, r_root, r_type); } - E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_root, r_root); + E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_type_size, l_root, r_root); E_IRNode *new_tree = op_tree; if(direct_type_size > 1) { E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Div, new_tree, const_tree); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Div, l_type_size, new_tree, const_tree); } result.root = new_tree; result.type_key = e_type_key_basic(E_TypeKind_U64); @@ -1342,11 +1348,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I B32 ptr_is_decay = l_is_decay; E_IRTreeAndType *ptr_tree = &l_tree; E_IRTreeAndType *arr_tree = &r_tree; + U64 ptr_size = l_type_size; if(l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Value) { ptr_is_decay = r_is_decay; ptr_tree = &r_tree; arr_tree = &l_tree; + ptr_size = r_type_size; } // rjf: resolve pointer to value, sized same as array @@ -1361,7 +1369,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_root, arr_tree->type_key); // rjf: generate - result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, mem_root, arr_root); + result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, ptr_size, mem_root, arr_root); result.type_key = e_type_key_basic(E_TypeKind_Bool); result.mode = E_Mode_Value; }break; @@ -2701,7 +2709,7 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) // rjf: fill bytecode ptr[0] = opcode; - MemoryCopy(ptr + 1, &op->value.u64, extra_byte_count); + MemoryCopy(ptr + 1, &op->value.u512.u8[0], extra_byte_count); // rjf: advance ptr = next_ptr; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 4b463442..96e4194f 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -138,8 +138,8 @@ internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child); internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v); internal E_IRNode *e_irtree_leaf_u128(Arena *arena, U128 u128); internal E_IRNode *e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c); -internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r); -internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r); +internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, U64 operand_size, E_IRNode *l, E_IRNode *r); +internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, U64 operand_size, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index f4ddca7f..fb580740 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2661,6 +2661,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) if(ext->base_ptr_member != 0) { Temp scratch = scratch_begin(&arena, 1); + U64 addr_size = e_type_byte_size_from_key(ext->base_ptr_member->type_key); // rjf: compute ir tree for struct base E_IRNode *struct_base_tree = &e_irnode_nil; @@ -2681,7 +2682,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) base_ptr_tree = struct_base_tree; if(ext->base_ptr_member->off != 0) { - base_ptr_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, struct_base_tree, e_irtree_const_u(arena, ext->base_ptr_member->off)); + base_ptr_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, addr_size, struct_base_tree, e_irtree_const_u(arena, ext->base_ptr_member->off)); } base_ptr_tree = e_irtree_mem_read_type(arena, base_ptr_tree, ext->base_ptr_member->type_key); } @@ -2692,8 +2693,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) { E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, &e_default_identifier_resolution_rule, 0, 1, expr->first->next); E_IRNode *idx_root = e_irtree_resolve_to_value(arena, idx_irtree.mode, idx_irtree.root, idx_irtree.type_key); - E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All)))); - idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, base_ptr_tree, off_root); + E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, addr_size, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All)))); + idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, addr_size, base_ptr_tree, off_root); } // rjf: form final result diff --git a/src/lib_rdi/rdi.c b/src/lib_rdi/rdi.c index 943411a9..d60dc325 100644 --- a/src/lib_rdi/rdi.c +++ b/src/lib_rdi/rdi.c @@ -85,8 +85,8 @@ RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), -RDI_EVAL_CTRLBITS(1, 2, 1), -RDI_EVAL_CTRLBITS(1, 2, 1), +RDI_EVAL_CTRLBITS(2, 2, 1), +RDI_EVAL_CTRLBITS(2, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 2, 1), diff --git a/src/rdi/rdi.mdesk b/src/rdi/rdi.mdesk index 6bbcfb95..f68f611d 100644 --- a/src/rdi/rdi.mdesk +++ b/src/rdi/rdi.mdesk @@ -1323,8 +1323,8 @@ RDI_EvalOpTable: {Mul 22 1 2 1} {Div 23 1 2 1} {Mod 24 1 2 1} - {LShift 25 1 2 1} - {RShift 26 1 2 1} + {LShift 25 2 2 1} + {RShift 26 2 2 1} {BitAnd 27 1 2 1} {BitOr 28 1 2 1} {BitXor 29 1 2 1}