Only store registers that are needed in arm64 gfunc_prolog code. Fix code in gen_bounds_epilog.
Unified · Split
| @@ -725,7 +725,7 @@ static void gen_bounds_epilog(void) · 724 unmodified lines | |||
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | /* generate bound check local freeing */ | 727 | /* generate bound check local freeing */ |
| 728 | o(0xa9be07e0); /* stp x0, x1, [sp, #-32]! */ | 728 | o(0xa9bf07e0); /* stp x0, x1, [sp, #-16]! */ |
| 729 | o(0x3c9f0fe0); /* str q0, [sp, #-16]! */ | 729 | o(0x3c9f0fe0); /* str q0, [sp, #-16]! */ |
| 730 | greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0); | 730 | greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0); |
| 731 | o(0x90000000 | 0); // adrp x0, #sym_data | 731 | o(0x90000000 | 0); // adrp x0, #sym_data |
| @@ -733,7 +733,7 @@ static void gen_bounds_epilog(void) · 1 unmodified line | |||
| 733 | o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] | 733 | o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] |
| 734 | gen_bounds_call(TOK___bound_local_delete); | 734 | gen_bounds_call(TOK___bound_local_delete); |
| 735 | o(0x3cc107e0); /* ldr q0, [sp], #16 */ | 735 | o(0x3cc107e0); /* ldr q0, [sp], #16 */ |
| 736 | o(0xa8c207e0); /* ldp x0, x1, [sp], #32 */ | 736 | o(0xa8c107e0); /* ldp x0, x1, [sp], #16 */ |
| 737 | } | 737 | } |
| 738 | #endif | 738 | #endif |
| 739 | 739 | ||
| @@ -1164,6 +1164,9 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 424 unmodified lines | |||
| 1164 | Sym *sym; | 1164 | Sym *sym; |
| 1165 | CType **t; | 1165 | CType **t; |
| 1166 | unsigned long *a; | 1166 | unsigned long *a; |
| 1167 | int use_x8 = 0; | ||
| 1168 | int last_int = 0; | ||
| 1169 | int last_float = 0; | ||
| 1167 | 1170 | ||
| 1168 | func_vc = 144; // offset of where x8 is stored | 1171 | func_vc = 144; // offset of where x8 is stored |
| 1169 | 1172 | ||
| @@ -1177,16 +1180,42 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 7 unmodified lines | |||
| 1177 | 1180 | ||
| 1178 | arm64_func_va_list_stack = arm64_pcs(n - 1, t, a); | 1181 | arm64_func_va_list_stack = arm64_pcs(n - 1, t, a); |
| 1179 | 1182 | ||
| 1183 | if (func_sym->type.ref->f.func_type == FUNC_ELLIPSIS) { | ||
| 1184 | use_x8 = 1; | ||
| 1185 | last_int = 4; | ||
| 1186 | last_float = 4; | ||
| 1187 | } | ||
| 1188 | if (a && a[0] == 1) | ||
| 1189 | use_x8 = 1; | ||
| 1190 | for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) { | ||
| 1191 | if (a[i] == 1) | ||
| 1192 | use_x8 = 1; | ||
| 1193 | if (a[i] < 16) { | ||
| 1194 | int last, align, size = type_size(&sym->type, &align); | ||
| 1195 | last = a[i] / 4 + 1 + (size - 1) / 8; | ||
| 1196 | last_int = last > last_int ? last : last_int; | ||
| 1197 | } | ||
| 1198 | else if (a[i] < 32) { | ||
| 1199 | int last, hfa = arm64_hfa(&sym->type, 0); | ||
| 1200 | last = a[i] / 4 - 3 + (hfa ? hfa - 1 : 0); | ||
| 1201 | last_float = last > last_float ? last : last_float; | ||
| 1202 | } | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | last_int = last_int > 4 ? 4 : last_int; | ||
| 1206 | last_float = last_float > 4 ? 4 : last_float; | ||
| 1207 | |||
| 1180 | o(0xa9b27bfd); // stp x29,x30,[sp,#-224]! | 1208 | o(0xa9b27bfd); // stp x29,x30,[sp,#-224]! |
| 1181 | o(0xad0087e0); // stp q0,q1,[sp,#16] | 1209 | for (i = 0; i < last_float; i++) |
| 1182 | o(0xad018fe2); // stp q2,q3,[sp,#48] | 1210 | // stp q0,q1,[sp,#16], stp q2,q3,[sp,#48] |
| 1183 | o(0xad0297e4); // stp q4,q5,[sp,#80] | 1211 | // stp q4,q5,[sp,#80], stp q6,q7,[sp,#112] |
| 1184 | o(0xad039fe6); // stp q6,q7,[sp,#112] | 1212 | o(0xad0087e0 + i * 0x10000 + (i << 11) + (i << 1)); |
| 1185 | o(0xa90923e8); // stp x8,x8,[sp,#144] | 1213 | if (use_x8) |
| 1186 | o(0xa90a07e0); // stp x0,x1,[sp,#160] | 1214 | o(0xa90923e8); // stp x8,x8,[sp,#144] |
| 1187 | o(0xa90b0fe2); // stp x2,x3,[sp,#176] | 1215 | for (i = 0; i < last_int; i++) |
| 1188 | o(0xa90c17e4); // stp x4,x5,[sp,#192] | 1216 | // stp x0,x1,[sp,#160], stp x2,x3,[sp,#176] |
| 1189 | o(0xa90d1fe6); // stp x6,x7,[sp,#208] | 1217 | // stp x4,x5,[sp,#192], stp x6,x7,[sp,#208] |
| 1218 | o(0xa90a07e0 + i * 0x10000 + (i << 11) + (i << 1)); | ||
| 1190 | 1219 | ||
| 1191 | arm64_func_va_list_gr_offs = -64; | 1220 | arm64_func_va_list_gr_offs = -64; |
| 1192 | arm64_func_va_list_vr_offs = -128; | 1221 | arm64_func_va_list_vr_offs = -128; |