|
| 1 | +use crate::dsl::{Feature::*, Inst, Location::*}; |
| 2 | +use crate::dsl::{align, fmt, inst, r, rex, rw, w}; |
| 3 | + |
| 4 | +#[rustfmt::skip] // Keeps instructions on a single line. |
| 5 | +pub fn list() -> Vec<Inst> { |
| 6 | + vec![ |
| 7 | + inst("movd", fmt("A", [w(xmm1), r(rm32)]), rex([0x66, 0x0F, 0x6E]).r(), _64b | compat | sse2), |
| 8 | + inst("movq", fmt("A", [w(xmm1), r(rm64)]), rex([0x66, 0x0F, 0x6E]).r().w(), _64b | sse2), |
| 9 | + inst("movd", fmt("B", [w(rm32), r(xmm2)]), rex([0x66, 0x0F, 0x7E]).r(), _64b | compat | sse2), |
| 10 | + inst("movq", fmt("B", [w(rm64), r(xmm2)]), rex([0x66, 0x0F, 0x7E]).r().w(), _64b | sse2), |
| 11 | + |
| 12 | + // Note that `movss` and `movsd` only have an "A" and "C" modes listed |
| 13 | + // in the Intel manual but here they're split into "*_M" and "*_R" to |
| 14 | + // model the different regalloc behavior each one has. Notably the |
| 15 | + // memory-using variant does the usual read or write the memory |
| 16 | + // depending on the instruction, but the "*_R" variant both reads and |
| 17 | + // writes the destination register because the upper bits are preserved. |
| 18 | + // |
| 19 | + // Additionally "C_R" is not specified here since it's not needed over |
| 20 | + // the "A_R" variant and it's additionally not encoded correctly as the |
| 21 | + // destination must be modeled in the ModRM:r/m byte, not the ModRM:reg |
| 22 | + // byte. Currently our encoding based on format doesn't account for this |
| 23 | + // special case, so it's just dropped here. |
| 24 | + inst("movss", fmt("A_M", [w(xmm1), r(m32)]), rex([0xF3, 0x0F, 0x10]).r(), _64b | sse), |
| 25 | + inst("movss", fmt("A_R", [rw(xmm1), r(xmm2)]), rex([0xF3, 0x0F, 0x10]).r(), _64b | sse), |
| 26 | + inst("movss", fmt("C_M", [w(m64), r(xmm1)]), rex([0xF3, 0x0F, 0x11]).r(), _64b | sse), |
| 27 | + inst("movsd", fmt("A_M", [w(xmm1), r(m32)]), rex([0xF2, 0x0F, 0x10]).r(), _64b | sse2), |
| 28 | + inst("movsd", fmt("A_R", [rw(xmm1), r(xmm2)]), rex([0xF2, 0x0F, 0x10]).r(), _64b | sse2), |
| 29 | + inst("movsd", fmt("C_M", [w(m64), r(xmm1)]), rex([0xF2, 0x0F, 0x11]).r(), _64b | sse2), |
| 30 | + |
| 31 | + inst("movapd", fmt("A", [w(xmm1), r(align(xmm_m128))]), rex([0x66, 0x0F, 0x28]).r(), _64b | sse2), |
| 32 | + inst("movapd", fmt("B", [w(align(xmm_m128)), r(xmm1)]), rex([0x66, 0x0F, 0x29]).r(), _64b | sse2), |
| 33 | + inst("movaps", fmt("A", [w(xmm1), r(align(xmm_m128))]), rex([0x0F, 0x28]).r(), _64b | sse), |
| 34 | + inst("movaps", fmt("B", [w(align(xmm_m128)), r(xmm1)]), rex([0x0F, 0x29]).r(), _64b | sse), |
| 35 | + inst("movupd", fmt("A", [w(xmm1), r(xmm_m128)]), rex([0x66, 0x0F, 0x10]).r(), _64b | sse2), |
| 36 | + inst("movupd", fmt("B", [w(xmm_m128), r(xmm1)]), rex([0x66, 0x0F, 0x11]).r(), _64b | sse2), |
| 37 | + inst("movups", fmt("A", [w(xmm1), r(xmm_m128)]), rex([0x0F, 0x10]).r(), _64b | sse), |
| 38 | + inst("movups", fmt("B", [w(xmm_m128), r(xmm1)]), rex([0x0F, 0x11]).r(), _64b | sse), |
| 39 | + inst("movdqa", fmt("A", [w(xmm1), r(align(xmm_m128))]), rex([0x66, 0x0F, 0x6F]).r(), _64b | sse2), |
| 40 | + inst("movdqa", fmt("B", [w(align(xmm_m128)), r(xmm1)]), rex([0x66, 0x0F, 0x7F]).r(), _64b | sse2), |
| 41 | + inst("movdqu", fmt("A", [w(xmm1), r(xmm_m128)]), rex([0xF3, 0x0F, 0x6F]).r(), _64b | sse2), |
| 42 | + inst("movdqu", fmt("B", [w(xmm_m128), r(xmm1)]), rex([0xF3, 0x0F, 0x7F]).r(), _64b | sse2), |
| 43 | + ] |
| 44 | +} |
0 commit comments