History

Fix alignment around struct for SSE.

- 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

Shinichiro Hamaji committed 16 years ago

Commit 1f6781f1 parent 4ab4efd2 files · +21 −9Browse files

Unified · Split

2 files
  1. tests/tcctest.c +3 −3
  2. x86_64-gen.c +18 −6
tests/tcctest.c+3−3
@@ -1061,9 +1061,9 @@ struct structa1 { · 1060 unmodified lines
1061 1061
1062struct structa1 ssta1;1062struct structa1 ssta1;
1063 1063
1064void struct_assign_test1(struct structa1 s1, int t)1064void 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
1069struct structa1 struct_assign_test2(struct structa1 s1, int t)1069struct 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#endif1091#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);
x86_64-gen.c+18−6
@@ -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) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t