From cf7b664ab2d84b33f41f6f580b1af887cf906c1c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 27 Aug 2024 11:35:45 -0700 Subject: [PATCH] bswap expression & ir --- src/eval/eval.mdesk | 3 ++- src/eval/eval_core.h | 2 ++ src/eval/eval_interpret.c | 16 ++++++++++++++++ src/eval/eval_ir.c | 32 ++++++++++++++++++++++++++++++++ src/eval/generated/eval.meta.c | 6 ++++-- src/eval/generated/eval.meta.h | 5 +++-- src/lib_rdi_format/rdi_format.c | 3 ++- src/lib_rdi_format/rdi_format.h | 6 ++++-- src/rdi_format/rdi_format.mdesk | 3 ++- 9 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 0e88e9ef..6e024028 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -86,6 +86,7 @@ E_ExprKindTable: { Cast Null 1 "cast" "(" ")" "" } { Sizeof UnaryPrefix 1 "sizeof" "sizeof" "" "" } + { ByteSwap UnaryPrefix 1 "bswap" "bswap" "(" ")"} { Neg UnaryPrefix 2 "-" "-" "" "" } { LogNot UnaryPrefix 2 "!" "!" "" "" } @@ -110,7 +111,7 @@ E_ExprKindTable: { LogAnd Binary 11 "&&" "" "&&" "" } { LogOr Binary 12 "||" "" "||" "" } - { Ternary Null 0 "? " "" "?" ":" } + { Ternary Null 0 "? " "" "?" ":"} { LeafBytecode Null 0 "bytecode" "" "" "" } { LeafMember Null 0 "member" "" "" "" } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 977aaf74..7b9e67d2 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -47,8 +47,10 @@ union E_Value U128 u128; U64 u64; U32 u32; + U16 u16; S64 s64; S32 s32; + S32 s16; F64 f64; F32 f32; }; diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 4970baef..f9dd1b10 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -770,6 +770,22 @@ e_interpret(String8 bytecode) MemoryCopy(&nval.u512[0], (U8 *)(&src_val.u512[0]) + offset, bytes_to_read); } }break; + + case RDI_EvalOp_ByteSwap: + { + U64 byte_size = imm.u64; + switch(byte_size) + { + default: + { + result.code = E_InterpretationCode_BadOp; + goto done; + }break; + case 2:{nval.u16 = bswap_u16(svals[0].u16);}break; + case 4:{nval.u32 = bswap_u32(svals[0].u32);}break; + case 8:{nval.u64 = bswap_u64(svals[0].u64);}break; + } + }break; } // rjf: push diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 6f7209cb..46b46abb 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -783,6 +783,38 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } }break; + //- rjf: byteswap + case E_ExprKind_ByteSwap: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + U64 r_type_size = e_type_byte_size_from_key(r_type); + E_Space space = r_tree.space; + + // rjf: bad conditions? -> error if applicable, exit + if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Byteswapping this type is not supported."); + break; + } + + // rjf: generate + { + E_IRNode *node = e_push_irnode(arena, RDI_EvalOp_ByteSwap); + E_IRNode *rhs = e_irtree_resolve_to_value(arena, space, r_tree.mode, r_tree.root, r_type); + e_irnode_push_child(node, rhs); + node->value.u64 = r_type_size; + result.root = node; + result.mode = E_Mode_Value; + result.space = space; + result.type_key = r_type; + } + }break; + //- rjf: unary operations case E_ExprKind_Neg: case E_ExprKind_LogNot: diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index b61b2d26..50ad5416 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[44] = +String8 e_expr_kind_strings[45] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -24,6 +24,7 @@ str8_lit_comp("Deref"), str8_lit_comp("Address"), str8_lit_comp("Cast"), str8_lit_comp("Sizeof"), +str8_lit_comp("ByteSwap"), str8_lit_comp("Neg"), str8_lit_comp("LogNot"), str8_lit_comp("BitNot"), @@ -77,7 +78,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[44] = +E_OpInfo e_expr_kind_op_info_table[45] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Nil") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Ref") }, @@ -87,6 +88,7 @@ E_OpInfo e_expr_kind_op_info_table[44] = { E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("Address") }, { E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("Cast") }, { E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp(""), str8_lit_comp("Sizeof") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp("ByteSwap") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("Neg") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("LogNot") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("BitNot") }, diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 2b1a86f9..44e07e9c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -98,6 +98,7 @@ E_ExprKind_Deref, E_ExprKind_Address, E_ExprKind_Cast, E_ExprKind_Sizeof, +E_ExprKind_ByteSwap, E_ExprKind_Neg, E_ExprKind_LogNot, E_ExprKind_BitNot, @@ -155,9 +156,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[44]; +extern String8 e_expr_kind_strings[45]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[44]; +extern E_OpInfo e_expr_kind_op_info_table[45]; extern U8 e_kind_basic_byte_size_table[55]; extern String8 e_kind_basic_string_table[55]; diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 430d704d..e4f20e25 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -92,7 +92,7 @@ RDI_U8 rdi_section_is_required_table[37] = 0, }; -RDI_U8 rdi_eval_op_ctrlbits_table[48] = +RDI_U8 rdi_eval_op_ctrlbits_table[49] = { RDI_EVAL_CTRLBITS(0, 0, 0), RDI_EVAL_CTRLBITS(0, 0, 0), @@ -141,6 +141,7 @@ RDI_EVAL_CTRLBITS(1, 0, 1), RDI_EVAL_CTRLBITS(0, 1, 0), RDI_EVAL_CTRLBITS(1, 0, 0), RDI_EVAL_CTRLBITS(1, 2, 1), +RDI_EVAL_CTRLBITS(1, 1, 1), RDI_EVAL_CTRLBITS(0, 0, 0), }; diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index 18d985e2..ede67a4d 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -484,7 +484,8 @@ RDI_EvalOp_Pick = 43, RDI_EvalOp_Pop = 44, RDI_EvalOp_Insert = 45, RDI_EvalOp_ValueRead = 46, -RDI_EvalOp_COUNT = 47, +RDI_EvalOp_ByteSwap = 47, +RDI_EvalOp_COUNT = 48, } RDI_EvalOpEnum; typedef RDI_U8 RDI_EvalTypeGroup; @@ -890,6 +891,7 @@ X(Pick)\ X(Pop)\ X(Insert)\ X(ValueRead)\ +X(ByteSwap)\ #define RDI_EvalTypeGroup_XList \ X(Other)\ @@ -1359,6 +1361,6 @@ RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConver extern RDI_U16 rdi_section_element_size_table[37]; extern RDI_U8 rdi_section_is_required_table[37]; -extern RDI_U8 rdi_eval_op_ctrlbits_table[48]; +extern RDI_U8 rdi_eval_op_ctrlbits_table[49]; #endif // RDI_FORMAT_H diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 296fe70a..9ea9161f 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1277,7 +1277,8 @@ RDI_EvalOpTable: {Pop 44 0 1 0} {Insert 45 1 0 0} {ValueRead 46 1 2 1} - {COUNT 47 0 0 0} + {ByteSwap 47 1 1 1} + {COUNT 48 0 0 0} } // NOTE(rjf): "ck" -> "conversion kind, when converted to type group", used in square matrix form