Skip to content

dotbmp/rexcode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rexcode

A high-performance x86-64 instruction encoder/decoder written in Odin.

Features

  • Encoder: Assembles instructions to machine code with label resolution and relocation support
  • Decoder: Disassembles machine code back to structured instructions
  • Printer: Generates assembly text output with optional syntax highlighting tokens
  • Table-driven: O(1) mnemonic lookup using pre-generated encoding tables
  • Comprehensive ISA coverage: GPR, SSE, AVX, AVX-512, BMI, FMA, AES-NI, and more

Usage

import "x64"

code: [4096]u8
labels: []x64.Label_Def
relocs: [dynamic]x64.Reloc
errors: [dynamic]x64.Encode_Error

// Build instructions
instructions := []x64.Instruction{
    x64.inst_r_r(.MOV, x64.RAX, x64.RDI),
    x64.inst_r_r(.ADD, x64.RAX, x64.RSI),
    x64.inst_none(.RET),
}

// Encode to machine code
result := x64.encode(instructions[:], labels, code[:], &relocs, &errors)
// result.code_size contains the number of bytes written

// Decode back to instructions
decoded_insts: [dynamic]x64.Instruction
decoded_info: [dynamic]x64.Instruction_Info
decoded_labels: [dynamic]x64.Label_Def
decode_errors: [dynamic]x64.Error

x64.decode(code[:result.code_size], nil, &decoded_insts, &decoded_info, &decoded_labels, &decode_errors)

// Print disassembly
disasm := x64.print(decoded_insts[:], decoded_info[:], decoded_labels[:], nil, nil)

Instruction Builders

Helper procedures for constructing instructions:

x64.inst_none(.RET)                                             // No operands
x64.inst_r(.PUSH, x64.RAX)                                      // Single register
x64.inst_r_r(.MOV, x64.RAX, x64.RBX)                            // Register to register
x64.inst_r_i(.MOV, x64.EAX, 42, 4)                              // Immediate (with size)
x64.inst_r_r_r(.VADDPS, x64.XMM0, x64.XMM1, x64.XMM2)           // 3-operand VEX
x64.inst_m_r(.MOV, x64.mem_base(x64.RSP), 8, x64.RAX)           // Memory destination
x64.inst_r_m(.MOV, x64.RAX, x64.mem_base_disp(x64.RBP, -8), 8)  // Memory source
x64.inst_rel(.JMP, label_id, 1)                                 // Relative branch with label

Memory Operands

x64.mem_base(x64.RAX)                             // [RAX]
x64.mem_base_disp(x64.RBP, -16)                   // [RBP - 16]
x64.mem_base_index(x64.RAX, x64.RCX, 4)           // [RAX + RCX*4]
x64.mem_base_index_disp(x64.RAX, x64.RCX, 8, 32)  // [RAX + RCX*8 + 32]
x64.mem_rip_rel(0)                                // [RIP + disp]

Labels

Labels enable forward/backward references in branches. Use Label_Map for named labels:

lm: x64.Label_Map
x64.label_map_init(&lm)
defer x64.label_map_destroy(&lm)

instructions: [dynamic]x64.Instruction

// Reserve forward reference
done := x64.label_reserve(&lm, "done")

// Define label at current position
loop := x64.label_named(&lm, "loop", &instructions)
x64.emit_r(&instructions, .DEC, x64.RDI)
x64.emit_rel(&instructions, .JNZ, loop)
x64.emit_rel(&instructions, .JMP, done)

// Define reserved label
x64.label_set(&lm, "done", &instructions)
x64.emit_ri(&instructions, .MOV, x64.EAX, 42, 4)
x64.emit_none(&instructions, .RET)

// Encode
result := x64.encode(instructions[:], lm.labels[:], code[:], &relocs, &errors)

// Print with named labels
output := x64.print(decoded_insts[:], decoded_info[:], lm.labels[:], label_names = &lm.names)
// Output:
//   loop:
//       dec rdi
//       jne loop
//       jmp done
//   done:
//       mov eax, 0x2a
//       ret

For simple cases without names, use dynamic arrays directly:

labels: [dynamic]x64.Label_Def
instructions: [dynamic]x64.Instruction

loop := x64.label(&labels, &instructions)        // Define at current position
x64.emit_r(&instructions, .DEC, x64.RDI)
x64.emit_rel(&instructions, .JNZ, loop)

done := x64.label_forward(&labels)               // Reserve for forward ref
x64.emit_rel(&instructions, .JMP, done)
labels[done] = x64.Label_Def(len(instructions))  // Define position

Running Tests

cd tests
odin run .

The test suite validates encoding, decoding, and execution of 2000+ test cases across integer, SSE, and AVX instructions.

Project Structure

x64/
  x64.odin           # Main encoder/decoder implementation
  enc_table.odin     # Encoding table
  decode_tables.odin # Generated decoding table
  tests/
    test.odin        # Test suite
  tools/             # Table generation utilities

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages