Search
lxdream.org :: lxdream/src/sh4/ia32mac.h :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/ia32mac.h
changeset 905:4c17ebd9ef5e
prev901:32c5cf5e206f
next906:268ea359f884
author nkeynes
date Wed Oct 29 23:51:58 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Use regparam calling conventions for all functions called from translated code,
along with a few other high-use functions. Can probably extend this to all functions,
but as it is this is a nice performance boost
file annotate diff log raw
1.1 --- a/src/sh4/ia32mac.h Sun Oct 26 02:28:29 2008 +0000
1.2 +++ b/src/sh4/ia32mac.h Wed Oct 29 23:51:58 2008 +0000
1.3 @@ -32,12 +32,73 @@
1.4 {
1.5 int adj = (-sh4_x86.stack_posn)&0x0F;
1.6 SUB_imm8s_r32( adj, R_ESP );
1.7 - load_imm32(R_EAX, (uint32_t)ptr);
1.8 - CALL_r32(R_EAX);
1.9 + load_imm32(R_ECX, (uint32_t)ptr);
1.10 + CALL_r32(R_ECX);
1.11 ADD_imm8s_r32( adj, R_ESP );
1.12 }
1.13
1.14 -#define CALL_FUNC1_SIZE 14
1.15 +#ifdef HAVE_FASTCALL
1.16 +static inline void call_func1( void *ptr, int arg1 )
1.17 +{
1.18 + int adj = (-sh4_x86.stack_posn)&0x0F;
1.19 + SUB_imm8s_r32( adj, R_ESP );
1.20 + if( arg1 != R_EAX ) {
1.21 + MOV_r32_r32( arg1, R_EAX );
1.22 + }
1.23 + load_imm32(R_ECX, (uint32_t)ptr);
1.24 + CALL_r32(R_ECX);
1.25 + ADD_imm8s_r32( adj, R_ESP );
1.26 +}
1.27 +
1.28 +static inline void call_func2( void *ptr, int arg1, int arg2 )
1.29 +{
1.30 + int adj = (-sh4_x86.stack_posn)&0x0F;
1.31 + SUB_imm8s_r32( adj, R_ESP );
1.32 + if( arg2 != R_EDX ) {
1.33 + MOV_r32_r32( arg2, R_EDX );
1.34 + }
1.35 + if( arg1 != R_EAX ) {
1.36 + MOV_r32_r32( arg1, R_EAX );
1.37 + }
1.38 + load_imm32(R_ECX, (uint32_t)ptr);
1.39 + CALL_r32(R_ECX);
1.40 + ADD_imm8s_r32( adj, R_ESP );
1.41 +}
1.42 +
1.43 +/**
1.44 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
1.45 + * the second in arg2b
1.46 + */
1.47 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
1.48 +{
1.49 + PUSH_r32(arg2b);
1.50 + PUSH_r32(addr);
1.51 + call_func2(sh4_write_long, addr, arg2a);
1.52 + POP_r32(R_EAX);
1.53 + POP_r32(R_EDX);
1.54 + ADD_imm8s_r32(4, R_EAX);
1.55 + call_func0(sh4_write_long);
1.56 +}
1.57 +
1.58 +/**
1.59 + * Read a double (64-bit) value from memory, writing the first word into arg2a
1.60 + * and the second into arg2b. The addr must not be in EAX
1.61 + */
1.62 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
1.63 +{
1.64 + PUSH_r32(addr);
1.65 + call_func1(sh4_read_long, addr);
1.66 + POP_r32(R_ECX);
1.67 + PUSH_r32(R_EAX);
1.68 + MOV_r32_r32(R_ECX, R_EAX);
1.69 + ADD_imm8s_r32(4, R_EAX);
1.70 + call_func0(sh4_read_long);
1.71 + if( arg2b != R_EAX ) {
1.72 + MOV_r32_r32(R_EAX, arg2b);
1.73 + }
1.74 + POP_r32(arg2a);
1.75 +}
1.76 +#else
1.77 static inline void call_func1( void *ptr, int arg1 )
1.78 {
1.79 int adj = (-4-sh4_x86.stack_posn)&0x0F;
1.80 @@ -65,9 +126,7 @@
1.81 /**
1.82 * Write a double (64-bit) value into memory, with the first word in arg2a, and
1.83 * the second in arg2b
1.84 - * NB: 30 bytes
1.85 */
1.86 -#define MEM_WRITE_DOUBLE_SIZE 36
1.87 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
1.88 {
1.89 int adj = (-8-sh4_x86.stack_posn)&0x0F;
1.90 @@ -91,9 +150,7 @@
1.91 /**
1.92 * Read a double (64-bit) value from memory, writing the first word into arg2a
1.93 * and the second into arg2b. The addr must not be in EAX
1.94 - * NB: 27 bytes
1.95 */
1.96 -#define MEM_READ_DOUBLE_SIZE 36
1.97 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
1.98 {
1.99 int adj = (-4-sh4_x86.stack_posn)&0x0F;
1.100 @@ -116,6 +173,8 @@
1.101 sh4_x86.stack_posn -= 4;
1.102 }
1.103
1.104 +#endif
1.105 +
1.106 /**
1.107 * Emit the 'start of block' assembly. Sets up the stack frame and save
1.108 * SI/DI as required
1.109 @@ -164,9 +223,6 @@
1.110 }
1.111
1.112
1.113 -#define EXIT_BLOCK_SIZE(pc) (24 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))
1.114 -
1.115 -
1.116 /**
1.117 * Exit the block to an absolute PC
1.118 */
1.119 @@ -188,8 +244,6 @@
1.120 RET();
1.121 }
1.122
1.123 -#define EXIT_BLOCK_REL_SIZE(pc) (27 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))
1.124 -
1.125 /**
1.126 * Exit the block to a relative PC
1.127 */
1.128 @@ -280,6 +334,47 @@
1.129 }
1.130 }
1.131
1.132 +
1.133 +/**
1.134 + * The unwind methods only work if we compiled with DWARF2 frame information
1.135 + * (ie -fexceptions), otherwise we have to use the direct frame scan.
1.136 + */
1.137 +#ifdef HAVE_EXCEPTIONS
1.138 +#include <unwind.h>
1.139 +
1.140 +struct UnwindInfo {
1.141 + int have_result;
1.142 + void *pc;
1.143 +};
1.144 +
1.145 +_Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )
1.146 +{
1.147 + void *ebp = (void *)_Unwind_GetGR(context, 5);
1.148 + void *expect = (((uint8_t *)&sh4r) + 128 );
1.149 + struct UnwindInfo *info = arg;
1.150 + if( ebp == expect ) {
1.151 + info->have_result = 1;
1.152 + info->pc = (void *)_Unwind_GetIP(context);
1.153 + } else if( info->have_result ) {
1.154 + return _URC_NORMAL_STOP;
1.155 + }
1.156 +
1.157 + return _URC_NO_REASON;
1.158 +}
1.159 +
1.160 +void *xlat_get_native_pc()
1.161 +{
1.162 + struct _Unwind_Exception exc;
1.163 + struct UnwindInfo info;
1.164 +
1.165 + info.have_result = 0;
1.166 + void *result = NULL;
1.167 + _Unwind_Backtrace( xlat_check_frame, &info );
1.168 + if( info.have_result )
1.169 + return info.pc;
1.170 + return NULL;
1.171 +}
1.172 +#else
1.173 void *xlat_get_native_pc()
1.174 {
1.175 void *result = NULL;
1.176 @@ -302,7 +397,7 @@
1.177 : "eax", "ecx", "edx" );
1.178 return result;
1.179 }
1.180 -
1.181 +#endif
1.182
1.183 #endif /* !lxdream_ia32mac.h */
1.184
.