Add @(require_results) to operand procedures

This commit is contained in:
gingerBill
2026-06-14 21:57:27 +01:00
parent 611cc807cd
commit 5c9cd0146d
10 changed files with 147 additions and 46 deletions

View File

@@ -66,18 +66,23 @@ Memory :: struct #packed {
}
#assert(size_of(Memory) == 12)
@(require_results)
mem_imm :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp, sign = 1, mode = .OFFSET}
}
@(require_results)
mem_imm_pre :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp, sign = 1, mode = .PRE_INDEX}
}
@(require_results)
mem_imm_post :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp, sign = 1, mode = .POST_INDEX}
}
@(require_results)
mem_reg :: #force_inline proc "contextless" (base, index: Register, sign: i8 = 1) -> Memory {
return Memory{base = base, index = index, sign = sign, mode = .OFFSET}
}
@(require_results)
mem_reg_shift :: #force_inline proc "contextless" (
base, index: Register, st: Shift_Type, amt: u8, sign: i8 = 1,
) -> Memory {
@@ -106,32 +111,41 @@ Operand :: struct #packed {
// ---- Operand builders ------------------------------------------------------
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 4, cond = 14}
}
@(require_results)
op_reg_shifted :: #force_inline proc "contextless" (
r: Register, st: Shift_Type, amt: u8,
) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 4, shift_type = st, shift_amt = amt, cond = 14}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64, size: u8 = 4) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = size, cond = 14}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = 4, cond = 14}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32, size: u8 = 4) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = size, cond = 14}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE, size = 4, cond = 14}
}
@(require_results)
op_reg_list :: #force_inline proc "contextless" (mask: u16) -> Operand {
return Operand{immediate = i64(mask), kind = .REG_LIST, size = 2, cond = 14}
}
@(require_results)
op_dpr_lane :: #force_inline proc "contextless" (d: Register, idx: u8) -> Operand {
return Operand{reg = d, kind = .REGISTER, size = 4, lane = idx, cond = 14}
}
@(require_results)
op_qpr_lane :: #force_inline proc "contextless" (q: Register, idx: u8) -> Operand {
return Operand{reg = q, kind = .REGISTER, size = 4, lane = idx, cond = 14}
}

View File

@@ -110,27 +110,39 @@ Operand :: struct #packed {
// Constructors -- generic
// -----------------------------------------------------------------------------
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand { return Operand{reg = r, kind = .REGISTER, size = 4} }
op_imm :: #force_inline proc "contextless" (v: i64, size: u8 = 4) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = size} }
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 4}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64, size: u8 = 4) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = size}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32, size: u8 = 4) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = size}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE, size = 4}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = 4}
}
@(require_results)
op_shifted :: #force_inline proc "contextless" (r: Register, type: Shift_Type, amount: u8) -> Operand {
return Operand{shifted = Shifted_Reg{reg = r, type = type, amount = amount}, kind = .SHIFTED_REG, size = 4}
}
@(require_results)
op_extended :: #force_inline proc "contextless" (r: Register, ext: Extend, amount: u8) -> Operand {
return Operand{extended = Extended_Reg{reg = r, extend = ext, amount = amount}, kind = .EXTENDED_REG, size = 4}
}
@(require_results)
op_cond :: #force_inline proc "contextless" (c: Cond) -> Operand {
return Operand{cond = u8(c), kind = .COND, size = 1}
}
@@ -141,15 +153,19 @@ op_cond :: #force_inline proc "contextless" (c: Cond) -> Operand {
// table form when multiple element sizes share a base mnemonic.
// -----------------------------------------------------------------------------
@(require_results)
op_z_b :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_Z | u16(n & 0x1F)), kind = .REGISTER, size = 1}
}
@(require_results)
op_z_h :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_Z | u16(n & 0x1F)), kind = .REGISTER, size = 2}
}
@(require_results)
op_z_s :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_Z | u16(n & 0x1F)), kind = .REGISTER, size = 4}
}
@(require_results)
op_z_d :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_Z | u16(n & 0x1F)), kind = .REGISTER, size = 8}
}
@@ -164,27 +180,35 @@ op_z_d :: #force_inline proc "contextless" (n: u8) -> Operand {
// to inspect.)
// -----------------------------------------------------------------------------
@(require_results)
op_v_8b :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 8}
}
@(require_results)
op_v_16b :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 16}
}
@(require_results)
op_v_4h :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 24}
}
@(require_results)
op_v_8h :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 32}
}
@(require_results)
op_v_2s :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 40}
}
@(require_results)
op_v_4s :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 48}
}
@(require_results)
op_v_1d :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 56}
}
@(require_results)
op_v_2d :: #force_inline proc "contextless" (n: u8) -> Operand {
return Operand{reg = Register(REG_V | u16(n & 0x1F)), kind = .REGISTER, size = 64}
}
@@ -193,18 +217,23 @@ op_v_2d :: #force_inline proc "contextless" (n: u8) -> Operand {
// Memory constructors (one per addressing mode)
// -----------------------------------------------------------------------------
@(require_results)
mem_offset :: #force_inline proc "contextless" (base: Register, disp: i32 = 0) -> Memory {
return Memory{base = base, index = NONE, disp = disp, mode = .OFFSET}
}
@(require_results)
mem_pre :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, index = NONE, disp = disp, mode = .PRE_INDEXED}
}
@(require_results)
mem_post :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, index = NONE, disp = disp, mode = .POST_INDEXED}
}
@(require_results)
mem_reg :: #force_inline proc "contextless" (base, index: Register, shift_amount: u8 = 0) -> Memory {
return Memory{base = base, index = index, mode = .REG_OFFSET, shift = shift_amount, extend = .UXTX}
}
@(require_results)
mem_ext :: #force_inline proc "contextless" (base, index: Register, ext: Extend, shift_amount: u8 = 0) -> Memory {
return Memory{base = base, index = index, mode = .EXT_REG_OFFSET, extend = ext, shift = shift_amount}
}

View File

@@ -28,6 +28,7 @@ Memory :: struct #packed {
}
#assert(size_of(Memory) == 8)
@(require_results)
mem :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp}
}
@@ -35,14 +36,18 @@ mem :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
// Convenience aliases that mirror x86's naming convention so cross-arch
// helper code reads the same.
mem_base_disp :: mem
@(require_results)
mem_base_only :: #force_inline proc "contextless" (base: Register) -> Memory {
return Memory{base = base, disp = 0}
}
@(require_results)
mem_base :: #force_inline proc "contextless" (m: Memory) -> Register {
return m.base
}
@(require_results)
mem_disp :: #force_inline proc "contextless" (m: Memory) -> i32 {
return m.disp
}
@@ -65,29 +70,35 @@ Operand :: struct #packed {
// Generic operand constructors
// -----------------------------------------------------------------------------
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 4}
}
@(require_results)
op_reg_sized :: #force_inline proc "contextless" (r: Register, size: u8) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = size}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory, size: u8) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = size}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64, size: u8) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = size}
}
// Branch/jump target operand. `label_id` indexes a Label_Definition
// array (resolved by the encoder during pass 2 -- same model as x86).
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = 4}
}
// Raw offset (skip label resolution).
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (offset: i64) -> Operand {
return Operand{relative = offset, kind = .RELATIVE, size = 4}
}
@@ -96,22 +107,27 @@ op_rel_offset :: #force_inline proc "contextless" (offset: i64) -> Operand {
// Typed register operand constructors (compile-time class safety)
// -----------------------------------------------------------------------------
@(require_results)
op_gpr :: #force_inline proc "contextless" (g: GPR) -> Operand {
return Operand{reg = Register(REG_GPR | u16(g)), kind = .REGISTER, size = 4}
}
@(require_results)
op_fpr :: #force_inline proc "contextless" (f: FPR) -> Operand {
return Operand{reg = Register(REG_FPR | u16(f)), kind = .REGISTER, size = 4}
}
@(require_results)
op_cp0 :: #force_inline proc "contextless" (c: CP0_Reg) -> Operand {
return Operand{reg = Register(REG_CP0 | u16(c)), kind = .REGISTER, size = 4}
}
@(require_results)
op_gte_data :: #force_inline proc "contextless" (r: GTE_DataReg) -> Operand {
return Operand{reg = Register(REG_CP2D | u16(r)), kind = .REGISTER, size = 4}
}
@(require_results)
op_gte_ctrl :: #force_inline proc "contextless" (r: GTE_CtrlReg) -> Operand {
return Operand{reg = Register(REG_CP2C | u16(r)), kind = .REGISTER, size = 4}
}

View File

@@ -56,17 +56,17 @@ Memory :: struct #packed {
// Memory constructors (one per addressing mode)
// -----------------------------------------------------------------------------
mem_zp :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP } }
mem_zp_x :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP_X } }
mem_zp_y :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP_Y } }
mem_abs :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS } }
mem_abs_x :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS_X } }
mem_abs_y :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS_Y } }
mem_ind :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .IND } }
mem_ind_x :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_X } }
mem_ind_y :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_Y } }
mem_ind_zp :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_ZP } }
mem_ind_abs_x :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .IND_ABS_X } }
@(require_results) mem_zp :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP } }
@(require_results) mem_zp_x :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP_X } }
@(require_results) mem_zp_y :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .ZP_Y } }
@(require_results) mem_abs :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS } }
@(require_results) mem_abs_x :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS_X } }
@(require_results) mem_abs_y :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .ABS_Y } }
@(require_results) mem_ind :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .IND } }
@(require_results) mem_ind_x :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_X } }
@(require_results) mem_ind_y :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_Y } }
@(require_results) mem_ind_zp :: #force_inline proc "contextless" (addr: u8) -> Memory { return Memory{address = u16(addr), mode = .IND_ZP } }
@(require_results) mem_ind_abs_x :: #force_inline proc "contextless" (addr: u16) -> Memory { return Memory{address = addr, mode = .IND_ABS_X } }
// -----------------------------------------------------------------------------
// Operand: kind-tagged union, 16 bytes
@@ -87,18 +87,22 @@ Operand :: struct #packed {
// Generic constructors -------------------------------------------------------
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 1}
}
@(require_results)
op_imm8 :: #force_inline proc "contextless" (v: i64) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = 1}
}
@(require_results)
op_imm16 :: #force_inline proc "contextless" (v: i64) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = 2}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
size: u8 = 2
switch m.mode {
@@ -110,23 +114,25 @@ op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = size}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32, size: u8 = 1) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = size}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (offset: i64) -> Operand {
return Operand{relative = offset, kind = .RELATIVE, size = 1}
}
// Address-mode-named operand helpers (call site reads like asm).
op_zp :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp(a)) }
op_zp_x :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp_x(a)) }
op_zp_y :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp_y(a)) }
op_abs :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs(a)) }
op_abs_x :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs_x(a)) }
op_abs_y :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs_y(a)) }
op_ind :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_ind(a)) }
op_ind_x :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_x(a)) }
op_ind_y :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_y(a)) }
op_ind_zp :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_zp(a)) }
op_ind_abs_x :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_ind_abs_x(a)) }
@(require_results) op_zp :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp(a)) }
@(require_results) op_zp_x :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp_x(a)) }
@(require_results) op_zp_y :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_zp_y(a)) }
@(require_results) op_abs :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs(a)) }
@(require_results) op_abs_x :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs_x(a)) }
@(require_results) op_abs_y :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_abs_y(a)) }
@(require_results) op_ind :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_ind(a)) }
@(require_results) op_ind_x :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_x(a)) }
@(require_results) op_ind_y :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_y(a)) }
@(require_results) op_ind_zp :: #force_inline proc "contextless" (a: u8) -> Operand { return op_mem(mem_ind_zp(a)) }
@(require_results) op_ind_abs_x :: #force_inline proc "contextless" (a: u16) -> Operand { return op_mem(mem_ind_abs_x(a)) }

View File

@@ -60,24 +60,24 @@ Memory :: bit_field u32 {
}
#assert(size_of(Memory) == 4)
mem_dp :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP } }
mem_dp_x :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_X } }
mem_dp_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_Y } }
mem_dp_ind :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND } }
mem_dp_ind_x :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_X } }
mem_dp_ind_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_Y } }
mem_dp_ind_long :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_LONG } }
mem_dp_ind_long_y:: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_LONG_Y } }
mem_abs :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS } }
mem_abs_x :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_X } }
mem_abs_y :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_Y } }
mem_abs_ind :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND } }
mem_abs_ind_long :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND_LONG } }
mem_abs_ind_x :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND_X } }
mem_long :: #force_inline proc "contextless" (a: u32) -> Memory { return Memory{address = a & 0xFFFFFF, mode = .LONG } }
mem_long_x :: #force_inline proc "contextless" (a: u32) -> Memory { return Memory{address = a & 0xFFFFFF, mode = .LONG_X } }
mem_sr :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .SR } }
mem_sr_ind_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .SR_IND_Y } }
@(require_results) mem_dp :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP } }
@(require_results) mem_dp_x :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_X } }
@(require_results) mem_dp_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_Y } }
@(require_results) mem_dp_ind :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND } }
@(require_results) mem_dp_ind_x :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_X } }
@(require_results) mem_dp_ind_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_Y } }
@(require_results) mem_dp_ind_long :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_LONG } }
@(require_results) mem_dp_ind_long_y:: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .DP_IND_LONG_Y } }
@(require_results) mem_abs :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS } }
@(require_results) mem_abs_x :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_X } }
@(require_results) mem_abs_y :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_Y } }
@(require_results) mem_abs_ind :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND } }
@(require_results) mem_abs_ind_long :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND_LONG } }
@(require_results) mem_abs_ind_x :: #force_inline proc "contextless" (a: u16) -> Memory { return Memory{address = u32(a), mode = .ABS_IND_X } }
@(require_results) mem_long :: #force_inline proc "contextless" (a: u32) -> Memory { return Memory{address = a & 0xFFFFFF, mode = .LONG } }
@(require_results) mem_long_x :: #force_inline proc "contextless" (a: u32) -> Memory { return Memory{address = a & 0xFFFFFF, mode = .LONG_X } }
@(require_results) mem_sr :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .SR } }
@(require_results) mem_sr_ind_y :: #force_inline proc "contextless" (a: u8) -> Memory { return Memory{address = u32(a), mode = .SR_IND_Y } }
Operand :: struct #packed {
using _: struct #raw_union {
@@ -92,10 +92,12 @@ Operand :: struct #packed {
}
#assert(size_of(Operand) == 16)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand { return Operand{reg = r, kind = .REGISTER, size = 1} }
op_imm8 :: #force_inline proc "contextless" (v: i64) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = 1} }
op_imm16 :: #force_inline proc "contextless" (v: i64) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = 2} }
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
@(require_results) op_reg :: #force_inline proc "contextless" (r: Register) -> Operand { return Operand{reg = r, kind = .REGISTER, size = 1} }
@(require_results) op_imm8 :: #force_inline proc "contextless" (v: i64) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = 1} }
@(require_results) op_imm16 :: #force_inline proc "contextless" (v: i64) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = 2} }
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
// Operand size = width of the address literal as encoded.
size: u8 = 2
switch m.mode {
@@ -110,9 +112,12 @@ op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = size}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32, size: u8 = 1) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = size}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE, size = 1}
}

View File

@@ -34,9 +34,11 @@ Memory :: struct #packed {
}
#assert(size_of(Memory) == 12)
@(require_results)
mem_d :: #force_inline proc "contextless" (base: Register, disp: i64) -> Memory {
return Memory{base = base, index = NONE, disp = disp}
}
@(require_results)
mem_x :: #force_inline proc "contextless" (base, index: Register) -> Memory {
return Memory{base = base, index = index, disp = 0}
}
@@ -54,18 +56,23 @@ Operand :: struct #packed {
}
// raw_union size = max(2, 12, 8, 8) = 12; + 1 kind + 1 size + 2 pad = 16 bytes
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE}
}

View File

@@ -19,9 +19,11 @@ Memory :: struct #packed {
}
#assert(size_of(Memory) == 12)
@(require_results)
mem_d :: #force_inline proc "contextless" (base: Register, disp: i64) -> Memory {
return Memory{base = base, index = NONE, disp = disp}
}
@(require_results)
mem_x :: #force_inline proc "contextless" (base, index: Register) -> Memory {
return Memory{base = base, index = index, disp = 0}
}
@@ -38,18 +40,23 @@ Operand :: struct #packed {
_: [2]u8,
}
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand {
return Operand{mem = m, kind = .MEMORY}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE}
}

View File

@@ -28,6 +28,7 @@ Memory :: struct #packed {
}
#assert(size_of(Memory) == 8)
@(require_results)
mem :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp}
}
@@ -45,20 +46,27 @@ Operand :: struct #packed {
}
#assert(size_of(Operand) == 16)
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand { return Operand{reg = r, kind = .REGISTER, size = 4} }
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64, size: u8) -> Operand { return Operand{immediate = v, kind = .IMMEDIATE, size = size} }
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory) -> Operand { return Operand{mem = m, kind = .MEMORY, size = 4} }
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32, size: u8 = 2) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = size}
}
@(require_results)
op_rel_offset :: #force_inline proc "contextless" (off: i64) -> Operand {
return Operand{relative = off, kind = .RELATIVE, size = 2}
}
// Typed constructors
@(require_results)
op_gpr :: #force_inline proc "contextless" (g: GPR) -> Operand {
return Operand{reg = Register(REG_GPR | u16(g)), kind = .REGISTER, size = 4}
}
@(require_results)
op_fpr :: #force_inline proc "contextless" (f: FPR) -> Operand {
return Operand{reg = Register(REG_FPR | u16(f)), kind = .REGISTER, size = 4}
}

View File

@@ -34,10 +34,12 @@ Vector_Mem :: struct #packed {
}
#assert(size_of(Vector_Mem) == 8)
@(require_results)
mem :: #force_inline proc "contextless" (base: Register, disp: i32) -> Memory {
return Memory{base = base, disp = disp}
}
@(require_results)
vmem :: #force_inline proc "contextless" (base: Register, element: u8, offset: i32) -> Vector_Mem {
return Vector_Mem{base = base, element = element, offset = offset}
}
@@ -58,26 +60,32 @@ Operand :: struct #packed {
}
#assert(size_of(Operand) == 16)
@(require_results)
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
return Operand{reg = r, kind = .REGISTER, size = 4}
}
@(require_results)
op_vr :: #force_inline proc "contextless" (r: Register, element: u8 = 0) -> Operand {
return Operand{reg = r, kind = .VECTOR_REG, size = 16, element = element}
}
@(require_results)
op_mem :: #force_inline proc "contextless" (m: Memory, size: u8) -> Operand {
return Operand{mem = m, kind = .MEMORY, size = size}
}
@(require_results)
op_vmem :: #force_inline proc "contextless" (m: Vector_Mem, size: u8) -> Operand {
return Operand{vmem = m, kind = .VECTOR_MEM, size = size}
}
@(require_results)
op_imm :: #force_inline proc "contextless" (v: i64, size: u8) -> Operand {
return Operand{immediate = v, kind = .IMMEDIATE, size = size}
}
@(require_results)
op_label :: #force_inline proc "contextless" (label_id: u32) -> Operand {
return Operand{relative = i64(label_id), kind = .RELATIVE, size = 4}
}

View File

@@ -37,6 +37,7 @@ Memory :: bit_field u64 {
index_class: u8 | 5,
}
@(require_results)
mem_make :: proc "contextless" (base: Register, index: Register, scale: u8, disp: i32, segment: Register) -> Memory {
mem: Memory = ---
mem.base_hw = MEM_BASE_NONE