mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:12:43 +00:00 
			
		
		
		
	 6c41267dcf
			
		
	
	
		6c41267dcf
		
	
	
	
	
		
			
			This also makes us a bit more accurate, due to better rounding of intermediate results. This also gives us the flush-to-zero and denormals-are-zero SSE settings for free! (Assuming UE is build with SSE)
		
			
				
	
	
		
			154 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * 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&);
 | |
| };
 | |
| 
 | |
| }
 |