Common/x64: remove legacy emitter and abi (#2504)
These are not used any more since we moved shader JIT to xbyak.
This commit is contained in:
		
							parent
							
								
									f7e96dc068
								
							
						
					
					
						commit
						0b9c59ff22
					
				| @ -61,14 +61,11 @@ set(HEADERS | ||||
| 
 | ||||
| if(ARCHITECTURE_x86_64) | ||||
|     set(SRCS ${SRCS} | ||||
|             x64/abi.cpp | ||||
|             x64/cpu_detect.cpp | ||||
|             x64/emitter.cpp) | ||||
|             ) | ||||
| 
 | ||||
|     set(HEADERS ${HEADERS} | ||||
|             x64/abi.h | ||||
|             x64/cpu_detect.h | ||||
|             x64/emitter.h | ||||
|             x64/xbyak_abi.h | ||||
|             x64/xbyak_util.h | ||||
|             ) | ||||
|  | ||||
| @ -1,350 +0,0 @@ | ||||
| // Copyright (C) 2003 Dolphin Project.
 | ||||
| 
 | ||||
| // This program is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, version 2.0 or later versions.
 | ||||
| 
 | ||||
| // This program is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License 2.0 for more details.
 | ||||
| 
 | ||||
| // A copy of the GPL 2.0 should have been included with the program.
 | ||||
| // If not, see http://www.gnu.org/licenses/
 | ||||
| 
 | ||||
| // Official SVN repository and contact information can be found at
 | ||||
| // http://code.google.com/p/dolphin-emu/
 | ||||
| 
 | ||||
| #include "abi.h" | ||||
| #include "emitter.h" | ||||
| 
 | ||||
| using namespace Gen; | ||||
| 
 | ||||
| // Shared code between Win64 and Unix64
 | ||||
| 
 | ||||
| void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, | ||||
|                                       size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp) { | ||||
|     size_t shadow = 0; | ||||
| #if defined(_WIN32) | ||||
|     shadow = 0x20; | ||||
| #endif | ||||
| 
 | ||||
|     int count = (mask & ABI_ALL_GPRS).Count(); | ||||
|     rsp_alignment -= count * 8; | ||||
|     size_t subtraction = 0; | ||||
|     int fpr_count = (mask & ABI_ALL_FPRS).Count(); | ||||
|     if (fpr_count) { | ||||
|         // If we have any XMMs to save, we must align the stack here.
 | ||||
|         subtraction = rsp_alignment & 0xf; | ||||
|     } | ||||
|     subtraction += 16 * fpr_count; | ||||
|     size_t xmm_base_subtraction = subtraction; | ||||
|     subtraction += needed_frame_size; | ||||
|     subtraction += shadow; | ||||
|     // Final alignment.
 | ||||
|     rsp_alignment -= subtraction; | ||||
|     subtraction += rsp_alignment & 0xf; | ||||
| 
 | ||||
|     *shadowp = shadow; | ||||
|     *subtractionp = subtraction; | ||||
|     *xmm_offsetp = subtraction - xmm_base_subtraction; | ||||
| } | ||||
| 
 | ||||
| size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, | ||||
|                                                  size_t needed_frame_size) { | ||||
|     size_t shadow, subtraction, xmm_offset; | ||||
|     ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, | ||||
|                            &xmm_offset); | ||||
| 
 | ||||
|     for (int r : mask& ABI_ALL_GPRS) | ||||
|         PUSH((X64Reg)r); | ||||
| 
 | ||||
|     if (subtraction) | ||||
|         SUB(64, R(RSP), subtraction >= 0x80 ? Imm32((u32)subtraction) : Imm8((u8)subtraction)); | ||||
| 
 | ||||
|     for (int x : mask& ABI_ALL_FPRS) { | ||||
|         MOVAPD(MDisp(RSP, (int)xmm_offset), (X64Reg)(x - 16)); | ||||
|         xmm_offset += 16; | ||||
|     } | ||||
| 
 | ||||
|     return shadow; | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, | ||||
|                                               size_t needed_frame_size) { | ||||
|     size_t shadow, subtraction, xmm_offset; | ||||
|     ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, | ||||
|                            &xmm_offset); | ||||
| 
 | ||||
|     for (int x : mask& ABI_ALL_FPRS) { | ||||
|         MOVAPD((X64Reg)(x - 16), MDisp(RSP, (int)xmm_offset)); | ||||
|         xmm_offset += 16; | ||||
|     } | ||||
| 
 | ||||
|     if (subtraction) | ||||
|         ADD(64, R(RSP), subtraction >= 0x80 ? Imm32((u32)subtraction) : Imm8((u8)subtraction)); | ||||
| 
 | ||||
|     for (int r = 15; r >= 0; r--) { | ||||
|         if (mask[r]) | ||||
|             POP((X64Reg)r); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Common functions
 | ||||
| void XEmitter::ABI_CallFunction(const void* func) { | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionC16(const void* func, u16 param1) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32((u32)param1)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32((u32)param2)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionC(const void* func, u32 param1) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionCC(const void* func, u32 param1, u32 param2) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionCCC(const void* func, u32 param1, u32 param2, u32 param3) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     MOV(32, R(ABI_PARAM3), Imm32(param3)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionCCP(const void* func, u32 param1, u32 param2, void* param3) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     MOV(64, R(ABI_PARAM3), ImmPtr(param3)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionCCCP(const void* func, u32 param1, u32 param2, u32 param3, | ||||
|                                     void* param4) { | ||||
|     MOV(32, R(ABI_PARAM1), Imm32(param1)); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     MOV(32, R(ABI_PARAM3), Imm32(param3)); | ||||
|     MOV(64, R(ABI_PARAM4), ImmPtr(param4)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionP(const void* func, void* param1) { | ||||
|     MOV(64, R(ABI_PARAM1), ImmPtr(param1)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionPA(const void* func, void* param1, const Gen::OpArg& arg2) { | ||||
|     MOV(64, R(ABI_PARAM1), ImmPtr(param1)); | ||||
|     if (!arg2.IsSimpleReg(ABI_PARAM2)) | ||||
|         MOV(32, R(ABI_PARAM2), arg2); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionPAA(const void* func, void* param1, const Gen::OpArg& arg2, | ||||
|                                    const Gen::OpArg& arg3) { | ||||
|     MOV(64, R(ABI_PARAM1), ImmPtr(param1)); | ||||
|     if (!arg2.IsSimpleReg(ABI_PARAM2)) | ||||
|         MOV(32, R(ABI_PARAM2), arg2); | ||||
|     if (!arg3.IsSimpleReg(ABI_PARAM3)) | ||||
|         MOV(32, R(ABI_PARAM3), arg3); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionPPC(const void* func, void* param1, void* param2, u32 param3) { | ||||
|     MOV(64, R(ABI_PARAM1), ImmPtr(param1)); | ||||
|     MOV(64, R(ABI_PARAM2), ImmPtr(param2)); | ||||
|     MOV(32, R(ABI_PARAM3), Imm32(param3)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Pass a register as a parameter.
 | ||||
| void XEmitter::ABI_CallFunctionR(const void* func, X64Reg reg1) { | ||||
|     if (reg1 != ABI_PARAM1) | ||||
|         MOV(32, R(ABI_PARAM1), R(reg1)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Pass two registers as parameters.
 | ||||
| void XEmitter::ABI_CallFunctionRR(const void* func, X64Reg reg1, X64Reg reg2) { | ||||
|     if (reg2 != ABI_PARAM1) { | ||||
|         if (reg1 != ABI_PARAM1) | ||||
|             MOV(64, R(ABI_PARAM1), R(reg1)); | ||||
|         if (reg2 != ABI_PARAM2) | ||||
|             MOV(64, R(ABI_PARAM2), R(reg2)); | ||||
|     } else { | ||||
|         if (reg2 != ABI_PARAM2) | ||||
|             MOV(64, R(ABI_PARAM2), R(reg2)); | ||||
|         if (reg1 != ABI_PARAM1) | ||||
|             MOV(64, R(ABI_PARAM1), R(reg1)); | ||||
|     } | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionAC(const void* func, const Gen::OpArg& arg1, u32 param2) { | ||||
|     if (!arg1.IsSimpleReg(ABI_PARAM1)) | ||||
|         MOV(32, R(ABI_PARAM1), arg1); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionACC(const void* func, const Gen::OpArg& arg1, u32 param2, | ||||
|                                    u32 param3) { | ||||
|     if (!arg1.IsSimpleReg(ABI_PARAM1)) | ||||
|         MOV(32, R(ABI_PARAM1), arg1); | ||||
|     MOV(32, R(ABI_PARAM2), Imm32(param2)); | ||||
|     MOV(64, R(ABI_PARAM3), Imm64(param3)); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionA(const void* func, const Gen::OpArg& arg1) { | ||||
|     if (!arg1.IsSimpleReg(ABI_PARAM1)) | ||||
|         MOV(32, R(ABI_PARAM1), arg1); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void XEmitter::ABI_CallFunctionAA(const void* func, const Gen::OpArg& arg1, | ||||
|                                   const Gen::OpArg& arg2) { | ||||
|     if (!arg1.IsSimpleReg(ABI_PARAM1)) | ||||
|         MOV(32, R(ABI_PARAM1), arg1); | ||||
|     if (!arg2.IsSimpleReg(ABI_PARAM2)) | ||||
|         MOV(32, R(ABI_PARAM2), arg2); | ||||
|     u64 distance = u64(func) - (u64(code) + 5); | ||||
|     if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { | ||||
|         // Far call
 | ||||
|         MOV(64, R(RAX), ImmPtr(func)); | ||||
|         CALLptr(R(RAX)); | ||||
|     } else { | ||||
|         CALL(func); | ||||
|     } | ||||
| } | ||||
| @ -1,58 +0,0 @@ | ||||
| // Copyright 2008 Dolphin Emulator Project
 | ||||
| // Licensed under GPLv2+
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/bit_set.h" | ||||
| #include "emitter.h" | ||||
| 
 | ||||
| // x64 ABI:s, and helpers to help follow them when JIT-ing code.
 | ||||
| // All convensions return values in EAX (+ possibly EDX).
 | ||||
| 
 | ||||
| // Windows 64-bit
 | ||||
| // * 4-reg "fastcall" variant, very new-skool stack handling
 | ||||
| // * Callee moves stack pointer, to make room for shadow regs for the biggest function _it itself
 | ||||
| // calls_
 | ||||
| // * Parameters passed in RCX, RDX, ... further parameters are MOVed into the allocated stack space.
 | ||||
| // Scratch:      RAX RCX RDX R8 R9 R10 R11
 | ||||
| // Callee-save:  RBX RSI RDI RBP R12 R13 R14 R15
 | ||||
| // Parameters:   RCX RDX R8 R9, further MOV-ed
 | ||||
| 
 | ||||
| // Linux 64-bit
 | ||||
| // * 6-reg "fastcall" variant, old skool stack handling (parameters are pushed)
 | ||||
| // Scratch:      RAX RCX RDX RSI RDI R8 R9 R10 R11
 | ||||
| // Callee-save:  RBX RBP R12 R13 R14 R15
 | ||||
| // Parameters:   RDI RSI RDX RCX R8 R9
 | ||||
| 
 | ||||
| #define ABI_ALL_FPRS BitSet32(0xffff0000) | ||||
| #define ABI_ALL_GPRS BitSet32(0x0000ffff) | ||||
| 
 | ||||
| #ifdef _WIN32 // 64-bit Windows - the really exotic calling convention
 | ||||
| 
 | ||||
| #define ABI_PARAM1 RCX | ||||
| #define ABI_PARAM2 RDX | ||||
| #define ABI_PARAM3 R8 | ||||
| #define ABI_PARAM4 R9 | ||||
| 
 | ||||
| // xmm0-xmm15 use the upper 16 bits in the functions that push/pop registers.
 | ||||
| #define ABI_ALL_CALLER_SAVED                                                                       \ | ||||
|     (BitSet32{RAX, RCX, RDX, R8, R9, R10, R11, XMM0 + 16, XMM1 + 16, XMM2 + 16, XMM3 + 16,         \ | ||||
|               XMM4 + 16, XMM5 + 16}) | ||||
| #else // 64-bit Unix / OS X
 | ||||
| 
 | ||||
| #define ABI_PARAM1 RDI | ||||
| #define ABI_PARAM2 RSI | ||||
| #define ABI_PARAM3 RDX | ||||
| #define ABI_PARAM4 RCX | ||||
| #define ABI_PARAM5 R8 | ||||
| #define ABI_PARAM6 R9 | ||||
| 
 | ||||
| // TODO: Avoid pushing all 16 XMM registers when possible. Most functions we call probably
 | ||||
| // don't actually clobber them.
 | ||||
| #define ABI_ALL_CALLER_SAVED (BitSet32{RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11} | ABI_ALL_FPRS) | ||||
| #endif // WIN32
 | ||||
| 
 | ||||
| #define ABI_ALL_CALLEE_SAVED (~ABI_ALL_CALLER_SAVED) | ||||
| 
 | ||||
| #define ABI_RETURN RAX | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -12,7 +12,6 @@ | ||||
| #include <xbyak.h> | ||||
| #include "common/bit_set.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/x64/emitter.h" | ||||
| #include "video_core/shader/shader.h" | ||||
| 
 | ||||
| using nihstro::Instruction; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Weiyi Wang
						Weiyi Wang