summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Src/ABI.cpp
diff options
context:
space:
mode:
authorbushing <bushing@gmail.com>2008-12-08 05:30:24 +0000
committerbushing <bushing@gmail.com>2008-12-08 05:30:24 +0000
commit49cfded60bb5b444d1828190eacc52bbb49a9cb8 (patch)
tree0823218c1f2f6eec307dadbdec18c5632625f052 /Source/Core/Common/Src/ABI.cpp
parent901fe7c00fec5e2aaf55d184edbcb6d092345d52 (diff)
set svn:eol-style=native for **.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1442 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/Common/Src/ABI.cpp')
-rw-r--r--Source/Core/Common/Src/ABI.cpp558
1 files changed, 279 insertions, 279 deletions
diff --git a/Source/Core/Common/Src/ABI.cpp b/Source/Core/Common/Src/ABI.cpp
index 2e29e2bc6c..26059494f2 100644
--- a/Source/Core/Common/Src/ABI.cpp
+++ b/Source/Core/Common/Src/ABI.cpp
@@ -1,279 +1,279 @@
-#include "Common.h"
-#include "x64Emitter.h"
-#include "ABI.h"
-
-using namespace Gen;
-
-// Shared code between Win64 and Unix64
-// ====================================
-
-// Sets up a __cdecl function.
-void ABI_EmitPrologue(int maxCallParams)
-{
-#ifdef _M_IX86
- // Don't really need to do anything
-#elif defined(_M_X64)
-#if _WIN32
- int stacksize = ((maxCallParams + 1) & ~1)*8 + 8;
- // Set up a stack frame so that we can call functions
- // TODO: use maxCallParams
- SUB(64, R(RSP), Imm8(stacksize));
-#endif
-#else
-#error Arch not supported
-#endif
-}
-void ABI_EmitEpilogue(int maxCallParams)
-{
-#ifdef _M_IX86
- RET();
-#elif defined(_M_X64)
-#ifdef _WIN32
- int stacksize = ((maxCallParams+1)&~1)*8 + 8;
- ADD(64, R(RSP), Imm8(stacksize));
-#endif
- RET();
-#else
-#error Arch not supported
-#endif
-}
-
-#ifdef _M_IX86 // All32
-
-// Shared code between Win32 and Unix32
-// ====================================
-
-void ABI_CallFunctionC(void *func, u32 param1) {
- ABI_AlignStack(1 * 4);
- PUSH(32, Imm32(param1));
- CALL(func);
- ABI_RestoreStack(1 * 4);
-}
-
-void ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
- ABI_AlignStack(2 * 4);
- PUSH(32, Imm32(param2));
- PUSH(32, Imm32(param1));
- CALL(func);
- ABI_RestoreStack(2 * 4);
-}
-
-// Pass a register as a paremeter.
-void ABI_CallFunctionR(void *func, X64Reg reg1) {
- ABI_AlignStack(1 * 4);
- PUSH(32, R(reg1));
- CALL(func);
- ABI_RestoreStack(1 * 4);
-}
-
-void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
-{
- ABI_AlignStack(2 * 4);
- PUSH(32, R(reg2));
- PUSH(32, R(reg1));
- CALL(func);
- ABI_RestoreStack(2 * 4);
-}
-
-void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
-{
- ABI_AlignStack(2 * 4);
- PUSH(32, arg1);
- PUSH(32, Imm32(param2));
- CALL(func);
- ABI_RestoreStack(2 * 4);
-}
-
-void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
- // Note: 4 * 4 = 16 bytes, so alignment is preserved.
- PUSH(EBP);
- PUSH(EBX);
- PUSH(ESI);
- PUSH(EDI);
-}
-
-void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
- POP(EDI);
- POP(ESI);
- POP(EBX);
- POP(EBP);
-}
-
-unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) {
- frameSize += 4; // reserve space for return address
- unsigned int alignedSize =
-#ifdef __GNUC__
- (frameSize + 15) & -16;
-#else
- frameSize;
-#endif
- return alignedSize;
-}
-
-
-void ABI_AlignStack(unsigned int frameSize) {
-// Mac OS X requires the stack to be 16-byte aligned before every call.
-// Linux requires the stack to be 16-byte aligned before calls that put SSE
-// vectors on the stack, but since we do not keep track of which calls do that,
-// it is effectively every call as well.
-// Windows binaries compiled with MSVC do not have such a restriction, but I
-// expect that GCC on Windows acts the same as GCC on Linux in this respect.
-// It would be nice if someone could verify this.
-#ifdef __GNUC__
- unsigned int fillSize =
- ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4);
- if (fillSize != 0) {
- SUB(32, R(ESP), Imm8(fillSize));
- }
-#endif
-}
-
-void ABI_RestoreStack(unsigned int frameSize) {
- unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize);
- alignedSize -= 4; // return address is POPped at end of call
- if (alignedSize != 0) {
- ADD(32, R(ESP), Imm8(alignedSize));
- }
-}
-
-#else
-
-void ABI_CallFunctionC(void *func, u32 param1) {
- MOV(32, R(ABI_PARAM1), Imm32(param1));
- CALL(func);
-}
-
-void ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
- MOV(32, R(ABI_PARAM1), Imm32(param1));
- MOV(32, R(ABI_PARAM2), Imm32(param2));
- CALL(func);
-}
-
-// Pass a register as a paremeter.
-void ABI_CallFunctionR(void *func, X64Reg reg1) {
- if (reg1 != ABI_PARAM1)
- MOV(32, R(ABI_PARAM1), R(reg1));
- CALL(func);
-}
-
-// Pass a register as a paremeter.
-void ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
- if (reg1 != ABI_PARAM1)
- MOV(32, R(ABI_PARAM1), R(reg1));
- if (reg2 != ABI_PARAM2)
- MOV(32, R(ABI_PARAM2), R(reg2));
- CALL(func);
-}
-
-void ABI_CallFunctionAC(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));
- CALL(func);
-}
-
-unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) {
- return frameSize;
-}
-
-void ABI_AlignStack(unsigned int /*frameSize*/) {
-}
-
-void ABI_RestoreStack(unsigned int /*frameSize*/) {
-}
-
-#ifdef _WIN32
-
-// Win64 Specific Code
-// ====================================
-void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
- //we only want to do this once
- PUSH(RBX);
- PUSH(RSI);
- PUSH(RDI);
- PUSH(RBP);
- PUSH(R12);
- PUSH(R13);
- PUSH(R14);
- PUSH(R15);
- //TODO: Also preserve XMM0-3?
- SUB(64, R(RSP), Imm8(0x28));
-}
-
-void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
- ADD(64, R(RSP), Imm8(0x28));
- POP(R15);
- POP(R14);
- POP(R13);
- POP(R12);
- POP(RBP);
- POP(RDI);
- POP(RSI);
- POP(RBX);
-}
-
-// Win64 Specific Code
-// ====================================
-void ABI_PushAllCallerSavedRegsAndAdjustStack() {
- PUSH(RCX);
- PUSH(RDX);
- PUSH(RSI);
- PUSH(RDI);
- PUSH(R8);
- PUSH(R9);
- PUSH(R10);
- PUSH(R11);
- //TODO: Also preserve XMM0-15?
- SUB(64, R(RSP), Imm8(0x28));
-}
-
-void ABI_PopAllCallerSavedRegsAndAdjustStack() {
- ADD(64, R(RSP), Imm8(0x28));
- POP(R11);
- POP(R10);
- POP(R9);
- POP(R8);
- POP(RDI);
- POP(RSI);
- POP(RDX);
- POP(RCX);
-}
-
-#else
-// Unix64 Specific Code
-// ====================================
-void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
- PUSH(RBX);
- PUSH(RBP);
- PUSH(R12);
- PUSH(R13);
- PUSH(R14);
- PUSH(R15);
- PUSH(R15); //just to align stack. duped push/pop doesn't hurt.
-}
-
-void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
- POP(R15);
- POP(R15);
- POP(R14);
- POP(R13);
- POP(R12);
- POP(RBP);
- POP(RBX);
-}
-
-void ABI_PushAllCallerSavedRegsAndAdjustStack() {
- INT3();
- //not yet supported
-}
-
-void ABI_PopAllCallerSavedRegsAndAdjustStack() {
- INT3();
- //not yet supported
-}
-
-#endif
-
-#endif
-
+#include "Common.h"
+#include "x64Emitter.h"
+#include "ABI.h"
+
+using namespace Gen;
+
+// Shared code between Win64 and Unix64
+// ====================================
+
+// Sets up a __cdecl function.
+void ABI_EmitPrologue(int maxCallParams)
+{
+#ifdef _M_IX86
+ // Don't really need to do anything
+#elif defined(_M_X64)
+#if _WIN32
+ int stacksize = ((maxCallParams + 1) & ~1)*8 + 8;
+ // Set up a stack frame so that we can call functions
+ // TODO: use maxCallParams
+ SUB(64, R(RSP), Imm8(stacksize));
+#endif
+#else
+#error Arch not supported
+#endif
+}
+void ABI_EmitEpilogue(int maxCallParams)
+{
+#ifdef _M_IX86
+ RET();
+#elif defined(_M_X64)
+#ifdef _WIN32
+ int stacksize = ((maxCallParams+1)&~1)*8 + 8;
+ ADD(64, R(RSP), Imm8(stacksize));
+#endif
+ RET();
+#else
+#error Arch not supported
+#endif
+}
+
+#ifdef _M_IX86 // All32
+
+// Shared code between Win32 and Unix32
+// ====================================
+
+void ABI_CallFunctionC(void *func, u32 param1) {
+ ABI_AlignStack(1 * 4);
+ PUSH(32, Imm32(param1));
+ CALL(func);
+ ABI_RestoreStack(1 * 4);
+}
+
+void ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
+ ABI_AlignStack(2 * 4);
+ PUSH(32, Imm32(param2));
+ PUSH(32, Imm32(param1));
+ CALL(func);
+ ABI_RestoreStack(2 * 4);
+}
+
+// Pass a register as a paremeter.
+void ABI_CallFunctionR(void *func, X64Reg reg1) {
+ ABI_AlignStack(1 * 4);
+ PUSH(32, R(reg1));
+ CALL(func);
+ ABI_RestoreStack(1 * 4);
+}
+
+void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
+{
+ ABI_AlignStack(2 * 4);
+ PUSH(32, R(reg2));
+ PUSH(32, R(reg1));
+ CALL(func);
+ ABI_RestoreStack(2 * 4);
+}
+
+void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
+{
+ ABI_AlignStack(2 * 4);
+ PUSH(32, arg1);
+ PUSH(32, Imm32(param2));
+ CALL(func);
+ ABI_RestoreStack(2 * 4);
+}
+
+void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
+ // Note: 4 * 4 = 16 bytes, so alignment is preserved.
+ PUSH(EBP);
+ PUSH(EBX);
+ PUSH(ESI);
+ PUSH(EDI);
+}
+
+void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
+ POP(EDI);
+ POP(ESI);
+ POP(EBX);
+ POP(EBP);
+}
+
+unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) {
+ frameSize += 4; // reserve space for return address
+ unsigned int alignedSize =
+#ifdef __GNUC__
+ (frameSize + 15) & -16;
+#else
+ frameSize;
+#endif
+ return alignedSize;
+}
+
+
+void ABI_AlignStack(unsigned int frameSize) {
+// Mac OS X requires the stack to be 16-byte aligned before every call.
+// Linux requires the stack to be 16-byte aligned before calls that put SSE
+// vectors on the stack, but since we do not keep track of which calls do that,
+// it is effectively every call as well.
+// Windows binaries compiled with MSVC do not have such a restriction, but I
+// expect that GCC on Windows acts the same as GCC on Linux in this respect.
+// It would be nice if someone could verify this.
+#ifdef __GNUC__
+ unsigned int fillSize =
+ ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4);
+ if (fillSize != 0) {
+ SUB(32, R(ESP), Imm8(fillSize));
+ }
+#endif
+}
+
+void ABI_RestoreStack(unsigned int frameSize) {
+ unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize);
+ alignedSize -= 4; // return address is POPped at end of call
+ if (alignedSize != 0) {
+ ADD(32, R(ESP), Imm8(alignedSize));
+ }
+}
+
+#else
+
+void ABI_CallFunctionC(void *func, u32 param1) {
+ MOV(32, R(ABI_PARAM1), Imm32(param1));
+ CALL(func);
+}
+
+void ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
+ MOV(32, R(ABI_PARAM1), Imm32(param1));
+ MOV(32, R(ABI_PARAM2), Imm32(param2));
+ CALL(func);
+}
+
+// Pass a register as a paremeter.
+void ABI_CallFunctionR(void *func, X64Reg reg1) {
+ if (reg1 != ABI_PARAM1)
+ MOV(32, R(ABI_PARAM1), R(reg1));
+ CALL(func);
+}
+
+// Pass a register as a paremeter.
+void ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
+ if (reg1 != ABI_PARAM1)
+ MOV(32, R(ABI_PARAM1), R(reg1));
+ if (reg2 != ABI_PARAM2)
+ MOV(32, R(ABI_PARAM2), R(reg2));
+ CALL(func);
+}
+
+void ABI_CallFunctionAC(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));
+ CALL(func);
+}
+
+unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) {
+ return frameSize;
+}
+
+void ABI_AlignStack(unsigned int /*frameSize*/) {
+}
+
+void ABI_RestoreStack(unsigned int /*frameSize*/) {
+}
+
+#ifdef _WIN32
+
+// Win64 Specific Code
+// ====================================
+void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
+ //we only want to do this once
+ PUSH(RBX);
+ PUSH(RSI);
+ PUSH(RDI);
+ PUSH(RBP);
+ PUSH(R12);
+ PUSH(R13);
+ PUSH(R14);
+ PUSH(R15);
+ //TODO: Also preserve XMM0-3?
+ SUB(64, R(RSP), Imm8(0x28));
+}
+
+void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
+ ADD(64, R(RSP), Imm8(0x28));
+ POP(R15);
+ POP(R14);
+ POP(R13);
+ POP(R12);
+ POP(RBP);
+ POP(RDI);
+ POP(RSI);
+ POP(RBX);
+}
+
+// Win64 Specific Code
+// ====================================
+void ABI_PushAllCallerSavedRegsAndAdjustStack() {
+ PUSH(RCX);
+ PUSH(RDX);
+ PUSH(RSI);
+ PUSH(RDI);
+ PUSH(R8);
+ PUSH(R9);
+ PUSH(R10);
+ PUSH(R11);
+ //TODO: Also preserve XMM0-15?
+ SUB(64, R(RSP), Imm8(0x28));
+}
+
+void ABI_PopAllCallerSavedRegsAndAdjustStack() {
+ ADD(64, R(RSP), Imm8(0x28));
+ POP(R11);
+ POP(R10);
+ POP(R9);
+ POP(R8);
+ POP(RDI);
+ POP(RSI);
+ POP(RDX);
+ POP(RCX);
+}
+
+#else
+// Unix64 Specific Code
+// ====================================
+void ABI_PushAllCalleeSavedRegsAndAdjustStack() {
+ PUSH(RBX);
+ PUSH(RBP);
+ PUSH(R12);
+ PUSH(R13);
+ PUSH(R14);
+ PUSH(R15);
+ PUSH(R15); //just to align stack. duped push/pop doesn't hurt.
+}
+
+void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
+ POP(R15);
+ POP(R15);
+ POP(R14);
+ POP(R13);
+ POP(R12);
+ POP(RBP);
+ POP(RBX);
+}
+
+void ABI_PushAllCallerSavedRegsAndAdjustStack() {
+ INT3();
+ //not yet supported
+}
+
+void ABI_PopAllCallerSavedRegsAndAdjustStack() {
+ INT3();
+ //not yet supported
+}
+
+#endif
+
+#endif
+