Generalizing data and operand bracketing, to make add instrunction work
This commit is contained in:
parent
bc0a8b65eb
commit
446848dffb
@ -61,8 +61,9 @@ InstructionInfo :: struct {
|
|||||||
has_displacement: bool,
|
has_displacement: bool,
|
||||||
has_segreg: bool,
|
has_segreg: bool,
|
||||||
has_flip: bool,
|
has_flip: bool,
|
||||||
|
has_bracketed_immediate: bool,
|
||||||
has_explicit_size: bool,
|
has_explicit_size: bool,
|
||||||
has_accumulator: bool,
|
has_sign_extension: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_first_last := RegInfo{ in_first_byte = true, shift_offset = 0 }
|
reg_first_last := RegInfo{ in_first_byte = true, shift_offset = 0 }
|
||||||
@ -74,22 +75,28 @@ instructions := [?]InstructionInfo {
|
|||||||
word_size = LastBit{}, has_flip = true },
|
word_size = LastBit{}, has_flip = true },
|
||||||
{ name = "mov", desc = "Immediate to register/memory", mask = 0b11111110, encoding = 0b11000110,
|
{ name = "mov", desc = "Immediate to register/memory", mask = 0b11111110, encoding = 0b11000110,
|
||||||
has_mod_rm = true, reg_info = nil, has_data = true, has_displacement = true,
|
has_mod_rm = true, reg_info = nil, has_data = true, has_displacement = true,
|
||||||
word_size = LastBit{}, has_explicit_size = true },
|
word_size = LastBit{}, has_bracketed_immediate = false, has_explicit_size = true },
|
||||||
{ name = "mov", desc = "Immediate to register", mask = 0b11110000, encoding = 0b10110000,
|
{ name = "mov", desc = "Immediate to register", mask = 0b11110000, encoding = 0b10110000,
|
||||||
has_mod_rm = false, reg_info = reg_first_last, has_data = true, has_displacement = false,
|
has_mod_rm = false, reg_info = reg_first_last, has_data = true, has_displacement = false,
|
||||||
word_size = FourthBit{} },
|
word_size = FourthBit{} },
|
||||||
{ name = "mov", desc = "Memory to accumulator", mask = 0b11111110, encoding = 0b10100000,
|
{ name = "mov", desc = "Memory to accumulator", mask = 0b11111110, encoding = 0b10100000,
|
||||||
has_mod_rm = false, reg_info = nil, has_data = true, has_displacement = false, has_flip = true,
|
has_mod_rm = false, reg_info = nil, has_data = true, has_displacement = false, has_flip = true,
|
||||||
word_size = LastBit{}, has_accumulator = true },
|
word_size = LastBit{}, has_bracketed_immediate = true },
|
||||||
{ name = "mov", desc = "Accumulator to memory", mask = 0b11111110, encoding = 0b10100010,
|
{ name = "mov", desc = "Accumulator to memory", mask = 0b11111110, encoding = 0b10100010,
|
||||||
has_mod_rm = false, reg_info = nil, has_data = true, has_displacement = false, has_flip = true,
|
has_mod_rm = false, reg_info = nil, has_data = true, has_displacement = false, has_flip = true,
|
||||||
word_size = LastBit{}, has_accumulator = true },
|
word_size = LastBit{}, has_bracketed_immediate = true },
|
||||||
{ name = "mov", desc = "Register/memory to segment register", mask = 0b11111111, encoding = 0b10001110,
|
{ name = "mov", desc = "Register/memory to segment register", mask = 0b11111111, encoding = 0b10001110,
|
||||||
has_mod_rm = true, reg_info = nil, has_segreg = true, has_displacement = true,
|
has_mod_rm = true, reg_info = nil, has_segreg = true, has_displacement = true,
|
||||||
word_size = None{} },
|
word_size = None{} },
|
||||||
{ name = "mov", desc = "Segment register to register/memory", mask = 0b11111111, encoding = 0b10001100,
|
{ name = "mov", desc = "Segment register to register/memory", mask = 0b11111111, encoding = 0b10001100,
|
||||||
has_mod_rm = true, reg_info = nil, has_segreg = true, has_displacement = true,
|
has_mod_rm = true, reg_info = nil, has_segreg = true, has_displacement = true,
|
||||||
word_size = None{} },
|
word_size = None{} },
|
||||||
|
{ name = "add", desc = "Register/memory to/from register", mask = 0b11111100, encoding = 0b00000000,
|
||||||
|
has_mod_rm = true, reg_info = reg_second_middle, has_data = false, has_displacement = true,
|
||||||
|
word_size = LastBit{}, has_flip = true },
|
||||||
|
{ name = "add", desc = "Immediate to register/memory", mask = 0b11111110, encoding = 0b10000000,
|
||||||
|
has_mod_rm = true, reg_info = nil, has_data = true, has_displacement = true,
|
||||||
|
word_size = LastBit{}, has_sign_extension = true },
|
||||||
}
|
}
|
||||||
|
|
||||||
None :: struct {}
|
None :: struct {}
|
||||||
@ -129,17 +136,11 @@ MemoryAddr :: struct {
|
|||||||
addr_id: u8,
|
addr_id: u8,
|
||||||
displacement: Displacement
|
displacement: Displacement
|
||||||
}
|
}
|
||||||
DirectAddress :: distinct i16
|
|
||||||
Accumulator8 :: distinct i8
|
|
||||||
Accumulator16 :: distinct i16
|
|
||||||
OperandType :: union {
|
OperandType :: union {
|
||||||
RegisterId,
|
RegisterId,
|
||||||
Immediate8,
|
Immediate8,
|
||||||
Immediate16,
|
Immediate16,
|
||||||
MemoryAddr,
|
MemoryAddr,
|
||||||
DirectAddress,
|
|
||||||
Accumulator8,
|
|
||||||
Accumulator16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inst_map := make(map[u8]InstructionInfo)
|
inst_map := make(map[u8]InstructionInfo)
|
||||||
@ -186,24 +187,19 @@ get_memory_string :: proc(memoryAddr: MemoryAddr) -> string {
|
|||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
get_memory_type_string :: proc(mem_type: OperandType, is_word: bool) -> string {
|
get_memory_type_string :: proc(mem_type: OperandType, is_word: bool, bracketed: bool) -> string {
|
||||||
|
string_val: string
|
||||||
switch val in mem_type {
|
switch val in mem_type {
|
||||||
case RegisterId:
|
case RegisterId:
|
||||||
return is_word ? registers[val].fullname : registers[val].bytename
|
string_val = is_word ? registers[val].fullname : registers[val].bytename
|
||||||
case Immediate8:
|
case Immediate8:
|
||||||
return fmt.aprintf("%d", val)
|
string_val = fmt.aprintf(bracketed ? "[%d]" : "%d", val)
|
||||||
case Immediate16:
|
case Immediate16:
|
||||||
return fmt.aprintf("%d", val)
|
string_val = fmt.aprintf(bracketed ? "[%d]" : "%d", val)
|
||||||
case MemoryAddr:
|
case MemoryAddr:
|
||||||
return get_memory_string(val)
|
string_val = get_memory_string(val)
|
||||||
case DirectAddress:
|
|
||||||
return fmt.aprintf("[%d]", val)
|
|
||||||
case Accumulator8:
|
|
||||||
return fmt.aprintf("[%d]", val)
|
|
||||||
case Accumulator16:
|
|
||||||
return fmt.aprintf("[%d]", val)
|
|
||||||
}
|
}
|
||||||
return ""
|
return string_val
|
||||||
}
|
}
|
||||||
|
|
||||||
get_i16 :: proc(data: []u8) -> i16 {
|
get_i16 :: proc(data: []u8) -> i16 {
|
||||||
@ -285,7 +281,6 @@ main :: proc() {
|
|||||||
processed := 1
|
processed := 1
|
||||||
curr_byte := data[idx]
|
curr_byte := data[idx]
|
||||||
|
|
||||||
|
|
||||||
instruction, ok := try_find_instruction(curr_byte)
|
instruction, ok := try_find_instruction(curr_byte)
|
||||||
if !ok {
|
if !ok {
|
||||||
txt := "unknown instruction"
|
txt := "unknown instruction"
|
||||||
@ -299,6 +294,7 @@ main :: proc() {
|
|||||||
is_word: bool
|
is_word: bool
|
||||||
is_immediate := false
|
is_immediate := false
|
||||||
flip_dst := false
|
flip_dst := false
|
||||||
|
bracket_operand := instruction.has_bracketed_immediate
|
||||||
rm: u8
|
rm: u8
|
||||||
mod: u8
|
mod: u8
|
||||||
reg: u8
|
reg: u8
|
||||||
@ -318,15 +314,19 @@ main :: proc() {
|
|||||||
reg = (b >> reg_info.shift_offset) & 0b111
|
reg = (b >> reg_info.shift_offset) & 0b111
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data_idx := idx + 1
|
||||||
|
|
||||||
if instruction.has_mod_rm {
|
if instruction.has_mod_rm {
|
||||||
mod = data[idx+1] >> 6
|
mod = data[idx+1] >> 6
|
||||||
rm = data[idx+1] & 0b00000111
|
rm = data[idx+1] & 0b00000111
|
||||||
|
|
||||||
|
data_idx += 1 + ((int)(mod) % 3)
|
||||||
processed += 1 + ((int)(mod) % 3)
|
processed += 1 + ((int)(mod) % 3)
|
||||||
|
|
||||||
if mod == 0 {
|
if mod == 0 {
|
||||||
if rm == 0b110 {
|
if rm == 0b110 {
|
||||||
lhs2 = (DirectAddress)(get_i16(data[idx+2:]))
|
lhs2 = (Immediate16)(get_i16(data[idx+2:]))
|
||||||
|
bracket_operand = true
|
||||||
processed += 2
|
processed += 2
|
||||||
} else {
|
} else {
|
||||||
lhs2 = MemoryAddr{ addr_id = rm , displacement = None{} }
|
lhs2 = MemoryAddr{ addr_id = rm , displacement = None{} }
|
||||||
@ -338,32 +338,25 @@ main :: proc() {
|
|||||||
} else if mod == 3 {
|
} else if mod == 3 {
|
||||||
lhs2 = (RegisterId)(registers[rm].code)
|
lhs2 = (RegisterId)(registers[rm].code)
|
||||||
}
|
}
|
||||||
if instruction.has_explicit_size {
|
|
||||||
imm_idx := idx + 2 + ((int)(mod) % 3)
|
|
||||||
rhs2 = (OperandType)(is_word ? (Immediate16)(get_i16(data[imm_idx:])) : (Immediate8)(data[imm_idx]))
|
|
||||||
processed += is_word ? 2 : 1
|
|
||||||
} else {
|
|
||||||
rhs2 = (RegisterId)(reg)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lhs2 = (RegisterId)(registers[reg].code)
|
lhs2 = (RegisterId)(registers[reg].code)
|
||||||
if instruction.has_accumulator {
|
|
||||||
rhs2 = (OperandType)(is_word ? ((Accumulator16)(get_i16(data[idx+1:]))) : ((Accumulator8)(data[idx+1])))
|
|
||||||
} else {
|
|
||||||
rhs2 = (OperandType)(is_word ? ((Immediate16)(get_i16(data[idx+1:]))) : ((Immediate8)(data[idx+1])))
|
|
||||||
}
|
}
|
||||||
|
if instruction.has_data {
|
||||||
processed += is_word ? 2 : 1
|
processed += is_word ? 2 : 1
|
||||||
|
rhs2 = (OperandType)(is_word ? (Immediate16)(get_i16(data[data_idx:])) : (Immediate8)(data[data_idx]))
|
||||||
|
} else {
|
||||||
|
rhs2 = (RegisterId)(reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flip_dst {
|
if flip_dst {
|
||||||
lhs2, rhs2 = rhs2, lhs2
|
lhs2, rhs2 = rhs2, lhs2
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs := get_memory_type_string(lhs2, is_word)
|
lhs := get_memory_type_string(lhs2, is_word, bracket_operand)
|
||||||
rhs := get_memory_type_string(rhs2, is_word)
|
rhs := get_memory_type_string(rhs2, is_word, bracket_operand)
|
||||||
size_string := instruction.has_explicit_size ? is_word ? "word " : "byte " : ""
|
size_string := instruction.has_explicit_size ? is_word ? "word " : "byte " : ""
|
||||||
full_inst := fmt.aprintf("%s %s, %s%s", instruction.name, lhs, size_string, rhs)
|
full_inst := fmt.aprintf("%s %s, %s%s", instruction.name, lhs, size_string, rhs)
|
||||||
fmt.printf("%s %*[1]s a", full_inst, RIGHT_ALIGN_AMOUNT - len(full_inst), ";;")
|
fmt.printf("%s %*[1]s", full_inst, RIGHT_ALIGN_AMOUNT - len(full_inst), ";;")
|
||||||
for i in 0..<processed {
|
for i in 0..<processed {
|
||||||
fmt.printf(" %08b", data[idx + i])
|
fmt.printf(" %08b", data[idx + i])
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user