Last active
October 16, 2019 09:18
-
-
Save eira-fransham/7c8d80ca6ed7c5289b7481056097c81e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Unless otherwise specified, all the different input/output bit sizes are needed. You might be able to write helpers to | |
-- make this easier. | |
adc | |
add | |
-- I'm sure you know this but just to make 100% certain: all of the `***ss`/`***sd` instructions operate on IEEE754 | |
-- floats and so need to use separate Low IR actions to the integer operations. Futhermore, `div` has signed and unsigned | |
-- integer variants, plus single- and double-precision float variants. So that might look like `DivIntS(NumBits)`, | |
-- `DivIntU(NumBits)` and `DivFloat(FloatSize)` where `FloatSize` is an enum of `Single`,`Double`. | |
addsd | |
addss | |
and | |
andpd | |
andps | |
-- These two might not need their own instruction definitions, we could just have a fallback encoding for `lzcnt`/`tzcnt` | |
-- that emits a stream of instructions using them. | |
bsf | |
bsr | |
-- TODO: To start with we can just have unique "call" and "ret" actions, but we might find it useful in the future to | |
-- explicitly write out that `call` writes `rip` to stack, increases the stack pointer and then does the jump. | |
-- F.E., we could imagine that TCE could be implemented by the backend simply noticing that the pushed RIP isn't | |
-- needed after the call and so realising that it can just emit a `jmp` (although Lightbeam currently isn't | |
-- sophisticated enough to have any way of knowing if the pushed RIP is used after the call) | |
call | |
-- You want to have an action `MovIf`, then one instruction definition per size that takes the condition code as a parameter | |
cmovcc | |
-- This should be defined exactly the same as `sub`, just without access to the result of the subtraction, since that's what | |
-- it does and defining it this way allows us to be smarter WRT DCE | |
cmp | |
comisd | |
comiss | |
-- These should all be their own unique actions | |
cvtsd2ss | |
cvtss2sd | |
cvttsd2si | |
cvttss2si | |
-- TODO: Make this its own action for now, although if we ever support storing values across multiple registers this could | |
-- be modelled as a signed `mov` from a single-register 32-bit value to a 64-bit value stored in 2 32-bit registers. | |
-- This has upsides w.r.t. making dealing with instructions that split their input across registers simpler (x64 only | |
-- has a couple but other architectures have way, way more). I don't want to try implementing this now just because it | |
-- might mean that we have to work out some way to encode the fact that an unsigned single-register->register-pair | |
-- mov is the same as zeroing one of the pair of registers - either by adding dummy synonym instruction definitions | |
-- or by adding special code to LIRC. | |
cdq | |
-- Don't try to model this as "2-argument div but one of the arguments is stored in multiple registers" - just give it 3 | |
-- params, 2 of which are specific registers, | |
div | |
divss | |
divsd | |
idiv | |
-- For 32-bit inputs this produces a 64-bit value across 2 registers, for 64-bit inputs it produces a 128-bit value across | |
-- 2 registers, etc. Just have two actions, `Mul32Low` and `Mul32Hi`, and have this instruction do both. | |
imul | |
-- With the jump instructions we have to deal with the fact that we don't know the distance of the label when emitting the | |
-- instruction, since it's emitted with a dummy parameter which is later overwritten using relocations. While `asmquery` | |
-- doesn't need to deal with relocations at all, it _does_ need to have some way to specify whether the jump is a `rel8`, a | |
-- `rel16` or a `rel32`. | |
-- Additionally, we don't have types in `asmquery`, but it's useful to at least keep input/output bit sizes consistent for | |
-- instructions, and so for `jcxz`/`jecxz` we would want to model it as an `IsZero` against `cx`/`ecx` followed by `JumpIf` | |
-- using the result of the `IsZero`, instead of `JumpIf` with a `cx`/`ecx` param. | |
jcc | |
jmp | |
lea | |
maxsd | |
maxss | |
minsd | |
minss | |
-- This will map to different actions depending on whether it's reg-reg or reg-mem/mem-reg. The memory variants will use | |
-- `Load`/`Store` whereas `reg-reg` will use `Move`. | |
mov | |
movapd | |
movaps | |
movd | |
movq | |
movsx | |
movzx | |
mul | |
mulsd | |
mulss | |
not | |
or | |
orpd | |
orps | |
-- This should be modelled as two separate actions, `Store` to `rsp` and `rsp += 1`, instead of a single `Pop` action | |
pop | |
push | |
ret | |
sal/sar/shl/shr | |
setcc | |
sqrtsd | |
sqrtss | |
sub | |
subsd | |
subss | |
-- As with `cmp`, this should be exactly the same as `and` but with the result of the `and` being internal | |
test | |
ud2 | |
xor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment