Handle accumulator differently, handle segment registers, handle unary, add instructions
This commit is contained in:
parent
390fedc848
commit
782ff93ace
@ -159,17 +159,19 @@ InstructionInfo :: struct {
|
|||||||
reg_info: Maybe(RegInfo),
|
reg_info: Maybe(RegInfo),
|
||||||
has_data: bool,
|
has_data: bool,
|
||||||
has_address: bool,
|
has_address: bool,
|
||||||
has_accumulator: bool,
|
uses_accumulator: bool,
|
||||||
has_segreg: bool,
|
has_segreg: bool,
|
||||||
has_flip: bool,
|
has_flip: bool,
|
||||||
has_sign_extension: bool,
|
has_sign_extension: bool,
|
||||||
is_jump: bool,
|
is_jump: bool,
|
||||||
|
is_unary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe we can get rid of it since I don't have to specify the shift_offset,
|
// TODO: Maybe we can get rid of it since I don't have to specify the shift_offset,
|
||||||
// not like it changes a lot
|
// not like it changes a lot
|
||||||
reg_first_last := RegInfo{ in_first_byte = true, shift_offset = 0 }
|
reg_first_last := RegInfo{ in_first_byte = true, shift_offset = 0 }
|
||||||
reg_second_middle := RegInfo{ in_first_byte = false, shift_offset = 3 }
|
reg_second_middle := RegInfo{ in_first_byte = false, shift_offset = 3 }
|
||||||
|
reg_first_middle := RegInfo{ in_first_byte = true, shift_offset = 3 }
|
||||||
|
|
||||||
instructions := [?]InstructionInfo {
|
instructions := [?]InstructionInfo {
|
||||||
{ opname = .MOV, desc = "Register/memory to/from register", mask = 0b11111100, encoding = 0b10001000,
|
{ opname = .MOV, desc = "Register/memory to/from register", mask = 0b11111100, encoding = 0b10001000,
|
||||||
@ -179,13 +181,29 @@ instructions := [?]InstructionInfo {
|
|||||||
{ opname = .MOV, desc = "Immediate to register", mask = 0b11110000, encoding = 0b10110000,
|
{ opname = .MOV, desc = "Immediate to register", mask = 0b11110000, encoding = 0b10110000,
|
||||||
reg_info = reg_first_last, has_data = true, word_size = FourthBit{} },
|
reg_info = reg_first_last, has_data = true, word_size = FourthBit{} },
|
||||||
{ opname = .MOV, desc = "Memory to accumulator", mask = 0b11111110, encoding = 0b10100000,
|
{ opname = .MOV, desc = "Memory to accumulator", mask = 0b11111110, encoding = 0b10100000,
|
||||||
has_flip = true, word_size = LastBit{}, has_accumulator = true },
|
has_flip = true, word_size = LastBit{}, uses_accumulator = true },
|
||||||
{ opname = .MOV, desc = "Accumulator to memory", mask = 0b11111110, encoding = 0b10100010,
|
{ opname = .MOV, desc = "Accumulator to memory", mask = 0b11111110, encoding = 0b10100010,
|
||||||
has_flip = true, word_size = LastBit{}, has_accumulator = true },
|
has_flip = true, word_size = LastBit{}, uses_accumulator = true },
|
||||||
{ opname = .MOV, desc = "Register/memory to segment register", mask = 0b11111111, encoding = 0b10001110,
|
{ opname = .MOV, desc = "Register/memory to segment register", mask = 0b11111111, encoding = 0b10001110,
|
||||||
has_segreg = true, has_address = true, word_size = None{} },
|
has_segreg = true, has_address = true, word_size = None{} },
|
||||||
{ opname = .MOV, desc = "Segment register to register/memory", mask = 0b11111111, encoding = 0b10001100,
|
{ opname = .MOV, desc = "Segment register to register/memory", mask = 0b11111111, encoding = 0b10001100,
|
||||||
has_segreg = true, has_address = true, word_size = None{} },
|
has_segreg = true, has_address = true, word_size = None{} },
|
||||||
|
{ opname = .PUSH, desc = "", mask = 0b11111111, encoding = 0b11111111,
|
||||||
|
has_address = true, word_size = None{}, is_unary = true },
|
||||||
|
{ opname = .PUSH, desc = "", mask = 0b11111000, encoding = 0b01010000,
|
||||||
|
reg_info = reg_first_last, word_size = Force{}, is_unary = true },
|
||||||
|
{ opname = .PUSH, desc = "", mask = 0b11100111, encoding = 0b00000110,
|
||||||
|
has_segreg = true, reg_info = reg_first_middle, word_size = Force{}, is_unary = true },
|
||||||
|
{ opname = .POP, desc = "", mask = 0b11111111, encoding = 0b10001111,
|
||||||
|
has_address = true, word_size = None{}, is_unary = true },
|
||||||
|
{ opname = .POP, desc = "", mask = 0b11111000, encoding = 0b01011000,
|
||||||
|
reg_info = reg_first_last, word_size = Force{}, is_unary = true },
|
||||||
|
{ opname = .POP, desc = "", mask = 0b11100111, encoding = 0b00000111,
|
||||||
|
has_segreg = true, reg_info = reg_first_middle, word_size = None{}, is_unary = true },
|
||||||
|
{ opname = .XCHG, desc = "", mask = 0b11111110, encoding = 0b10000110,
|
||||||
|
reg_info = reg_second_middle, has_address = true, word_size = LastBit{}, has_flip = true},
|
||||||
|
{ opname = .XCHG, desc = "", mask = 0b11111000, encoding = 0b10010000,
|
||||||
|
reg_info = reg_first_last, uses_accumulator = true, word_size = Force{}, },
|
||||||
{ opname = .TBD, desc = "Reg/memory with register to either", mask = 0b11000100, encoding = 0b00000000,
|
{ opname = .TBD, desc = "Reg/memory with register to either", mask = 0b11000100, encoding = 0b00000000,
|
||||||
opcode_id = .First, reg_info = reg_second_middle, has_address = true, word_size = LastBit{}, has_flip = true },
|
opcode_id = .First, reg_info = reg_second_middle, has_address = true, word_size = LastBit{}, has_flip = true },
|
||||||
{ opname = .TBD, desc = "Immediate to register/memory", mask = 0b11111100, encoding = 0b10000000,
|
{ opname = .TBD, desc = "Immediate to register/memory", mask = 0b11111100, encoding = 0b10000000,
|
||||||
@ -299,6 +317,8 @@ get_memory_type_string :: proc(mem_type: OperandType, is_word: bool) -> string {
|
|||||||
string_val = get_memory_string(val)
|
string_val = get_memory_string(val)
|
||||||
case Accumulator:
|
case Accumulator:
|
||||||
string_val = fmt.aprintf("[%d]", val)
|
string_val = fmt.aprintf("[%d]", val)
|
||||||
|
case SegmentRegister:
|
||||||
|
string_val = segment_registers[val].fullname
|
||||||
}
|
}
|
||||||
return string_val
|
return string_val
|
||||||
}
|
}
|
||||||
@ -383,13 +403,17 @@ main :: proc() {
|
|||||||
// asdf :u16 = 0b00000011_11101000
|
// asdf :u16 = 0b00000011_11101000
|
||||||
// asdf2 :i16 = (i16)(asdf)
|
// asdf2 :i16 = (i16)(asdf)
|
||||||
// fmt.printfln("%d", asdf2)
|
// fmt.printfln("%d", asdf2)
|
||||||
|
print_at_end := false
|
||||||
read_next := false
|
read_next := false
|
||||||
src_dst := true
|
src_dst := true
|
||||||
idx := 0
|
idx := 0
|
||||||
added_label := false
|
added_label := false
|
||||||
line_count := 0
|
line_count := 0
|
||||||
|
// last_opname: string
|
||||||
|
last_opname: [3]byte
|
||||||
instruction_builder := strings.builder_make()
|
instruction_builder := strings.builder_make()
|
||||||
instruction_list := make([dynamic]string, 128)
|
instruction_list := make([dynamic]string, 512)
|
||||||
|
fmt.println("bits 16")
|
||||||
for idx < bytes_read {
|
for idx < bytes_read {
|
||||||
processed := 1
|
processed := 1
|
||||||
curr_byte := data[idx]
|
curr_byte := data[idx]
|
||||||
@ -422,6 +446,7 @@ main :: proc() {
|
|||||||
switch val in instruction.word_size {
|
switch val in instruction.word_size {
|
||||||
case LastBit: is_word = curr_byte & 1 == 1
|
case LastBit: is_word = curr_byte & 1 == 1
|
||||||
case FourthBit: is_word = curr_byte & 0b0000_1000 != 0
|
case FourthBit: is_word = curr_byte & 0b0000_1000 != 0
|
||||||
|
case Force: is_word = true
|
||||||
case None:
|
case None:
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,6 +484,10 @@ main :: proc() {
|
|||||||
} else if mod == 3 {
|
} else if mod == 3 {
|
||||||
lhs2 = (RegisterId)(registers[rm].code)
|
lhs2 = (RegisterId)(registers[rm].code)
|
||||||
}
|
}
|
||||||
|
} else if instruction.has_segreg {
|
||||||
|
lhs2 = (SegmentRegister)(segment_registers[reg].code)
|
||||||
|
} else if instruction.uses_accumulator {
|
||||||
|
lhs2 = (RegisterId)(registers[0].code)
|
||||||
} else {
|
} else {
|
||||||
lhs2 = (RegisterId)(registers[reg].code)
|
lhs2 = (RegisterId)(registers[reg].code)
|
||||||
}
|
}
|
||||||
@ -470,12 +499,16 @@ main :: proc() {
|
|||||||
processed += word_signed ? 2 : 1
|
processed += word_signed ? 2 : 1
|
||||||
rhs2 = (OperandType)(word_signed ? (Immediate16)(get_i16(data[data_idx:])) : (Immediate8)(data[data_idx]))
|
rhs2 = (OperandType)(word_signed ? (Immediate16)(get_i16(data[data_idx:])) : (Immediate8)(data[data_idx]))
|
||||||
has_immediate = true
|
has_immediate = true
|
||||||
} else if instruction.has_accumulator {
|
} else if instruction.uses_accumulator {
|
||||||
|
if _, ok := instruction.word_size.(LastBit); ok {
|
||||||
processed += is_word ? 2 : 1
|
processed += is_word ? 2 : 1
|
||||||
rhs2 = (OperandType)(is_word ? (Accumulator)(get_i16(data[data_idx:])) : (Accumulator)(data[data_idx]))
|
rhs2 = (OperandType)(is_word ? (Accumulator)(get_i16(data[data_idx:])) : (Accumulator)(data[data_idx]))
|
||||||
} else {
|
} else {
|
||||||
rhs2 = (RegisterId)(reg)
|
rhs2 = (RegisterId)(reg)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
rhs2 = (RegisterId)(reg)
|
||||||
|
}
|
||||||
|
|
||||||
if flip_dst {
|
if flip_dst {
|
||||||
lhs2, rhs2 = rhs2, lhs2
|
lhs2, rhs2 = rhs2, lhs2
|
||||||
@ -500,6 +533,11 @@ main :: proc() {
|
|||||||
value := (i8)(data[idx+1]) + 2
|
value := (i8)(data[idx+1]) + 2
|
||||||
full_inst = fmt.aprintf("%s $%s%d ; %d", strings.to_lower(opname), value >= 0 ? "+" : "", value, value - 2)
|
full_inst = fmt.aprintf("%s $%s%d ; %d", strings.to_lower(opname), value >= 0 ? "+" : "", value, value - 2)
|
||||||
processed += 1
|
processed += 1
|
||||||
|
} else if instruction.is_unary {
|
||||||
|
if instruction.has_address {
|
||||||
|
size_string = "word "
|
||||||
|
}
|
||||||
|
full_inst = fmt.aprintf("%s %s%s", opname, size_string, lhs)
|
||||||
} else {
|
} else {
|
||||||
opname = strings.to_lower(opname)
|
opname = strings.to_lower(opname)
|
||||||
if opname == "mov" {
|
if opname == "mov" {
|
||||||
@ -512,13 +550,28 @@ main :: proc() {
|
|||||||
for i in 0..<processed {
|
for i in 0..<processed {
|
||||||
fmt.sbprintf(&instruction_builder, " %08b", data[idx + i])
|
fmt.sbprintf(&instruction_builder, " %08b", data[idx + i])
|
||||||
}
|
}
|
||||||
|
if print_at_end {
|
||||||
instruction_list[line_count] = strings.clone(strings.to_string(instruction_builder))
|
instruction_list[line_count] = strings.clone(strings.to_string(instruction_builder))
|
||||||
|
} else {
|
||||||
|
op := strings.to_string(instruction_builder)
|
||||||
|
if op[0:3] != string(last_opname[:]) {
|
||||||
|
fmt.println()
|
||||||
|
}
|
||||||
|
copy(last_opname[:], op[0:3])
|
||||||
|
fmt.println(op)
|
||||||
|
}
|
||||||
idx += processed
|
idx += processed
|
||||||
line_count += 1
|
line_count += 1
|
||||||
strings.builder_reset(&instruction_builder)
|
strings.builder_reset(&instruction_builder)
|
||||||
}
|
}
|
||||||
fmt.println("bits 16\n")
|
if print_at_end {
|
||||||
for i in 0..<line_count {
|
for i in 0..<line_count {
|
||||||
|
opname := instruction_list[i]
|
||||||
|
if !strings.has_prefix(opname, string(last_opname[:])) {
|
||||||
|
fmt.println()
|
||||||
|
}
|
||||||
|
copy(last_opname[:], opname[0:3])
|
||||||
fmt.println(instruction_list[i])
|
fmt.println(instruction_list[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user