Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public final class InstructionChecker {
Map.entry(Opcode.VPCMPEQQ, List.of(RX_RX_M128)),
Map.entry(Opcode.VPCMPNEQB, List.of(RK_RY_RY, RK_RY_M256)),
Map.entry(Opcode.VZEROALL, List.of(NO_ARGS)),
Map.entry(Opcode.VMOVQ, List.of(R64_RX, RX_M64, M64_RX)),
Map.entry(Opcode.VMOVQ, List.of(R64_RX, RX_RX, RX_M64, M64_RX)),
Map.entry(Opcode.VMOVD, List.of(RX_M32)),
Map.entry(Opcode.PCMPISTRI, List.of(RX_RX_I8, RX_M128_I8)),
Map.entry(Opcode.PUNPCKLBW, List.of(RX_RX)),
Expand Down
54 changes: 36 additions & 18 deletions id/src/main/java/com/ledmington/cpu/InstructionDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3779,9 +3779,12 @@ private static Instruction parseVex2Opcodes(
yield Instruction.builder()
.opcode(Opcode.VMOVQ)
.op(RegisterXMM.fromByte(getByteFromReg(vex2, modrm)))
.op(parseIndirectOperand(b, pref, modrm)
.pointer(PointerSize.QWORD_PTR)
.build())
.op(
isIndirectOperandNeeded(modrm)
? parseIndirectOperand(b, pref, modrm)
.pointer(PointerSize.QWORD_PTR)
.build()
: RegisterXMM.fromByte(getByteFromRM(pref, modrm)))
.build();
}
case VMOVQ_M64_RXMM_OPCODE -> {
Expand Down Expand Up @@ -3896,10 +3899,17 @@ private static Instruction parseVex3Opcodes(
return switch (opcodeFirstByte) {
case VMOVQ_OPCODE -> {
final ModRM modrm = modrm(b);
final byte r1 = getByteFromRM(vex3, modrm);
final byte r2 = or(vex3.x() ? 0 : (byte) 0b00010000, getByteFromReg(vex3, modrm));
yield Instruction.builder()
.opcode(Opcode.VMOVQ)
.op(Register64.fromByte(getByteFromRM(vex3, modrm)))
.op(RegisterXMM.fromByte(getByteFromReg(vex3, modrm)))
.op(vex3.x() ? Register64.fromByte(r1) : RegisterXMM.fromByte(r1))
.op(
isIndirectOperandNeeded(modrm)
? parseIndirectOperand(b, pref, modrm)
.pointer(PointerSize.XMMWORD_PTR)
.build()
: (RegisterXMM.fromByte(r2)))
.build();
}
case KMOVQ_RK_R64_OPCODE -> {
Expand Down Expand Up @@ -4114,12 +4124,12 @@ private static Instruction parseEvexOpcodes(
final byte VPMINUD_OPCODE = (byte) 0x3b;
final byte VPCMPNEQUB_OPCODE = (byte) 0x3e;
final byte VPCMPxxB_OPCODE = (byte) 0x3f;
final byte VMOVQ_RX_M128_OPCODE = (byte) 0x6e;
final byte VMOVQ_R_M_OPCODE = (byte) 0x6e;
final byte VMOVDQU64_RZMM_M512_OPCODE = (byte) 0x6f;
final byte VPCMPEQB_OPCODE = (byte) 0x74;
final byte VPBROADCASTB_OPCODE = (byte) 0x7a;
final byte VPBROADCASTD_OPCODE = (byte) 0x7c;
final byte VMOVQ_R64_RX_OPCODE = (byte) 0x7e;
final byte VMOVQ_R_R_OPCODE = (byte) 0x7e;
final byte VMOVDQU64_M512_RZMM_OPCODE = (byte) 0x7f;
final byte VPMINUB_OPCODE = (byte) 0xda;
final byte VMOVNTDQ_OPCODE = (byte) 0xe7;
Expand Down Expand Up @@ -4219,21 +4229,29 @@ private static Instruction parseEvexOpcodes(
.op(RegisterZMM.fromByte(getByteFromReg(evex, modrm)))
.build();
}
case VMOVQ_R64_RX_OPCODE -> {
case VMOVQ_R_R_OPCODE -> {
final ModRM modrm = modrm(b);
yield new GeneralInstruction(
Opcode.VMOVQ,
Register64.fromByte(getByteFromRM(evex, modrm)),
RegisterXMM.fromByte(or(evex.r1() ? 0 : (byte) 0b00010000, getByteFromReg(evex, modrm))));
final byte r1 = getByteFromReg(evex, modrm);
final byte r2 = or(evex.b() ? 0 : (byte) 0b00010000, getByteFromRM(evex, modrm));
yield Instruction.builder()
.opcode(Opcode.VMOVQ)
.op(
evex.p() == (byte) 0b00000010
? RegisterXMM.fromByte(or(evex.r1() ? 0 : (byte) 0b00010000, r1))
: Register64.fromByte(modrm.reg()))
.op(RegisterXMM.fromByte(r2))
.build();
}
case VMOVQ_RX_M128_OPCODE -> {
case VMOVQ_R_M_OPCODE -> {
final ModRM modrm = modrm(b);
yield new GeneralInstruction(
Opcode.VMOVQ,
RegisterXMM.fromByte(or(evex.r1() ? 0 : (byte) 0b00010000, getByteFromReg(evex, modrm))),
parseIndirectOperand(b, pref, modrm)
final byte r1 = or(evex.r1() ? 0 : (byte) 0b00010000, getByteFromReg(evex, modrm));
yield Instruction.builder()
.opcode(Opcode.VMOVQ)
.op(RegisterXMM.fromByte(r1))
.op(parseIndirectOperand(b, pref, modrm)
.pointer(PointerSize.QWORD_PTR)
.build());
.build())
.build();
}
case VPCMPNEQUB_OPCODE -> {
final ModRM modrm = modrm(b);
Expand Down
18 changes: 9 additions & 9 deletions id/src/main/java/com/ledmington/cpu/x86/EvexPrefix.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,6 @@ public boolean r1() {
return r1;
}

/**
* Returns the M field value.
*
* @return The M field.
*/
public byte m() {
return m;
}

/**
* Returns the W bit value.
*
Expand All @@ -190,6 +181,15 @@ public byte v() {
return v;
}

/**
* Returns the P field value.
*
* @return The P field.
*/
public byte p() {
return p;
}

/**
* Returns the Z bit value.
*
Expand Down
31 changes: 29 additions & 2 deletions id/src/test/java/com/ledmington/cpu/X64Encodings.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@
import static com.ledmington.cpu.x86.RegisterXMM.XMM13;
import static com.ledmington.cpu.x86.RegisterXMM.XMM14;
import static com.ledmington.cpu.x86.RegisterXMM.XMM15;
import static com.ledmington.cpu.x86.RegisterXMM.XMM16;
import static com.ledmington.cpu.x86.RegisterXMM.XMM17;
import static com.ledmington.cpu.x86.RegisterXMM.XMM18;
import static com.ledmington.cpu.x86.RegisterXMM.XMM2;
import static com.ledmington.cpu.x86.RegisterXMM.XMM3;
import static com.ledmington.cpu.x86.RegisterXMM.XMM30;
import static com.ledmington.cpu.x86.RegisterXMM.XMM4;
import static com.ledmington.cpu.x86.RegisterXMM.XMM5;
import static com.ledmington.cpu.x86.RegisterXMM.XMM6;
Expand Down Expand Up @@ -10321,7 +10321,10 @@ Opcode.MOVABS, new SegmentedAddress(DS, new Immediate(0x12345678deadbeefL)), EAX
test(new GeneralInstruction(Opcode.VZEROALL), "vzeroall", "c5 fc 77"),
// Vmovq
test(new GeneralInstruction(Opcode.VMOVQ, RDI, XMM0), "vmovq rdi,xmm0", "c4 e1 f9 7e c7"),
test(new GeneralInstruction(Opcode.VMOVQ, RDI, XMM16), "vmovq rdi,xmm16", "62 e1 fd 08 7e c7"),
test(new GeneralInstruction(Opcode.VMOVQ, RSI, XMM30), "vmovq rsi,xmm30", "62 61 fd 08 7e f6"),
test(new GeneralInstruction(Opcode.VMOVQ, XMM0, XMM1), "vmovq xmm0,xmm1", "c5 fa 7e c1"),
test(new GeneralInstruction(Opcode.VMOVQ, XMM9, XMM18), "vmovq xmm9,xmm18", "62 31 fe 08 7e ca"),
test(new GeneralInstruction(Opcode.VMOVQ, XMM18, XMM9), "vmovq xmm18,xmm9", "62 c1 fe 08 7e d1"),
test(
new GeneralInstruction(
Opcode.VMOVQ,
Expand Down Expand Up @@ -10356,6 +10359,30 @@ Opcode.MOVABS, new SegmentedAddress(DS, new Immediate(0x12345678deadbeefL)), EAX
XMM0),
"vmovq QWORD PTR [rdi],xmm0",
"c5 f9 d6 07"),
test(
new GeneralInstruction(
Opcode.VMOVQ,
XMM0,
IndirectOperand.builder()
.pointer(QWORD_PTR)
.base(RDI)
.index(R9)
.scale(1)
.build()),
"vmovq xmm0,QWORD PTR [rdi+r9*1]",
"c4 a1 7a 7e 04 0f"),
test(
new GeneralInstruction(
Opcode.VMOVQ,
XMM17,
IndirectOperand.builder()
.pointer(QWORD_PTR)
.base(RDI)
.index(R9)
.scale(1)
.build()),
"vmovq xmm17,QWORD PTR [rdi+r9*1]",
"62 a1 fd 08 6e 0c 0f"),
// Vmovd
test(
new GeneralInstruction(
Expand Down
Loading