1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
/*
* Copyright (c) 2022, Leon Albrecht <leon.a@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/FPControl.h>
#include <AK/SIMD.h>
#include <AK/Types.h>
#include <LibX86/Instruction.h>
#include <math.h>
namespace UserspaceEmulator {
using AK::RoundingMode;
using namespace AK::SIMD;
class Emulator;
class SoftCPU;
union XMM {
f32x4 ps;
f64x2 pd;
i8x16 psb;
u8x16 pub;
i16x8 psw;
u16x8 puw;
u32x4 pudw;
u64x2 puqw;
};
class SoftVPU {
public:
SoftVPU(Emulator& emulator, SoftCPU& cpu)
: m_emulator(emulator)
, m_cpu(cpu)
, m_mxcsr { 0x1F80 }
{
}
XMM& operator[](u8 index) { return m_xmm[index]; }
enum class RoundingMode : u8 {
NEAREST = 0b00,
DOWN = 0b01,
UP = 0b10,
TRUNC = 0b11
};
enum class ComparePredicate : u8 {
EQ = 0,
LT = 1,
LE = 2,
UNORD = 3,
NEQ = 4,
NLT = 5,
NLE = 6,
ORD = 7
// FIXME: More with VEX prefix
};
private:
friend SoftCPU;
Emulator& m_emulator;
SoftCPU& m_cpu;
XMM m_xmm[8];
// FIXME: Maybe unimplemented features:
// * DAZ
// * FTZ
AK::MXCSR m_mxcsr;
void PREFETCHTNTA(X86::Instruction const&);
void PREFETCHT0(X86::Instruction const&);
void PREFETCHT1(X86::Instruction const&);
void PREFETCHT2(X86::Instruction const&);
void LDMXCSR(X86::Instruction const&);
void STMXCSR(X86::Instruction const&);
void MOVUPS_xmm1_xmm2m128(X86::Instruction const&);
void MOVSS_xmm1_xmm2m32(X86::Instruction const&);
void MOVUPS_xmm1m128_xmm2(X86::Instruction const&);
void MOVSS_xmm1m32_xmm2(X86::Instruction const&);
void MOVLPS_xmm1_xmm2m64(X86::Instruction const&);
void MOVLPS_m64_xmm2(X86::Instruction const&);
void UNPCKLPS_xmm1_xmm2m128(X86::Instruction const&);
void UNPCKHPS_xmm1_xmm2m128(X86::Instruction const&);
void MOVHPS_xmm1_xmm2m64(X86::Instruction const&);
void MOVHPS_m64_xmm2(X86::Instruction const&);
void MOVAPS_xmm1_xmm2m128(X86::Instruction const&);
void MOVAPS_xmm1m128_xmm2(X86::Instruction const&);
void CVTPI2PS_xmm1_mm2m64(X86::Instruction const&);
void CVTSI2SS_xmm1_rm32(X86::Instruction const&);
void MOVNTPS_xmm1m128_xmm2(X86::Instruction const&);
void CVTTPS2PI_mm1_xmm2m64(X86::Instruction const&);
void CVTTSS2SI_r32_xmm2m32(X86::Instruction const&);
void CVTPS2PI_xmm1_mm2m64(X86::Instruction const&);
void CVTSS2SI_r32_xmm2m32(X86::Instruction const&);
void UCOMISS_xmm1_xmm2m32(X86::Instruction const&);
void COMISS_xmm1_xmm2m32(X86::Instruction const&);
void MOVMSKPS_reg_xmm(X86::Instruction const&);
void SQRTPS_xmm1_xmm2m128(X86::Instruction const&);
void SQRTSS_xmm1_xmm2m32(X86::Instruction const&);
void RSQRTPS_xmm1_xmm2m128(X86::Instruction const&);
void RSQRTSS_xmm1_xmm2m32(X86::Instruction const&);
void RCPPS_xmm1_xmm2m128(X86::Instruction const&);
void RCPSS_xmm1_xmm2m32(X86::Instruction const&);
void ANDPS_xmm1_xmm2m128(X86::Instruction const&);
void ANDNPS_xmm1_xmm2m128(X86::Instruction const&);
void ORPS_xmm1_xmm2m128(X86::Instruction const&);
void XORPS_xmm1_xmm2m128(X86::Instruction const&);
void ADDPS_xmm1_xmm2m128(X86::Instruction const&);
void ADDSS_xmm1_xmm2m32(X86::Instruction const&);
void MULPS_xmm1_xmm2m128(X86::Instruction const&);
void MULSS_xmm1_xmm2m32(X86::Instruction const&);
void SUBPS_xmm1_xmm2m128(X86::Instruction const&);
void SUBSS_xmm1_xmm2m32(X86::Instruction const&);
void MINPS_xmm1_xmm2m128(X86::Instruction const&);
void MINSS_xmm1_xmm2m32(X86::Instruction const&);
void DIVPS_xmm1_xmm2m128(X86::Instruction const&);
void DIVSS_xmm1_xmm2m32(X86::Instruction const&);
void MAXPS_xmm1_xmm2m128(X86::Instruction const&);
void MAXSS_xmm1_xmm2m32(X86::Instruction const&);
void PSHUFW_mm1_mm2m64_imm8(X86::Instruction const&);
void CMPPS_xmm1_xmm2m128_imm8(X86::Instruction const&);
void CMPSS_xmm1_xmm2m32_imm8(X86::Instruction const&);
void PINSRW_mm1_r32m16_imm8(X86::Instruction const&);
void PINSRW_xmm1_r32m16_imm8(X86::Instruction const&);
void PEXTRW_reg_mm1_imm8(X86::Instruction const&);
void PEXTRW_reg_xmm1_imm8(X86::Instruction const&);
void SHUFPS_xmm1_xmm2m128_imm8(X86::Instruction const&);
void PMOVMSKB_reg_mm1(X86::Instruction const&);
void PMOVMSKB_reg_xmm1(X86::Instruction const&);
void PMINUB_mm1_mm2m64(X86::Instruction const&);
void PMINUB_xmm1_xmm2m128(X86::Instruction const&);
void PMAXUB_mm1_mm2m64(X86::Instruction const&);
void PMAXUB_xmm1_xmm2m128(X86::Instruction const&);
void PAVGB_mm1_mm2m64(X86::Instruction const&);
void PAVGB_xmm1_xmm2m128(X86::Instruction const&);
void PAVGW_mm1_mm2m64(X86::Instruction const&);
void PAVGW_xmm1_xmm2m128(X86::Instruction const&);
void PMULHUW_mm1_mm2m64(X86::Instruction const&);
void PMULHUW_xmm1_xmm2m64(X86::Instruction const&);
void MOVNTQ_m64_mm1(X86::Instruction const&);
void PMINSB_mm1_mm2m64(X86::Instruction const&);
void PMINSB_xmm1_xmm2m128(X86::Instruction const&);
void PMAXSB_mm1_mm2m64(X86::Instruction const&);
void PMAXSB_xmm1_xmm2m128(X86::Instruction const&);
void PSADBB_mm1_mm2m64(X86::Instruction const&);
void PSADBB_xmm1_xmm2m128(X86::Instruction const&);
void MASKMOVQ_mm1_mm2m64(X86::Instruction const&);
};
}
|