diff --git a/code/8086/decoder.c b/code/8086/decoder.c index c48f402..f11941a 100644 --- a/code/8086/decoder.c +++ b/code/8086/decoder.c @@ -39,18 +39,18 @@ typedef Struct_(X8616_DecodePlex) { U1 post_opcode; U1 mod_rm; - U1 d; - U1 w; - U1 s; - U1 v; - U1 z; - U1 reg_opcode; - U1 sr_opcode; + X8616_Direction d; + X8616_Width w; + X8616_Sign s; + X8616_VariableShift v; + X8616_Repeat z; + X8616_DecodedReg reg_opcode; + X8616_Segment sr_opcode; - U1 mod; - U1 reg; - U1 rm; - U1 sr_modrm; + X8616_Mod mod; + X8616_DecodedReg reg; + X8616_EA rm; + X8616_Segment sr_modrm; X8616_WidthMode width; @@ -103,11 +103,11 @@ x8616_decode_apply_prefix(X8616_DecodePlex_R plex, X8616_DecodePlan_R plan, U1 o plex->prefixes.lock |= plan->prefix_kind == x8616_prefix_lock; if (plan->prefix_kind == x8616_prefix_repeat) { plex->prefixes.has_repeat = 1; - plex->prefixes.repeat = (opcode >> plan->z_shift) & 0b1; + plex->prefixes.repeat = C_(X8616_Repeat, (opcode >> plan->z_shift) & 0b1); } if (plan->prefix_kind == x8616_prefix_segment) { plex->prefixes.has_segment = 1; - plex->prefixes.segment = (opcode >> plan->sr_shift) & 0b11; + plex->prefixes.segment = C_(X8616_Segment, (opcode >> plan->sr_shift) & 0b11); } } @@ -251,13 +251,13 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) } X8616_DecodePlan const* plan = plex->plan; - plex->d = (plex->opcode >> plan->d_shift) & 0b1; - plex->w = (plex->opcode >> plan->w_shift) & 0b1; - plex->s = (plex->opcode >> plan->s_shift) & 0b1; - plex->v = (plex->opcode >> plan->v_shift) & 0b1; - plex->z = (plex->opcode >> plan->z_shift) & 0b1; - plex->reg_opcode = (plex->opcode >> plan->reg_shift) & 0b111; - plex->sr_opcode = (plex->opcode >> plan->sr_shift) & 0b11; + plex->d = C_(X8616_Direction, (plex->opcode >> plan->d_shift) & 0b1); + plex->w = C_(X8616_Width, (plex->opcode >> plan->w_shift) & 0b1); + plex->s = C_(X8616_Sign, (plex->opcode >> plan->s_shift) & 0b1); + plex->v = C_(X8616_VariableShift, (plex->opcode >> plan->v_shift) & 0b1); + plex->z = C_(X8616_Repeat, (plex->opcode >> plan->z_shift) & 0b1); + plex->reg_opcode.r16 = C_(X8616_Reg16, (plex->opcode >> plan->reg_shift) & 0b111); + plex->sr_opcode = C_(X8616_Segment, (plex->opcode >> plan->sr_shift) & 0b11); plex->width = plan->width; if (plex->width == x8616_width_dynamic && (plan->flags & x8616_plan_has_w)) @@ -272,16 +272,16 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) if (plan->flags & x8616_plan_has_modrm) { plex->mod_rm = plex->body[plex->body_at]; - plex->mod = x8616_modrm_mod(plex->mod_rm); - plex->reg = x8616_modrm_reg(plex->mod_rm); - plex->rm = x8616_modrm_rm(plex->mod_rm); - plex->sr_modrm = x8616_modrm_sr(plex->mod_rm); + plex->mod = C_(X8616_Mod, x8616_modrm_mod(plex->mod_rm)); + plex->reg.r16 = C_(X8616_Reg16, x8616_modrm_reg(plex->mod_rm)); + plex->rm = C_(X8616_EA, x8616_modrm_rm(plex->mod_rm)); + plex->sr_modrm = C_(X8616_Segment, x8616_modrm_sr(plex->mod_rm)); plex->body_at += 1; } plex->displacement_at = plex->body_at; - if (plan->flags & x8616_plan_uses_rm) plex->displacement_bytes = x8616_decode_disp_bytes[(plex->mod << 3) | plex->rm]; + if (plan->flags & x8616_plan_uses_rm) plex->displacement_bytes = x8616_decode_disp_bytes[(u1_(plex->mod) << 3) | u1_(plex->rm)]; plex->direct_memory = (plan->flags & x8616_plan_uses_rm) && plex->mod == x8616_mod_mem && plex->rm == x8616_ea_direct; @@ -321,19 +321,19 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) source[x8616_operand_reg_modrm].flags = x8616_decoded_operand_register; source[x8616_operand_reg_modrm].width = plex->width; - source[x8616_operand_reg_modrm].reg.r16 = C_(X8616_Reg16, plex->reg); + source[x8616_operand_reg_modrm].reg = plex->reg; source[x8616_operand_reg_opcode].flags = x8616_decoded_operand_register; source[x8616_operand_reg_opcode].width = plex->width; - source[x8616_operand_reg_opcode].reg.r16 = C_(X8616_Reg16, plex->reg_opcode); + source[x8616_operand_reg_opcode].reg = plex->reg_opcode; source[x8616_operand_segment_modrm].flags = x8616_decoded_operand_segment; source[x8616_operand_segment_modrm].width = x8616_width_word; - source[x8616_operand_segment_modrm].segment = C_(X8616_Segment, plex->sr_modrm); + source[x8616_operand_segment_modrm].segment = plex->sr_modrm; source[x8616_operand_segment_opcode].flags = x8616_decoded_operand_segment; source[x8616_operand_segment_opcode].width = x8616_width_word; - source[x8616_operand_segment_opcode].segment = C_(X8616_Segment, plex->sr_opcode); + source[x8616_operand_segment_opcode].segment = plex->sr_opcode; source[x8616_operand_acc].flags = x8616_decoded_operand_register | x8616_decoded_operand_implicit; source[x8616_operand_acc].width = plex->width; @@ -350,8 +350,8 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) } else { source[x8616_operand_rm].flags = x8616_decoded_operand_memory; - source[x8616_operand_rm].mod = C_(X8616_Mod, plex->mod); - source[x8616_operand_rm].ea = C_(X8616_EA, plex->rm); + source[x8616_operand_rm].mod = plex->mod; + source[x8616_operand_rm].ea = plex->rm; source[x8616_operand_rm].displacement = plex->displacement; source[x8616_operand_rm].displacement_bytes = plex->displacement_bytes; if (plex->direct_memory) { @@ -407,7 +407,7 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) } // Final projection. Authored operand order is d=0; d=1 exchanges the two source slots without introducing a separate decoder path. - U1 swap = C_(U1, ((plan->flags & x8616_plan_has_d) != 0) & plex->d); + U1 swap = C_(U1, ((plan->flags & x8616_plan_has_d) != 0) & u1_(plex->d)); plex->instruction.operands[swap] = source[plan->operands[0]]; plex->instruction.operands[swap ^ 1] = source[plan->operands[1]]; @@ -416,11 +416,11 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) plex->instruction.decode_flags = (plex->encoding_invalid ? x8616_decode_invalid : 0) | (plex->classification_truncated ? x8616_decode_truncated : 0); plex->instruction.width = plex->width; plex->instruction.prefixes = plex->prefixes; - plex->instruction.operand_count = plan->operand_count; - plex->instruction.opcode = x8616_decode_opcode(plan, plex->opcode); - plex->instruction.d = C_(X8616_Direction, (plan->flags & x8616_plan_has_d) ? plex->d : 0); - plex->instruction.w = C_(X8616_Width, (plan->flags & x8616_plan_has_w) ? plex->w : 0); - plex->instruction.has_mod_rm = (plan->flags & x8616_plan_has_modrm) != 0; + plex->instruction.operand_count = plan->operand_count; + plex->instruction.opcode = x8616_decode_opcode(plan, plex->opcode); + plex->instruction.d = (plan->flags & x8616_plan_has_d) ? plex->d : x8616_d_rm_dst; + plex->instruction.w = (plan->flags & x8616_plan_has_w) ? plex->w : x8616_w_byte; + plex->instruction.has_mod_rm = (plan->flags & x8616_plan_has_modrm) != 0; U4 total_required = prefix_at + plex->body_required; U4 total_available = plex->source_size; @@ -435,27 +435,28 @@ x8616_decode_one_plex(X8616_DecodePlex* plex) X8616_DecodeInfo x8616_decode(X8616_DecodeRequest request) { X8616_DecodeInfo result = {0}; - result.instruction_capacity = request.instruction_capacity; + result.instruction_cap = request.instruction_cap; - while (result.source_consumed < request.source_size && result.instruction_count < request.instruction_capacity) { + while (result.source_consumed < request.source_len && result.instruction_count < request.instruction_cap) { X8616_DecodePlex plex = {0}; plex.source = request.source + result.source_consumed; - plex.source_size = request.source_size - result.source_consumed; + plex.source_size = request.source_len - result.source_consumed; plex.source_offset = result.source_consumed; plex.info_arena = request.info_arena; plex.msgs = & result.msgs; U4 consumed = x8616_decode_one_plex(& plex); - request.instructions[result.instruction_count++] = plex.instruction; + request.out_instructions[result.instruction_count] = plex.instruction; + result.instruction_count += 1; if (consumed == false) consumed = 1; result.source_consumed += consumed; } - if (result.source_consumed < request.source_size && result.instruction_count == request.instruction_capacity) { + if (result.source_consumed < request.source_len && result.instruction_count == request.instruction_cap) { x8616_info_push(request.info_arena, & result.msgs, x8616_info_warning , x8616_info_output_full , result.source_consumed , 0 - , request.instruction_capacity + , request.instruction_cap , result.instruction_count ); } diff --git a/code/8086/decoder.h b/code/8086/decoder.h index 4ab635d..23ca174 100644 --- a/code/8086/decoder.h +++ b/code/8086/decoder.h @@ -67,11 +67,10 @@ typedef Struct_(X8616_DecodedInstruction) { X8616_DecodeFlags decode_flags; X8616_WidthMode width; X8616_DecodedPrefixes prefixes; - X8616_DecodedOperand operands[2]; - U1 operand_count; - X8616_OpcodePrefix opcode; - X8616_Direction d; - X8616_Width w; + X8616_DecodedOperand operands[2]; U1 operand_count; + X8616_OpcodePrefix opcode; + X8616_Direction d; + X8616_Width w; B1 has_mod_rm; U1 size; U1 size_required; @@ -142,20 +141,18 @@ enum { }; typedef Struct_(X8616_DecodeRequest) { - U1* source; - U4 source_size; - - X8616_DecodedInstruction* instructions; - U4 instruction_capacity; - + U1* source; + X8616_DecodedInstruction* out_instructions; + U4 source_len; + U4 instruction_cap; FArena* info_arena; }; typedef Struct_(X8616_DecodeInfo) { + X8616_InfoList msgs; U4 source_consumed; U4 instruction_count; - U4 instruction_capacity; - X8616_InfoList msgs; + U4 instruction_cap; }; X8616_DecodeInfo x8616_decode(X8616_DecodeRequest request); diff --git a/code/8086/encoder_table.h b/code/8086/encoder_table.h index 5153af2..b89547a 100644 --- a/code/8086/encoder_table.h +++ b/code/8086/encoder_table.h @@ -3,15 +3,15 @@ # include "encoder.h" #endif -// ============================================================================ +// ========================================================================================= // Encoding Table // -// Part 1 target: the instruction cross-section exercised by Computer Enhance -// listing 0042. Later Part 1 simulation listings use a subset of this table. +// Part 1 target: the instruction cross-section exercised by Computer Enhance listing 0042. +// Later Part 1 simulation listings use a subset of this table. // -// Fixed opcode bits are kept in binary/signature form; ModR/M /digit selectors -// use their encoded enumeration values. -// ============================================================================ +// Fixed opcode bits are kept in binary/signature form; +// ModR/M /digit selectors use their encoded enumeration values. +// ========================================================================================= RO_ global X8616_Encoding x8616_encodings[] = { diff --git a/code/8086/info.h b/code/8086/info.h index 019a223..9e57b28 100644 --- a/code/8086/info.h +++ b/code/8086/info.h @@ -26,6 +26,11 @@ typedef Enum_(U1, X8616_InfoCode) { x8616_info_gen_ambiguous_decode = 0x09, x8616_info_gen_dispatch_mismatch = 0x0A, + x8616_info_serialize_bad_request = 0x0B, + x8616_info_serialize_invalid_record = 0x0C, + x8616_info_serialize_unsupported_form = 0x0D, + x8616_info_serialize_output_full = 0x0E, + x8616_info_count, }; @@ -35,8 +40,8 @@ typedef Struct_(X8616_InfoMsg) { X8616_InfoMsg* next; X8616_InfoKind kind; X8616_InfoCode code; - U4 source_offset; U2 source_size; + U4 source_offset; U4 expected; U4 actual; Str8 text; @@ -45,17 +50,21 @@ typedef Struct_(X8616_InfoMsg) { /* Static templates use the same vocabulary as Duffle's str8_fmt_ktl_buf path. The decoder itself never expands these. */ RO_ global Str8 x8616_info_templates[x8616_info_count] = { - [x8616_info_none] = slit8(""), - [x8616_info_invalid_opcode] = slit8("Opcode is not in the Part 1 8086 decode table at ."), - [x8616_info_invalid_opcode_extension] = slit8("Opcode extension does not match the selected encoding at ."), - [x8616_info_invalid_post_opcode] = slit8("Post-opcode byte does not match expected at ."), - [x8616_info_truncated_instruction] = slit8("Instruction at needs bytes; are available."), - [x8616_info_output_full] = slit8("Decoded-instruction output is full: capacity , produced ."), - [x8616_info_gen_multiple_payloads] = slit8("Encoding describes more than one stream payload."), - [x8616_info_gen_body_cap_exceeded] = slit8("Encoding requires body bytes; decoder body capacity is ."), - [x8616_info_gen_aux_cap_exceeded] = slit8("Generated auxiliary decode table exceeds capacity ."), - [x8616_info_gen_ambiguous_decode] = slit8("Decode is ambiguous for opcode/second-byte key : plans and ."), - [x8616_info_gen_dispatch_mismatch] = slit8("Generated dispatch mismatch for opcode/second-byte key : expected , actual ."), + [x8616_info_none] = slit8(""), + [x8616_info_invalid_opcode] = slit8("Opcode is not in the Part 1 8086 decode table at ."), + [x8616_info_invalid_opcode_extension] = slit8("Opcode extension does not match the selected encoding at ."), + [x8616_info_invalid_post_opcode] = slit8("Post-opcode byte does not match expected at ."), + [x8616_info_truncated_instruction] = slit8("Instruction at needs bytes; are available."), + [x8616_info_output_full] = slit8("Decoded-instruction output is full: capacity , produced ."), + [x8616_info_gen_multiple_payloads] = slit8("Encoding describes more than one stream payload."), + [x8616_info_gen_body_cap_exceeded] = slit8("Encoding requires body bytes; decoder body capacity is ."), + [x8616_info_gen_aux_cap_exceeded] = slit8("Generated auxiliary decode table exceeds capacity ."), + [x8616_info_gen_ambiguous_decode] = slit8("Decode is ambiguous for opcode/second-byte key : plans and ."), + [x8616_info_gen_dispatch_mismatch] = slit8("Generated dispatch mismatch for opcode/second-byte key : expected , actual ."), + [x8616_info_serialize_bad_request] = slit8("Serialize request is missing instructions, output, scratch, or info arena."), + [x8616_info_serialize_invalid_record] = slit8("Serialize record is not printable (op )."), + [x8616_info_serialize_unsupported_form] = slit8("Serialize record has an unsupported display form (op )."), + [x8616_info_serialize_output_full] = slit8("Serialize output is full at record : capacity , produced ."), }; typedef Struct_(X8616_InfoList) { diff --git a/code/8086/info_render.h b/code/8086/info_render.h index f48af43..46ed196 100644 --- a/code/8086/info_render.h +++ b/code/8086/info_render.h @@ -5,10 +5,6 @@ # include "info.h" #endif -/* Numeric representation remains a presentation decision. - Feed whatever Duffle-formatted Str8 values you want here (hex for opcode - facts, decimal for capacities, etc.) and the existing formatter does - the composition. */ typedef Struct_(X8616_InfoTextValues) { Str8 offset; Str8 expected; Str8 actual; }; FI_ Str8 diff --git a/code/8086/serializer.c b/code/8086/serializer.c index 7964486..c1b7f51 100644 --- a/code/8086/serializer.c +++ b/code/8086/serializer.c @@ -2,10 +2,6 @@ # include "serializer.h" #endif -enum { - X8616_SERIALIZE_HEADER_LEN = 9, -}; - RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n"); RO_ global Str8 x8616_serialize_mnemonic[] = { @@ -162,12 +158,11 @@ FI_ X8616_SerializeStatus x8616_serialize_put_or_full(Str8Gen_R gen, Str8 piece) } internal B4 x8616_serialize_put_u4(Str8Gen_R gen, U4 value) { - Info_str8_from_u4 info = str8_from_u4_info(value, 10, 0, 0); - UTF8 digits[16]; - B4 ok = info.size_required != 0 && info.size_required <= Array_len(digits) && info.size_required <= gen->cap - gen->len; + Info_str8_from_u4 info = str8_from_u4_info(value, 10, 0, 0); UTF8 digits[16]; + B4 ok = info.size_required != 0 && info.size_required <= Array_len(digits) && info.size_required <= gen->cap - gen->len; if (ok) { Str8 text = str8_from_u4_buf(slice_ut(digits, info.size_required), value, 10, 0, 0, info); - ok = x8616_serialize_put(gen, text); + ok = x8616_serialize_put(gen, text); } return ok; } @@ -333,13 +328,13 @@ FI_ B4 x8616_serialize_is_string(X8616_Op op) { switch (op) { return 0; }} -FI_ B4 x8616_serialize_has_memory(X8616_DecodedInstruction* inst) { +FI_ B4 x8616_serialize_has_memory(X8616_DecodedInstruction_R inst) { for (U1 id = 0; id < inst->operand_count; ++id) { if (inst->operands[id].flags & x8616_decoded_operand_memory) return 1; } return 0; } internal X8616_SerializeStatus -x8616_serialize_put_operand(Str8Gen_R gen, X8616_DecodedInstruction* inst, X8616_DecodedOperand* operand) +x8616_serialize_put_operand(Str8Gen_R gen, X8616_DecodedInstruction_R inst, X8616_DecodedOperand_R operand) { X8616_SerializeStatus status = x8616_serialize_ok; X8616_SerializeSizeWhere where = x8616_serialize_size_where(inst->op, inst->operand_count, inst->operands); @@ -408,6 +403,21 @@ FI_ X8616_DecodedOperandFlags x8616_serialize_base_flags(X8616_DecodedOperandFla FI_ B4 x8616_serialize_one_flag(X8616_DecodedOperandFlags flags) { U2 bits = C_(U2, flags); return (bits != 0) && ((bits & (bits - 1)) == 0); } +internal void +x8616_serialize_push(FArena_R arena, X8616_InfoList_R msgs, X8616_SerializeStatus status, U4 id, U2 size, U4 expected, U4 actual) { + if (status == x8616_serialize_ok || arena == 0) return; + X8616_InfoKind kind = x8616_info_error; + X8616_InfoCode code = x8616_info_serialize_invalid_record; + if (status == x8616_serialize_output_full) { + kind = x8616_info_warning; + code = x8616_info_serialize_output_full; + } + else if (status == x8616_serialize_unsupported_form) { + code = x8616_info_serialize_unsupported_form; + } + x8616_info_push(arena, msgs, kind, code, id, size, expected, actual); +} + internal X8616_SerializeStatus x8616_serialize_validate(X8616_DecodedInstruction_R inst) { @@ -452,7 +462,7 @@ status_failed: return status; } -internal X8616_SerializeStatus +internal X8616_SerializeStatus x8616_serialize_instruction_line(Str8Gen_R line, X8616_DecodedInstruction* inst) { X8616_SerializeStatus st = x8616_serialize_ok; @@ -477,7 +487,7 @@ x8616_serialize_instruction_line(Str8Gen_R line, X8616_DecodedInstruction* inst) if (st == x8616_serialize_ok && inst->operand_count) { st = x8616_serialize_put_or_full(line, slit8(" ")); for (U1 id = 0; st == x8616_serialize_ok && id < inst->operand_count; ++id) { - if (id) st = x8616_serialize_put_or_full(line, slit8(", ")); + if (id) st = x8616_serialize_put_or_full(line, slit8(", ")); if (st == x8616_serialize_ok) st = x8616_serialize_put_operand(line, inst, & inst->operands[id]); } } @@ -485,38 +495,70 @@ x8616_serialize_instruction_line(Str8Gen_R line, X8616_DecodedInstruction* inst) return st; } -X8616_SerializeInfo -x8616_serialize_instructions(X8616_SerializeRequest request) +X8616_SerializeInfo x8616_serialize_instructions(X8616_SerializeRequest request) { X8616_SerializeInfo result = {0}; result.text.ptr = C_(UTF8*, request.output.ptr); - B4 invalid_record = + X8616_InfoList local = {0}; + X8616_InfoList_R msgs = request.msgs ? request.msgs : & local; + + B4 bad_request = (request.instruction_count && request.instructions == 0) || (request.output.len && request.output.ptr == 0) - || (request.scratch.len && request.scratch.ptr == 0); - if (invalid_record) { result.status = x8616_serialize_invalid_record; goto exit; } - if (request.output.len < X8616_SERIALIZE_HEADER_LEN) { result.status = x8616_serialize_output_full; goto exit; } + || (request.scratch.len && request.scratch.ptr == 0) + || (request.info_arena == 0); + if (bad_request) + { + if (request.info_arena) { + x8616_info_push(request.info_arena, msgs, x8616_info_error + , x8616_info_serialize_bad_request, 0, 0, 0, 0); + } + else { + msgs->count += 1; + msgs->error_count += 1; + msgs->dropped_count += 1; + } + goto exit; + } + if (request.output.len < x8616_serialize_header.len) { + x8616_serialize_push(request.info_arena, msgs, x8616_serialize_output_full + , 0, 0, u4_(x8616_serialize_header.len), u4_(request.output.len)); + goto exit; + } Str8Gen gen = str8gen_make(request.output); - if (x8616_serialize_header.len > gen.cap - gen.len) { result.status = x8616_serialize_output_full; goto exit; } str8gen_append_str8(& gen, x8616_serialize_header); result.text.len = gen.len; - for (U4 id = 0; id < request.instruction_count; ++id) { - X8616_SerializeStatus line_status = x8616_serialize_validate(& request.instructions[id]); - if (line_status != x8616_serialize_ok) { result.status = line_status; goto exit; } + for (U4 id = 0; id < request.instruction_count; ++id) + { + X8616_DecodedInstruction_R inst = & request.instructions[id]; + X8616_SerializeStatus line_status = x8616_serialize_validate(inst); + if (line_status != x8616_serialize_ok) { + x8616_serialize_push(request.info_arena, msgs, line_status + , id, inst->size, 0, u4_(inst->op)); + continue; + } Str8Gen line = str8gen_make(request.scratch); - line_status = x8616_serialize_instruction_line(& line, & request.instructions[id]); - if (line_status != x8616_serialize_ok) { result.status = line_status; goto exit; } + line_status = x8616_serialize_instruction_line(& line, inst); + if (line_status != x8616_serialize_ok) { + x8616_serialize_push(request.info_arena, msgs, line_status + , id, inst->size, u4_(request.scratch.len), u4_(line.len)); + continue; + } Str8 text = str8(line.ptr, line.len); - if (text.len > gen.cap - gen.len) { result.status = x8616_serialize_output_full; goto exit; } + if (text.len > gen.cap - gen.len) { + x8616_serialize_push(request.info_arena, msgs, x8616_serialize_output_full + , id, inst->size, u4_(request.output.len), u4_(gen.len)); + goto exit; + } str8gen_append_str8(& gen, text); result.text.len = gen.len; result.instructions_written += 1; } - result.status = x8616_serialize_ok; exit: + result.msgs = *msgs; return result; } diff --git a/code/8086/serializer.h b/code/8086/serializer.h index dc1350e..8261457 100644 --- a/code/8086/serializer.h +++ b/code/8086/serializer.h @@ -12,15 +12,18 @@ typedef Enum_(U1, X8616_SerializeStatus) { typedef Struct_(X8616_SerializeRequest) { X8616_DecodedInstruction* instructions; - U4 instruction_count; + U4 instruction_count; byte_pad(4); Slice output; Slice scratch; + FArena* info_arena; + X8616_InfoList_R msgs; }; typedef Struct_(X8616_SerializeInfo) { - Str8 text; - U4 instructions_written; - X8616_SerializeStatus status; + X8616_InfoList msgs; + Str8 text; + U4 instructions_written; + byte_pad(4); }; X8616_SerializeInfo x8616_serialize_instructions(X8616_SerializeRequest request); diff --git a/code/duffle/dsl.h b/code/duffle/dsl.h index 6ff9264..a1cb8f8 100644 --- a/code/duffle/dsl.h +++ b/code/duffle/dsl.h @@ -55,7 +55,6 @@ Standard: c23 #define LP_ static // static data within procedure scope #define internal static // internal - #define attribute(directive) __attribute__((directive)) #define asm __asm__ @@ -74,39 +73,6 @@ Standard: c23 #define R_ restrict #define V_ volatile -// R_ (restrict) establishes an "Eigen" or "Proprius" mapping. -// Unlike volatile (V_), which assumes the memory can be changed by anything, -// R_ tells the compiler that this pointer holds the *sole*, private (idios) ownership of the memory slice. -// Writes to this memory are exclusively bound to this single symbolic mapping for the duration of the scope, guaranteeing zero aliasing. - -#pragma region Fictional //, used for intiution - -#define EUB_ restrict // Execute Unit Bound: Data is siloed in the ALU Register File. The Load/Store Unit is bypassed. (Route to Execution Unit. Keep in registers) -#define ISO_ restrict // Isolated Provenance: Alternative to Exu_. Guarantees electrical memory isolation, - // unlocking the compiler’s ability to safely pack data across multiple parallel SIMD lanes (vectorization). -#define LSU_ volatile // Load/Store Unit Bound: The compiler is forbidden from caching in registers. Forces physical L1 Cache matrix sampling. -#define LIVE_ volatile // Live External Data: Alternative to Lsu_ emphasizing the memory is tapped by an external electrical actor. - -#define latch_store /* ~: atomic_store*/ // Blasts voltages from the Store Buffer into the L1 SRAM, physically flipping the cross-coupled inverters to lock the state. -#define pulse_rfo /* ~: atomic_xchg*/ // Broadcasts an electrical RFO (Request For Ownership) pulse across the CPU mesh network to invalidate other L1 caches. -#define tact_acquire /* ~: memory_order_acquire*/ // Clamp. Sends a voltage signal to the instruction decoder to halt the Out-of-Order engine until the load resolves. -#define tact_release /* ~: memory_order_release*/ // Drain. Forces the Store Buffer flip-flops to completely empty into the L1 cache before proceeding. - -// ----------------------------------------------------------------------------- -// Out-of-Order (OoO) Pipeline Modifiers -// ----------------------------------------------------------------------------- -#define ooo_drift_ __ATOMIC_RELAXED // OoO engine allowed to drift -#define ooo_anchor_ __ATOMIC_ACQUIRE // Anchor the Load Queue (halt spec lookahead) -#define ooo_drain_ __ATOMIC_RELEASE // Drain the Store Buffer (force writeback) -#define ooo_weld_ __ATOMIC_SEQ_CST // Weld pipeline (total order bus lock) - -// Latch operations with physical queue modifiers -#define latch_load_anchor(ptr) //__atomic_load_n(ptr, ooo_anchor_) -#define latch_store_drain(ptr, val) //__atomic_store_n(ptr, val, ooo_drain_) -#define pulse_xchg_weld(ptr, val) //__atomic_exchange_n(ptr, val, ooo_weld_) - -#pragma endregion Fictional - #define r_(ptr) C_(T_(ptr[0])*R_, ptr) // Constrain pointer to restrict #define v_(ptr) C_(T_(ptr[0])V_*, ptr) // #define tr_(type, ptr) C_(type *R_, ptr) diff --git a/code/part_1/sim_8086.c b/code/part_1/sim_8086.c index 9bd350e..ca95ffd 100644 --- a/code/part_1/sim_8086.c +++ b/code/part_1/sim_8086.c @@ -99,11 +99,11 @@ int main() Slice_X8616_DecodedInstruction decoded = farena_push_array(& decode_arena, X8616_DecodedInstruction, data.len); X8616_DecodeInfo info = x8616_decode_( - .source = data.ptr, - .source_size = data.len, - .instructions = decoded.ptr, - .instruction_capacity = decoded.len, - .info_arena = & decode_arena, + .source = data.ptr, + .source_len = data.len, + .out_instructions = decoded.ptr, + .instruction_cap = decoded.len, + .info_arena = & decode_arena, ); if (info.source_consumed != data.len || info.instruction_count == 0 || info.msgs.error_count || info.msgs.dropped_count) { ms_exit_process(10); @@ -114,8 +114,10 @@ int main() .instruction_count = info.instruction_count, .output = slice_ut_arr(smem.text_mem), .scratch = slice_ut_arr(smem.Scratchpad), + .info_arena = & decode_arena, + .msgs = & info.msgs, }); - if (text.status != x8616_serialize_ok || text.instructions_written != info.instruction_count) { + if (text.msgs.error_count || text.msgs.dropped_count || text.instructions_written != info.instruction_count) { ms_exit_process(13); return 13; }