Skip to content
Merged
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
24 changes: 16 additions & 8 deletions scripts/test_latx_hbr_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
class HbrAuditTest(unittest.TestCase):
def test_repository_inventory(self):
result = latx_hbr_audit.audit(REPO_ROOT)
self.assertEqual(result["counts"]["translator_supported"], 1098)
self.assertEqual(result["counts"]["shbr_relevant"], 774)
self.assertEqual(result["counts"]["opcode_specific"], 774)
self.assertEqual(result["counts"]["translator_supported"], 1101)
self.assertEqual(result["counts"]["shbr_relevant"], 777)
self.assertEqual(result["counts"]["opcode_specific"], 777)
self.assertEqual(result["counts"]["conservative_unmodeled"], 0)
self.assertEqual(len(result["rows"]), 774)
self.assertEqual(len(result["promoted_opcode_specific"]), 618)
self.assertEqual(result["generated_opcode_specific"], 519)
self.assertEqual(len(result["rows"]), 777)
self.assertEqual(len(result["promoted_opcode_specific"]), 621)
self.assertEqual(result["generated_opcode_specific"], 522)
gather = next(
row for row in result["rows"] if row["mnemonic"] == "VGATHERDPD"
)
Expand All @@ -36,13 +36,21 @@ def test_repository_inventory(self):
)
self.assertEqual(
result["translator_mnemonic_sha256"],
"32bdf9f0e48c0b73ac1f3f0e914d2af621540ffd7c6ccebb86d059c14137250d",
"f8b9761a04c987ad075b4986d1dec5aab06a2f9c6dd992c3adcba6881a25a2a8",
)
xrstor = next(
row for row in result["rows"] if row["mnemonic"] == "XRSTOR"
)
self.assertEqual(xrstor["policy"], "implicit-read-write-all")
self.assertIn("preserve path", xrstor["high32"]["reads"])
xsave64 = next(
row for row in result["rows"] if row["mnemonic"] == "XSAVE64"
)
self.assertEqual(xsave64["policy"], "implicit-read-all")
xrstor64 = next(
row for row in result["rows"] if row["mnemonic"] == "XRSTOR64"
)
self.assertEqual(xrstor64["policy"], "implicit-read-write-all")

def test_commented_hbr_case_is_ignored(self):
models = latx_hbr_audit.parse_hbr_models(
Expand Down Expand Up @@ -115,7 +123,7 @@ def test_single_domain_model_fails(self):
def test_exact_family_rules(self):
data = json.loads(INVENTORY.read_text(encoding="utf-8"))
rules = generate_latx_hbr_semantics.exact_rules(data)
self.assertEqual(len(rules), 519)
self.assertEqual(len(rules), 522)
self.assertEqual(
rules["VFMADD132SS"],
{"high32": "DEST", "high64": "DEST"},
Expand Down
4 changes: 2 additions & 2 deletions scripts/test_latx_hbr_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
class ShbrMetricsTests(unittest.TestCase):
def test_current_metrics(self):
result = latx_hbr_metrics.collect(REPO_ROOT)
self.assertEqual(result["coverage"]["precise"], 774)
self.assertEqual(result["coverage"]["precise"], 777)
self.assertEqual(result["coverage"]["conservative"], 0)
self.assertEqual(result["coverage"]["relevant"], 774)
self.assertEqual(result["coverage"]["relevant"], 777)
self.assertEqual(result["generation_site_counts"]["SHBR_ON_32"], 12)
self.assertEqual(result["generation_site_counts"]["SHBR_ON_64"], 10)
self.assertEqual(result["minimum_removed_per_full_hit"]["lasx"], 22)
Expand Down
3 changes: 3 additions & 0 deletions target/i386/latx/optimization/hbr-xmm-semantics.inc
Original file line number Diff line number Diff line change
Expand Up @@ -517,5 +517,8 @@
[WRAP(VUNPCKLPS)] = { SHBR_RULE_ACCESS, SHBR_RULE_OTHER },
[WRAP(VZEROALL)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XRSTOR)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XRSTOR64)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XSAVE)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XSAVE64)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XSAVEOPT)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
[WRAP(XSAVEOPT64)] = { SHBR_RULE_IMPLICIT, SHBR_RULE_IMPLICIT },
39 changes: 32 additions & 7 deletions target/i386/latx/optimization/hbr-xmm-semantics.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"note": "Intel SDM is authoritative; Intel XED validates decoded operand access and Felix Cloutier is a per-family navigation aid."
},
"expected_counts": {
"translator_supported": 1098,
"opcode_specific": 774,
"translator_supported": 1101,
"opcode_specific": 777,
"conservative_unmodeled": 0,
"strict_xmm_scope": 766,
"strict_xmm_scope": 769,
"ymm_alias_only": 8,
"shbr_relevant": 774
"shbr_relevant": 777
},
"promoted_opcode_specific": [
"VADDPD",
Expand Down Expand Up @@ -126,7 +126,7 @@
"VPSUBW",
"VPXOR"
],
"translator_mnemonic_sha256": "32bdf9f0e48c0b73ac1f3f0e914d2af621540ffd7c6ccebb86d059c14137250d",
"translator_mnemonic_sha256": "f8b9761a04c987ad075b4986d1dec5aab06a2f9c6dd992c3adcba6881a25a2a8",
"form_resolution": {
"key": "mnemonic plus encoding family",
"runtime_fields": [
Expand Down Expand Up @@ -244,8 +244,11 @@
"SQRTPD": {"high32": "ACCESS_READ", "high64": "ACCESS_READ"},
"SQRTPS": {"high32": "ACCESS_READ", "high64": "ACCESS_READ"},
"XRSTOR": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"XRSTOR64": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"XSAVE": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"XSAVE64": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"XSAVEOPT": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"XSAVEOPT64": {"high32": "IMPLICIT", "high64": "IMPLICIT"},
"VBROADCASTF128": {"high32": "BROADCAST", "high64": "BROADCAST"},
"VBROADCASTI128": {"high32": "BROADCAST", "high64": "BROADCAST"},
"VBROADCASTSD": {"high32": "BROADCAST", "high64": "BROADCAST"},
Expand Down Expand Up @@ -505,12 +508,24 @@
"all-xmm"
]
},
"XSAVE64": {
"policy": "implicit-read-all",
"implicit": [
"all-xmm"
]
},
"XSAVEOPT": {
"policy": "implicit-read-all",
"implicit": [
"all-xmm"
]
},
"XSAVEOPT64": {
"policy": "implicit-read-all",
"implicit": [
"all-xmm"
]
},
"FXRSTOR": {
"policy": "implicit-write-all",
"implicit": [
Expand All @@ -530,6 +545,13 @@
],
"condition": "SSE state is restored only when EDX:EAX requests XSTATE_SSE"
},
"XRSTOR64": {
"policy": "implicit-read-write-all",
"implicit": [
"all-xmm"
],
"condition": "SSE state is restored only when EDX:EAX requests XSTATE_SSE"
},
"VZEROALL": {
"policy": "implicit-write-all",
"implicit": [
Expand Down Expand Up @@ -572,7 +594,7 @@
"unmodeled_groups": [
{
"name": "legacy_unmodeled",
"expected_count": 141,
"expected_count": 144,
"form_scope": "legacy-or-non-vex",
"policy": "conservative-explicit",
"mnemonics": [
Expand Down Expand Up @@ -715,8 +737,11 @@
"SQRTPD",
"SQRTPS",
"XRSTOR",
"XRSTOR64",
"XSAVE",
"XSAVEOPT"
"XSAVE64",
"XSAVEOPT",
"XSAVEOPT64"
]
},
{
Expand Down
6 changes: 6 additions & 0 deletions target/i386/latx/optimization/hbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,7 +1884,9 @@ static bool apply_implicit_semantic(TranslationBlock *tb, IR1_INST *ir1,
case WRAP(FXSAVE):
case WRAP(FXSAVE64):
case WRAP(XSAVE):
case WRAP(XSAVE64):
case WRAP(XSAVEOPT):
case WRAP(XSAVEOPT64):
ir1->shbr_read |= SHBR_XMM_ALL;
for (int i = 0; i < XMM_NUM; i++) {
ir1->xmm_use |= xmm[i];
Expand All @@ -1898,6 +1900,7 @@ static bool apply_implicit_semantic(TranslationBlock *tb, IR1_INST *ir1,
}
return true;
case WRAP(XRSTOR):
case WRAP(XRSTOR64):
/* XRSTOR preserves XMM when EDX:EAX does not request SSE state. */
ir1->shbr_read |= SHBR_XMM_ALL;
ir1->shbr_def |= SHBR_XMM_ALL;
Expand Down Expand Up @@ -1932,10 +1935,13 @@ static bool has_implicit_semantic(IR1_INST *ir1)
case WRAP(FXSAVE):
case WRAP(FXSAVE64):
case WRAP(XSAVE):
case WRAP(XSAVE64):
case WRAP(XSAVEOPT):
case WRAP(XSAVEOPT64):
case WRAP(FXRSTOR):
case WRAP(FXRSTOR64):
case WRAP(XRSTOR):
case WRAP(XRSTOR64):
case WRAP(VZEROALL):
case WRAP(BLENDVPD):
case WRAP(BLENDVPS):
Expand Down
6 changes: 6 additions & 0 deletions target/i386/latx/translator/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1771,8 +1771,11 @@ static bool (*translate_functions[])(IR1_INST *) = {
TRANS_FUNC_GEN(XGETBV, xgetbv_wrap),
TRANS_FUNC_GEN(XSETBV, xsetbv_wrap),
TRANS_FUNC_GEN(XSAVE, xsave_wrap),
TRANS_FUNC_GEN(XSAVE64, xsave_wrap),
TRANS_FUNC_GEN(XSAVEOPT, xsaveopt_wrap),
TRANS_FUNC_GEN(XSAVEOPT64, xsaveopt_wrap),
TRANS_FUNC_GEN(XRSTOR, xrstor_wrap),
TRANS_FUNC_GEN(XRSTOR64, xrstor_wrap),
TRANS_FUNC_GEN(VPBROADCASTD, vpbroadcastd),
//TRANS_FUNC_GEN(VPMAXSD, vpmaxsd),
//TRANS_FUNC_GEN(VPMINSD, vpminsd),
Expand Down Expand Up @@ -2414,8 +2417,11 @@ static SoftFPURegionClass softfpu_region_class(IR1_OPCODE opcode)
case dt_X86_INS_XGETBV:
case dt_X86_INS_XSETBV:
case dt_X86_INS_XSAVE:
case dt_X86_INS_XSAVE64:
case dt_X86_INS_XSAVEOPT:
case dt_X86_INS_XSAVEOPT64:
case dt_X86_INS_XRSTOR:
case dt_X86_INS_XRSTOR64:
#endif
return SOFTFPU_REGION_REQUIRED;
case dt_X86_INS_FILD:
Expand Down
6 changes: 6 additions & 0 deletions tests/integration/registrations/avx/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ if 'x86_64-linux-user' in target_dirs
'args': [emulators['latx-x86_64'], files('../../sse41-ymmh-preserve.asm')],
'timeout': 120,
}]
latx_integration_tests += [{
'name': 'test-xsave64-roundtrip',
'runner': find_program('../../test-avx-regressions.py'),
'args': [emulators['latx-x86_64'], files('../../xsave64-roundtrip.S')],
'timeout': 120,
}]
latx_integration_tests += [{
'name': 'test-avx-compare-jcc',
'runner': find_program('../../test-avx-regressions.py'),
Expand Down
76 changes: 76 additions & 0 deletions tests/integration/xsave64-roundtrip.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* x86-64 XSAVE64/XRSTOR64 must save and restore the non-volatile XMM
* registers. Wine's syscall dispatcher relies on this across win32u calls;
* a missing XSAVE64 translation corrupts dialog sizes and other state held
* in XMM6-XMM15.
*/
.intel_syntax noprefix
.global _start
.section .text
_start:
lea rbx, [area]
add rbx, 63
and rbx, -64

movdqu xmm6, [pat6]
movdqu xmm7, [pat7]

mov eax, 3
xor edx, edx
xsave64 [rbx]

mov rax, [rbx + 0x100]
cmp rax, [pat6]
jne fail
mov rax, [rbx + 0x108]
cmp rax, [pat6 + 8]
jne fail
mov rax, [rbx + 0x110]
cmp rax, [pat7]
jne fail
mov rax, [rbx + 0x118]
cmp rax, [pat7 + 8]
jne fail

movdqu xmm6, [pat8]
movdqu xmm7, [pat9]

mov eax, 3
xor edx, edx
xrstor64 [rbx]

movdqu [actual], xmm6
movdqu [actual + 16], xmm7
mov rax, [actual]
cmp rax, [pat6]
jne fail
mov rax, [actual + 8]
cmp rax, [pat6 + 8]
jne fail
mov rax, [actual + 16]
cmp rax, [pat7]
jne fail
mov rax, [actual + 24]
cmp rax, [pat7 + 8]
jne fail

xor edi, edi
jmp exit
fail:
mov edi, 1
exit:
mov eax, 60
syscall

.section .rodata
.p2align 4
pat6: .quad 0x1111111111111111, 0x2222222222222222
pat7: .quad 0x3333333333333333, 0x4444444444444444
pat8: .quad 0x5555555555555555, 0x6666666666666666
pat9: .quad 0x7777777777777777, 0x8888888888888888

.section .bss
.p2align 6
area: .skip 2048
actual: .skip 32
Loading