diff options
| -rw-r--r-- | amd64.e | 429 |
1 files changed, 288 insertions, 141 deletions
diff --git a/amd64.e b/amd64.e index 04c4aa7..d2fa2cd 100644 --- a/amd64.e +++ b/amd64.e @@ -23,6 +23,53 @@ ~ TODO define instructions, assembly code, machine code, opcodes. if we ever ~ also want to recommend a childrens' introduction to binary, this might be ~ the place to do it. +~ +~ +~ Hex-transformed output +~ ~~~~~~~~~~~~~~~~~~~~~~ +~ +~ In addition to the actual semantics of the assembly words, there's an +~ important layer of meaning atop them. The hex transform, described in detail +~ in transform.e, modifies a compilation process to produce a commented hex +~ dump instead of a binary. It includes a magic-comment feature which allows +~ words that have opinions on what their output's hex dump should look like to +~ express them. +~ +~ The code in this file makes extensive use of the magic-comment feature. +~ Any comment which starts with : as its first word is a magic comment meant +~ for the hex transform. When the hex transform is not in use, these are +~ ordinary comments and are ignored. When it is in use, they create and modify +~ metadata annotations in a complex way. +~ +~ The magic comments in this file follows two important conventions: First, +~ entries are created by whichever word directly corresponds to a top-level +~ assembly instruction from the perspective of someone programming with it, +~ at some point prior to calling any word which might pack output. Second, +~ output bytes are accounted for by whichever word directly calls a pack* word +~ for them. +~ +~ Thus, for example, the word "syscall" has a comment which creates an entry +~ describing its length as 2 bytes, which never varies. +~ +~ The word "mov-reg64-imm32", on the other hand, has a comment which +~ creates an entry describing is length as 5 bytes - the opcode and the +~ immediate value, which are output with calls to pack8 and pack32 in that +~ word. However, the actual length of the instruction is 5 bytes. When +~ mov-reg64-imm32 calls rex-w, a magic comment there modifies the most recent +~ entry in-place, marking it as being one byte longer. Subsequently, +~ mov-reg64-imm32 calls addressing-reg64, which calls modrm, which again +~ modifies the same entry. Notice that addressing-reg64 didn't need to do +~ anything, because it isn't directly responsible for any packing. +~ +~ Notice that when an entry is modified in place, it needs to have been +~ created first. Attempting to do it in the wrong order will have an +~ undesired effect, most likely editing the entry of an unrelated instruction. +~ The hex transform doesn't have detailed knowledge of assembly, and isn't in +~ a position to know that the edits that are happening are sensible. +~ +~ Hopefully these examples show why an accounting convention is needed. The +~ good news is that the convention is quite robust and needs essentially no +~ play-by-play commentary, just this explainer at the top. ~ Keywords @@ -263,22 +310,54 @@ s" :cc-greater" keyword ~ don't have to revisit this topic. ~ ~ (output point -- output point) -: rex-0 0x40 pack8 ; -: rex-w 0x48 pack8 ; -: rex-r 0x44 pack8 ; -: rex-x 0x42 pack8 ; -: rex-b 0x41 pack8 ; -: rex-wr 0x4C pack8 ; -: rex-wx 0x4A pack8 ; -: rex-wb 0x49 pack8 ; -: rex-rx 0x46 pack8 ; -: rex-rb 0x45 pack8 ; -: rex-xb 0x43 pack8 ; -: rex-wrx 0x4E pack8 ; -: rex-wrb 0x4D pack8 ; -: rex-wxb 0x4B pack8 ; -: rex-rxb 0x47 pack8 ; -: rex-wrxb 0x4F pack8 ; +: rex-0 + ~ : 1 adjust-length + 0x40 pack8 ; +: rex-w + ~ : 1 adjust-length + 0x48 pack8 ; +: rex-r + ~ : 1 adjust-length + 0x44 pack8 ; +: rex-x + ~ : 1 adjust-length + 0x42 pack8 ; +: rex-b + ~ : 1 adjust-length + 0x41 pack8 ; +: rex-wr + ~ : 1 adjust-length + 0x4C pack8 ; +: rex-wx + ~ : 1 adjust-length + 0x4A pack8 ; +: rex-wb + ~ : 1 adjust-length + 0x49 pack8 ; +: rex-rx + ~ : 1 adjust-length + 0x46 pack8 ; +: rex-rb + ~ : 1 adjust-length + 0x45 pack8 ; +: rex-xb + ~ : 1 adjust-length + 0x43 pack8 ; +: rex-wrx + ~ : 1 adjust-length + 0x4E pack8 ; +: rex-wrb + ~ : 1 adjust-length + 0x4D pack8 ; +: rex-wxb + ~ : 1 adjust-length + 0x4B pack8 ; +: rex-rxb + ~ : 1 adjust-length + 0x47 pack8 ; +: rex-wrxb + ~ : 1 adjust-length + 0x4F pack8 ; ~ Some opcodes use their low three bits as a field to give a register name. @@ -293,7 +372,9 @@ s" :cc-greater" keyword ~ ~ (output point, 3-bit encoded value for register, opcode byte ~ -- output point) -: opcodereg | pack8 ; +: opcodereg + ~ : 1 adjust-length + | pack8 ; ~ Some opcodes use their low four bits as a field to give a condition code. @@ -304,7 +385,9 @@ s" :cc-greater" keyword ~ ~ (output point, 4-bit encoded value for condition code, opcode byte ~ -- output point) -: opcodecc | pack8 ; +: opcodecc + ~ : 1 adjust-length + | pack8 ; ~ A Mod/RM byte ("mode / register-or-memory") is part of the encoding of @@ -317,7 +400,9 @@ s" :cc-greater" keyword ~ ~ (output point, mod field, register/opcode field, register/memory field ~ -- output point) -: modrm swap 8 * | swap 64 * | pack8 ; +: modrm + ~ : 1 adjust-length + swap 8 * | swap 64 * | pack8 ; ~ An SIB byte ("scale, index, base") is part of the encoding of many ~ instructions. It's divided into three fields, with the names you've already @@ -327,7 +412,9 @@ s" :cc-greater" keyword ~ its fields. ~ ~ (output point, scale field, index field, base field -- output point) -: sib swap 8 * | swap 64 * | pack8 ; +: sib + ~ : 1 adjust-length + swap 8 * | swap 64 * | pack8 ; ~ Addressing modes @@ -419,6 +506,7 @@ s" :cc-greater" keyword ~ If the R/M register was rsp, we need an SIB byte; otherwise, skip it. 3roll { 0 4 :rsp reg64 sib } if ~ The displacement byte. + ~ : 1 adjust-length swap pack8 ; ~ (output point, reg/op field value, reg/mem field register, @@ -433,6 +521,7 @@ s" :cc-greater" keyword ~ If the R/M register was rsp, we need an SIB byte; otherwise, skip it. 3roll { 0 4 :rsp reg64 sib } if ~ The displacement value. + ~ : 4 adjust-length swap pack32 ; ~ (output point, reg/op field value, @@ -456,6 +545,7 @@ s" :cc-greater" keyword ~ Reg/mem value 4 means to use an SIB byte (at least, with this mode). 6 roll 1 7 roll 4 modrm 5 unroll 5 unroll reg64 3unroll reg64 3unroll scalefield 3unroll sib + ~ : 1 adjust-length swap pack8 ; @@ -466,47 +556,55 @@ s" :cc-greater" keyword ~ grouping. These are the ones that were easy to deal with. ~ (output point -- output point) -: cld ~ : cld +: cld + ~ : 1 cld 0xFC pack8 ; -: std ~ : std +: std + ~ : 1 std 0xFD pack8 ; -: syscall ~ : syscall +: syscall + ~ : 2 syscall 0x0F pack8 0x05 pack8 ; -: hlt ~ : hlt +: hlt + ~ : 1 hlt 0xF4 pack8 ; ~ (output point, source register -- output point) -: push-reg64 ~ : push-reg64 +: push-reg64 + ~ : 0 push-reg64 reg64 0x50 opcodereg ; -: push-extrareg64 ~ : push-extrareg64 +: push-extrareg64 + ~ : 0 push-extrareg64 swap rex-b swap extrareg64 0x50 opcodereg ; ~ Note the use of the B rex bit here; this instruction puts the register ~ number in the opcode field, so it uses Table 3-1. ~ (output point, target register -- output point) -: pop-reg64 ~ : pop-reg64 +: pop-reg64 + ~ : 1 pop-reg64 reg64 0x58 opcodereg ; -: pop-extrareg64 ~ : pop-extrareg64 +: pop-extrareg64 + ~ : 2 pop-extrareg64 swap rex-b swap extrareg64 0x58 opcodereg ; ~ Note the use of the B rex bit here; this instruction puts the register ~ number in the opcode field, so it uses Table 3-1. ~ (output point, immediate value -- output point) : push-imm32-extended64 - ~ : push-imm32-extended64 + ~ : 5 push-imm32-extended64 swap 0x68 pack8 swap pack32 ; ~ (output point, source register, source displacement value, target register ~ -- output point) : lea-reg64-disp8-reg64 - ~ : lea-reg64-disp8-reg64 + ~ : 1 lea-reg64-disp8-reg64 4 roll rex-w 0x8D pack8 4 unroll reg64 3unroll addressing-disp8-reg64 ; ~ (output point, source register, source displacement value, target register ~ -- output point) : lea-reg64-disp32-reg64 - ~ : lea-reg64-disp32-reg64 + ~ : 1 lea-reg64-disp32-reg64 4 roll rex-w 0x8D pack8 4 unroll reg64 3unroll addressing-disp32-reg64 ; @@ -514,7 +612,7 @@ s" :cc-greater" keyword ~ source base register, source index register, source index scale factor, ~ target register -- output point) : lea-reg64-indexed-reg64 - ~ : lea-reg64-indexed-reg64 + ~ : 1 lea-reg64-indexed-reg64 5 roll rex-w 0x8D pack8 5 unroll reg64 4 unroll 3unroll swap addressing-indexed-reg64 ; @@ -523,7 +621,7 @@ s" :cc-greater" keyword ~ source displacement value, ~ target register -- output point) : lea-reg64-disp8-indexed-reg64 - ~ : lea-reg64-disp8-indexed-reg64 + ~ : 1 lea-reg64-disp8-indexed-reg64 6 roll rex-w 0x8D pack8 6 unroll reg64 5 unroll 3 roll 4 roll 3 roll addressing-disp8-indexed-reg64 ; @@ -543,50 +641,51 @@ s" :cc-greater" keyword ~ (output point, immediate value, register -- output point) : mov-reg64-imm32 - ~ : mov-reg64-imm32 - 3roll rex-w 0xC7 pack8 swap + ~ : 5 mov-reg64-imm32 + 3roll + rex-w 0xC7 pack8 swap 0 swap addressing-reg64 swap pack32 ; : mov-reg64-imm64 - ~ : mov-reg64-imm64 + ~ : 8 mov-reg64-imm64 3roll rex-w swap reg64 0xB8 opcodereg swap pack64 ; : mov-extrareg64-imm64 - ~ : mov-extrareg64-imm64 + ~ : 8 mov-extrareg64-imm64 ~ Note the use of the B rex bit here; this instruction puts the register ~ number in the opcode field, so it uses Table 3-1. 3roll rex-wb swap extrareg64 0xB8 opcodereg swap pack64 ; ~ (output point, source register, target register -- output point) : mov-reg64-reg64 - ~ : mov-reg64-reg64 + ~ : 1 mov-reg64-reg64 3roll rex-w 0x89 pack8 3unroll swap reg64 swap addressing-reg64 ; : mov-indirect-reg64-reg64 - ~ : mov-indirect-reg64-reg64 + ~ : 1 mov-indirect-reg64-reg64 3roll rex-w 0x89 pack8 3unroll swap reg64 swap addressing-indirect-reg64 ; ~ (output point, source register, target register, target displacement value ~ -- output point) : mov-disp8-reg64-reg64 - ~ : mov-disp8-reg64-reg64 + ~ : 1 mov-disp8-reg64-reg64 4 roll rex-w 0x89 pack8 4 unroll 3roll reg64 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-reg64-indirect-reg64 - ~ : mov-reg64-indirect-reg64 + ~ : 1 mov-reg64-indirect-reg64 3roll rex-w 0x8B pack8 3unroll reg64 swap addressing-indirect-reg64 ; ~ (output point, source register, source displacement value, target register ~ -- output point) : mov-reg64-disp8-reg64 - ~ : mov-reg64-disp8-reg64 + ~ : 1 mov-reg64-disp8-reg64 4 roll rex-w 0x8B pack8 4 unroll reg64 3unroll addressing-disp8-reg64 ; : mov-reg64-disp32-reg64 - ~ : mov-reg64-disp32-reg64 + ~ : 1 mov-reg64-disp32-reg64 4 roll rex-w 0x89 pack8 4 unroll 3roll reg64 swap 3roll addressing-disp32-reg64 ; @@ -594,7 +693,7 @@ s" :cc-greater" keyword ~ source base register, source index register, source index scale factor, ~ target register -- output point) : mov-reg64-indexed-reg64 - ~ : mov-reg64-indexed-reg64 + ~ : 1 mov-reg64-indexed-reg64 5 roll rex-w 0x8B pack8 5 unroll reg64 4 unroll 3unroll swap addressing-indexed-reg64 ; @@ -602,92 +701,92 @@ s" :cc-greater" keyword ~ target base register, target index register, target index scale factor ~ -- output point) : mov-indexed-reg64-reg64 - ~ : mov-indexed-reg64-reg64 + ~ : 1 mov-indexed-reg64-reg64 5 roll rex-w 0x89 pack8 5 unroll 4 roll reg64 4 unroll 3unroll swap addressing-indexed-reg64 ; ~ (output point, source register, target register -- output point) : mov-indirect-reg64-reg32 - ~ : mov-indirect-reg64-reg32 + ~ : 1 mov-indirect-reg64-reg32 3roll 0x89 pack8 3unroll swap reg32 swap addressing-indirect-reg64 ; -~ (output point, source regisgter, target register, target displacement value +~ (output point, source register, target register, target displacement value ~ -- output point) : mov-disp8-reg64-reg32 - ~ : mov-disp8-reg64-reg32 + ~ : 1 mov-disp8-reg64-reg32 4 roll 0x89 pack8 4 unroll 3roll reg32 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-reg32-indirect-reg64 - ~ : mov-reg32-indirect-reg64 + ~ : 1 mov-reg32-indirect-reg64 3roll 0x8B pack8 3unroll reg32 swap addressing-indirect-reg64 ; ~ (output point, source register, source displacement value, target register ~ -- output point) : mov-reg32-disp8-reg64 - ~ : mov-reg32-disp8-reg64 + ~ : 1 mov-reg32-disp8-reg64 4 roll 0x8B pack8 4 unroll reg32 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-indirect-reg64-reg16 - ~ : mov-indirect-reg64-reg16 + ~ : 2 mov-indirect-reg64-reg16 3roll 0x66 pack8 0x89 pack8 3unroll swap reg16 swap addressing-indirect-reg64 ; ~ (output point, source register, target register, target displacement value ~ -- output point) : mov-disp8-reg64-reg16 - ~ : mov-disp8-reg64-reg16 + ~ : 2 mov-disp8-reg64-reg16 4 roll 0x66 pack8 0x89 pack8 4 unroll 3roll reg16 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-reg16-indirect-reg64 - ~ : mov-reg16-indirect-reg64 + ~ : 2 mov-reg16-indirect-reg64 3roll 0x66 pack8 0x8B pack8 3unroll reg16 swap addressing-indirect-reg64 ; ~ (output point, source register, target displacement value, target register ~ -- output point) : mov-reg16-disp8-reg64 - ~ : mov-reg16-disp8-reg64 + ~ : 2 mov-reg16-disp8-reg64 4 roll 0x66 pack8 0x8B pack8 4 unroll reg16 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-indirect-reg64-reg8 - ~ : mov-indirect-reg64-reg8 + ~ : 1 mov-indirect-reg64-reg8 3roll 0x88 pack8 3unroll swap reg8 swap addressing-indirect-reg64 ; ~ (output point, source register, target register, target displacement value ~ -- output point) : mov-disp8-reg64-reg8 - ~ : mov-disp8-reg64-reg8 + ~ : 1 mov-disp8-reg64-reg8 4 roll 0x88 pack8 4 unroll 3roll reg8 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-reg8-indirect-reg64 - ~ : mov-reg8-indirect-reg64 + ~ : 1 mov-reg8-indirect-reg64 3roll 0x8A pack8 3unroll reg8 swap addressing-indirect-reg64 ; ~ (output point, source register, source displacement value, target register ~ -- output point) : mov-reg8-disp8-reg64 - ~ : mov-reg8-disp8-reg64 + ~ : 2 mov-reg8-disp8-reg64 4 roll pack8 0x8A pack8 4 unroll reg8 3unroll addressing-disp8-reg64 ; ~ (output point, source register, target register -- output point) : mov-reg8-reg8 - ~ : mov-reg8-reg8 + ~ : 1 mov-reg8-reg8 3roll 0x88 pack8 3unroll swap reg8 swap addressing-reg8 ; @@ -722,109 +821,157 @@ s" :cc-greater" keyword ~ here... ~ (output point -- output point) -: movs8 ~ : movs8 +: movs8 + ~ : 1 movs8 0xA4 pack8 ; -: movs16 ~ : movs16 +: movs16 + ~ : 2 movs16 0x66 pack8 0xA5 pack8 ; -: movs32 ~ : movs32 +: movs32 + ~ : 1 movs32 0xA5 pack8 ; -: movs64 ~ : movs64 +: movs64 + ~ : 1 movs64 rex-w 0xA5 pack8 ; -: rep-movs8 ~ : rep-movs8 +: rep-movs8 + ~ : 2 rep-movs8 0xF3 pack8 0xA4 pack8 ; -: rep-movs16 ~ : rep-movs16 +: rep-movs16 + ~ : 3 rep-movs16 0xF3 pack8 0x66 pack8 0xA5 pack8 ; -: rep-movs32 ~ : rep-movs32 +: rep-movs32 + ~ : 2 rep-movs32 0xF3 pack8 0xA5 pack8 ; -: rep-movs64 ~ : rep-movs64 +: rep-movs64 + ~ : 2 rep-movs64 0xF3 pack8 rex-w 0xA5 pack8 ; ~ (output point -- output point) -: lods8 ~ : lods8 +: lods8 + ~ : 1 lods8 0xAC pack8 ; -: lods16 ~ : lods16 +: lods16 + ~ : 2 lods16 0x66 pack8 0xAd pack8 ; -: lods32 ~ : lods32 +: lods32 + ~ : 1 lods32 0xAD pack8 ; -: lods64 ~ : lods64 +: lods64 + ~ : 1 lods64 rex-w 0xAD pack8 ; -: rep-lods8 ~ : rep-lods8 +: rep-lods8 + ~ : 2 rep-lods8 0xF3 pack8 0xAC pack8 ; -: rep-lods16 ~ : rep-lods16 +: rep-lods16 + ~ : 3 rep-lods16 0xF3 pack8 0x66 pack8 0xAD pack8 ; -: rep-lods32 ~ : rep-lods32 +: rep-lods32 + ~ : 2 rep-lods32 0xF3 pack8 0xAD pack8 ; -: rep-lods64 ~ : rep-lods64 +: rep-lods64 + ~ : 2 rep-lods64 0xF3 pack8 rex-w 0xAD pack8 ; ~ (output point -- output point) -: stos8 ~ : stos8 +: stos8 + ~ : 1 stos8 0xAA pack8 ; -: stos16 ~ : stos16 +: stos16 + ~ : 2 stos16 0x66 pack8 0xAB pack8 ; -: stos32 ~ : stos32 +: stos32 + ~ : 1 stos32 0xAB pack8 ; -: stos64 ~ : stos64 +: stos64 + ~ : 1 stos64 rex-w 0xAB pack8 ; -: rep-stos8 ~ : rep-stos8 +: rep-stos8 + ~ : 2 rep-stos8 0xF3 pack8 0xAA pack8 ; -: rep-stos16 ~ : rep-stos16 +: rep-stos16 + ~ : 3 rep-stos16 0xF3 pack8 0x66 pack8 0xAB pack8 ; -: rep-stos32 ~ : rep-stos32 +: rep-stos32 + ~ : 2 rep-stos32 0xF3 pack8 0xAB pack8 ; -: rep-stos64 ~ : rep-stos64 +: rep-stos64 + ~ : 2 rep-stos64 0xF3 pack8 rex-w 0xAB pack8 ; ~ (output point -- output point) -: cmps8 ~ : cmps8 +: cmps8 + ~ : 1 cmps8 0xA6 pack8 ; -: cmps16 ~ : cmps16 +: cmps16 + ~ : 2 cmps16 0x66 pack8 0xA7 pack8 ; -: cmps32 ~ : cmps32 +: cmps32 + ~ : 1 cmps32 0xA7 pack8 ; -: cmps64 ~ : cmps64 +: cmps64 + ~ : 1 cmps64 rex-w 0xA7 pack8 ; -: repz-cmps8 ~ : repz-cmps8 +: repz-cmps8 + ~ : 2 repz-cmps8 0xF3 pack8 0xA6 pack8 ; -: repz-cmps16 ~ : repz-cmps16 +: repz-cmps16 + ~ : 3 repz-cmps16 0xF3 pack8 0x66 pack8 0xA7 pack8 ; -: repz-cmps32 ~ : repz-cmps32 +: repz-cmps32 + ~ : 2 repz-cmps32 0xF3 pack8 0xA7 pack8 ; -: repz-cmps64 ~ : repz-cmps64 +: repz-cmps64 + ~ : 2 repz-cmps64 0xF3 pack8 rex-w 0xA7 pack8 ; -: repnz-cmps8 ~ : repnz-cmps8 +: repnz-cmps8 + ~ : 2 repnz-cmps8 0xF2 pack8 0xA6 pack8 ; -: repnz-cmps16 ~ : repnz-cmps16 +: repnz-cmps16 + ~ : 3 repnz-cmps16 0xF2 pack8 0x66 pack8 0xA7 pack8 ; -: repnz-cmps32 ~ : repnz-cmps32 +: repnz-cmps32 + ~ : 2 repnz-cmps32 0xF2 pack8 0xA7 pack8 ; -: repnz-cmps64 ~ : repnz-cmps64 +: repnz-cmps64 + ~ : 2 repnz-cmps64 0xF2 pack8 rex-w 0xA7 pack8 ; ~ (output point -- output point) -: scas8 ~ : scas8 +: scas8 + ~ : 1 scas8 0xA8 pack8 ; -: scas16 ~ : scas16 +: scas16 + ~ : 2 scas16 0x66 pack8 0xAF pack8 ; -: scas32 ~ : scas32 +: scas32 + ~ : 1 scas32 0xAF pack8 ; -: scas64 ~ : scas64 +: scas64 + ~ : 1 scas64 rex-w 0xAF pack8 ; -: repz-scas8 ~ : repz-scas8 +: repz-scas8 + ~ : 2 repz-scas8 0xF3 pack8 0xAE pack8 ; -: repz-scas16 ~ : repz-scas16 +: repz-scas16 + ~ : 3 repz-scas16 0xF3 pack8 0x66 pack8 0xAF pack8 ; -: repz-scas32 ~ : repz-scas32 +: repz-scas32 + ~ : 2 repz-scas32 0xF3 pack8 0xAF pack8 ; -: repz-scas64 ~ : repz-scas64 +: repz-scas64 + ~ : 2 repz-scas64 0xF3 pack8 rex-w 0xAF pack8 ; -: repnz-scas8 ~ : repnz-scas8 +: repnz-scas8 + ~ : 2 repnz-scas8 0xF2 pack8 0xAE pack8 ; -: repnz-scas16 ~ : repnz-scas16 +: repnz-scas16 + ~ : 3 repnz-scas16 0xF2 pack8 0x66 pack8 0xAF pack8 ; -: repnz-scas32 ~ : repnz-scas32 +: repnz-scas32 + ~ : 2 repnz-scas32 0xF2 pack8 0xAF pack8 ; -: repnz-scas64 ~ : repnz-scas64 +: repnz-scas64 + ~ : 2 repnz-scas64 0xF2 pack8 rex-w 0xAF pack8 ; @@ -843,25 +990,25 @@ s" :cc-greater" keyword ~ (output point, source register, target register -- output point) : add-reg64-reg64 - ~ : add-reg64-reg64 + ~ : 1 add-reg64-reg64 3roll rex-w 0x01 pack8 3unroll swap reg64 swap addressing-reg64 ; ~ (output point, source register, target register -- output point) : add-indirect-reg64-reg64 - ~ : add-indirect-reg64-reg64 + ~ : 1 add-indirect-reg64-reg64 3roll rex-w 0x01 pack8 3unroll swap reg64 swap addressing-indirect-reg64 ; ~ (output point, source register, target register -- output point) : add-reg64-indirect-reg64 - ~ : add-reg64-indirect-reg64 + ~ : 1 add-reg64-indirect-reg64 3roll rex-w 0x03 pack8 3unroll reg64 swap addressing-indirect-reg64 ; ~ (output point, immediate value, target register -- output point) : add-reg64-imm8 - ~ : add-reg64-imm8 + ~ : 2 add-reg64-imm8 3roll rex-w 0x83 pack8 swap 0 swap addressing-reg64 swap pack8 ; @@ -869,13 +1016,13 @@ s" :cc-greater" keyword ~ ~ (output point, source register, target register -- output point) : sub-reg64-reg64 - ~ : sub-reg64-reg64 + ~ : 1 sub-reg64-reg64 3roll rex-w 0x2B pack8 3unroll reg64 swap addressing-reg64 ; ~ (output point, source register, target register -- output point) : sub-indirect-reg64-reg64 - ~ : sub-indirect-reg64-reg64 + ~ : 1 sub-indirect-reg64-reg64 3roll rex-w 0x2B pack8 3unroll swap reg64 swap addressing-indirect-reg64 ; @@ -883,7 +1030,7 @@ s" :cc-greater" keyword ~ ~ (output point, immediate value, target register -- output point) : sub-reg64-imm8 - ~ : sub-reg64-imm8 + ~ : 2 sub-reg64-imm8 3roll rex-w 0x83 pack8 swap 5 swap addressing-reg64 swap pack8 ; @@ -891,7 +1038,7 @@ s" :cc-greater" keyword ~ ~ (output point, source register, target register -- output point) : sbb-reg64-imm8 - ~ : sbb-reg64-imm8 + ~ : 2 sbb-reg64-imm8 3roll rex-w 0x83 pack8 swap 3 swap addressing-reg64 swap pack8 ; @@ -899,7 +1046,7 @@ s" :cc-greater" keyword ~ ~ (output point, source register -- output point) : mul-reg64 - ~ : mul-reg64 + ~ : 1 mul-reg64 swap rex-w 0xF7 pack8 swap 4 swap addressing-reg64 ; @@ -912,7 +1059,7 @@ s" :cc-greater" keyword ~ ~ (output point, divisor register -- output point) : divmod-reg64 - ~ : divmod-reg64 + ~ : 1 divmod-reg64 swap rex-w 0xF7 pack8 swap 6 swap addressing-reg64 ; @@ -920,82 +1067,82 @@ s" :cc-greater" keyword ~ ~ (output point, divisor register -- output point) : idivmod-reg64 - ~ : idivmod-reg64 + ~ : 1 idivmod-reg64 swap rex-w 0xF7 pack8 swap 7 swap addressing-reg64 ; ~ (output point, target register -- output point) : inc-reg64 - ~ : inc-reg64 + ~ : 1 inc-reg64 swap rex-w 0xFF pack8 swap 0 swap addressing-reg64 ; ~ (output point, target register -- output point) : dec-reg64 - ~ : dec-reg64 + ~ : 1 dec-reg64 swap rex-w 0xFF pack8 swap 1 swap addressing-reg64 ; ~ (output point, source register, target register -- output point) : and-reg64-reg64 - ~ : and-reg64-reg64 + ~ : 1 and-reg64-reg64 3roll rex-w 0x23 pack8 3unroll reg64 swap addressing-reg64 ; ~ (output point, source value, target register -- output point) : and-reg64-imm8 - ~ : and-reg64-imm8 + ~ : 2 and-reg64-imm8 3roll rex-w 0x83 pack8 swap 4 swap addressing-reg64 swap pack8 ; ~ (output point, source register, target register -- output point) : or-reg64-reg64 - ~ : or-reg64-reg64 + ~ : 1 or-reg64-reg64 3roll rex-w 0x0B pack8 3unroll reg64 swap addressing-reg64 ; ~ (output point, source value, target register -- output point) : or-reg64-imm8 - ~ : or-reg64-imm8 + ~ : 2 or-reg64-imm8 3roll rex-w 0x83 pack8 swap 1 swap addressing-reg64 swap pack8 ; ~ (output point, source register, target register -- output point) : xor-reg64-reg64 - ~ : xor-reg64-reg64 + ~ : 1 xor-reg64-reg64 3roll rex-w 0x33 pack8 3unroll reg64 swap addressing-reg64 ; ~ (output point, target register -- output point) : not-reg64 - ~ : not-reg64 + ~ : 1 not-reg64 swap rex-w 0xF7 pack8 swap 2 swap addressing-reg64 ; ~ (output point, bit count, target register -- output point) : rol-reg64-imm8 - ~ : rol-reg64-imm8 + ~ : 2 rol-reg64-imm8 3roll rex-w 0xC1 pack8 swap 0 swap addressing-reg64 swap pack8 ; ~ (output point, bit count, target register -- output point) : rol-reg8-imm8 - ~ : rol-reg8-imm8 + ~ : 2 rol-reg8-imm8 3roll 0xC0 pack8 swap 0 swap addressing-reg8 swap pack8 ; ~ (output point, bit count, target register -- output point) : ror-reg64-imm8 - ~ : ror-reg64-imm8 + ~ : 1 ror-reg64-imm8 3roll rex-w 0xC1 swap 1 swap addressing-reg64 swap pack8 ; ~ (output point, bit count, target register -- output point) : ror-reg8-imm8 - ~ : ror-reg8-imm8 + ~ : 2 ror-reg8-imm8 3roll 0xC0 pack8 swap 1 swap addressing-reg64 swap pack8 ; @@ -1013,7 +1160,7 @@ s" :cc-greater" keyword ~ ~ (output point, left register, right register -- output point) : cmp-reg64-reg64 - ~ : cmp-reg64-reg64 + ~ : 1 cmp-reg64-reg64 3roll rex-w 0x3B pack8 3unroll reg64 swap addressing-reg64 ; @@ -1021,7 +1168,7 @@ s" :cc-greater" keyword ~ ~ (output point, immediate value, target register -- output point) : cmp-reg64-imm8 - ~ : cmp-reg64-imm8 + ~ : 2 cmp-reg64-imm8 3roll rex-w 0x83 pack8 ~ (immediate value, register, output point) swap 7 swap addressing-reg64 @@ -1037,45 +1184,45 @@ s" :cc-greater" keyword ~ ~ (output point, left register, right register -- output point) : test-reg64-reg64 - ~ : test-reg64-reg64 + ~ : 1 test-reg64-reg64 3roll rex-w 0x85 pack8 3unroll swap reg64 swap addressing-reg64 ; ~ (output point, condition code, target register -- output point) : set-reg8-cc - ~ : set-reg8-cc + ~ : 1 set-reg8-cc 3roll 0x0F pack8 3roll condition-code 0x90 opcodecc swap reg8 3 0 3roll modrm ; ~ (output point, address offset value, condition code -- output point) : jmp-cc-rel-imm8 - ~ : jmp-cc-rel-imm8 + ~ : 1 jmp-cc-rel-imm8 3roll swap condition-code 0x70 opcodecc swap pack8 ; ~ (output point, address offset value, condition code -- output point) : jmp-cc-rel-imm32 - ~ : jmp-cc-rel-imm32 + ~ : 5 jmp-cc-rel-imm32 3unroll 0x0F pack8 swap condition-code 0x70 opcodecc swap pack32 ; ~ (output point, register -- output point) : jmp-abs-indirect-reg64 - ~ : jmp-abs-indirect-reg64 + ~ : 1 jmp-abs-indirect-reg64 swap 0xFF pack8 swap 4 swap addressing-indirect-reg64 ; ~ (output point, address offset value -- output point) : jmp-rel-imm8 - ~ : jmp-rel-imm8 + ~ : 2 jmp-rel-imm8 swap 0xEB pack8 swap pack8 ; ~ (output point, address offset value -- output point) : jmp-rel-imm32 - ~ : jmp-rel-imm32 + ~ : 5 jmp-rel-imm32 swap 0xE9 pack8 swap pack32 ; @@ -1083,7 +1230,7 @@ s" :cc-greater" keyword ~ ~ (output point, address offset value -- output point) : call-rel-imm32 - ~ : call-rel-imm32 + ~ : 5 call-rel-imm32 swap 0xE8 pack8 swap pack32 ; @@ -1091,6 +1238,6 @@ s" :cc-greater" keyword ~ ~ (output point) : ret - ~ : ret + ~ : 1 ret 0xC3 pack8 ; |