mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-19 16:42:33 +00:00
Add @(require_results) to operand procedures
This commit is contained in:
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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)) }
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user