Mercurial > repos > blastem
comparison gen_x86.c @ 894:a7774fc2de4b
Partially working change to do proper stack alignment rather than doing a lame alignment check when calling a C compile dfunction. 68K core seems okay, but Z80 is busted.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 25 Nov 2015 08:40:45 -0800 |
parents | 724bbec47f86 |
children | 07bfbbbb4b2e |
comparison
equal
deleted
inserted
replaced
893:4f46b4cd5035 | 894:a7774fc2de4b |
---|---|
1590 *(out++) = PRE_REX | REX_RM_FIELD; | 1590 *(out++) = PRE_REX | REX_RM_FIELD; |
1591 reg -= R8 - X86_R8; | 1591 reg -= R8 - X86_R8; |
1592 } | 1592 } |
1593 *(out++) = OP_PUSH | reg; | 1593 *(out++) = OP_PUSH | reg; |
1594 code->cur = out; | 1594 code->cur = out; |
1595 code->stack_off += sizeof(void *); | |
1595 } | 1596 } |
1596 | 1597 |
1597 void push_rdisp(code_info *code, uint8_t base, int32_t disp) | 1598 void push_rdisp(code_info *code, uint8_t base, int32_t disp) |
1598 { | 1599 { |
1599 //This instruction has no explicit size, so we pass SZ_B | 1600 //This instruction has no explicit size, so we pass SZ_B |
1600 //to avoid any prefixes or bits being set | 1601 //to avoid any prefixes or bits being set |
1601 x86_rdisp_size(code, OP_SINGLE_EA, OP_EX_PUSH_EA, base, disp, SZ_B); | 1602 x86_rdisp_size(code, OP_SINGLE_EA, OP_EX_PUSH_EA, base, disp, SZ_B); |
1603 code->stack_off += sizeof(void *); | |
1602 } | 1604 } |
1603 | 1605 |
1604 void pop_r(code_info *code, uint8_t reg) | 1606 void pop_r(code_info *code, uint8_t reg) |
1605 { | 1607 { |
1606 check_alloc_code(code, 2); | 1608 check_alloc_code(code, 2); |
1609 *(out++) = PRE_REX | REX_RM_FIELD; | 1611 *(out++) = PRE_REX | REX_RM_FIELD; |
1610 reg -= R8 - X86_R8; | 1612 reg -= R8 - X86_R8; |
1611 } | 1613 } |
1612 *(out++) = OP_POP | reg; | 1614 *(out++) = OP_POP | reg; |
1613 code->cur = out; | 1615 code->cur = out; |
1616 code->stack_off -= sizeof(void *); | |
1614 } | 1617 } |
1615 | 1618 |
1616 void pop_rind(code_info *code, uint8_t reg) | 1619 void pop_rind(code_info *code, uint8_t reg) |
1617 { | 1620 { |
1618 check_alloc_code(code, 3); | 1621 check_alloc_code(code, 3); |
1622 reg -= R8 - X86_R8; | 1625 reg -= R8 - X86_R8; |
1623 } | 1626 } |
1624 *(out++) = PRE_XOP; | 1627 *(out++) = PRE_XOP; |
1625 *(out++) = MODE_REG_INDIRECT | reg; | 1628 *(out++) = MODE_REG_INDIRECT | reg; |
1626 code->cur = out; | 1629 code->cur = out; |
1630 code->stack_off -= sizeof(void *); | |
1627 } | 1631 } |
1628 | 1632 |
1629 void setcc_r(code_info *code, uint8_t cc, uint8_t dst) | 1633 void setcc_r(code_info *code, uint8_t cc, uint8_t dst) |
1630 { | 1634 { |
1631 check_alloc_code(code, 4); | 1635 check_alloc_code(code, 4); |
1964 code->cur = out; | 1968 code->cur = out; |
1965 } | 1969 } |
1966 | 1970 |
1967 void call(code_info *code, code_ptr fun) | 1971 void call(code_info *code, code_ptr fun) |
1968 { | 1972 { |
1973 code->stack_off += sizeof(void *); | |
1974 int32_t adjust = 0; | |
1975 if (code->stack_off & 0xF) { | |
1976 adjust = 16 - (code->stack_off & 0xF); | |
1977 code->stack_off += adjust; | |
1978 sub_ir(code, adjust, RSP, SZ_PTR); | |
1979 } | |
1969 check_alloc_code(code, 5); | 1980 check_alloc_code(code, 5); |
1970 code_ptr out = code->cur; | 1981 code_ptr out = code->cur; |
1971 ptrdiff_t disp = fun-(out+5); | 1982 ptrdiff_t disp = fun-(out+5); |
1972 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { | 1983 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { |
1973 *(out++) = OP_CALL; | 1984 *(out++) = OP_CALL; |
1981 } else { | 1992 } else { |
1982 //TODO: Implement far call??? | 1993 //TODO: Implement far call??? |
1983 fatal_error("call: %p - %p = %lX which is out of range for a 32-bit displacement\n", fun, out + 5, (long)disp); | 1994 fatal_error("call: %p - %p = %lX which is out of range for a 32-bit displacement\n", fun, out + 5, (long)disp); |
1984 } | 1995 } |
1985 code->cur = out; | 1996 code->cur = out; |
1997 if (adjust) { | |
1998 add_ir(code, adjust, RSP, SZ_PTR); | |
1999 } | |
2000 code->stack_off -= sizeof(void *) + adjust; | |
1986 } | 2001 } |
1987 | 2002 |
1988 void call_raxfallback(code_info *code, code_ptr fun) | 2003 void call_raxfallback(code_info *code, code_ptr fun) |
1989 { | 2004 { |
1990 check_alloc_code(code, 5); | 2005 check_alloc_code(code, 5); |
2006 code->cur = out; | 2021 code->cur = out; |
2007 } | 2022 } |
2008 | 2023 |
2009 void call_r(code_info *code, uint8_t dst) | 2024 void call_r(code_info *code, uint8_t dst) |
2010 { | 2025 { |
2026 code->stack_off += sizeof(void *); | |
2027 int32_t adjust = 0; | |
2028 if (code->stack_off & 0xF) { | |
2029 adjust = 16 - (code->stack_off & 0xF); | |
2030 code->stack_off += adjust; | |
2031 sub_ir(code, adjust, RSP, SZ_PTR); | |
2032 } | |
2011 check_alloc_code(code, 2); | 2033 check_alloc_code(code, 2); |
2012 code_ptr out = code->cur; | 2034 code_ptr out = code->cur; |
2013 *(out++) = OP_SINGLE_EA; | 2035 *(out++) = OP_SINGLE_EA; |
2014 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3); | 2036 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3); |
2015 code->cur = out; | 2037 code->cur = out; |
2038 if (adjust) { | |
2039 add_ir(code, adjust, RSP, SZ_PTR); | |
2040 } | |
2041 code->stack_off -= sizeof(void *) + adjust; | |
2016 } | 2042 } |
2017 | 2043 |
2018 void retn(code_info *code) | 2044 void retn(code_info *code) |
2019 { | 2045 { |
2020 check_alloc_code(code, 1); | 2046 check_alloc_code(code, 1); |
2082 #endif | 2108 #endif |
2083 for (int i = stack_args -1; i >= 0; i--) | 2109 for (int i = stack_args -1; i >= 0; i--) |
2084 { | 2110 { |
2085 push_r(code, arg_arr[i]); | 2111 push_r(code, arg_arr[i]); |
2086 } | 2112 } |
2087 | 2113 uint32_t stack_off_call = code->stack_off + sizeof(void *); |
2088 return stack_args * sizeof(void *); | 2114 uint32_t adjust = 0; |
2115 if (stack_off_call & 0xF) { | |
2116 adjust = 16 - (stack_off_call & 0xF); | |
2117 sub_ir(code, adjust, RSP, SZ_PTR); | |
2118 code->stack_off += adjust; | |
2119 } | |
2120 | |
2121 return stack_args * sizeof(void *) + adjust; | |
2089 } | 2122 } |
2090 | 2123 |
2091 void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...) | 2124 void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...) |
2092 { | 2125 { |
2093 va_list args; | 2126 va_list args; |
2095 uint32_t adjust = prep_args(code, num_args, args); | 2128 uint32_t adjust = prep_args(code, num_args, args); |
2096 va_end(args); | 2129 va_end(args); |
2097 call_raxfallback(code, fun); | 2130 call_raxfallback(code, fun); |
2098 if (adjust) { | 2131 if (adjust) { |
2099 add_ir(code, adjust, RSP, SZ_PTR); | 2132 add_ir(code, adjust, RSP, SZ_PTR); |
2100 } | 2133 code->stack_off -= adjust; |
2101 } | 2134 } |
2102 | 2135 } |
2136 /* | |
2103 void call_args_abi(code_info *code, code_ptr fun, uint32_t num_args, ...) | 2137 void call_args_abi(code_info *code, code_ptr fun, uint32_t num_args, ...) |
2104 { | 2138 { |
2105 va_list args; | 2139 va_list args; |
2106 va_start(args, num_args); | 2140 va_start(args, num_args); |
2107 uint32_t adjust = prep_args(code, num_args, args); | 2141 uint32_t adjust = prep_args(code, num_args, args); |
2123 call_raxfallback(code, fun); | 2157 call_raxfallback(code, fun); |
2124 add_ir(code, adjust + 8 , RSP, SZ_PTR); | 2158 add_ir(code, adjust + 8 , RSP, SZ_PTR); |
2125 *no_adjust_rsp = code->cur - (no_adjust_rsp+1); | 2159 *no_adjust_rsp = code->cur - (no_adjust_rsp+1); |
2126 #endif | 2160 #endif |
2127 } | 2161 } |
2128 | 2162 */ |
2129 void save_callee_save_regs(code_info *code) | 2163 void save_callee_save_regs(code_info *code) |
2130 { | 2164 { |
2131 push_r(code, RBX); | 2165 push_r(code, RBX); |
2132 push_r(code, RBP); | 2166 push_r(code, RBP); |
2133 #ifdef X86_64 | 2167 #ifdef X86_64 |