ISA’s instructions are declared specifying it’s arguments and machine code format. The syntax is:
inst <name>[<size>](<arglist>) {
<instruction-specification>
}
<name>
should start with a letter followed by any
combination of [a-z][A-Z][0-9]_
characters.<size>
is the size in bits of the
instruction.<arglist>
is a command separated list of
arguments that the instructions expects.<instruction-specification>
is a comma separated
list of bitfields in the instruction.bitfield Reg[4]
bitfield Opcode[8] {
imm[1]
op[7]
}
register r0[32] = Reg{0}
register r1[32] = Reg{1}
...
register r15[32] = Reg{15}
inst mov[16](arg1: register[32], arg2: register[32]) {
opcode = Opcode {
imm = 0b0,
op = 0x1a,
},
reg1 = Reg{arg1},
reg2 = Reg{arg2},
}
This specify an instruction named mov
, 16 bits size,
that expects two 32 bit registers as arguments. On the assembly
perspective, this instruction looks like:
mov <reg32>, <reg32>
The machine code format is specified on the body of the instruction,
where it’s uses a sequence of one Opcode
bitfield and two
Reg
bitfields. Having the format like:
15 14 13 12 11 10 09 08 | 07 06 05 04 03 02 01 00
-- -- -- -- -- -- -- -- | -- -- -- -- -- -- -- --
| | | | | | |
| | | | | | |
| +--- op == 0x1a ---+ | | reg2 == arg2
+-- imm == 0 reg1 == arg1
Example:
Assembly: mov r2, r10
Hex machine code: 1a 2a
Bin machine code: 00011010 00101010