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_segreg: bool,
|
||||
has_flip: bool,
|
||||
has_bracketed_immediate: bool,
|
||||
has_explicit_size: bool,
|
||||
has_accumulator: bool,
|
||||
has_sign_extension: bool,
|
||||
}
|
||||
|
||||
reg_first_last := RegInfo{ in_first_byte = true, shift_offset = 0 }
|
||||
@ -74,22 +75,28 @@ instructions := [?]InstructionInfo {
|
||||
word_size = LastBit{}, has_flip = true },
|
||||
{ name = "mov", desc = "Immediate to register/memory", mask = 0b11111110, encoding = 0b11000110,
|
||||
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,
|
||||
has_mod_rm = false, reg_info = reg_first_last, has_data = true, has_displacement = false,
|
||||
word_size = FourthBit{} },
|
||||
{ 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,
|
||||
word_size = LastBit{}, has_accumulator = true },
|
||||
word_size = LastBit{}, has_bracketed_immediate = true },
|
||||
{ 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,
|
||||
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,
|
||||
has_mod_rm = true, reg_info = nil, has_segreg = true, has_displacement = true,
|
||||
word_size = None{} },
|
||||
{ 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,
|
||||
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 {}
|
||||
@ -129,17 +136,11 @@ MemoryAddr :: struct {
|
||||
addr_id: u8,
|
||||
displacement: Displacement
|
||||
}
|
||||
DirectAddress :: distinct i16
|
||||
Accumulator8 :: distinct i8
|
||||
Accumulator16 :: distinct i16
|
||||
OperandType :: union {
|
||||
RegisterId,
|
||||
Immediate8,
|
||||
Immediate16,
|
||||
MemoryAddr,
|
||||
DirectAddress,
|
||||
Accumulator8,
|
||||
Accumulator16,
|
||||
}
|
||||
|
||||
inst_map := make(map[u8]InstructionInfo)
|
||||
@ -186,24 +187,19 @@ get_memory_string :: proc(memoryAddr: MemoryAddr) -> string {
|
||||
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 {
|
||||
case RegisterId:
|
||||
return is_word ? registers[val].fullname : registers[val].bytename
|
||||
string_val = is_word ? registers[val].fullname : registers[val].bytename
|
||||
case Immediate8:
|
||||
return fmt.aprintf("%d", val)
|
||||
string_val = fmt.aprintf(bracketed ? "[%d]" : "%d", val)
|
||||
case Immediate16:
|
||||
return fmt.aprintf("%d", val)
|
||||
string_val = fmt.aprintf(bracketed ? "[%d]" : "%d", val)
|
||||
case MemoryAddr:
|
||||
return 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)
|
||||
string_val = get_memory_string(val)
|
||||
}
|
||||
return ""
|
||||
return string_val
|
||||
}
|
||||
|
||||
get_i16 :: proc(data: []u8) -> i16 {
|
||||
@ -285,7 +281,6 @@ main :: proc() {
|
||||
processed := 1
|
||||
curr_byte := data[idx]
|
||||
|
||||
|
||||
instruction, ok := try_find_instruction(curr_byte)
|
||||
if !ok {
|
||||
txt := "unknown instruction"
|
||||
@ -299,6 +294,7 @@ main :: proc() {
|
||||
is_word: bool
|
||||
is_immediate := false
|
||||
flip_dst := false
|
||||
bracket_operand := instruction.has_bracketed_immediate
|
||||
rm: u8
|
||||
mod: u8
|
||||
reg: u8
|
||||
@ -318,15 +314,19 @@ main :: proc() {
|
||||
reg = (b >> reg_info.shift_offset) & 0b111
|
||||
}
|
||||
|
||||
data_idx := idx + 1
|
||||
|
||||
if instruction.has_mod_rm {
|
||||
mod = data[idx+1] >> 6
|
||||
rm = data[idx+1] & 0b00000111
|
||||
|
||||
data_idx += 1 + ((int)(mod) % 3)
|
||||
processed += 1 + ((int)(mod) % 3)
|
||||
|
||||
if mod == 0 {
|
||||
if rm == 0b110 {
|
||||
lhs2 = (DirectAddress)(get_i16(data[idx+2:]))
|
||||
lhs2 = (Immediate16)(get_i16(data[idx+2:]))
|
||||
bracket_operand = true
|
||||
processed += 2
|
||||
} else {
|
||||
lhs2 = MemoryAddr{ addr_id = rm , displacement = None{} }
|
||||
@ -338,32 +338,25 @@ main :: proc() {
|
||||
} else if mod == 3 {
|
||||
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 {
|
||||
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
|
||||
rhs2 = (OperandType)(is_word ? (Immediate16)(get_i16(data[data_idx:])) : (Immediate8)(data[data_idx]))
|
||||
} else {
|
||||
rhs2 = (RegisterId)(reg)
|
||||
}
|
||||
|
||||
if flip_dst {
|
||||
lhs2, rhs2 = rhs2, lhs2
|
||||
}
|
||||
|
||||
lhs := get_memory_type_string(lhs2, is_word)
|
||||
rhs := get_memory_type_string(rhs2, is_word)
|
||||
lhs := get_memory_type_string(lhs2, is_word, bracket_operand)
|
||||
rhs := get_memory_type_string(rhs2, is_word, bracket_operand)
|
||||
size_string := instruction.has_explicit_size ? is_word ? "word " : "byte " : ""
|
||||
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 {
|
||||
fmt.printf(" %08b", data[idx + i])
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user