mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-18 21:51:08 +00:00
Minimize Instruction and Operand across ISAs further with struct #raw_union #packed
This commit is contained in:
@@ -21,7 +21,7 @@ Instruction_Flags :: bit_field u8 {
|
||||
}
|
||||
|
||||
Instruction :: struct #packed {
|
||||
ops: [4]Operand `fmt:"v,operand_count"`, // 4 * 22 = 88
|
||||
ops: [4]Operand `fmt:"v,operand_count"`, // 4 * 18 = 68
|
||||
mnemonic: Mnemonic, // 2
|
||||
cond: u8, // 0..15 (AL=14)
|
||||
operand_count: u8, // 0..4
|
||||
@@ -35,9 +35,9 @@ Instruction :: struct #packed {
|
||||
// bits). User-constructed instructions leave it at 0; the encoder then
|
||||
// falls back to first-shape-match. Stored as u16 over the two padding bytes.
|
||||
form_id: u16,
|
||||
_: [7]u8,
|
||||
}
|
||||
#assert(size_of(Instruction) == 97)
|
||||
// 88 + 9 = 97 bytes (packed)
|
||||
#assert(size_of(Instruction) == 88)
|
||||
|
||||
// =============================================================================
|
||||
// Builders
|
||||
|
||||
@@ -94,7 +94,7 @@ mem_reg_shift :: #force_inline proc "contextless" (
|
||||
// ---- Operand structure -----------------------------------------------------
|
||||
|
||||
Operand :: struct #packed {
|
||||
using _: struct #raw_union {
|
||||
using _: struct #raw_union #packed {
|
||||
reg: Register,
|
||||
mem: Memory,
|
||||
immediate: i64,
|
||||
@@ -107,9 +107,7 @@ Operand :: struct #packed {
|
||||
lane: u8, // SIMD lane index for DPR_ELEM / QPR_ELEM
|
||||
cond: u8, // condition code 0..15 (default = AL = 14)
|
||||
}
|
||||
#assert(size_of(Operand) == 22)
|
||||
// 16-byte raw_union (Memory is largest) + 6 bytes of trailing fields = 22 bytes
|
||||
// (packed; no alignment padding).
|
||||
#assert(size_of(Operand) == 18)
|
||||
|
||||
// ---- Operand builders ------------------------------------------------------
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ Instruction :: struct #packed {
|
||||
operand_count: u8, // 1
|
||||
flags: Instruction_Flags, // 1
|
||||
length: u8, // 1 -- always 4
|
||||
_: [3]u8,
|
||||
}
|
||||
#assert(size_of(Instruction) == 77)
|
||||
#assert(size_of(Instruction) == 64)
|
||||
|
||||
// =============================================================================
|
||||
// Builders -- the most common shapes; less-common forms can be built
|
||||
|
||||
@@ -89,7 +89,7 @@ Extended_Reg :: struct #packed {
|
||||
|
||||
// 16-byte tagged operand. The union holds whichever payload matches `kind`.
|
||||
Operand :: struct #packed {
|
||||
using _: struct #raw_union {
|
||||
using _: struct #raw_union #packed {
|
||||
reg: Register, // 2
|
||||
mem: Memory, // 12
|
||||
immediate: i64, // 8
|
||||
@@ -97,11 +97,11 @@ Operand :: struct #packed {
|
||||
shifted: Shifted_Reg, // 8
|
||||
extended: Extended_Reg, // 8
|
||||
cond: u8, // 1
|
||||
}, // 16 total because of alignment
|
||||
}, // 12 total because of alignment
|
||||
kind: Operand_Kind, // 1
|
||||
size: u8, // 1 -- carried width info; meaning varies
|
||||
}
|
||||
#assert(size_of(Operand) == 18)
|
||||
#assert(size_of(Operand) == 14)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constructors -- generic
|
||||
|
||||
@@ -20,7 +20,7 @@ Instruction_Flags :: bit_field u8 {
|
||||
}
|
||||
|
||||
Instruction :: struct #packed {
|
||||
ops: [4]Operand `fmt:"v,operand_count"`, // 4 * 18 = 68
|
||||
ops: [4]Operand `fmt:"v,operand_count"`, // 4 * 14 = 56
|
||||
mnemonic: Mnemonic, // 2
|
||||
operand_count: u8, // 0..4
|
||||
flags: Instruction_Flags, // 1
|
||||
@@ -28,7 +28,7 @@ Instruction :: struct #packed {
|
||||
length: u8, // 4 or 8 (prefixed)
|
||||
form_id: u16, // 0 = no hint; otherwise 1 + form index
|
||||
}
|
||||
#assert(size_of(Instruction) == 80)
|
||||
#assert(size_of(Instruction) == 64)
|
||||
|
||||
// =============================================================================
|
||||
// Builders
|
||||
|
||||
@@ -46,7 +46,7 @@ mem_x :: #force_inline proc "contextless" (base, index: Register) -> Memory {
|
||||
}
|
||||
|
||||
Operand :: struct #packed {
|
||||
using _: struct #raw_union {
|
||||
using _: struct #raw_union #packed {
|
||||
reg: Register,
|
||||
mem: Memory,
|
||||
immediate: i64,
|
||||
@@ -55,7 +55,7 @@ Operand :: struct #packed {
|
||||
kind: Operand_Kind,
|
||||
size: u8, // operand size in bytes (4 = word, 8 = dword)
|
||||
}
|
||||
#assert(size_of(Operand) == 18)
|
||||
#assert(size_of(Operand) == 14)
|
||||
|
||||
@(require_results)
|
||||
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
|
||||
|
||||
@@ -26,7 +26,7 @@ Instruction :: struct #packed {
|
||||
length: u8, // 2 or 4
|
||||
form_id: u16,
|
||||
}
|
||||
#assert(size_of(Instruction) == 80)
|
||||
#assert(size_of(Instruction) == 64)
|
||||
|
||||
@(require_results)
|
||||
inst_none :: #force_inline proc "contextless" (m: Mnemonic) -> Instruction {
|
||||
|
||||
@@ -31,7 +31,7 @@ mem_x :: #force_inline proc "contextless" (base, index: Register) -> Memory {
|
||||
}
|
||||
|
||||
Operand :: struct #packed {
|
||||
using _: struct #raw_union {
|
||||
using _: struct #raw_union #packed {
|
||||
reg: Register,
|
||||
mem: Memory,
|
||||
immediate: i64,
|
||||
@@ -40,7 +40,7 @@ Operand :: struct #packed {
|
||||
kind: Operand_Kind,
|
||||
size: u8,
|
||||
}
|
||||
#assert(size_of(Operand) == 18)
|
||||
#assert(size_of(Operand) == 14)
|
||||
|
||||
@(require_results)
|
||||
op_reg :: #force_inline proc "contextless" (r: Register) -> Operand {
|
||||
|
||||
Reference in New Issue
Block a user