There are no priviledge checks, so these instructions will all work in all
modes.
--HG--
extra : convert_revision : ff893eb569313d8aecbfffb47bcbd1c2d65cd393
Fixed the asz assembler symbol.
Adjusted the condion checks to have appropriate options.
Implemented the SCAS microcode.
Attached SCAS into the decoder.
--HG--
extra : convert_revision : 17bf9ddae6bc2069e43b076f8f83c4e54fb7966c
Make instructions observe segment prefixes, default segment rules, segment
base addresses.
Also fix some microcode and add sib and riprel "keywords" to the x86
specialization of the microassembler.
--HG--
extra : convert_revision : be5a3b33d33f243ed6e1ad63faea8495e46d0ac9
1. Microops are created. These are StaticInsts use templates to provide a basic form of polymorphism without having to make the microassembler smarter.
2. An instruction class is created which has a "templated" microcode program as it's docstring. The template parameters are refernced with ^ following by a number.
3. An instruction in the decoder references an instruction template using it's mnemonic. The parameters to it's format end up replacing the placeholders. These parameters describe a source for an operand which could be memory, a register, or an immediate. It it's a register, the register index is used. If it's memory, eventually a load/store will be pre/postpended to the instruction template and it's destination register will be used in place of the ^. If it's an immediate, the immediate is used. Some operand types, specifically those that come from the ModRM byte, need to be decoded further into memory vs. register versions. This is accomplished by making the decode_block text for these instructions another case statement based off ModRM.
4. Once all of the template parameters have been handled, the instruction goes throw the microcode assembler which resolves labels and creates a list of python op objects. If an operand is a register, it uses a % prefix, an immediate uses $, and a label uses @. If the operand is just letters, numbers, and underscores, it can appear immediately after the prefix. If it's not, it can be encolsed in non nested {}s.
5. If there is a single "op" object (which corresponds to a single microop) the decoder is set up to return it directly. If not, a macroop wrapper is created around it.
In the future, I'm considering seperating the operand type specialization from the template substitution step. A problem this introduces is that either the template arguments need to be kept around for the specialization step, or they need to be re-extracted. Re-extraction might be the way to go so that the operand formats can be coded directly into the micro assembler template without having to pass them in as parameters. I don't know if that's actually useful, though.
src/arch/x86/isa/decoder/one_byte_opcodes.isa:
src/arch/x86/isa/microasm.isa:
src/arch/x86/isa/microops/microops.isa:
src/arch/x86/isa/operands.isa:
src/arch/x86/isa/microops/base.isa:
Implemented polymorphic microops and changed around the microcode assembler syntax.
--HG--
extra : convert_revision : e341f7b8ea9350a31e586a3d33250137e5954f43
MicroOp: A single operation actually implemented in hardware.
MacroOp: A collection of microops which are executed as a unit.
Instruction: An architected instruction which can be implemented with a macroop or a microop.
--HG--
extra : convert_revision : 1cfc8409cc686c75220767839f55a30551aa6f13