- Fix a wrong calculation for size of struct - Handle cases where struct size isn't multple of 8 - Recover vstack after memcpy for pushing struct - Add a float parameter for struct_assign_test1 to check SSE alignment
Unified · Split
| @@ -1061,9 +1061,9 @@ struct structa1 { · 1060 unmodified lines | |||
| 1061 | 1061 | ||
| 1062 | struct structa1 ssta1; | 1062 | struct structa1 ssta1; |
| 1063 | 1063 | ||
| 1064 | void struct_assign_test1(struct structa1 s1, int t) | 1064 | void struct_assign_test1(struct structa1 s1, int t, float f) |
| 1065 | { | 1065 | { |
| 1066 | printf("%d %d %d\n", s1.f1, s1.f2, t); | 1066 | printf("%d %d %d %f\n", s1.f1, s1.f2, t, f); |
| 1067 | } | 1067 | } |
| 1068 | 1068 | ||
| 1069 | struct structa1 struct_assign_test2(struct structa1 s1, int t) | 1069 | struct structa1 struct_assign_test2(struct structa1 s1, int t) |
| @@ -1089,7 +1089,7 @@ void struct_assign_test(void) · 19 unmodified lines | |||
| 1089 | lsta2.f1 = 1; | 1089 | lsta2.f1 = 1; |
| 1090 | lsta2.f2 = 2; | 1090 | lsta2.f2 = 2; |
| 1091 | #endif | 1091 | #endif |
| 1092 | struct_assign_test1(lsta2, 3); | 1092 | struct_assign_test1(lsta2, 3, 4.5); |
| 1093 | 1093 | ||
| 1094 | printf("before call: %d %d\n", lsta2.f1, lsta2.f2); | 1094 | printf("before call: %d %d\n", lsta2.f1, lsta2.f2); |
| 1095 | lsta2 = struct_assign_test2(lsta2, 4); | 1095 | lsta2 = struct_assign_test2(lsta2, 4); |
| @@ -820,7 +820,8 @@ void gfunc_call(int nb_args) · 819 unmodified lines | |||
| 820 | args_size = 0; | 820 | args_size = 0; |
| 821 | for(i = 0; i < nb_args; i++) { | 821 | for(i = 0; i < nb_args; i++) { |
| 822 | if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) { | 822 | if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) { |
| 823 | args_size += type_size(&vtop->type, &align); | 823 | args_size += type_size(&vtop[-i].type, &align); |
| 824 | args_size = (args_size + 3) & ~3; | ||
| 824 | } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) { | 825 | } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) { |
| 825 | args_size += 16; | 826 | args_size += 16; |
| 826 | } else if (is_sse_float(vtop[-i].type.t)) { | 827 | } else if (is_sse_float(vtop[-i].type.t)) { |
| @@ -840,9 +841,16 @@ void gfunc_call(int nb_args) · 13 unmodified lines | |||
| 840 | sse_reg = nb_sse_args; | 841 | sse_reg = nb_sse_args; |
| 841 | 842 | ||
| 842 | /* adjust stack to align SSE boundary */ | 843 | /* adjust stack to align SSE boundary */ |
| 843 | if (args_size &= 8) { | 844 | if (args_size &= 15) { |
| 844 | o(0x50); /* push $rax */ | 845 | /* fetch cpu flag before the following sub will change the value */ |
| 846 | if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP) | ||
| 847 | gv(RC_INT); | ||
| 848 | |||
| 849 | args_size = 16 - args_size; | ||
| 850 | o(0x48); | ||
| 851 | oad(0xec81, args_size); /* sub $xxx, %rsp */ | ||
| 845 | } | 852 | } |
| 853 | |||
| 846 | for(i = 0; i < nb_args; i++) { | 854 | for(i = 0; i < nb_args; i++) { |
| 847 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 855 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 848 | size = type_size(&vtop->type, &align); | 856 | size = type_size(&vtop->type, &align); |
| @@ -856,12 +864,16 @@ void gfunc_call(int nb_args) · 7 unmodified lines | |||
| 856 | orex(1, r, 0, 0x89); /* mov %rsp, r */ | 864 | orex(1, r, 0, 0x89); /* mov %rsp, r */ |
| 857 | o(0xe0 + REG_VALUE(r)); | 865 | o(0xe0 + REG_VALUE(r)); |
| 858 | { | 866 | { |
| 859 | /* following code breaks vtop[1] */ | 867 | /* following code breaks vtop[1], vtop[2], and vtop[3] */ |
| 860 | SValue tmp = vtop[1]; | 868 | SValue tmp1 = vtop[1]; |
| 869 | SValue tmp2 = vtop[2]; | ||
| 870 | SValue tmp3 = vtop[3]; | ||
| 861 | vset(&vtop->type, r | VT_LVAL, 0); | 871 | vset(&vtop->type, r | VT_LVAL, 0); |
| 862 | vswap(); | 872 | vswap(); |
| 863 | vstore(); | 873 | vstore(); |
| 864 | vtop[1] = tmp; | 874 | vtop[1] = tmp1; |
| 875 | vtop[2] = tmp2; | ||
| 876 | vtop[3] = tmp3; | ||
| 865 | } | 877 | } |
| 866 | args_size += size; | 878 | args_size += size; |
| 867 | } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | 879 | } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { |