package decoder_8086 OpName :: enum { TBD1, TBD2, TBD3, TBD4, TBD5, TBD6, MOV, PUSH, POP, XCHG, IN, OUT, XLAT, LEA, LDS, LES, LAHF, SAHF, PUSHF, POPF, ADD, ADC, INC, AAA, DAA, SUB, SBB, DEC, NEG, CMP, AAS, DAS, AAM, DIV, IDIV, AAD, CBW, CWD, NOT, TEST, REP, RET, RETF, INT, INT3, INTO, IRET, CLC, CMC, STC, CLD, STD, CLI, STI, HLT, WAIT, ESC, LOCK, SEGMENT, CALL, JMP, JNZ, JNGE, JE, JZ, JL, JLE, JNG, JB, JNAE, JP, JPE, JNA, JBE, JO, JS, JNE, JNL, JGE, JNLE, JG, JNB, JAE, JNBE, JA, JNP, JPO, JNO, JNS, LOOP, LOOPZ, LOOPNZ, JCXZ, } // TODO: We should figure out another way of handling this case. The way we're doing it // isn't that great; we return a string with the instruction name, but ideally we have all // the instructions accounted for, because eventually we will need the final parsed // instruction to contain all the information related to it test_inst := InstructionInfo { opname = .NOT, desc = "", mask = 0b11111110, encoding = 0b11110110, dst = .RegisterMemory, src = .Immediate, word_size = .LastBit } instructions := [?]InstructionInfo { { opname = .TBD1, desc = "Immediate to accumulator", mask = 0b11000110, encoding = 0b00000100, check_second_encoding = true, dst = .Accumulator, src = .Immediate, word_size = .LastBit, }, { opname = .TBD2, desc = "", check_second_encoding = true, mask = 0b11111110, encoding = 0b11111110, src = .RegisterMemory, word_size = .LastBit, }, { opname = .TBD3, desc = "", check_second_encoding = true, mask = 0b11000100, encoding = 0b00000000, dst = .RegisterMemory, src = .Register, word_size = .LastBit, reg_info = .SecondByteMiddle3, has_flip = true }, { opname = .TBD4, desc = "", check_second_encoding = true, mask = 0b11111100, encoding = 0b10000000, dst = .RegisterMemory, src = .Immediate, word_size = .LastBit, has_sign_extension = true }, { opname = .TBD5, desc = "", check_second_encoding = true, mask = 0b11111110, encoding = 0b11110110, // dst = .Immediate, src = .RegisterMemory, word_size = .LastBit, }, src = .RegisterMemory, word_size = .LastBit, }, { opname = .TBD6, desc = "", check_second_encoding = true, mask = 0b11111100, encoding = 0b11010000, dst = .RegisterMemory, src = .ShiftRotate, word_size = .LastBit, }, { opname = .MOV, desc = "Register/memory to/from register", mask = 0b11111100, encoding = 0b10001000, dst = .RegisterMemory, src = .Register, word_size = .LastBit, reg_info = .SecondByteMiddle3, has_flip = true }, { opname = .MOV, desc = "Immediate to register/memory", mask = 0b11111110, encoding = 0b11000110, dst = .RegisterMemory, src = .Immediate, word_size = .LastBit, }, { opname = .MOV, desc = "Immediate to register", mask = 0b11110000, encoding = 0b10110000, dst = .Register, src = .Immediate, word_size = .FourthBit, reg_info = .FirstByteLast3 }, { opname = .MOV, desc = "Memory to accumulator", mask = 0b11111110, encoding = 0b10100000, dst = .Accumulator, src = .DirectAddress, word_size = .LastBit, }, { opname = .MOV, desc = "Accumulator to memory", mask = 0b11111110, encoding = 0b10100010, dst = .DirectAddress, src = .Accumulator, word_size = .LastBit, }, { opname = .MOV, desc = "Accumulator to memory", mask = 0b11111111, encoding = 0b10001100, dst = .RegisterMemory, src = .SegmentRegister, reg_info = .SecondByteMiddle3 }, { opname = .PUSH, desc = "", mask = 0b11111000, encoding = 0b01010000, src = .Register, reg_info = .FirstByteLast3, word_size = .Always16, }, { opname = .PUSH, desc = "", mask = 0b11100111, encoding = 0b00000110, src = .SegmentRegister, reg_info = .FirstByteMiddle3, word_size = .Always16, }, { opname = .POP, desc = "", mask = 0b11111111, encoding = 0b10001111, src = .RegisterMemory, word_size = .Always16 }, { opname = .POP, desc = "", mask = 0b11111000, encoding = 0b01011000, src = .Register, reg_info = .FirstByteLast3, word_size = .Always16, }, { opname = .POP, desc = "", mask = 0b11100111, encoding = 0b00000111, src = .SegmentRegister, reg_info = .FirstByteMiddle3, word_size = .Always16, }, { opname = .XCHG, desc = "", mask = 0b11111110, encoding = 0b10000110, dst = .RegisterMemory, src = .Register, reg_info = .SecondByteMiddle3, word_size = .LastBit, has_flip = true }, { opname = .XCHG, desc = "", mask = 0b11111000, encoding = 0b10010000, dst = .Accumulator, src = .Register, reg_info = .FirstByteLast3, has_flip = true, word_size = .Always16 }, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11100100, dst = .Accumulator, src = .ImmediateUnsigned }, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11101100, dst = .Accumulator, src = .VariablePort, word_size = .LastBit, }, { opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11100110, dst = .ImmediateUnsigned, src = .Accumulator, word_size = .LastBit, }, { opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11101110, dst = .VariablePort, src = .Accumulator, word_size = .LastBit, }, { opname = .TEST, desc = "", mask = 0b11111110, encoding = 0b10101000, dst = .Accumulator, src = .Immediate, word_size = .LastBit }, { opname = .XLAT, desc = "", mask = 0b11111111, encoding = 0b11010111,}, { opname = .LEA, desc = "", mask = 0b11111111, encoding = 0b10001101, dst = .Register, src = .RegisterMemory, reg_info = .SecondByteMiddle3, word_size = .Always16 }, { opname = .LDS, desc = "", mask = 0b11111111, encoding = 0b11000101, dst = .Register, src = .RegisterMemory, reg_info = .SecondByteMiddle3, word_size = .Always16 }, { opname = .LES, desc = "", mask = 0b11111111, encoding = 0b11000100, dst = .Register, src = .RegisterMemory, reg_info = .SecondByteMiddle3, word_size = .Always16 }, { opname = .LAHF, desc = "", mask = 0b11111111, encoding = 0b10011111,}, { opname = .SAHF, desc = "", mask = 0b11111111, encoding = 0b10011110,}, { opname = .PUSHF, desc = "", mask = 0b11111111, encoding = 0b10011100,}, { opname = .POPF, desc = "", mask = 0b11111111, encoding = 0b10011101,}, { opname = .INC, desc = "", mask = 0b11111000, encoding = 0b01000000, src = .Register, reg_info = .FirstByteLast3, word_size = .Always16 }, { opname = .AAA, desc = "", mask = 0b11111111, encoding = 0b00110111,}, { opname = .DAA, desc = "", mask = 0b11111111, encoding = 0b00100111,}, { opname = .DEC, desc = "", mask = 0b11111000, encoding = 0b01001000, src = .Register, reg_info = .FirstByteLast3, word_size = .Always16 }, { opname = .AAS, desc = "", mask = 0b11111111, encoding = 0b00111111,}, { opname = .DAS, desc = "", mask = 0b11111111, encoding = 0b00101111,}, { opname = .AAM, desc = "", mask = 0b11111111, encoding = 0b11010100,}, { opname = .AAD, desc = "", mask = 0b11111111, encoding = 0b11010101, consume_extra_bytes = 1 }, { opname = .CBW, desc = "", mask = 0b11111111, encoding = 0b10011000,}, { opname = .CWD, desc = "", mask = 0b11111111, encoding = 0b10011001,}, { opname = .TEST, desc = "", mask = 0b11111100, encoding = 0b10000100, dst = .RegisterMemory, src = .Register, word_size = .LastBit, reg_info = .SecondByteMiddle3, has_flip = true }, { opname = .REP, desc = "", mask = 0b11111110, encoding = 0b11110010, src = .Repeat }, { opname = .RET, desc = "", mask = 0b11111111, encoding = 0b11000011,}, { opname = .RET, src = .Immediate, word_size = .Always16, desc = "", mask = 0b11111111, encoding = 0b11000010,}, { opname = .RETF, desc = "", mask = 0b11111111, encoding = 0b11001011,}, { opname = .RETF, desc = "", mask = 0b11111111, encoding = 0b11001010, src = .Immediate, word_size = .Always16 }, { opname = .INT, src = .Immediate, desc = "", mask = 0b11111111, encoding = 0b11001101,}, { opname = .INT3, desc = "", mask = 0b11111111, encoding = 0b11001100,}, { opname = .INTO, desc = "", mask = 0b11111111, encoding = 0b11001110,}, { opname = .IRET, desc = "", mask = 0b11111111, encoding = 0b11001111,}, { opname = .CLC, desc = "", mask = 0b11111111, encoding = 0b11111000,}, { opname = .CMC, desc = "", mask = 0b11111111, encoding = 0b11110101,}, { opname = .STC, desc = "", mask = 0b11111111, encoding = 0b11111001,}, { opname = .CLD, desc = "", mask = 0b11111111, encoding = 0b11111100,}, { opname = .STD, desc = "", mask = 0b11111111, encoding = 0b11111101,}, { opname = .CLI, desc = "", mask = 0b11111111, encoding = 0b11111010,}, { opname = .STI, desc = "", mask = 0b11111111, encoding = 0b11111011,}, { opname = .HLT, desc = "", mask = 0b11111111, encoding = 0b11110100,}, { opname = .WAIT, desc = "", mask = 0b11111111, encoding = 0b10011011,}, { opname = .LOCK, desc = "", mask = 0b11111111, encoding = 0b11110000,}, { opname = .SEGMENT, desc = "", mask = 0b11100111, encoding = 0b00100110,}, { opname = .CALL, desc = "", mask = 0b11111111, encoding = 0b10011010, src = .Intersegment }, { opname = .JMP, desc = "", mask = 0b11111111, encoding = 0b11101010, src = .Intersegment }, { opname = .JMP, desc = "", mask = 0b11111111, encoding = 0b11101001, src = .DirectWithinSegment }, { opname = .CALL, desc = "", mask = 0b11111111, encoding = 0b11101000, src = .DirectWithinSegment }, { opname = .JE, mask = 0b11111111, encoding = 0b01110100, src = .Jump, desc = "Jump on not zero", }, { opname = .JZ, mask = 0b11111111, encoding = 0b01110100, src = .Jump, desc = "Jump on not zero", }, { opname = .JL, mask = 0b11111111, encoding = 0b01111100, src = .Jump, desc = "Jump on not zero", }, { opname = .JNGE, mask = 0b11111111, encoding = 0b01111100, src = .Jump, desc = "Jump on not zero", }, { opname = .JLE, mask = 0b11111111, encoding = 0b01111110, src = .Jump, desc = "Jump on not zero", }, { opname = .JNG, mask = 0b11111111, encoding = 0b01111110, src = .Jump, desc = "Jump on not zero", }, { opname = .JB, mask = 0b11111111, encoding = 0b01110010, src = .Jump, desc = "Jump on not zero", }, { opname = .JNAE, mask = 0b11111111, encoding = 0b01110010, src = .Jump, desc = "Jump on not zero", }, { opname = .JBE, mask = 0b11111111, encoding = 0b01110110, src = .Jump, desc = "Jump on not zero", }, { opname = .JNA, mask = 0b11111111, encoding = 0b01110110, src = .Jump, desc = "Jump on not zero", }, { opname = .JP, mask = 0b11111111, encoding = 0b01111010, src = .Jump, desc = "Jump on not zero", }, { opname = .JPE, mask = 0b11111111, encoding = 0b01111010, src = .Jump, desc = "Jump on not zero", }, { opname = .JO, mask = 0b11111111, encoding = 0b01110000, src = .Jump, desc = "Jump on not zero", }, { opname = .JS, mask = 0b11111111, encoding = 0b01111000, src = .Jump, desc = "Jump on not zero", }, { opname = .JNE, mask = 0b11111111, encoding = 0b01110101, src = .Jump, desc = "Jump on not zero", }, { opname = .JNZ, mask = 0b11111111, encoding = 0b01110101, src = .Jump, desc = "Jump on not zero", }, { opname = .JNL, mask = 0b11111111, encoding = 0b01111101, src = .Jump, desc = "Jump on not zero", }, { opname = .JGE, mask = 0b11111111, encoding = 0b01111101, src = .Jump, desc = "Jump on not zero", }, { opname = .JNLE, mask = 0b11111111, encoding = 0b01111111, src = .Jump, desc = "Jump on not zero", }, { opname = .JG, mask = 0b11111111, encoding = 0b01111111, src = .Jump, desc = "Jump on not zero", }, { opname = .JNB, mask = 0b11111111, encoding = 0b01110011, src = .Jump, desc = "Jump on not zero", }, { opname = .JAE, mask = 0b11111111, encoding = 0b01110011, src = .Jump, desc = "Jump on not zero", }, { opname = .JNBE, mask = 0b11111111, encoding = 0b01110111, src = .Jump, desc = "Jump on not zero", }, { opname = .JA, mask = 0b11111111, encoding = 0b01110111, src = .Jump, desc = "Jump on not zero", }, { opname = .JNP, mask = 0b11111111, encoding = 0b01111011, src = .Jump, desc = "Jump on not zero", }, { opname = .JPO, mask = 0b11111111, encoding = 0b01111011, src = .Jump, desc = "Jump on not zero", }, { opname = .JNO, mask = 0b11111111, encoding = 0b01110001, src = .Jump, desc = "Jump on not zero", }, { opname = .JNS, mask = 0b11111111, encoding = 0b01111001, src = .Jump, desc = "Jump on not zero", }, { opname = .LOOP, mask = 0b11111111, encoding = 0b11100010, src = .Jump, desc = "Jump on not zero", }, { opname = .LOOPZ, mask = 0b11111111, encoding = 0b11100001, src = .Jump, desc = "Jump on not zero", }, { opname = .LOOPNZ, mask = 0b11111111, encoding = 0b11100000, src = .Jump, desc = "Jump on not zero", }, { opname = .JCXZ, mask = 0b11111111, encoding = 0b11100011, src = .Jump, desc = "Jump on not zero", }, }