Add @(require_results) to instruction procedures

This commit is contained in:
gingerBill
2026-06-14 21:54:24 +01:00
parent ced500fc94
commit 611cc807cd
10 changed files with 129 additions and 0 deletions

View File

@@ -40,39 +40,47 @@ Instruction :: struct #packed {
// Builders
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = mode == .A32 ? 4 : 2, mode = mode, cond = 14}
}
// 1-operand
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, r: Register, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(r), {}, {}, {}}}
}
@(require_results)
inst_i :: #force_inline proc "contextless" (m: Mnemonic, v: i64, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_imm(v), {}, {}, {}}}
}
// 2-operand
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rm: Register, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_reg(rm), {}, {}}}
}
@(require_results)
inst_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, v: i64, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_imm(v), {}, {}}}
}
// 3-operand data-proc (ADD/SUB/AND/etc.)
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rn, rm: Register, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_reg(rn), op_reg(rm), {}}}
}
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd, rn: Register, v: i64, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_reg(rn), op_imm(v), {}}}
}
@(require_results)
inst_r_r_r_shifted :: #force_inline proc "contextless" (
m: Mnemonic, rd, rn, rm: Register, st: Shift_Type, amt: u8, mode: Mode = .A32,
) -> Instruction {
@@ -81,33 +89,39 @@ inst_r_r_r_shifted :: #force_inline proc "contextless" (
}
// 4-operand MLA / MLS / SMLAL etc.
@(require_results)
inst_r_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rn, rm, ra: Register, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 4, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_reg(rn), op_reg(rm), op_reg(ra)}}
}
// Memory load/store
@(require_results)
inst_load :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, mm: Memory, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(rd), op_mem(mm), {}, {}}}
}
@(require_results)
inst_store :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, mm: Memory, mode: Mode = .A32) -> Instruction {
return inst_load(m, rd, mm, mode)
}
// LDM/STM/PUSH/POP block move
@(require_results)
inst_block :: #force_inline proc "contextless" (m: Mnemonic, base: Register, mask: u16, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_reg(base), op_reg_list(mask), {}, {}}}
}
// Branches with label
@(require_results)
inst_branch :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32, mode: Mode = .A32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = mode == .A32 ? 4 : 4, mode = mode, cond = 14,
ops = {op_label(label_id), {}, {}, {}}}
}
// Set condition code on any builder
@(require_results)
inst_set_cond :: #force_inline proc "contextless" (inst: Instruction, cond: u8) -> Instruction {
out := inst
out.cond = cond
@@ -115,6 +129,7 @@ inst_set_cond :: #force_inline proc "contextless" (inst: Instruction, cond: u8)
}
// Set S flag (sets APSR.NZCV)
@(require_results)
inst_set_flags :: #force_inline proc "contextless" (inst: Instruction) -> Instruction {
out := inst
out.flags.sets_flags = true

View File

@@ -22,89 +22,104 @@ Instruction :: struct #packed {
// inline by the caller using the Instruction struct directly.
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 4}
}
// Single-register (e.g. BR, BLR).
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, r: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_reg(r), {}, {}, {}}}
}
// 2-register (e.g. CLZ, RBIT).
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rn: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_reg(rn), {}, {}}}
}
// 3-register (e.g. ADD shifted, MUL, UDIV, ASRV).
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rn, rm: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rn), op_reg(rm), {}}}
}
// 4-register R4-type (MADD, MSUB, SMADDL, ...).
@(require_results)
inst_r_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rn, rm, ra: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 4, length = 4,
ops = {op_reg(rd), op_reg(rn), op_reg(rm), op_reg(ra)}}
}
// 2-register + immediate (e.g. ADD imm).
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd, rn: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rn), op_imm(imm), {}}}
}
// 1-register + immediate (e.g. MOVZ).
@(require_results)
inst_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_imm(imm), {}, {}}}
}
// MOVZ/MOVN/MOVK with explicit hw shift (0/16/32/48).
@(require_results)
inst_mov_imm :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, imm: i64, hw: u8) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_imm(imm), op_imm(i64(hw), 1), {}}}
}
// Load/store register: Rt + memory.
@(require_results)
inst_ldst :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rt), op_mem(mm), {}, {}}}
}
// Load/store pair: Rt, Rt2, memory.
@(require_results)
inst_ldp_stp :: #force_inline proc "contextless" (m: Mnemonic, rt, rt2: Register, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rt), op_reg(rt2), op_mem(mm), {}}}
}
// PC-relative branch (B, BL).
@(require_results)
inst_branch :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_label(label_id, 4), {}, {}, {}}}
}
// Conditional branch (B.cond label).
@(require_results)
inst_b_cond :: #force_inline proc "contextless" (c: Cond, label_id: u32) -> Instruction {
return Instruction{mnemonic = .B_COND, operand_count = 2, length = 4,
ops = {op_cond(c), op_label(label_id, 4), {}, {}}}
}
// CBZ/CBNZ: Rt, label.
@(require_results)
inst_cbz :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rt), op_label(label_id, 4), {}, {}}}
}
// TBZ/TBNZ: Rt, bit, label.
@(require_results)
inst_tbz :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, bit: u8, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rt), op_imm(i64(bit), 1), op_label(label_id, 4), {}}}
}
// CSEL/CSINC/CSINV/CSNEG: Rd, Rn, Rm, cond.
@(require_results)
inst_csel :: #force_inline proc "contextless" (m: Mnemonic, rd, rn, rm: Register, c: Cond) -> Instruction {
return Instruction{mnemonic = m, operand_count = 4, length = 4,
ops = {op_reg(rd), op_reg(rn), op_reg(rm), op_cond(c)}}

View File

@@ -26,44 +26,52 @@ Instruction :: struct #packed {
// Builders (mirror x86's `inst_*` shapes; per the cross-arch contract)
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 4}
}
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, a: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_reg(a), {}, {}, {}}}
}
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, dst, src: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(dst), op_reg(src), {}, {}}}
}
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, dst, s1, s2: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(dst), op_reg(s1), op_reg(s2), {}}}
}
// MIPS three-operand immediate: $rt, $rs, imm (e.g. ADDI rt, rs, imm).
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rt, rs: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rt), op_reg(rs), op_imm(imm, 2), {}}}
}
// Two-operand immediate (e.g. LUI rt, imm; LI variants).
@(require_results)
inst_r_i :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rt), op_imm(imm, 2), {}, {}}}
}
// Load/store: reg + memory (LW $rt, disp($rs)).
@(require_results)
inst_r_m :: #force_inline proc "contextless" (m: Mnemonic, r: Register, mm: Memory, size: u8 = 4) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(r), op_mem(mm, size), {}, {}}}
}
// Shift by immediate: $rd, $rt, shamt (SLL/SRL/SRA).
@(require_results)
inst_shift :: #force_inline proc "contextless" (m: Mnemonic, rd, rt: Register, shamt: u8) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rt), op_imm(i64(shamt), 1), {}}}
@@ -74,30 +82,35 @@ inst_shift_v :: inst_r_r_r
// Single-operand: JR $rs, JALR $rd (with implicit RA), MFHI/MFLO/MTHI/MTLO,
// SYSCALL/BREAK take an imm code so they use inst_i below.
@(require_results)
inst_i :: #force_inline proc "contextless" (m: Mnemonic, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_imm(imm, 4), {}, {}, {}}}
}
// Two-reg branch + label (BEQ/BNE: rs, rt, target).
@(require_results)
inst_branch2 :: #force_inline proc "contextless" (m: Mnemonic, rs, rt: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rs), op_reg(rt), op_label(label_id), {}}}
}
// One-reg branch + label (BLTZ/BGEZ/BLEZ/BGTZ/BLTZAL/BGEZAL/...).
@(require_results)
inst_branch1 :: #force_inline proc "contextless" (m: Mnemonic, rs: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rs), op_label(label_id), {}, {}}}
}
// J-type jump (J/JAL: target only).
@(require_results)
inst_jump :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_label(label_id), {}, {}, {}}}
}
// COP0 move with explicit selector: MFC0 $rt, $rd, sel (R2+).
@(require_results)
inst_cp0_sel :: #force_inline proc "contextless" (m: Mnemonic, rt, rd: Register, sel: u8) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rt), op_reg(rd), op_imm(i64(sel), 1), {}}}

View File

@@ -25,10 +25,12 @@ Instruction :: struct #packed {
// Builders (mirror the contract: shape spelled out, comma-separated)
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 1}
}
@(require_results)
inst_a :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
// Explicit accumulator (e.g. `ROL A`). Encodes to 1 byte (opcode only)
// and counts as 1 operand for the matcher.
@@ -38,6 +40,7 @@ inst_a :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
}
}
@(require_results)
inst_i :: #force_inline proc "contextless" (m: Mnemonic, imm: i64) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 1, length = 2,
@@ -45,6 +48,7 @@ inst_i :: #force_inline proc "contextless" (m: Mnemonic, imm: i64) -> Instructio
}
}
@(require_results)
inst_m :: #force_inline proc "contextless" (m: Mnemonic, mm: Memory) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 1, length = 0, // filled by encoder
@@ -52,6 +56,7 @@ inst_m :: #force_inline proc "contextless" (m: Mnemonic, mm: Memory) -> Instruct
}
}
@(require_results)
inst_rel :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 1, length = 2,
@@ -60,6 +65,7 @@ inst_rel :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Ins
}
// BBR/BBS: zero-page byte + relative branch (3-byte encoding).
@(require_results)
inst_zp_rel :: #force_inline proc "contextless" (m: Mnemonic, zp: u8, label_id: u32) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 2, length = 3,
@@ -68,6 +74,7 @@ inst_zp_rel :: #force_inline proc "contextless" (m: Mnemonic, zp: u8, label_id:
}
// HuC6280 TST # imm, addr (3 or 4 bytes depending on addressing mode).
@(require_results)
inst_tst :: #force_inline proc "contextless" (m: Mnemonic, imm: i64, mm: Memory) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 2, length = 0,
@@ -76,6 +83,7 @@ inst_tst :: #force_inline proc "contextless" (m: Mnemonic, imm: i64, mm: Memory)
}
// HuC6280 block transfer: src, dst, length (7-byte encoding).
@(require_results)
inst_block :: #force_inline proc "contextless" (m: Mnemonic, src, dst, length_val: u16) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 3, length = 7,

View File

@@ -18,35 +18,42 @@ Instruction :: struct #packed {
}
#assert(size_of(Instruction) == 40)
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 1}
}
@(require_results)
inst_a :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 1,
ops = {op_reg(A), {}}}
}
@(require_results)
inst_i8 :: #force_inline proc "contextless" (m: Mnemonic, v: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 2,
ops = {op_imm8(v), {}}}
}
@(require_results)
inst_i16 :: #force_inline proc "contextless" (m: Mnemonic, v: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 3,
ops = {op_imm16(v), {}}}
}
@(require_results)
inst_m :: #force_inline proc "contextless" (m: Mnemonic, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 0,
ops = {op_mem(mm), {}}}
}
@(require_results)
inst_rel :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 2,
ops = {op_label(label_id, 1), {}}}
}
@(require_results)
inst_rel_long :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 3,
ops = {op_label(label_id, 2), {}}}
@@ -54,6 +61,7 @@ inst_rel_long :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -
// MVN/MVP src, dst -- caller writes "natural" order; encoder reverses to
// the WDC-specified opcode | dst_bank | src_bank byte layout.
@(require_results)
inst_block_move :: #force_inline proc "contextless" (m: Mnemonic, src_bank, dst_bank: u8) -> Instruction {
return Instruction{
mnemonic = m, operand_count = 2, length = 3,

View File

@@ -32,74 +32,89 @@ Instruction :: struct #packed {
// Builders
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 4, mode = mode}
}
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, r: Register, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4, mode = mode,
ops = {op_reg(r), {}, {}, {}}}
}
@(require_results)
inst_i :: #force_inline proc "contextless" (m: Mnemonic, v: i64, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4, mode = mode,
ops = {op_imm(v), {}, {}, {}}}
}
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, ra: Register, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4, mode = mode,
ops = {op_reg(rd), op_reg(ra), {}, {}}}
}
@(require_results)
inst_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, v: i64, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4, mode = mode,
ops = {op_reg(rd), op_imm(v), {}, {}}}
}
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, ra, rb: Register, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4, mode = mode,
ops = {op_reg(rd), op_reg(ra), op_reg(rb), {}}}
}
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd, ra: Register, v: i64, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4, mode = mode,
ops = {op_reg(rd), op_reg(ra), op_imm(v), {}}}
}
@(require_results)
inst_r_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, ra, rb, rc: Register, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 4, length = 4, mode = mode,
ops = {op_reg(rd), op_reg(ra), op_reg(rb), op_reg(rc)}}
}
// Memory load/store: RT, [RA + disp] or [RA + RB].
@(require_results)
inst_load :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, mm: Memory, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4, mode = mode,
ops = {op_reg(rt), op_mem(mm), {}, {}}}
}
@(require_results)
inst_store :: #force_inline proc "contextless" (m: Mnemonic, rs: Register, mm: Memory, mode: Mode = .PPC32) -> Instruction {
return inst_load(m, rs, mm, mode)
}
// Branches with label resolution
@(require_results)
inst_branch :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4, mode = mode,
ops = {op_label(label_id), {}, {}, {}}}
}
// Conditional branch with BO/BI baked into the mnemonic (BEQ/BNE/...) + label
@(require_results)
inst_branch_cond :: #force_inline proc "contextless" (m: Mnemonic, crf: Register, label_id: u32, mode: Mode = .PPC32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4, mode = mode,
ops = {op_reg(crf), op_label(label_id), {}, {}}}
}
// Flag setters
@(require_results)
inst_set_rc :: #force_inline proc "contextless" (inst: Instruction) -> Instruction {
out := inst
out.flags.sets_cr0 = true
return out
}
@(require_results)
inst_set_oe :: #force_inline proc "contextless" (inst: Instruction) -> Instruction {
out := inst
out.flags.has_oe = true
return out
}
@(require_results)
inst_set_lk :: #force_inline proc "contextless" (inst: Instruction) -> Instruction {
out := inst
out.flags.lk = true

View File

@@ -25,39 +25,47 @@ Instruction :: struct #packed {
form_id: u16,
}
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 2, mode = .PPC32_VLE}
}
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, r: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 2, mode = .PPC32_VLE,
ops = {op_reg(r), {}, {}, {}}}
}
@(require_results)
inst_i :: #force_inline proc "contextless" (m: Mnemonic, v: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4, mode = .PPC32_VLE,
ops = {op_imm(v), {}, {}, {}}}
}
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, ra: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 2, mode = .PPC32_VLE,
ops = {op_reg(rd), op_reg(ra), {}, {}}}
}
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, ra, rb: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4, mode = .PPC32_VLE,
ops = {op_reg(rd), op_reg(ra), op_reg(rb), {}}}
}
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd, ra: Register, v: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4, mode = .PPC32_VLE,
ops = {op_reg(rd), op_reg(ra), op_imm(v), {}}}
}
@(require_results)
inst_load :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4, mode = .PPC32_VLE,
ops = {op_reg(rt), op_mem(mm), {}, {}}}
}
@(require_results)
inst_branch :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4, mode = .PPC32_VLE,
ops = {op_label(label_id), {}, {}, {}}}

View File

@@ -26,83 +26,97 @@ Instruction :: struct #packed {
// Builders (shape spelled out, comma-separated)
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 4}
}
// R-type: rd, rs1, rs2
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rs1, rs2: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rs1), op_reg(rs2), {}}}
}
// I-type (ALU): rd, rs1, imm12
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rd, rs1: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rs1), op_imm(imm, 2), {}}}
}
// I-type (shift): rd, rs1, shamt
@(require_results)
inst_shift :: #force_inline proc "contextless" (m: Mnemonic, rd, rs1: Register, shamt: u8) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rs1), op_imm(i64(shamt), 1), {}}}
}
// I-type load: rd, disp(base)
@(require_results)
inst_load :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_mem(mm), {}, {}}}
}
// S-type store: rs2 (data), disp(base)
@(require_results)
inst_store :: #force_inline proc "contextless" (m: Mnemonic, rs2: Register, mm: Memory) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rs2), op_mem(mm), {}, {}}}
}
// U-type: rd, imm20
@(require_results)
inst_u :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_imm(imm, 4), {}, {}}}
}
// J-type: rd, label
@(require_results)
inst_jal :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_label(label_id, 4), {}, {}}}
}
// B-type branch: rs1, rs2, label
@(require_results)
inst_branch :: #force_inline proc "contextless" (m: Mnemonic, rs1, rs2: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rs1), op_reg(rs2), op_label(label_id, 2), {}}}
}
// JALR: rd, rs1, imm12 (indirect jump with offset)
@(require_results)
inst_jalr :: #force_inline proc "contextless" (rd, rs1: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = .JALR, operand_count = 3, length = 4,
ops = {op_reg(rd), op_reg(rs1), op_imm(imm, 2), {}}}
}
// CSR ops: rd, csr, rs1
@(require_results)
inst_csr :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, csr: u16, rs1: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_imm(i64(csr), 2), op_reg(rs1), {}}}
}
// CSR immediate ops: rd, csr, zimm5
@(require_results)
inst_csr_i :: #force_inline proc "contextless" (m: Mnemonic, rd: Register, csr: u16, zimm5: u8) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rd), op_imm(i64(csr), 2), op_imm(i64(zimm5), 1), {}}}
}
// FP R4-type: rd, rs1, rs2, rs3 (FMADD/FMSUB/FNMADD/FNMSUB)
@(require_results)
inst_r4 :: #force_inline proc "contextless" (m: Mnemonic, rd, rs1, rs2, rs3: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 4, length = 4,
ops = {op_reg(rd), op_reg(rs1), op_reg(rs2), op_reg(rs3)}}
}
// FP R-type with 2 regs: rd, rs1 (FSQRT, FCVT, FMV, FCLASS, ...)
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, rd, rs1: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rd), op_reg(rs1), {}, {}}}

View File

@@ -22,55 +22,67 @@ Instruction :: struct #packed {
// Builders (mirror x86/mips conventions)
// =============================================================================
@(require_results)
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
return Instruction{mnemonic = m, operand_count = 0, length = 4}
}
@(require_results)
inst_r :: #force_inline proc "contextless" (m: Mnemonic, a: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_reg(a), {}, {}, {}}}
}
@(require_results)
inst_r_r :: #force_inline proc "contextless" (m: Mnemonic, d, s: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(d), op_reg(s), {}, {}}}
}
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (m: Mnemonic, d, s1, s2: Register) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(d), op_reg(s1), op_reg(s2), {}}}
}
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (m: Mnemonic, rt, rs: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rt), op_reg(rs), op_imm(imm, 2), {}}}
}
@(require_results)
inst_r_i :: #force_inline proc "contextless" (m: Mnemonic, rt: Register, imm: i64) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rt), op_imm(imm, 2), {}, {}}}
}
@(require_results)
inst_r_m :: #force_inline proc "contextless" (m: Mnemonic, r: Register, mm: Memory, size: u8 = 4) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(r), op_mem(mm, size), {}, {}}}
}
// Vector ALU: 3-operand vector op with optional element selector on vt.
@(require_results)
inst_v_v_v :: #force_inline proc "contextless" (m: Mnemonic, vd, vs, vt: Register, vt_element: u8 = 0) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_vr(vd), op_vr(vs), op_vr(vt, vt_element), {}}}
}
// Vector load/store: $vt[element], offset(base).
@(require_results)
inst_v_vmem :: #force_inline proc "contextless" (m: Mnemonic, vt: Register, vmem_op: Vector_Mem) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_vr(vt, vmem_op.element), op_vmem(vmem_op, 16), {}, {}}}
}
// Branch helpers
@(require_results)
inst_branch1 :: #force_inline proc "contextless" (m: Mnemonic, rs: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 2, length = 4,
ops = {op_reg(rs), op_label(label_id), {}, {}}}
}
@(require_results)
inst_branch2 :: #force_inline proc "contextless" (m: Mnemonic, rs, rt: Register, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 3, length = 4,
ops = {op_reg(rs), op_reg(rt), op_label(label_id), {}}}
}
@(require_results)
inst_jump :: #force_inline proc "contextless" (m: Mnemonic, label_id: u32) -> Instruction {
return Instruction{mnemonic = m, operand_count = 1, length = 4,
ops = {op_label(label_id), {}, {}, {}}}

View File

@@ -42,6 +42,7 @@ Instruction :: struct #packed {
// -----------------------------------------------------------------------------
// Convenient instruction builders for common patterns
@(require_results)
inst_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -50,6 +51,7 @@ inst_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, s
}
}
@(require_results)
inst_r_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Register, source: Memory, size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -58,6 +60,7 @@ inst_r_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: R
}
}
@(require_results)
inst_m_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Memory, size: u8, source: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -66,6 +69,7 @@ inst_m_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: M
}
}
@(require_results)
inst_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Register, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -74,6 +78,7 @@ inst_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: R
}
}
@(require_results)
inst_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, r: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -82,6 +87,7 @@ inst_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, r: Register) ->
}
}
@(require_results)
inst_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, m: Memory, size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -90,6 +96,7 @@ inst_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, m: Memory, size:
}
}
@(require_results)
inst_none :: #force_inline proc "contextless" (mnemonic: Mnemonic) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -97,6 +104,7 @@ inst_none :: #force_inline proc "contextless" (mnemonic: Mnemonic) -> Instructio
}
}
@(require_results)
inst_rel :: #force_inline proc "contextless" (mnemonic: Mnemonic, label_id: u32, size: u8 = 4) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -106,6 +114,7 @@ inst_rel :: #force_inline proc "contextless" (mnemonic: Mnemonic, label_id: u32,
}
// 3-operand register instructions (VEX/EVEX: VADDPS xmm0, xmm1, xmm2)
@(require_results)
inst_r_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1, source2: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -115,6 +124,7 @@ inst_r_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination,
}
// 3-operand register-register-memory (VEX/EVEX: VADDPS xmm0, xmm1, [mem])
@(require_results)
inst_r_r_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1: Register, source2: Memory, size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -124,6 +134,7 @@ inst_r_r_m :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination,
}
// 3-operand register-register-immediate (e.g., SHLD r64, r64, imm8)
@(require_results)
inst_r_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source: Register, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -133,6 +144,7 @@ inst_r_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination,
}
// Memoryory-immediate (MOV [mem], imm32)
@(require_results)
inst_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Memory, size: u8, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -142,6 +154,7 @@ inst_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: M
}
// Single immediate (PUSH imm32, RET imm16, INT imm8, etc.)
@(require_results)
inst_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -151,6 +164,7 @@ inst_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, immediate: i64,
}
// 3-operand register-memory-immediate (IMUL r64, m64, imm32)
@(require_results)
inst_r_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Register, source: Memory, mem_size: u8, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -160,6 +174,7 @@ inst_r_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination:
}
// 3-operand memory-register-immediate (SHLD m64, r64, imm8)
@(require_results)
inst_m_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Memory, mem_size: u8, source: Register, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -169,6 +184,7 @@ inst_m_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination:
}
// Relative offset (JMP rel8, JCC rel32, etc.) - uses raw offset, not label
@(require_results)
inst_rel_offset :: #force_inline proc "contextless" (mnemonic: Mnemonic, offset: i64, offset_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -178,6 +194,7 @@ inst_rel_offset :: #force_inline proc "contextless" (mnemonic: Mnemonic, offset:
}
// 3-operand register-memory-register (BEXTR r64, m64, r64)
@(require_results)
inst_r_m_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination: Register, source1: Memory, mem_size: u8, source2: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -187,6 +204,7 @@ inst_r_m_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination:
}
// 4-operand register instructions (EVEX with 4 operands)
@(require_results)
inst_r_r_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1, source2, source3: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -196,6 +214,7 @@ inst_r_r_r_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destinatio
}
// 4-operand: 3 registers + immediate (VCMPPS xmm, xmm, xmm, imm8)
@(require_results)
inst_r_r_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1, source2: Register, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -205,6 +224,7 @@ inst_r_r_r_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destinatio
}
// 4-operand: 2 registers + memory + immediate (VCMPPS xmm, xmm, m128, imm8)
@(require_results)
inst_r_r_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1: Register, source2: Memory, mem_size: u8, immediate: i64, immediate_size: u8) -> Instruction {
return Instruction{
mnemonic = mnemonic,
@@ -214,6 +234,7 @@ inst_r_r_m_i :: #force_inline proc "contextless" (mnemonic: Mnemonic, destinatio
}
// 4-operand: 2 registers + memory + register (VBLENDVPS xmm, xmm, m128, xmm)
@(require_results)
inst_r_r_m_r :: #force_inline proc "contextless" (mnemonic: Mnemonic, destination, source1: Register, source2: Memory, mem_size: u8, source3: Register) -> Instruction {
return Instruction{
mnemonic = mnemonic,