Mercurial > repos > blastem
comparison gen_x86.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | e45a317802bd |
children | d15c68157288 |
comparison
equal
deleted
inserted
replaced
1692:5dacaef602a7 | 2053:3414a4423de1 |
---|---|
128 X86_R11, | 128 X86_R11, |
129 X86_R12, | 129 X86_R12, |
130 X86_R13, | 130 X86_R13, |
131 X86_R14, | 131 X86_R14, |
132 X86_R15 | 132 X86_R15 |
133 } x86_regs_enc; | 133 }; |
134 | 134 |
135 char * x86_reg_names[] = { | 135 char * x86_reg_names[] = { |
136 #ifdef X86_64 | 136 #ifdef X86_64 |
137 "rax", | 137 "rax", |
138 "rcx", | 138 "rcx", |
169 char * x86_sizes[] = { | 169 char * x86_sizes[] = { |
170 "b", "w", "d", "q" | 170 "b", "w", "d", "q" |
171 }; | 171 }; |
172 | 172 |
173 #ifdef X86_64 | 173 #ifdef X86_64 |
174 #define CHECK_DISP(disp) (disp <= 0x7FFFFFFF && disp >= -2147483648) | 174 #define CHECK_DISP(disp) (disp <= ((ptrdiff_t)INT32_MAX) && disp >= ((ptrdiff_t)INT32_MIN)) |
175 #else | 175 #else |
176 #define CHECK_DISP(disp) 1 | 176 #define CHECK_DISP(disp) 1 |
177 #endif | 177 #endif |
178 | 178 |
179 void jmp_nocheck(code_info *code, code_ptr dest) | 179 void jmp_nocheck(code_info *code, code_ptr dest) |
1259 void mov_ir(code_info *code, int64_t val, uint8_t dst, uint8_t size) | 1259 void mov_ir(code_info *code, int64_t val, uint8_t dst, uint8_t size) |
1260 { | 1260 { |
1261 check_alloc_code(code, 14); | 1261 check_alloc_code(code, 14); |
1262 code_ptr out = code->cur; | 1262 code_ptr out = code->cur; |
1263 uint8_t sign_extend = 0; | 1263 uint8_t sign_extend = 0; |
1264 if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) { | 1264 if (size == SZ_Q && val <= ((int64_t)INT32_MAX) && val >= ((int64_t)INT32_MIN)) { |
1265 sign_extend = 1; | 1265 sign_extend = 1; |
1266 } | 1266 } |
1267 if (size == SZ_W) { | 1267 if (size == SZ_W) { |
1268 *(out++) = PRE_SIZE; | 1268 *(out++) = PRE_SIZE; |
1269 } | 1269 } |
2109 { | 2109 { |
2110 arg_arr[i] = va_arg(args, int); | 2110 arg_arr[i] = va_arg(args, int); |
2111 } | 2111 } |
2112 #ifdef X86_64 | 2112 #ifdef X86_64 |
2113 uint32_t stack_args = 0; | 2113 uint32_t stack_args = 0; |
2114 #ifdef _WIN32 | |
2115 //Microsoft is too good for the ABI that everyone else uses on x86-64 apparently | |
2116 uint8_t abi_regs[] = {RCX, RDX, R8, R9}; | |
2117 #else | |
2114 uint8_t abi_regs[] = {RDI, RSI, RDX, RCX, R8, R9}; | 2118 uint8_t abi_regs[] = {RDI, RSI, RDX, RCX, R8, R9}; |
2119 #endif | |
2115 int8_t reg_swap[R15+1]; | 2120 int8_t reg_swap[R15+1]; |
2116 uint32_t usage = 0; | 2121 uint32_t usage = 0; |
2117 memset(reg_swap, -1, sizeof(reg_swap)); | 2122 memset(reg_swap, -1, sizeof(reg_swap)); |
2118 for (int i = 0; i < num_args; i ++) | 2123 for (int i = 0; i < num_args; i ++) |
2119 { | 2124 { |
2151 for (int i = stack_args -1; i >= 0; i--) | 2156 for (int i = stack_args -1; i >= 0; i--) |
2152 { | 2157 { |
2153 push_r(code, arg_arr[i]); | 2158 push_r(code, arg_arr[i]); |
2154 } | 2159 } |
2155 free(arg_arr); | 2160 free(arg_arr); |
2161 #if defined(X86_64) && defined(_WIN32) | |
2162 sub_ir(code, 32, RSP, SZ_PTR); | |
2163 code->stack_off += 32; | |
2164 adjust += 32; | |
2165 #endif | |
2156 | 2166 |
2157 return stack_args * sizeof(void *) + adjust; | 2167 return stack_args * sizeof(void *) + adjust; |
2158 } | 2168 } |
2159 | 2169 |
2160 void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...) | 2170 void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...) |
2216 #ifdef X86_64 | 2226 #ifdef X86_64 |
2217 push_r(code, R12); | 2227 push_r(code, R12); |
2218 push_r(code, R13); | 2228 push_r(code, R13); |
2219 push_r(code, R14); | 2229 push_r(code, R14); |
2220 push_r(code, R15); | 2230 push_r(code, R15); |
2221 #else | 2231 #endif |
2232 #if !defined(X86_64) || defined(_WIN32) | |
2222 push_r(code, RDI); | 2233 push_r(code, RDI); |
2223 push_r(code, RSI); | 2234 push_r(code, RSI); |
2224 #endif | 2235 #endif |
2225 } | 2236 } |
2226 | 2237 |
2227 void restore_callee_save_regs(code_info *code) | 2238 void restore_callee_save_regs(code_info *code) |
2228 { | 2239 { |
2240 #if !defined(X86_64) || defined(_WIN32) | |
2241 pop_r(code, RSI); | |
2242 pop_r(code, RDI); | |
2243 #endif | |
2229 #ifdef X86_64 | 2244 #ifdef X86_64 |
2230 pop_r(code, R15); | 2245 pop_r(code, R15); |
2231 pop_r(code, R14); | 2246 pop_r(code, R14); |
2232 pop_r(code, R13); | 2247 pop_r(code, R13); |
2233 pop_r(code, R12); | 2248 pop_r(code, R12); |
2234 #else | |
2235 pop_r(code, RSI); | |
2236 pop_r(code, RDI); | |
2237 #endif | 2249 #endif |
2238 pop_r(code, RBP); | 2250 pop_r(code, RBP); |
2239 pop_r(code, RBX); | 2251 pop_r(code, RBX); |
2240 } | 2252 } |
2241 | 2253 |