mirror of
https://github.com/Ed94/perfaware.git
synced 2026-09-14 03:39:23 +00:00
drafting an asm parser (rudimentary)
This commit is contained in:
@@ -31,6 +31,11 @@ typedef Enum_(U1, X8616_InfoCode) {
|
||||
x8616_info_serialize_unsupported_form = 0x0D,
|
||||
x8616_info_serialize_output_full = 0x0E,
|
||||
|
||||
x8616_info_parse_bad_request = 0x0F,
|
||||
x8616_info_parse_syntax = 0x10,
|
||||
x8616_info_parse_unknown_mnemonic = 0x11,
|
||||
x8616_info_parse_output_full = 0x12,
|
||||
|
||||
x8616_info_count,
|
||||
};
|
||||
|
||||
@@ -65,6 +70,10 @@ RO_ global Str8 x8616_info_templates[x8616_info_count] = {
|
||||
[x8616_info_serialize_invalid_record] = slit8("Serialize record <offset> is not printable (op <actual>)."),
|
||||
[x8616_info_serialize_unsupported_form] = slit8("Serialize record <offset> has an unsupported display form (op <actual>)."),
|
||||
[x8616_info_serialize_output_full] = slit8("Serialize output is full at record <offset>: capacity <expected>, produced <actual>."),
|
||||
[x8616_info_parse_bad_request] = slit8("Parse request is missing source, output, or info arena."),
|
||||
[x8616_info_parse_syntax] = slit8("Parse syntax error at <offset>."),
|
||||
[x8616_info_parse_unknown_mnemonic] = slit8("Unknown mnemonic at <offset>."),
|
||||
[x8616_info_parse_output_full] = slit8("Parse output is full: capacity <expected>, produced <actual>."),
|
||||
};
|
||||
|
||||
typedef Struct_(X8616_InfoList) {
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "parser.h"
|
||||
# include "serializer_tables.h"
|
||||
#endif
|
||||
|
||||
FI_ void x8616_parse_skip_ws(Str8_R cur) {
|
||||
while (cur->len && char_is_space(cur->ptr[0])) { cur->ptr += 1; cur->len -= 1; }
|
||||
}
|
||||
|
||||
FI_ B4 x8616_parse_eat(Str8_R cur, Str8 lit) {
|
||||
B4 too_big = cur->len < lit.len;
|
||||
B4 miss = too_big || mem_match(u8_(cur->ptr), u8_(lit.ptr), lit.len) == 0;
|
||||
if (miss) return 0;
|
||||
cur->ptr += lit.len;
|
||||
cur->len -= lit.len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
FI_ U4 x8616_parse_lookup(Str8_R cur, Str8* table, U4 table_len) {
|
||||
U4 best = table_len;
|
||||
U8 best_len = 0;
|
||||
for (U4 i = 0; i < table_len; ++i)
|
||||
{
|
||||
Str8 lit = table[i];
|
||||
B4 empty = lit.len == 0;
|
||||
B4 too_big = lit.len > cur->len;
|
||||
B4 worse = lit.len <= best_len;
|
||||
B4 skip = empty || too_big || worse;
|
||||
B4 miss = skip || mem_match(u8_(cur->ptr), u8_(lit.ptr), lit.len) == 0;
|
||||
if (miss) continue;
|
||||
best = i;
|
||||
best_len = lit.len;
|
||||
}
|
||||
if (best < table_len) {
|
||||
cur->ptr += best_len;
|
||||
cur->len -= best_len;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
FI_ B4 x8616_parse_number(Str8_R cur, U2_R value, B4_R neg_out) {
|
||||
x8616_parse_skip_ws(cur);
|
||||
B4 neg = 0;
|
||||
if (x8616_parse_eat(cur, slit8("-"))) neg = 1;
|
||||
if (cur->len == 0 || char_is_digit(cur->ptr[0], 10) == 0) return 0;
|
||||
U8 start = 0;
|
||||
while (start < cur->len && char_is_digit(cur->ptr[start], 10)) start += 1;
|
||||
U8 mag = u8_from_str8(str8(cur->ptr, start), 10);
|
||||
cur->ptr += start;
|
||||
cur->len -= start;
|
||||
value[0] = u2_(mag);
|
||||
neg_out[0] = neg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
internal B4 x8616_parse_memory(Str8_R cur, X8616_DecodedOperand_R op)
|
||||
{
|
||||
B4 ok = 1;
|
||||
if (x8616_parse_eat(cur, slit8("[")) == 0) { ok = 0; goto exit; }
|
||||
x8616_parse_skip_ws(cur);
|
||||
|
||||
U4 ea_n = Array_len(x8616_serialize_ea);
|
||||
U4 ea = x8616_parse_lookup(cur, x8616_serialize_ea, ea_n);
|
||||
if (ea < ea_n)
|
||||
{
|
||||
op->flags = x8616_decoded_operand_memory;
|
||||
op->ea = C_(X8616_EA, ea);
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_eat(cur, slit8("+"))) {
|
||||
U2 mag = 0; B4 neg = 0;
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; }
|
||||
op->displacement = neg ? s2_(-s4_(mag)) : s2_(mag);
|
||||
op->displacement_bytes = (u2_(op->displacement) > 0x7F && op->displacement >= 0) || op->displacement < -128 ? 2 : (op->displacement ? 1 : 0);
|
||||
}
|
||||
else if (x8616_parse_eat(cur, slit8("-"))) {
|
||||
U2 mag = 0; B4 dummy = 0;
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_number(cur, & mag, & dummy) == 0) { ok = 0; goto exit; }
|
||||
op->displacement = s2_(-s4_(mag));
|
||||
op->displacement_bytes = op->displacement < -128 ? 2 : 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
U2 mag = 0; B4 neg = 0;
|
||||
if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; }
|
||||
op->flags = x8616_decoded_operand_memory | x8616_decoded_operand_direct;
|
||||
op->address = mag;
|
||||
op->ea = x8616_ea_direct;
|
||||
}
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_eat(cur, slit8("]")) == 0) { ok = 0; goto exit; }
|
||||
exit:
|
||||
return ok;
|
||||
}
|
||||
|
||||
internal B4
|
||||
x8616_parse_operand(Str8_R cur, X8616_DecodedInstruction_R inst, X8616_DecodedOperand_R op)
|
||||
{
|
||||
B4 ok = 1;
|
||||
x8616_parse_skip_ws(cur);
|
||||
X8616_WidthMode size = x8616_width_dynamic;
|
||||
if (x8616_parse_eat(cur, slit8("byte "))) size = x8616_width_byte;
|
||||
else if (x8616_parse_eat(cur, slit8("word "))) size = x8616_width_word;
|
||||
if (x8616_parse_eat(cur, slit8("far "))) inst->flags |= x8616_encoding_far;
|
||||
x8616_parse_skip_ws(cur);
|
||||
|
||||
U4 seg_n = Array_len(x8616_serialize_seg);
|
||||
Str8 save = cur[0];
|
||||
U4 seg = x8616_parse_lookup(cur, x8616_serialize_seg, seg_n);
|
||||
if (seg < seg_n)
|
||||
{
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_eat(cur, slit8(":"))) {
|
||||
inst->prefixes.has_segment = 1;
|
||||
inst->prefixes.segment = C_(X8616_Segment, seg);
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_memory(cur, op) == 0) { ok = 0; goto exit; }
|
||||
}
|
||||
else {
|
||||
op->flags = x8616_decoded_operand_segment;
|
||||
op->segment = C_(X8616_Segment, seg);
|
||||
op->width = x8616_width_word;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur[0] = save;
|
||||
U4 r16_n = Array_len(x8616_serialize_reg16);
|
||||
U4 r8_n = Array_len(x8616_serialize_reg8);
|
||||
U4 r16 = x8616_parse_lookup(cur, x8616_serialize_reg16, r16_n);
|
||||
if (r16 < r16_n) {
|
||||
op->flags = x8616_decoded_operand_register;
|
||||
op->width = x8616_width_word;
|
||||
op->reg.r16 = C_(X8616_Reg16, r16);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur[0] = save;
|
||||
U4 r8 = x8616_parse_lookup(cur, x8616_serialize_reg8, r8_n);
|
||||
if (r8 < r8_n) {
|
||||
op->flags = x8616_decoded_operand_register;
|
||||
op->width = x8616_width_byte;
|
||||
op->reg.r8 = C_(X8616_Reg8, r8);
|
||||
}
|
||||
else if (x8616_parse_eat(cur, slit8("$"))) {
|
||||
B4 neg = 0;
|
||||
if (x8616_parse_eat(cur, slit8("+"))) {}
|
||||
else if (x8616_parse_eat(cur, slit8("-"))) neg = 1;
|
||||
else { ok = 0; goto exit; }
|
||||
U2 mag = 0; B4 extra = 0;
|
||||
if (x8616_parse_number(cur, & mag, & extra) == 0) { ok = 0; goto exit; }
|
||||
if (extra) neg = 1;
|
||||
op->flags = x8616_decoded_operand_relative;
|
||||
op->displacement = neg ? s2_(-s4_(mag)) : s2_(mag);
|
||||
op->width = x8616_width_byte;
|
||||
}
|
||||
else if (cur->len && cur->ptr[0] == '[') {
|
||||
if (x8616_parse_memory(cur, op) == 0) { ok = 0; goto exit; }
|
||||
}
|
||||
else
|
||||
{
|
||||
U2 mag = 0; B4 neg = 0;
|
||||
Str8 before = *cur;
|
||||
if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; }
|
||||
x8616_parse_skip_ws(cur);
|
||||
if (x8616_parse_eat(cur, slit8(":"))) {
|
||||
U2 off = 0; B4 off_neg = 0;
|
||||
if (x8616_parse_number(cur, & off, & off_neg) == 0) { ok = 0; goto exit; }
|
||||
op->flags = x8616_decoded_operand_far_ptr;
|
||||
op->far_segment = mag;
|
||||
op->far_offset = off;
|
||||
}
|
||||
else {
|
||||
*cur = before;
|
||||
if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; }
|
||||
op->flags = x8616_decoded_operand_immediate;
|
||||
op->immediate = mag;
|
||||
if (neg) {
|
||||
op->flags |= x8616_decoded_operand_sign_extended;
|
||||
op->immediate = u2_(s2_(-s4_(mag)));
|
||||
}
|
||||
op->immediate_bytes = mag > 0xFF ? 2 : 1;
|
||||
op->width = mag > 0xFF ? x8616_width_word : x8616_width_byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size != x8616_width_dynamic) {
|
||||
op->width = size;
|
||||
if (inst->width == x8616_width_dynamic) inst->width = size;
|
||||
}
|
||||
exit:
|
||||
return ok;
|
||||
}
|
||||
|
||||
internal B4 x8616_parse_line(Str8 line, X8616_DecodedInstruction_R inst)
|
||||
{
|
||||
B4 ok = 1;
|
||||
x8616_parse_skip_ws(& line);
|
||||
if (line.len == 0) { ok = 0; goto exit; }
|
||||
|
||||
if (x8616_parse_eat(& line, slit8("lock "))) inst->prefixes.lock = 1;
|
||||
if (x8616_parse_eat(& line, slit8("repne "))) {
|
||||
inst->prefixes.has_repeat = 1;
|
||||
inst->prefixes.repeat = x8616_repne;
|
||||
}
|
||||
else if (x8616_parse_eat(& line, slit8("rep "))) {
|
||||
inst->prefixes.has_repeat = 1;
|
||||
inst->prefixes.repeat = x8616_rep;
|
||||
}
|
||||
|
||||
U4 mnem_n = Array_len(x8616_serialize_mnemonic);
|
||||
U4 mnem = x8616_parse_lookup(& line, x8616_serialize_mnemonic, mnem_n);
|
||||
if (mnem >= mnem_n) { ok = 0; goto exit; }
|
||||
inst->op = C_(X8616_Op, mnem);
|
||||
|
||||
if (inst->op == x8616_op_movs || inst->op == x8616_op_cmps || inst->op == x8616_op_scas
|
||||
|| inst->op == x8616_op_lods || inst->op == x8616_op_stos) {
|
||||
if (x8616_parse_eat(& line, slit8("b"))) inst->width = x8616_width_byte;
|
||||
else if (x8616_parse_eat(& line, slit8("w"))) inst->width = x8616_width_word;
|
||||
}
|
||||
|
||||
x8616_parse_skip_ws(& line);
|
||||
if (line.len == 0) goto exit;
|
||||
|
||||
if (x8616_parse_operand(& line, inst, inst->operands + 0) == 0) { ok = 0; goto exit; }
|
||||
inst->operand_count = 1;
|
||||
x8616_parse_skip_ws(& line);
|
||||
if (x8616_parse_eat(& line, slit8(","))) {
|
||||
if (x8616_parse_operand(& line, inst, inst->operands + 1) == 0) { ok = 0; goto exit; }
|
||||
inst->operand_count = 2;
|
||||
}
|
||||
x8616_parse_skip_ws(& line);
|
||||
if (inst->width == x8616_width_dynamic) {
|
||||
if (inst->operand_count && inst->operands[0].width != x8616_width_dynamic)
|
||||
inst->width = inst->operands[0].width;
|
||||
}
|
||||
ok = line.len == 0;
|
||||
exit:
|
||||
return ok;
|
||||
}
|
||||
|
||||
X8616_ParseInfo x8616_parse_instructions(X8616_ParseRequest request)
|
||||
{
|
||||
X8616_ParseInfo result = {0};
|
||||
X8616_InfoList local = {0};
|
||||
X8616_InfoList_R msgs = request.msgs ? request.msgs : & local;
|
||||
U4 offset = 0;
|
||||
|
||||
B4 bad = request.source.ptr == 0 && request.source.len != 0;
|
||||
bad |= request.instruction_cap && request.out_instructions == 0;
|
||||
bad |= request.info_arena == 0;
|
||||
if (bad) {
|
||||
if (request.info_arena) {
|
||||
x8616_info_push(request.info_arena, msgs, x8616_info_error
|
||||
, x8616_info_parse_bad_request, 0, 0, 0, 0);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Str8 cur = request.source;
|
||||
if (x8616_parse_eat(& cur, x8616_serialize_header)) {}
|
||||
|
||||
offset = u4_(request.source.len - cur.len);
|
||||
while (cur.len)
|
||||
{
|
||||
U8 n = 0;
|
||||
while (n < cur.len && cur.ptr[n] != '\n') n += 1;
|
||||
Str8 line = str8(cur.ptr, n);
|
||||
U8 step = n + (n < cur.len);
|
||||
U4 line_at = offset;
|
||||
cur.ptr += step;
|
||||
cur.len -= step;
|
||||
offset += u4_(step);
|
||||
|
||||
while (line.len && char_is_space(line.ptr[line.len - 1])) line.len -= 1;
|
||||
x8616_parse_skip_ws(& line);
|
||||
if (line.len == 0) continue;
|
||||
|
||||
if (result.instruction_count == request.instruction_cap) {
|
||||
x8616_info_push(request.info_arena, msgs, x8616_info_error
|
||||
, x8616_info_parse_output_full, line_at, 0, request.instruction_cap, result.instruction_count);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
X8616_DecodedInstruction inst = {0};
|
||||
if (x8616_parse_line(line, & inst) == 0) {
|
||||
x8616_info_push(request.info_arena, msgs, x8616_info_error
|
||||
, x8616_info_parse_syntax, line_at, u2_(line.len), 0, 0);
|
||||
continue;
|
||||
}
|
||||
request.out_instructions[result.instruction_count] = inst;
|
||||
result.instruction_count += 1;
|
||||
}
|
||||
|
||||
exit:
|
||||
result.source_consumed = offset;
|
||||
result.msgs = *msgs;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "decoder.h"
|
||||
#endif
|
||||
|
||||
typedef Struct_(X8616_ParseRequest) {
|
||||
Str8 source;
|
||||
X8616_DecodedInstruction* out_instructions;
|
||||
U4 instruction_cap;
|
||||
FArena* info_arena;
|
||||
X8616_InfoList_R msgs;
|
||||
};
|
||||
|
||||
typedef Struct_(X8616_ParseInfo) {
|
||||
X8616_InfoList msgs;
|
||||
U4 instruction_count;
|
||||
U4 source_consumed;
|
||||
};
|
||||
|
||||
X8616_ParseInfo x8616_parse_instructions(X8616_ParseRequest request);
|
||||
+1
-138
@@ -1,145 +1,8 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "serializer.h"
|
||||
# include "serializer_tables.h"
|
||||
#endif
|
||||
|
||||
RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n");
|
||||
|
||||
RO_ global Str8 x8616_serialize_mnemonic[] = {
|
||||
[x8616_op_invalid] = slit8(""),
|
||||
[x8616_op_nop] = slit8("nop"),
|
||||
[x8616_op_mov] = slit8("mov"),
|
||||
[x8616_op_add] = slit8("add"),
|
||||
[x8616_op_or] = slit8("or"),
|
||||
[x8616_op_adc] = slit8("adc"),
|
||||
[x8616_op_sbb] = slit8("sbb"),
|
||||
[x8616_op_and] = slit8("and"),
|
||||
[x8616_op_sub] = slit8("sub"),
|
||||
[x8616_op_xor] = slit8("xor"),
|
||||
[x8616_op_cmp] = slit8("cmp"),
|
||||
[x8616_op_push] = slit8("push"),
|
||||
[x8616_op_pop] = slit8("pop"),
|
||||
[x8616_op_xchg] = slit8("xchg"),
|
||||
[x8616_op_in] = slit8("in"),
|
||||
[x8616_op_out] = slit8("out"),
|
||||
[x8616_op_xlat] = slit8("xlat"),
|
||||
[x8616_op_lea] = slit8("lea"),
|
||||
[x8616_op_lds] = slit8("lds"),
|
||||
[x8616_op_les] = slit8("les"),
|
||||
[x8616_op_lahf] = slit8("lahf"),
|
||||
[x8616_op_sahf] = slit8("sahf"),
|
||||
[x8616_op_pushf] = slit8("pushf"),
|
||||
[x8616_op_popf] = slit8("popf"),
|
||||
[x8616_op_inc] = slit8("inc"),
|
||||
[x8616_op_aaa] = slit8("aaa"),
|
||||
[x8616_op_daa] = slit8("daa"),
|
||||
[x8616_op_dec] = slit8("dec"),
|
||||
[x8616_op_neg] = slit8("neg"),
|
||||
[x8616_op_aas] = slit8("aas"),
|
||||
[x8616_op_das] = slit8("das"),
|
||||
[x8616_op_mul] = slit8("mul"),
|
||||
[x8616_op_imul] = slit8("imul"),
|
||||
[x8616_op_aam] = slit8("aam"),
|
||||
[x8616_op_div] = slit8("div"),
|
||||
[x8616_op_idiv] = slit8("idiv"),
|
||||
[x8616_op_aad] = slit8("aad"),
|
||||
[x8616_op_cbw] = slit8("cbw"),
|
||||
[x8616_op_cwd] = slit8("cwd"),
|
||||
[x8616_op_not] = slit8("not"),
|
||||
[x8616_op_shl] = slit8("shl"),
|
||||
[x8616_op_shr] = slit8("shr"),
|
||||
[x8616_op_sar] = slit8("sar"),
|
||||
[x8616_op_rol] = slit8("rol"),
|
||||
[x8616_op_ror] = slit8("ror"),
|
||||
[x8616_op_rcl] = slit8("rcl"),
|
||||
[x8616_op_rcr] = slit8("rcr"),
|
||||
[x8616_op_test] = slit8("test"),
|
||||
[x8616_op_rep] = slit8(""),
|
||||
[x8616_op_movs] = slit8("movs"),
|
||||
[x8616_op_cmps] = slit8("cmps"),
|
||||
[x8616_op_scas] = slit8("scas"),
|
||||
[x8616_op_lods] = slit8("lods"),
|
||||
[x8616_op_stos] = slit8("stos"),
|
||||
[x8616_op_call] = slit8("call"),
|
||||
[x8616_op_jmp] = slit8("jmp"),
|
||||
[x8616_op_ret] = slit8("ret"),
|
||||
[x8616_op_retf] = slit8("retf"),
|
||||
[x8616_op_je] = slit8("je"),
|
||||
[x8616_op_jl] = slit8("jl"),
|
||||
[x8616_op_jle] = slit8("jle"),
|
||||
[x8616_op_jb] = slit8("jb"),
|
||||
[x8616_op_jbe] = slit8("jbe"),
|
||||
[x8616_op_jp] = slit8("jp"),
|
||||
[x8616_op_jo] = slit8("jo"),
|
||||
[x8616_op_js] = slit8("js"),
|
||||
[x8616_op_jne] = slit8("jne"),
|
||||
[x8616_op_jnl] = slit8("jnl"),
|
||||
[x8616_op_jg] = slit8("jg"),
|
||||
[x8616_op_jnb] = slit8("jnb"),
|
||||
[x8616_op_ja] = slit8("ja"),
|
||||
[x8616_op_jnp] = slit8("jnp"),
|
||||
[x8616_op_jno] = slit8("jno"),
|
||||
[x8616_op_jns] = slit8("jns"),
|
||||
[x8616_op_loop] = slit8("loop"),
|
||||
[x8616_op_loopz] = slit8("loopz"),
|
||||
[x8616_op_loopnz] = slit8("loopnz"),
|
||||
[x8616_op_jcxz] = slit8("jcxz"),
|
||||
[x8616_op_int] = slit8("int"),
|
||||
[x8616_op_int3] = slit8("int3"),
|
||||
[x8616_op_into] = slit8("into"),
|
||||
[x8616_op_iret] = slit8("iret"),
|
||||
[x8616_op_clc] = slit8("clc"),
|
||||
[x8616_op_cmc] = slit8("cmc"),
|
||||
[x8616_op_stc] = slit8("stc"),
|
||||
[x8616_op_cld] = slit8("cld"),
|
||||
[x8616_op_std] = slit8("std"),
|
||||
[x8616_op_cli] = slit8("cli"),
|
||||
[x8616_op_sti] = slit8("sti"),
|
||||
[x8616_op_hlt] = slit8("hlt"),
|
||||
[x8616_op_wait] = slit8("wait"),
|
||||
[x8616_op_lock] = slit8(""),
|
||||
[x8616_op_segment] = slit8(""),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_reg8[] = {
|
||||
[x8616_al] = slit8("al"),
|
||||
[x8616_cl] = slit8("cl"),
|
||||
[x8616_dl] = slit8("dl"),
|
||||
[x8616_bl] = slit8("bl"),
|
||||
[x8616_ah] = slit8("ah"),
|
||||
[x8616_ch] = slit8("ch"),
|
||||
[x8616_dh] = slit8("dh"),
|
||||
[x8616_bh] = slit8("bh"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_reg16[] = {
|
||||
[x8616_ax] = slit8("ax"),
|
||||
[x8616_cx] = slit8("cx"),
|
||||
[x8616_dx] = slit8("dx"),
|
||||
[x8616_bx] = slit8("bx"),
|
||||
[x8616_sp] = slit8("sp"),
|
||||
[x8616_bp] = slit8("bp"),
|
||||
[x8616_si] = slit8("si"),
|
||||
[x8616_di] = slit8("di"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_seg[] = {
|
||||
[x8616_es] = slit8("es"),
|
||||
[x8616_cs] = slit8("cs"),
|
||||
[x8616_ss] = slit8("ss"),
|
||||
[x8616_ds] = slit8("ds"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_ea[] = {
|
||||
[x8616_ea_bx_si] = slit8("bx + si"),
|
||||
[x8616_ea_bx_di] = slit8("bx + di"),
|
||||
[x8616_ea_bp_si] = slit8("bp + si"),
|
||||
[x8616_ea_bp_di] = slit8("bp + di"),
|
||||
[x8616_ea_si] = slit8("si"),
|
||||
[x8616_ea_di] = slit8("di"),
|
||||
[x8616_ea_bp] = slit8("bp"),
|
||||
[x8616_ea_bx] = slit8("bx"),
|
||||
};
|
||||
|
||||
typedef Enum_(U1, X8616_SerializeSizeWhere) {
|
||||
x8616_serialize_size_none = 0x00,
|
||||
x8616_serialize_size_before_mem = 0x01,
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "encoder.h"
|
||||
#endif
|
||||
|
||||
RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n");
|
||||
|
||||
RO_ global Str8 x8616_serialize_mnemonic[] = {
|
||||
[x8616_op_invalid] = slit8(""),
|
||||
[x8616_op_nop] = slit8("nop"),
|
||||
[x8616_op_mov] = slit8("mov"),
|
||||
[x8616_op_add] = slit8("add"),
|
||||
[x8616_op_or] = slit8("or"),
|
||||
[x8616_op_adc] = slit8("adc"),
|
||||
[x8616_op_sbb] = slit8("sbb"),
|
||||
[x8616_op_and] = slit8("and"),
|
||||
[x8616_op_sub] = slit8("sub"),
|
||||
[x8616_op_xor] = slit8("xor"),
|
||||
[x8616_op_cmp] = slit8("cmp"),
|
||||
[x8616_op_push] = slit8("push"),
|
||||
[x8616_op_pop] = slit8("pop"),
|
||||
[x8616_op_xchg] = slit8("xchg"),
|
||||
[x8616_op_in] = slit8("in"),
|
||||
[x8616_op_out] = slit8("out"),
|
||||
[x8616_op_xlat] = slit8("xlat"),
|
||||
[x8616_op_lea] = slit8("lea"),
|
||||
[x8616_op_lds] = slit8("lds"),
|
||||
[x8616_op_les] = slit8("les"),
|
||||
[x8616_op_lahf] = slit8("lahf"),
|
||||
[x8616_op_sahf] = slit8("sahf"),
|
||||
[x8616_op_pushf] = slit8("pushf"),
|
||||
[x8616_op_popf] = slit8("popf"),
|
||||
[x8616_op_inc] = slit8("inc"),
|
||||
[x8616_op_aaa] = slit8("aaa"),
|
||||
[x8616_op_daa] = slit8("daa"),
|
||||
[x8616_op_dec] = slit8("dec"),
|
||||
[x8616_op_neg] = slit8("neg"),
|
||||
[x8616_op_aas] = slit8("aas"),
|
||||
[x8616_op_das] = slit8("das"),
|
||||
[x8616_op_mul] = slit8("mul"),
|
||||
[x8616_op_imul] = slit8("imul"),
|
||||
[x8616_op_aam] = slit8("aam"),
|
||||
[x8616_op_div] = slit8("div"),
|
||||
[x8616_op_idiv] = slit8("idiv"),
|
||||
[x8616_op_aad] = slit8("aad"),
|
||||
[x8616_op_cbw] = slit8("cbw"),
|
||||
[x8616_op_cwd] = slit8("cwd"),
|
||||
[x8616_op_not] = slit8("not"),
|
||||
[x8616_op_shl] = slit8("shl"),
|
||||
[x8616_op_shr] = slit8("shr"),
|
||||
[x8616_op_sar] = slit8("sar"),
|
||||
[x8616_op_rol] = slit8("rol"),
|
||||
[x8616_op_ror] = slit8("ror"),
|
||||
[x8616_op_rcl] = slit8("rcl"),
|
||||
[x8616_op_rcr] = slit8("rcr"),
|
||||
[x8616_op_test] = slit8("test"),
|
||||
[x8616_op_rep] = slit8(""),
|
||||
[x8616_op_movs] = slit8("movs"),
|
||||
[x8616_op_cmps] = slit8("cmps"),
|
||||
[x8616_op_scas] = slit8("scas"),
|
||||
[x8616_op_lods] = slit8("lods"),
|
||||
[x8616_op_stos] = slit8("stos"),
|
||||
[x8616_op_call] = slit8("call"),
|
||||
[x8616_op_jmp] = slit8("jmp"),
|
||||
[x8616_op_ret] = slit8("ret"),
|
||||
[x8616_op_retf] = slit8("retf"),
|
||||
[x8616_op_je] = slit8("je"),
|
||||
[x8616_op_jl] = slit8("jl"),
|
||||
[x8616_op_jle] = slit8("jle"),
|
||||
[x8616_op_jb] = slit8("jb"),
|
||||
[x8616_op_jbe] = slit8("jbe"),
|
||||
[x8616_op_jp] = slit8("jp"),
|
||||
[x8616_op_jo] = slit8("jo"),
|
||||
[x8616_op_js] = slit8("js"),
|
||||
[x8616_op_jne] = slit8("jne"),
|
||||
[x8616_op_jnl] = slit8("jnl"),
|
||||
[x8616_op_jg] = slit8("jg"),
|
||||
[x8616_op_jnb] = slit8("jnb"),
|
||||
[x8616_op_ja] = slit8("ja"),
|
||||
[x8616_op_jnp] = slit8("jnp"),
|
||||
[x8616_op_jno] = slit8("jno"),
|
||||
[x8616_op_jns] = slit8("jns"),
|
||||
[x8616_op_loop] = slit8("loop"),
|
||||
[x8616_op_loopz] = slit8("loopz"),
|
||||
[x8616_op_loopnz] = slit8("loopnz"),
|
||||
[x8616_op_jcxz] = slit8("jcxz"),
|
||||
[x8616_op_int] = slit8("int"),
|
||||
[x8616_op_int3] = slit8("int3"),
|
||||
[x8616_op_into] = slit8("into"),
|
||||
[x8616_op_iret] = slit8("iret"),
|
||||
[x8616_op_clc] = slit8("clc"),
|
||||
[x8616_op_cmc] = slit8("cmc"),
|
||||
[x8616_op_stc] = slit8("stc"),
|
||||
[x8616_op_cld] = slit8("cld"),
|
||||
[x8616_op_std] = slit8("std"),
|
||||
[x8616_op_cli] = slit8("cli"),
|
||||
[x8616_op_sti] = slit8("sti"),
|
||||
[x8616_op_hlt] = slit8("hlt"),
|
||||
[x8616_op_wait] = slit8("wait"),
|
||||
[x8616_op_lock] = slit8(""),
|
||||
[x8616_op_segment] = slit8(""),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_reg8[] = {
|
||||
[x8616_al] = slit8("al"),
|
||||
[x8616_cl] = slit8("cl"),
|
||||
[x8616_dl] = slit8("dl"),
|
||||
[x8616_bl] = slit8("bl"),
|
||||
[x8616_ah] = slit8("ah"),
|
||||
[x8616_ch] = slit8("ch"),
|
||||
[x8616_dh] = slit8("dh"),
|
||||
[x8616_bh] = slit8("bh"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_reg16[] = {
|
||||
[x8616_ax] = slit8("ax"),
|
||||
[x8616_cx] = slit8("cx"),
|
||||
[x8616_dx] = slit8("dx"),
|
||||
[x8616_bx] = slit8("bx"),
|
||||
[x8616_sp] = slit8("sp"),
|
||||
[x8616_bp] = slit8("bp"),
|
||||
[x8616_si] = slit8("si"),
|
||||
[x8616_di] = slit8("di"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_seg[] = {
|
||||
[x8616_es] = slit8("es"),
|
||||
[x8616_cs] = slit8("cs"),
|
||||
[x8616_ss] = slit8("ss"),
|
||||
[x8616_ds] = slit8("ds"),
|
||||
};
|
||||
|
||||
RO_ global Str8 x8616_serialize_ea[] = {
|
||||
[x8616_ea_bx_si] = slit8("bx + si"),
|
||||
[x8616_ea_bx_di] = slit8("bx + di"),
|
||||
[x8616_ea_bp_si] = slit8("bp + si"),
|
||||
[x8616_ea_bp_di] = slit8("bp + di"),
|
||||
[x8616_ea_si] = slit8("si"),
|
||||
[x8616_ea_di] = slit8("di"),
|
||||
[x8616_ea_bp] = slit8("bp"),
|
||||
[x8616_ea_bx] = slit8("bx"),
|
||||
};
|
||||
@@ -21,6 +21,7 @@ RO_ U8 integer_symbol_reverse[128] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
};
|
||||
|
||||
FI_ B4 char_is_space(UTF8 c) { return(c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v'); }
|
||||
FI_ B4 char_is_upper(UTF8 c) { return('A' <= c && c <= 'Z'); }
|
||||
FI_ UTF8 char_to_lower(UTF8 c) { if (char_is_upper(c)) { c += ('a' - 'A'); } return(c); }
|
||||
FI_ B4 char_is_digit(UTF8 c, U4 base) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "8086/info_render.h"
|
||||
#include "8086/decoder.h"
|
||||
#include "8086/serializer.h"
|
||||
#include "8086/serializer_tables.h"
|
||||
#include "8086/gen/decoder_table.h"
|
||||
|
||||
#include "8086/decoder.c"
|
||||
|
||||
Reference in New Issue
Block a user