feat(asm): encode the legacy amd64 SSE and MMX families
The packed integer and float binaries, the imm8-controlled SSE4.1 forms, the variable blends with their X0 mask, the high/low half moves, the sign-mask extractions, the non-temporal stores, the MOVQ bank crossings and their odd spellings, the MMX shifts and shuffle and the cache-line mask stores, plus the scalar leaves LEAVE, INVPCID and the RTM controls. Every encoding is pinned byte for byte against go tool asm through every corpus line the toolchain's own amd64enc.s carries for the families (1465 lines). Two corpus-wide gaps fell out of the comparison: the 64-bit MOV immediate uses the zero-extending form across the unsigned 32-bit span, and the MMX-to-GPR MOVQ puts the bank register in reg. Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
257feace6e
commit
6af3fd60d5
5 files changed
+2159
-13
No files matched your search
@@ -53,6 +53,10 @@ var systemNoOperand = map[string][]byte{
|
||||
"SYSEXIT": {0x0F, 0x35},
|
||||
"SYSEXIT64": {0x48, 0x0F, 0x35},
|
||||
"SYSRET": {0x0F, 0x07},
|
||||
"LEAVE": {0xC9},
|
||||
"LEAVEQ": {0xC9},
|
||||
"XEND": {0x0F, 0x01, 0xD5},
|
||||
"XTEST": {0x0F, 0x01, 0xD6},
|
||||
"CBW": {0x66, 0x98},
|
||||
"CWDE": {0x98},
|
||||
"CDQE": {0x48, 0x98},
|
||||
@@ -253,6 +257,40 @@ func (e *enc) encodeSystem(upper string, ops []Operand) (bool, error) {
|
||||
}
|
||||
return true, e.emit(i)
|
||||
}
|
||||
// INVPCID invalidates a translation-cache entry: 66 0F38 82 with the
|
||||
// type in a general register and the descriptor in memory.
|
||||
if upper == "INVPCID" {
|
||||
if len(ops) != 2 {
|
||||
return true, fmt.Errorf("INVPCID expects 2 operands, got %d", len(ops))
|
||||
}
|
||||
if !isX86Mem(ops[0]) {
|
||||
return true, fmt.Errorf("INVPCID requires a memory descriptor first")
|
||||
}
|
||||
srcReg, ok := ops[1].(Reg)
|
||||
if !ok || srcReg.isVec() {
|
||||
return true, fmt.Errorf("INVPCID: the second operand must be a general register")
|
||||
}
|
||||
i := &instr{prefix: 0x66, opcode: []byte{0x0F, 0x38, 0x82}, modrm: -1, sib: -1}
|
||||
if err := setRM(i, srcReg, ops[0], 8); err != nil {
|
||||
return true, err
|
||||
}
|
||||
return true, e.emit(i)
|
||||
}
|
||||
// XABORT carries its imm8 status byte in the C6 F8 group form.
|
||||
if upper == "XABORT" {
|
||||
if len(ops) != 1 {
|
||||
return true, fmt.Errorf("XABORT expects 1 immediate operand, got %d", len(ops))
|
||||
}
|
||||
imm, ok := ops[0].(Imm)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("XABORT requires an immediate")
|
||||
}
|
||||
immByte, err := imm8(int64(imm))
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return true, e.emit(&instr{opcode: []byte{0xC6, 0xF8}, modrm: -1, sib: -1, imm: []byte{immByte}})
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user