Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1413)

Side by Side Diff: src/cmd/8g/cgen.c

Issue 6962043: code review 6962043: cmd/dist, cmd/8g: implement GO386=387/sse to choose FPU... (Closed)
Patch Set: diff -r b2bc77ca3160 https://go.googlecode.com/hg/ Created 12 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/libc.h ('k') | src/cmd/8g/gg.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // TODO(rsc): 5 // TODO(rsc):
6 // assume CLD? 6 // assume CLD?
7 7
8 #include <u.h> 8 #include <u.h>
9 #include <libc.h> 9 #include <libc.h>
10 #include "gg.h" 10 #include "gg.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 * generate: 42 * generate:
43 * res = n; 43 * res = n;
44 * simplifies and calls gmove. 44 * simplifies and calls gmove.
45 * 45 *
46 * TODO: 46 * TODO:
47 * sudoaddable 47 * sudoaddable
48 */ 48 */
49 void 49 void
50 cgen(Node *n, Node *res) 50 cgen(Node *n, Node *res)
51 { 51 {
52 » Node *nl, *nr, *r, n1, n2, nt, f0, f1; 52 » Node *nl, *nr, *r, n1, n2, nt;
53 Prog *p1, *p2, *p3; 53 Prog *p1, *p2, *p3;
54 int a; 54 int a;
55 55
56 if(debug['g']) { 56 if(debug['g']) {
57 dump("\ncgen-n", n); 57 dump("\ncgen-n", n);
58 dump("cgen-res", res); 58 dump("cgen-res", res);
59 } 59 }
60 60
61 if(n == N || n->type == T) 61 if(n == N || n->type == T)
62 fatal("cgen: n nil"); 62 fatal("cgen: n nil");
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 case OLSH: 181 case OLSH:
182 case ORSH: 182 case ORSH:
183 case OAND: 183 case OAND:
184 case OOR: 184 case OOR:
185 case OXOR: 185 case OXOR:
186 cgen64(n, res); 186 cgen64(n, res);
187 return; 187 return;
188 } 188 }
189 } 189 }
190 190
191 » if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) 191 » if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) {
192 » » goto flt; 192 » » cgen_float(n, res);
193 » » return;
194 » }
193 195
194 switch(n->op) { 196 switch(n->op) {
195 default: 197 default:
196 dump("cgen", n); 198 dump("cgen", n);
197 fatal("cgen %O", n->op); 199 fatal("cgen %O", n->op);
198 break; 200 break;
199 201
200 case OREAL: 202 case OREAL:
201 case OIMAG: 203 case OIMAG:
202 case OCOMPLEX: 204 case OCOMPLEX:
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 regfree(&n1); 426 regfree(&n1);
425 } 427 }
426 return; 428 return;
427 429
428 uop: // unary 430 uop: // unary
429 tempname(&n1, nl->type); 431 tempname(&n1, nl->type);
430 cgen(nl, &n1); 432 cgen(nl, &n1);
431 gins(a, N, &n1); 433 gins(a, N, &n1);
432 gmove(&n1, res); 434 gmove(&n1, res);
433 return; 435 return;
434
435 flt: // floating-point. 387 (not SSE2) to interoperate with 8c
436 nodreg(&f0, nl->type, D_F0);
437 nodreg(&f1, n->type, D_F0+1);
438 if(nr != N)
439 goto flt2;
440
441 // unary
442 cgen(nl, &f0);
443 if(n->op != OCONV && n->op != OPLUS)
444 gins(foptoas(n->op, n->type, 0), N, N);
445 gmove(&f0, res);
446 return;
447
448 flt2: // binary
449 if(nl->ullman >= nr->ullman) {
450 cgen(nl, &f0);
451 if(nr->addable)
452 gins(foptoas(n->op, n->type, 0), nr, &f0);
453 else {
454 cgen(nr, &f0);
455 gins(foptoas(n->op, n->type, Fpop), &f0, &f1);
456 }
457 } else {
458 cgen(nr, &f0);
459 if(nl->addable)
460 gins(foptoas(n->op, n->type, Frev), nl, &f0);
461 else {
462 cgen(nl, &f0);
463 gins(foptoas(n->op, n->type, Frev|Fpop), &f0, &f1);
464 }
465 }
466 gmove(&f0, res);
467 return;
468 } 436 }
469 437
470 /* 438 /*
471 * generate an addressable node in res, containing the value of n. 439 * generate an addressable node in res, containing the value of n.
472 * n is an array index, and might be any size; res width is <= 32-bit. 440 * n is an array index, and might be any size; res width is <= 32-bit.
473 * returns Prog* to patch to panic call. 441 * returns Prog* to patch to panic call.
474 */ 442 */
475 static Prog* 443 static Prog*
476 igenindex(Node *n, Node *res, int bounded) 444 igenindex(Node *n, Node *res, int bounded)
477 { 445 {
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 880
913 /* 881 /*
914 * branch gen 882 * branch gen
915 * if(n == true) goto to; 883 * if(n == true) goto to;
916 */ 884 */
917 void 885 void
918 bgen(Node *n, int true, int likely, Prog *to) 886 bgen(Node *n, int true, int likely, Prog *to)
919 { 887 {
920 int et, a; 888 int et, a;
921 Node *nl, *nr, *r; 889 Node *nl, *nr, *r;
922 » Node n1, n2, tmp, t1, t2, ax; 890 » Node n1, n2, tmp;
923 » NodeList *ll;
924 Prog *p1, *p2; 891 Prog *p1, *p2;
925 892
926 if(debug['g']) { 893 if(debug['g']) {
927 dump("\nbgen", n); 894 dump("\nbgen", n);
928 } 895 }
929 896
930 if(n == N) 897 if(n == N)
931 n = nodbool(1); 898 n = nodbool(1);
932 899
933 if(n->ninit != nil) 900 if(n->ninit != nil)
934 genlist(n->ninit); 901 genlist(n->ninit);
935 902
936 if(n->type == T) { 903 if(n->type == T) {
937 convlit(&n, types[TBOOL]); 904 convlit(&n, types[TBOOL]);
938 if(n->type == T) 905 if(n->type == T)
939 return; 906 return;
940 } 907 }
941 908
942 et = n->type->etype; 909 et = n->type->etype;
943 if(et != TBOOL) { 910 if(et != TBOOL) {
944 yyerror("cgen: bad type %T for %O", n->type, n->op); 911 yyerror("cgen: bad type %T for %O", n->type, n->op);
945 patch(gins(AEND, N, N), to); 912 patch(gins(AEND, N, N), to);
946 return; 913 return;
947 } 914 }
915 nl = n->left;
948 nr = N; 916 nr = N;
949 917
918 if(nl != N && isfloat[nl->type->etype]) {
919 bgen_float(n, true, likely, to);
920 return;
921 }
922
950 switch(n->op) { 923 switch(n->op) {
951 default: 924 default:
952 def: 925 def:
953 regalloc(&n1, n->type, N); 926 regalloc(&n1, n->type, N);
954 cgen(n, &n1); 927 cgen(n, &n1);
955 nodconst(&n2, n->type, 0); 928 nodconst(&n2, n->type, 0);
956 gins(optoas(OCMP, n->type), &n1, &n2); 929 gins(optoas(OCMP, n->type), &n1, &n2);
957 a = AJNE; 930 a = AJNE;
958 if(!true) 931 if(!true)
959 a = AJEQ; 932 a = AJEQ;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 break; 997 break;
1025 998
1026 case OEQ: 999 case OEQ:
1027 case ONE: 1000 case ONE:
1028 case OLT: 1001 case OLT:
1029 case OGT: 1002 case OGT:
1030 case OLE: 1003 case OLE:
1031 case OGE: 1004 case OGE:
1032 a = n->op; 1005 a = n->op;
1033 if(!true) { 1006 if(!true) {
1034 if(isfloat[nl->type->etype]) {
1035 // brcom is not valid on floats when NaN is invo lved.
1036 p1 = gbranch(AJMP, T, 0);
1037 p2 = gbranch(AJMP, T, 0);
1038 patch(p1, pc);
1039 ll = n->ninit; // avoid re-genning ninit
1040 n->ninit = nil;
1041 bgen(n, 1, -likely, p2);
1042 n->ninit = ll;
1043 patch(gbranch(AJMP, T, 0), to);
1044 patch(p2, pc);
1045 break;
1046 }·······························
1047 a = brcom(a); 1007 a = brcom(a);
1048 true = !true; 1008 true = !true;
1049 } 1009 }
1050 1010
1051 // make simplest on right 1011 // make simplest on right
1052 if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) { 1012 if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
1053 a = brrev(a); 1013 a = brrev(a);
1054 r = nl; 1014 r = nl;
1055 nl = nr; 1015 nl = nr;
1056 nr = r; 1016 nr = r;
(...skipping 25 matching lines...) Expand all
1082 a = optoas(a, types[tptr]); 1042 a = optoas(a, types[tptr]);
1083 igen(nl, &n1, N); 1043 igen(nl, &n1, N);
1084 n1.type = types[tptr]; 1044 n1.type = types[tptr];
1085 nodconst(&tmp, types[tptr], 0); 1045 nodconst(&tmp, types[tptr], 0);
1086 gins(optoas(OCMP, types[tptr]), &n1, &tmp); 1046 gins(optoas(OCMP, types[tptr]), &n1, &tmp);
1087 patch(gbranch(a, types[tptr], likely), to); 1047 patch(gbranch(a, types[tptr], likely), to);
1088 regfree(&n1); 1048 regfree(&n1);
1089 break; 1049 break;
1090 } 1050 }
1091 1051
1092 if(isfloat[nr->type->etype]) {
1093 a = brrev(a); // because the args are stacked
1094 if(a == OGE || a == OGT) {
1095 // only < and <= work right with NaN; reverse if needed
1096 r = nr;
1097 nr = nl;
1098 nl = r;
1099 a = brrev(a);
1100 }
1101 nodreg(&tmp, nr->type, D_F0);
1102 nodreg(&n2, nr->type, D_F0 + 1);
1103 nodreg(&ax, types[TUINT16], D_AX);
1104 et = simsimtype(nr->type);
1105 if(et == TFLOAT64) {
1106 if(nl->ullman > nr->ullman) {
1107 cgen(nl, &tmp);
1108 cgen(nr, &tmp);
1109 gins(AFXCHD, &tmp, &n2);
1110 } else {
1111 cgen(nr, &tmp);
1112 cgen(nl, &tmp);
1113 }
1114 gins(AFUCOMIP, &tmp, &n2);
1115 gins(AFMOVDP, &tmp, &tmp); // annoying pop but still better than STSW+SAHF
1116 } else {
1117 // TODO(rsc): The moves back and forth to memory
1118 // here are for truncating the value to 32 bits.
1119 // This handles 32-bit comparison but presumably
1120 // all the other ops have the same problem.
1121 // We need to figure out what the right general
1122 // solution is, besides telling people to use fl oat64.
1123 tempname(&t1, types[TFLOAT32]);
1124 tempname(&t2, types[TFLOAT32]);
1125 cgen(nr, &t1);
1126 cgen(nl, &t2);
1127 gmove(&t2, &tmp);
1128 gins(AFCOMFP, &t1, &tmp);
1129 gins(AFSTSW, N, &ax);
1130 gins(ASAHF, N, N);
1131 }
1132 if(a == OEQ) {
1133 // neither NE nor P
1134 p1 = gbranch(AJNE, T, -likely);
1135 p2 = gbranch(AJPS, T, -likely);
1136 patch(gbranch(AJMP, T, 0), to);
1137 patch(p1, pc);
1138 patch(p2, pc);
1139 } else if(a == ONE) {
1140 // either NE or P
1141 patch(gbranch(AJNE, T, likely), to);
1142 patch(gbranch(AJPS, T, likely), to);
1143 } else
1144 patch(gbranch(optoas(a, nr->type), T, likely), t o);
1145 break;
1146 }
1147 if(iscomplex[nl->type->etype]) { 1052 if(iscomplex[nl->type->etype]) {
1148 complexbool(a, nl, nr, true, likely, to); 1053 complexbool(a, nl, nr, true, likely, to);
1149 break; 1054 break;
1150 } 1055 }
1151 1056
1152 if(is64(nr->type)) { 1057 if(is64(nr->type)) {
1153 if(!nl->addable) { 1058 if(!nl->addable) {
1154 tempname(&n1, nl->type); 1059 tempname(&n1, nl->type);
1155 cgen(nl, &n1); 1060 cgen(nl, &n1);
1156 nl = &n1; 1061 nl = &n1;
1157 } 1062 }
1158 if(!nr->addable) { 1063 if(!nr->addable) {
1159 tempname(&n2, nr->type); 1064 tempname(&n2, nr->type);
1160 cgen(nr, &n2); 1065 cgen(nr, &n2);
1161 nr = &n2; 1066 nr = &n2;
1162 } 1067 }
1163 cmp64(nl, nr, a, likely, to); 1068 cmp64(nl, nr, a, likely, to);
1164 break; 1069 break;
1165 } 1070 }
1166 1071
1167 a = optoas(a, nr->type);
1168
1169 if(nr->ullman >= UINF) { 1072 if(nr->ullman >= UINF) {
1170 if(!nl->addable) { 1073 if(!nl->addable) {
1171 tempname(&n1, nl->type); 1074 tempname(&n1, nl->type);
1172 cgen(nl, &n1); 1075 cgen(nl, &n1);
1173 nl = &n1; 1076 nl = &n1;
1174 } 1077 }
1175 if(!nr->addable) { 1078 if(!nr->addable) {
1176 tempname(&tmp, nr->type); 1079 tempname(&tmp, nr->type);
1177 cgen(nr, &tmp); 1080 cgen(nr, &tmp);
1178 nr = &tmp; 1081 nr = &tmp;
1179 } 1082 }
1180 regalloc(&n2, nr->type, N); 1083 regalloc(&n2, nr->type, N);
1181 cgen(nr, &n2); 1084 cgen(nr, &n2);
1085 nr = &n2;
1182 goto cmp; 1086 goto cmp;
1183 } 1087 }
1184 1088
1185 if(!nl->addable) { 1089 if(!nl->addable) {
1186 tempname(&n1, nl->type); 1090 tempname(&n1, nl->type);
1187 cgen(nl, &n1); 1091 cgen(nl, &n1);
1188 nl = &n1; 1092 nl = &n1;
1189 } 1093 }
1190 1094
1191 if(smallintconst(nr)) { 1095 if(smallintconst(nr)) {
1192 gins(optoas(OCMP, nr->type), nl, nr); 1096 gins(optoas(OCMP, nr->type), nl, nr);
1193 » » » patch(gbranch(a, nr->type, likely), to); 1097 » » » patch(gbranch(optoas(a, nr->type), nr->type, likely), to );
1194 break; 1098 break;
1195 } 1099 }
1196 1100
1197 if(!nr->addable) { 1101 if(!nr->addable) {
1198 tempname(&tmp, nr->type); 1102 tempname(&tmp, nr->type);
1199 cgen(nr, &tmp); 1103 cgen(nr, &tmp);
1200 nr = &tmp; 1104 nr = &tmp;
1201 } 1105 }
1202 regalloc(&n2, nr->type, N); 1106 regalloc(&n2, nr->type, N);
1203 gmove(nr, &n2); 1107 gmove(nr, &n2);
1108 nr = &n2;
1204 1109
1205 cmp: 1110 cmp:
1206 » » gins(optoas(OCMP, nr->type), nl, &n2); 1111 » » gins(optoas(OCMP, nr->type), nl, nr);
1207 » » patch(gbranch(a, nr->type, likely), to); 1112 » » patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
1208 » » regfree(&n2); 1113
1114 » » if(nl->op == OREGISTER)
1115 » » » regfree(nl);
1116 » » regfree(nr);
1209 break; 1117 break;
1210 } 1118 }
1211 } 1119 }
1212 1120
1213 /* 1121 /*
1214 * n is on stack, either local variable 1122 * n is on stack, either local variable
1215 * or return value from function call. 1123 * or return value from function call.
1216 * return n's offset from SP. 1124 * return n's offset from SP.
1217 */ 1125 */
1218 int32 1126 int32
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 regfree(&nodl); 1435 regfree(&nodl);
1528 return 0; 1436 return 0;
1529 1437
1530 yes: 1438 yes:
1531 if(freer) 1439 if(freer)
1532 regfree(&nodr); 1440 regfree(&nodr);
1533 if(freel) 1441 if(freel)
1534 regfree(&nodl); 1442 regfree(&nodl);
1535 return 1; 1443 return 1;
1536 } 1444 }
OLDNEW
« no previous file with comments | « include/libc.h ('k') | src/cmd/8g/gg.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b