Reusable MachV machine-code emitter
Dependencies
///|
test "emit a tiny AArch64 return stub" {
let code = MachineCode::MachineCode(isa=AArch64, record_disasm=false)
code.emit_ret(30)
let bytes = code.get_bytes()
inspect(bytes.length(), content="4")
inspect(code.current_pos(), content="4")
}///|
test "record an unresolved external call fixup" {
let code = MachineCode::MachineCode(isa=AMD64, record_disasm=false)
code.emit_byte(0xe8)
code.add_external_call_fixup(1, ExternalName("env.print_i32"))
for _ in 0..<4 {
code.emit_byte(0)
}
inspect(code.get_bytes().length(), content="5")
inspect(code.get_call_fixups().length(), content="1")
}pub(all) struct CallFixup {
offset : Int
target : RelocTarget
veneer_offset : Int
} derive(Eq, Debug)pub(all) enum CondCode {
EQ
NE
HS
LO
MI
PL
VS
VC
HI
LS
GE
LT
GT
LE
AL
}pub struct EmitStackFrame {
setup_area_size : Int
gpr_save_size : Int
fpr_save_size : Int
spill_size : Int
outgoing_args_size : Int
gpr_save_offset : Int
fpr_save_offset : Int
spill_offset : Int
outgoing_args_offset : Int
total_size : Int
frame_size : Int
saved_gprs : Array[Int]
saved_fprs : Array[Int]
has_setup_area : Bool
needs_context_reg : Bool
cache_context_0 : Bool
cache_context_1 : Bool
embedding_abi : EmbeddingABI?
}fn EmitStackFrame::build(clobbered_gprs : Array[Int], clobbered_fprs : Array[Int], num_spill_slots : Int, has_calls? : Bool, outgoing_args_size? : Int, needs_context_reg? : Bool, cache_context_0? : Bool, cache_context_1? : Bool, force_frame_setup? : Bool, has_incoming_stack_args? : Bool, embedding_abi? : EmbeddingABI?, isa? : ISA) -> EmitStackFramefn EmitStackFrame::require_embedding_context_layout(self : EmitStackFrame) -> EmbeddingContextLayouttype Instructionpub struct MachineCode {
isa : ISA
bytes : Array[Int]
pos : Int
labels : Map[Int, Int]
next_internal_label : Int
fixups : Array[Fixup]
x86_rel32_fixups : Array[X86Rel32Fixup]
func_addr_fixups : Array[FuncAddrFixup]
call_fixups : Array[CallFixup]
gc_safepoint_offsets : Array[Int]
gc_safepoint_root_counts : Array[Int]
gc_safepoint_root_indices : Array[Array[Int]]
amd64_const_labels : Map[String, Int]
amd64_const_entries : Array[Amd64ConstEntry]
disasm : Array[(Int, String)]
record_disasm : Bool
debug_prev_func_idx_spill_offset : Int
}fn MachineCode::add_call_fixup(self : MachineCode, offset : Int, symbol : CodeSymbol, veneer_offset? : Int) -> Unitfn MachineCode::add_call_target_fixup(self : MachineCode, offset : Int, target : RelocTarget, veneer_offset? : Int) -> Unitfn MachineCode::add_code_addr_fixup(self : MachineCode, offset : Int, symbol : CodeSymbol, reg : Int) -> Unitfn MachineCode::add_external_call_fixup(self : MachineCode, offset : Int, symbol : ExternalName, veneer_offset? : Int) -> Unitfn MachineCode::add_external_func_addr_fixup(self : MachineCode, offset : Int, symbol : ExternalName, reg : Int) -> Unitfn MachineCode::add_func_addr_target_fixup(self : MachineCode, offset : Int, target : RelocTarget, reg : Int) -> Unitfn MachineCode::add_x86_rel32_fixup(self : MachineCode, target_block : Int, disp_offset : Int, next_ip_offset : Int) -> Unitfn MachineCode::emit_add_imm32_shifted12(self : MachineCode, rd : Int, rn : Int, imm12 : Int) -> Unitfn MachineCode::emit_add_shifted(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_add_shifted32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_add_sxtw(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_add_uxtw(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_and_shifted(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_and_shifted32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_eor_shifted(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_eor_shifted32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_extr_imm(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_extr_imm32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_fcvtzs(self : MachineCode, rd : Int, rn : Int, int64~ : Bool, double~ : Bool) -> Unitfn MachineCode::emit_fcvtzu(self : MachineCode, rd : Int, rn : Int, int64~ : Bool, double~ : Bool) -> Unitfn MachineCode::emit_ldp_d_offset(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, offset : Int) -> Unitfn MachineCode::emit_ldp_d_post(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, imm : Int) -> Unitfn MachineCode::emit_ldp_offset(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, offset : Int) -> Unitfn MachineCode::emit_ldp_post(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, imm : Int) -> Unitfn MachineCode::emit_ldr_reg_offset(self : MachineCode, rt : Int, rn : Int, rm : Int, option : Int, size_bits : Int, shift : Int) -> Unitfn MachineCode::emit_ldr_reg_scaled(self : MachineCode, rt : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_ldr_w_reg_scaled(self : MachineCode, rt : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_orr_shifted(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_orr_shifted32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_scvtf(self : MachineCode, rd : Int, rn : Int, int64~ : Bool, double~ : Bool) -> Unitfn MachineCode::emit_stp_d_offset(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, offset : Int) -> Unitfn MachineCode::emit_stp_d_pre(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, imm : Int) -> Unitfn MachineCode::emit_stp_offset(self : MachineCode, rt1 : Int, rt2 : Int, rn : Int, offset : Int) -> Unitfn MachineCode::emit_str_reg_offset(self : MachineCode, rt : Int, rn : Int, rm : Int, option : Int, size_bits : Int, shift : Int) -> Unitfn MachineCode::emit_str_reg_scaled(self : MachineCode, rt : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_str_w_reg_scaled(self : MachineCode, rt : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_sub_imm32_shifted12(self : MachineCode, rd : Int, rn : Int, imm12 : Int) -> Unitfn MachineCode::emit_sub_shifted(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_sub_shifted32(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : ShiftType, amount : Int) -> Unitfn MachineCode::emit_sub_sxtw(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_sub_uxtw(self : MachineCode, rd : Int, rn : Int, rm : Int, shift : Int) -> Unitfn MachineCode::emit_ucvtf(self : MachineCode, rd : Int, rn : Int, int64~ : Bool, double~ : Bool) -> Unitfn MachineCode::record_gc_safepoint(self : MachineCode, offset : Int, root_count? : Int, root_indices? : Array[Int]) -> Intfn MachineCode::x86_emit_cmppd_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_cmpps_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_cvttpd2dq_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_cvttps2dq_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_insertps_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_lea_r32_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_lea_r64_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_lea_r64_riprel32(self : MachineCode, dst : Int, target_label : Int) -> Unitfn MachineCode::x86_emit_mov_m16_r16_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src : Int) -> Unitfn MachineCode::x86_emit_mov_m32_r32_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src : Int) -> Unitfn MachineCode::x86_emit_mov_m64_r64_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src : Int) -> Unitfn MachineCode::x86_emit_mov_m8_r8_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src : Int) -> Unitfn MachineCode::x86_emit_mov_r32_m32_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_mov_r64_m64_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movdqu_m128_xmm(self : MachineCode, base : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movdqu_m128_xmm_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movdqu_xmm_m128(self : MachineCode, dst_xmm : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movdqu_xmm_m128_base_index_scale_disp(self : MachineCode, dst_xmm : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsd_m64_xmm(self : MachineCode, base : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movsd_m64_xmm_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movsd_xmm_m64(self : MachineCode, dst_xmm : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsd_xmm_m64_base_index_scale_disp(self : MachineCode, dst_xmm : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movss_m32_xmm(self : MachineCode, base : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movss_m32_xmm_base_index_scale_disp(self : MachineCode, base : Int, index : Int, scale : Int, disp : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_movss_xmm_m32(self : MachineCode, dst_xmm : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movss_xmm_m32_base_index_scale_disp(self : MachineCode, dst_xmm : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsx_r64_m16(self : MachineCode, dst : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsx_r64_m16_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsx_r64_m8(self : MachineCode, dst : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsx_r64_m8_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movsxd_r64_m32(self : MachineCode, dst : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movzx_r32_m16(self : MachineCode, dst : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movzx_r32_m16_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movzx_r32_m8(self : MachineCode, dst : Int, base : Int, disp : Int) -> Unitfn MachineCode::x86_emit_movzx_r32_m8_base_index_scale_disp(self : MachineCode, dst : Int, base : Int, index : Int, scale : Int, disp : Int) -> Unitfn MachineCode::x86_emit_padd_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_palignr_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pcmpeq_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_pcmpgt_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_pextrb_r32_xmm_imm8(self : MachineCode, dst : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pextrd_r32_xmm_imm8(self : MachineCode, dst : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pextrq_r64_xmm_imm8(self : MachineCode, dst : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pextrw_r32_xmm_imm8(self : MachineCode, dst : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pinsrb_xmm_r32_imm8(self : MachineCode, dst_xmm : Int, src : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pinsrd_xmm_r32_imm8(self : MachineCode, dst_xmm : Int, src : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pinsrq_xmm_r64_imm8(self : MachineCode, dst_xmm : Int, src : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pinsrw_xmm_r32_imm8(self : MachineCode, dst_xmm : Int, src : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pmaddubsw_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_pshufd_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_pshuflw_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_psll_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_psra_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_psrl_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_psub_xmm_xmm(self : MachineCode, lane_size : LaneSize, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpckhbw_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpckhdq_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpckhwd_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpcklbw_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpckldq_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_punpcklwd_xmm_xmm(self : MachineCode, dst_xmm : Int, src_xmm : Int) -> Unitfn MachineCode::x86_emit_roundpd_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_roundps_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_roundsd_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_roundss_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_shufpd_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unitfn MachineCode::x86_emit_shufps_xmm_xmm_imm8(self : MachineCode, dst_xmm : Int, src_xmm : Int, imm8 : Int) -> Unittype X86Rel32Fixupfn emit_function(func : Function, isa? : ISA, debug_func_idx? : Int?, force_frame_setup? : Bool, embedding_abi? : EmbeddingABI?, record_disasm? : Bool) -> MachineCodefn emit_function_with_regalloc(func : Function, output : Output, isa? : ISA, debug_func_idx? : Int?, force_frame_setup? : Bool, embedding_abi? : EmbeddingABI?, record_disasm? : Bool) -> MachineCodeReusable MachV machine-code emitter
Dependencies