preserve operand size info for shift operations, use along with typegroup to do correct sign preservation on shifts

This commit is contained in:
Ryan Fleury
2025-10-07 14:20:36 -07:00
parent f60ccb60f1
commit ab841035c0
6 changed files with 127 additions and 83 deletions
+92 -57
View File
@@ -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
+25 -17
View File
@@ -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<<idx);
}
result = e_irtree_binary_op_u(arena, RDI_EvalOp_RShift, result, e_irtree_const_u(arena, type->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;
+2 -2
View File
@@ -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);
+4 -3
View File
@@ -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
+2 -2
View File
@@ -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),
+2 -2
View File
@@ -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}