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