LEFT | RIGHT |
(no file at all) | |
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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 // these call bgen to get a bool value | 189 // these call bgen to get a bool value |
190 case OOROR: | 190 case OOROR: |
191 case OANDAND: | 191 case OANDAND: |
192 case OEQ: | 192 case OEQ: |
193 case ONE: | 193 case ONE: |
194 case OLT: | 194 case OLT: |
195 case OLE: | 195 case OLE: |
196 case OGE: | 196 case OGE: |
197 case OGT: | 197 case OGT: |
198 case ONOT: | 198 case ONOT: |
199 » » p1 = gbranch(AJMP, T); | 199 » » p1 = gbranch(AJMP, T, 0); |
200 p2 = pc; | 200 p2 = pc; |
201 gmove(nodbool(1), res); | 201 gmove(nodbool(1), res); |
202 » » p3 = gbranch(AJMP, T); | 202 » » p3 = gbranch(AJMP, T, 0); |
203 patch(p1, pc); | 203 patch(p1, pc); |
204 » » bgen(n, 1, p2); | 204 » » bgen(n, 1, 0, p2); |
205 gmove(nodbool(0), res); | 205 gmove(nodbool(0), res); |
206 patch(p3, pc); | 206 patch(p3, pc); |
207 return; | 207 return; |
208 | 208 |
209 case OPLUS: | 209 case OPLUS: |
210 cgen(nl, res); | 210 cgen(nl, res); |
211 return; | 211 return; |
212 | 212 |
213 case OMINUS: | 213 case OMINUS: |
214 case OCOM: | 214 case OCOM: |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 // map has len in the first 32-bit word. | 268 // map has len in the first 32-bit word. |
269 // a zero pointer means zero length | 269 // a zero pointer means zero length |
270 tempname(&n1, types[tptr]); | 270 tempname(&n1, types[tptr]); |
271 cgen(nl, &n1); | 271 cgen(nl, &n1); |
272 regalloc(&n2, types[tptr], N); | 272 regalloc(&n2, types[tptr], N); |
273 gmove(&n1, &n2); | 273 gmove(&n1, &n2); |
274 n1 = n2; | 274 n1 = n2; |
275 | 275 |
276 nodconst(&n2, types[tptr], 0); | 276 nodconst(&n2, types[tptr], 0); |
277 gins(optoas(OCMP, types[tptr]), &n1, &n2); | 277 gins(optoas(OCMP, types[tptr]), &n1, &n2); |
278 » » » p1 = gbranch(optoas(OEQ, types[tptr]), T); | 278 » » » p1 = gbranch(optoas(OEQ, types[tptr]), T, -1); |
279 | 279 |
280 n2 = n1; | 280 n2 = n1; |
281 n2.op = OINDREG; | 281 n2.op = OINDREG; |
282 n2.type = types[TINT32]; | 282 n2.type = types[TINT32]; |
283 gmove(&n2, &n1); | 283 gmove(&n2, &n1); |
284 | 284 |
285 patch(p1, pc); | 285 patch(p1, pc); |
286 | 286 |
287 gmove(&n1, res); | 287 gmove(&n1, res); |
288 regfree(&n1); | 288 regfree(&n1); |
(...skipping 13 matching lines...) Expand all Loading... |
302 | 302 |
303 case OCAP: | 303 case OCAP: |
304 if(istype(nl->type, TCHAN)) { | 304 if(istype(nl->type, TCHAN)) { |
305 // chan has cap in the second 32-bit word. | 305 // chan has cap in the second 32-bit word. |
306 // a zero pointer means zero length | 306 // a zero pointer means zero length |
307 regalloc(&n1, types[tptr], res); | 307 regalloc(&n1, types[tptr], res); |
308 cgen(nl, &n1); | 308 cgen(nl, &n1); |
309 | 309 |
310 nodconst(&n2, types[tptr], 0); | 310 nodconst(&n2, types[tptr], 0); |
311 gins(optoas(OCMP, types[tptr]), &n1, &n2); | 311 gins(optoas(OCMP, types[tptr]), &n1, &n2); |
312 » » » p1 = gbranch(optoas(OEQ, types[tptr]), T); | 312 » » » p1 = gbranch(optoas(OEQ, types[tptr]), T, -1); |
313 | 313 |
314 n2 = n1; | 314 n2 = n1; |
315 n2.op = OINDREG; | 315 n2.op = OINDREG; |
316 n2.xoffset = 4; | 316 n2.xoffset = 4; |
317 n2.type = types[TINT32]; | 317 n2.type = types[TINT32]; |
318 gmove(&n2, &n1); | 318 gmove(&n2, &n1); |
319 | 319 |
320 patch(p1, pc); | 320 patch(p1, pc); |
321 | 321 |
322 gmove(&n1, res); | 322 gmove(&n1, res); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 cgen(n, &tmp); | 464 cgen(n, &tmp); |
465 split64(&tmp, &lo, &hi); | 465 split64(&tmp, &lo, &hi); |
466 gmove(&lo, res); | 466 gmove(&lo, res); |
467 if(debug['B']) { | 467 if(debug['B']) { |
468 splitclean(); | 468 splitclean(); |
469 return nil; | 469 return nil; |
470 } | 470 } |
471 nodconst(&zero, types[TINT32], 0); | 471 nodconst(&zero, types[TINT32], 0); |
472 gins(ACMPL, &hi, &zero); | 472 gins(ACMPL, &hi, &zero); |
473 splitclean(); | 473 splitclean(); |
474 » return gbranch(AJNE, T); | 474 » return gbranch(AJNE, T, +1); |
475 } | 475 } |
476 ················ | 476 ················ |
477 /* | 477 /* |
478 * address gen | 478 * address gen |
479 * res = &n; | 479 * res = &n; |
480 */ | 480 */ |
481 void | 481 void |
482 agen(Node *n, Node *res) | 482 agen(Node *n, Node *res) |
483 { | 483 { |
484 Node *nl, *nr; | 484 Node *nl, *nr; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 fatal("constant string constant index"); | 588 fatal("constant string constant index"); |
589 v = mpgetfix(nr->val.u.xval); | 589 v = mpgetfix(nr->val.u.xval); |
590 if(isslice(nl->type) || nl->type->etype == TSTRING) { | 590 if(isslice(nl->type) || nl->type->etype == TSTRING) { |
591 if(!debug['B'] && !n->bounded) { | 591 if(!debug['B'] && !n->bounded) { |
592 n1 = n3; | 592 n1 = n3; |
593 n1.op = OINDREG; | 593 n1.op = OINDREG; |
594 n1.type = types[tptr]; | 594 n1.type = types[tptr]; |
595 n1.xoffset = Array_nel; | 595 n1.xoffset = Array_nel; |
596 nodconst(&n2, types[TUINT32], v); | 596 nodconst(&n2, types[TUINT32], v); |
597 gins(optoas(OCMP, types[TUINT32]), &n1,
&n2); | 597 gins(optoas(OCMP, types[TUINT32]), &n1,
&n2); |
598 » » » » » p1 = gbranch(optoas(OGT, types[TUINT32])
, T); | 598 » » » » » p1 = gbranch(optoas(OGT, types[TUINT32])
, T, +1); |
599 » » » » » expecttaken(p1, 1); | 599 » » » » » ginscall(panicindex, -1); |
600 » » » » » ginscall(panicindex, 0); | |
601 patch(p1, pc); | 600 patch(p1, pc); |
602 } | 601 } |
603 | 602 |
604 n1 = n3; | 603 n1 = n3; |
605 n1.op = OINDREG; | 604 n1.op = OINDREG; |
606 n1.type = types[tptr]; | 605 n1.type = types[tptr]; |
607 n1.xoffset = Array_array; | 606 n1.xoffset = Array_array; |
608 gmove(&n1, &n3); | 607 gmove(&n1, &n3); |
609 } | 608 } |
610 | 609 |
(...skipping 15 matching lines...) Expand all Loading... |
626 if(isconst(nl, CTSTR)) | 625 if(isconst(nl, CTSTR)) |
627 nodconst(&n1, types[TUINT32], nl->val.u.sval->le
n); | 626 nodconst(&n1, types[TUINT32], nl->val.u.sval->le
n); |
628 else if(isslice(nl->type) || nl->type->etype == TSTRING)
{ | 627 else if(isslice(nl->type) || nl->type->etype == TSTRING)
{ |
629 n1 = n3; | 628 n1 = n3; |
630 n1.op = OINDREG; | 629 n1.op = OINDREG; |
631 n1.type = types[tptr]; | 630 n1.type = types[tptr]; |
632 n1.xoffset = Array_nel; | 631 n1.xoffset = Array_nel; |
633 } else | 632 } else |
634 nodconst(&n1, types[TUINT32], nl->type->bound); | 633 nodconst(&n1, types[TUINT32], nl->type->bound); |
635 gins(optoas(OCMP, types[TUINT32]), &n2, &n1); | 634 gins(optoas(OCMP, types[TUINT32]), &n2, &n1); |
636 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T); | 635 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1); |
637 » » » expecttaken(p1, 1); | |
638 if(p2) | 636 if(p2) |
639 patch(p2, pc); | 637 patch(p2, pc); |
640 » » » ginscall(panicindex, 0); | 638 » » » ginscall(panicindex, -1); |
641 patch(p1, pc); | 639 patch(p1, pc); |
642 } | 640 } |
643 ················ | 641 ················ |
644 if(isconst(nl, CTSTR)) { | 642 if(isconst(nl, CTSTR)) { |
645 regalloc(&n3, types[tptr], res); | 643 regalloc(&n3, types[tptr], res); |
646 p1 = gins(ALEAL, N, &n3); | 644 p1 = gins(ALEAL, N, &n3); |
647 datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->
from); | 645 datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->
from); |
648 p1->from.scale = 1; | 646 p1->from.scale = 1; |
649 p1->from.index = n2.val.u.reg; | 647 p1->from.index = n2.val.u.reg; |
650 goto indexdone; | 648 goto indexdone; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 agen(n, &n1); | 793 agen(n, &n1); |
796 regalloc(a, types[tptr], res); | 794 regalloc(a, types[tptr], res); |
797 gmove(&n1, a); | 795 gmove(&n1, a); |
798 } | 796 } |
799 | 797 |
800 /* | 798 /* |
801 * branch gen | 799 * branch gen |
802 * if(n == true) goto to; | 800 * if(n == true) goto to; |
803 */ | 801 */ |
804 void | 802 void |
805 bgen(Node *n, int true, Prog *to) | 803 bgen(Node *n, int true, int likely, Prog *to) |
806 { | 804 { |
807 int et, a; | 805 int et, a; |
808 Node *nl, *nr, *r; | 806 Node *nl, *nr, *r; |
809 Node n1, n2, tmp, t1, t2, ax; | 807 Node n1, n2, tmp, t1, t2, ax; |
810 NodeList *ll; | 808 NodeList *ll; |
811 Prog *p1, *p2; | 809 Prog *p1, *p2; |
812 | 810 |
813 if(debug['g']) { | 811 if(debug['g']) { |
814 dump("\nbgen", n); | 812 dump("\nbgen", n); |
815 } | 813 } |
(...skipping 21 matching lines...) Expand all Loading... |
837 switch(n->op) { | 835 switch(n->op) { |
838 default: | 836 default: |
839 def: | 837 def: |
840 regalloc(&n1, n->type, N); | 838 regalloc(&n1, n->type, N); |
841 cgen(n, &n1); | 839 cgen(n, &n1); |
842 nodconst(&n2, n->type, 0); | 840 nodconst(&n2, n->type, 0); |
843 gins(optoas(OCMP, n->type), &n1, &n2); | 841 gins(optoas(OCMP, n->type), &n1, &n2); |
844 a = AJNE; | 842 a = AJNE; |
845 if(!true) | 843 if(!true) |
846 a = AJEQ; | 844 a = AJEQ; |
847 » » patch(gbranch(a, n->type), to); | 845 » » patch(gbranch(a, n->type, likely), to); |
848 regfree(&n1); | 846 regfree(&n1); |
849 return; | 847 return; |
850 | 848 |
851 case OLITERAL: | 849 case OLITERAL: |
852 // need to ask if it is bool? | 850 // need to ask if it is bool? |
853 if(!true == !n->val.u.bval) | 851 if(!true == !n->val.u.bval) |
854 » » » patch(gbranch(AJMP, T), to); | 852 » » » patch(gbranch(AJMP, T, 0), to); |
855 return; | 853 return; |
856 | 854 |
857 case ONAME: | 855 case ONAME: |
858 if(!n->addable) | 856 if(!n->addable) |
859 goto def; | 857 goto def; |
860 nodconst(&n1, n->type, 0); | 858 nodconst(&n1, n->type, 0); |
861 gins(optoas(OCMP, n->type), n, &n1); | 859 gins(optoas(OCMP, n->type), n, &n1); |
862 a = AJNE; | 860 a = AJNE; |
863 if(!true) | 861 if(!true) |
864 a = AJEQ; | 862 a = AJEQ; |
865 » » patch(gbranch(a, n->type), to); | 863 » » patch(gbranch(a, n->type, likely), to); |
866 return; | 864 return; |
867 | 865 |
868 case OANDAND: | 866 case OANDAND: |
869 if(!true) | 867 if(!true) |
870 goto caseor; | 868 goto caseor; |
871 | 869 |
872 caseand: | 870 caseand: |
873 » » p1 = gbranch(AJMP, T); | 871 » » p1 = gbranch(AJMP, T, 0); |
874 » » p2 = gbranch(AJMP, T); | 872 » » p2 = gbranch(AJMP, T, 0); |
875 patch(p1, pc); | 873 patch(p1, pc); |
876 » » bgen(n->left, !true, p2); | 874 » » bgen(n->left, !true, -likely, p2); |
877 » » bgen(n->right, !true, p2); | 875 » » bgen(n->right, !true, -likely, p2); |
878 » » p1 = gbranch(AJMP, T); | 876 » » p1 = gbranch(AJMP, T, 0); |
879 patch(p1, to); | 877 patch(p1, to); |
880 patch(p2, pc); | 878 patch(p2, pc); |
881 return; | 879 return; |
882 | 880 |
883 case OOROR: | 881 case OOROR: |
884 if(!true) | 882 if(!true) |
885 goto caseand; | 883 goto caseand; |
886 | 884 |
887 caseor: | 885 caseor: |
888 » » bgen(n->left, true, to); | 886 » » bgen(n->left, true, likely, to); |
889 » » bgen(n->right, true, to); | 887 » » bgen(n->right, true, likely, to); |
890 return; | 888 return; |
891 | 889 |
892 case OEQ: | 890 case OEQ: |
893 case ONE: | 891 case ONE: |
894 case OLT: | 892 case OLT: |
895 case OGT: | 893 case OGT: |
896 case OLE: | 894 case OLE: |
897 case OGE: | 895 case OGE: |
898 nr = n->right; | 896 nr = n->right; |
899 if(nr == N || nr->type == T) | 897 if(nr == N || nr->type == T) |
900 return; | 898 return; |
901 | 899 |
902 case ONOT: // unary | 900 case ONOT: // unary |
903 nl = n->left; | 901 nl = n->left; |
904 if(nl == N || nl->type == T) | 902 if(nl == N || nl->type == T) |
905 return; | 903 return; |
906 } | 904 } |
907 | 905 |
908 switch(n->op) { | 906 switch(n->op) { |
909 case ONOT: | 907 case ONOT: |
910 » » bgen(nl, !true, to); | 908 » » bgen(nl, !true, likely, to); |
911 break; | 909 break; |
912 | 910 |
913 case OEQ: | 911 case OEQ: |
914 case ONE: | 912 case ONE: |
915 case OLT: | 913 case OLT: |
916 case OGT: | 914 case OGT: |
917 case OLE: | 915 case OLE: |
918 case OGE: | 916 case OGE: |
919 a = n->op; | 917 a = n->op; |
920 if(!true) { | 918 if(!true) { |
921 if(isfloat[nl->type->etype]) { | 919 if(isfloat[nl->type->etype]) { |
922 // brcom is not valid on floats when NaN is invo
lved. | 920 // brcom is not valid on floats when NaN is invo
lved. |
923 » » » » p1 = gbranch(AJMP, T); | 921 » » » » p1 = gbranch(AJMP, T, 0); |
924 » » » » p2 = gbranch(AJMP, T); | 922 » » » » p2 = gbranch(AJMP, T, 0); |
925 patch(p1, pc); | 923 patch(p1, pc); |
926 ll = n->ninit; // avoid re-genning ninit | 924 ll = n->ninit; // avoid re-genning ninit |
927 n->ninit = nil; | 925 n->ninit = nil; |
928 » » » » bgen(n, 1, p2); | 926 » » » » bgen(n, 1, -likely, p2); |
929 n->ninit = ll; | 927 n->ninit = ll; |
930 » » » » patch(gbranch(AJMP, T), to); | 928 » » » » patch(gbranch(AJMP, T, 0), to); |
931 patch(p2, pc); | 929 patch(p2, pc); |
932 break; | 930 break; |
933 }······························· | 931 }······························· |
934 a = brcom(a); | 932 a = brcom(a); |
935 true = !true; | 933 true = !true; |
936 } | 934 } |
937 | 935 |
938 // make simplest on right | 936 // make simplest on right |
939 if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman
< UINF)) { | 937 if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman
< UINF)) { |
940 a = brrev(a); | 938 a = brrev(a); |
(...skipping 10 matching lines...) Expand all Loading... |
951 } | 949 } |
952 a = optoas(a, types[tptr]); | 950 a = optoas(a, types[tptr]); |
953 regalloc(&n1, types[tptr], N); | 951 regalloc(&n1, types[tptr], N); |
954 agen(nl, &n1); | 952 agen(nl, &n1); |
955 n2 = n1; | 953 n2 = n1; |
956 n2.op = OINDREG; | 954 n2.op = OINDREG; |
957 n2.xoffset = Array_array; | 955 n2.xoffset = Array_array; |
958 n2.type = types[tptr]; | 956 n2.type = types[tptr]; |
959 nodconst(&tmp, types[tptr], 0); | 957 nodconst(&tmp, types[tptr], 0); |
960 gins(optoas(OCMP, types[tptr]), &n2, &tmp); | 958 gins(optoas(OCMP, types[tptr]), &n2, &tmp); |
961 » » » patch(gbranch(a, types[tptr]), to); | 959 » » » patch(gbranch(a, types[tptr], likely), to); |
962 regfree(&n1); | 960 regfree(&n1); |
963 break; | 961 break; |
964 } | 962 } |
965 | 963 |
966 if(isinter(nl->type)) { | 964 if(isinter(nl->type)) { |
967 // front end should only leave cmp to literal nil | 965 // front end should only leave cmp to literal nil |
968 if((a != OEQ && a != ONE) || nr->op != OLITERAL) { | 966 if((a != OEQ && a != ONE) || nr->op != OLITERAL) { |
969 yyerror("illegal interface comparison"); | 967 yyerror("illegal interface comparison"); |
970 break; | 968 break; |
971 } | 969 } |
972 a = optoas(a, types[tptr]); | 970 a = optoas(a, types[tptr]); |
973 regalloc(&n1, types[tptr], N); | 971 regalloc(&n1, types[tptr], N); |
974 agen(nl, &n1); | 972 agen(nl, &n1); |
975 n2 = n1; | 973 n2 = n1; |
976 n2.op = OINDREG; | 974 n2.op = OINDREG; |
977 n2.xoffset = 0; | 975 n2.xoffset = 0; |
978 nodconst(&tmp, types[tptr], 0); | 976 nodconst(&tmp, types[tptr], 0); |
979 gins(optoas(OCMP, types[tptr]), &n2, &tmp); | 977 gins(optoas(OCMP, types[tptr]), &n2, &tmp); |
980 » » » patch(gbranch(a, types[tptr]), to); | 978 » » » patch(gbranch(a, types[tptr], likely), to); |
981 regfree(&n1); | 979 regfree(&n1); |
982 break; | 980 break; |
983 } | 981 } |
984 | 982 |
985 if(isfloat[nr->type->etype]) { | 983 if(isfloat[nr->type->etype]) { |
986 a = brrev(a); // because the args are stacked | 984 a = brrev(a); // because the args are stacked |
987 if(a == OGE || a == OGT) { | 985 if(a == OGE || a == OGT) { |
988 // only < and <= work right with NaN; reverse if
needed | 986 // only < and <= work right with NaN; reverse if
needed |
989 r = nr; | 987 r = nr; |
990 nr = nl; | 988 nr = nl; |
(...skipping 26 matching lines...) Expand all Loading... |
1017 tempname(&t2, types[TFLOAT32]); | 1015 tempname(&t2, types[TFLOAT32]); |
1018 cgen(nr, &t1); | 1016 cgen(nr, &t1); |
1019 cgen(nl, &t2); | 1017 cgen(nl, &t2); |
1020 gmove(&t2, &tmp); | 1018 gmove(&t2, &tmp); |
1021 gins(AFCOMFP, &t1, &tmp); | 1019 gins(AFCOMFP, &t1, &tmp); |
1022 gins(AFSTSW, N, &ax); | 1020 gins(AFSTSW, N, &ax); |
1023 gins(ASAHF, N, N); | 1021 gins(ASAHF, N, N); |
1024 } | 1022 } |
1025 if(a == OEQ) { | 1023 if(a == OEQ) { |
1026 // neither NE nor P | 1024 // neither NE nor P |
1027 » » » » p1 = gbranch(AJNE, T); | 1025 » » » » p1 = gbranch(AJNE, T, -likely); |
1028 » » » » p2 = gbranch(AJPS, T); | 1026 » » » » p2 = gbranch(AJPS, T, -likely); |
1029 » » » » patch(gbranch(AJMP, T), to); | 1027 » » » » patch(gbranch(AJMP, T, 0), to); |
1030 patch(p1, pc); | 1028 patch(p1, pc); |
1031 patch(p2, pc); | 1029 patch(p2, pc); |
1032 } else if(a == ONE) { | 1030 } else if(a == ONE) { |
1033 // either NE or P | 1031 // either NE or P |
1034 » » » » patch(gbranch(AJNE, T), to); | 1032 » » » » patch(gbranch(AJNE, T, likely), to); |
1035 » » » » patch(gbranch(AJPS, T), to); | 1033 » » » » patch(gbranch(AJPS, T, likely), to); |
1036 } else | 1034 } else |
1037 » » » » patch(gbranch(optoas(a, nr->type), T), to); | 1035 » » » » patch(gbranch(optoas(a, nr->type), T, likely), t
o); |
1038 break; | 1036 break; |
1039 } | 1037 } |
1040 if(iscomplex[nl->type->etype]) { | 1038 if(iscomplex[nl->type->etype]) { |
1041 » » » complexbool(a, nl, nr, true, to); | 1039 » » » complexbool(a, nl, nr, true, likely, to); |
1042 break; | 1040 break; |
1043 } | 1041 } |
1044 | 1042 |
1045 if(is64(nr->type)) { | 1043 if(is64(nr->type)) { |
1046 if(!nl->addable) { | 1044 if(!nl->addable) { |
1047 tempname(&n1, nl->type); | 1045 tempname(&n1, nl->type); |
1048 cgen(nl, &n1); | 1046 cgen(nl, &n1); |
1049 nl = &n1; | 1047 nl = &n1; |
1050 } | 1048 } |
1051 if(!nr->addable) { | 1049 if(!nr->addable) { |
1052 tempname(&n2, nr->type); | 1050 tempname(&n2, nr->type); |
1053 cgen(nr, &n2); | 1051 cgen(nr, &n2); |
1054 nr = &n2; | 1052 nr = &n2; |
1055 } | 1053 } |
1056 » » » cmp64(nl, nr, a, to); | 1054 » » » cmp64(nl, nr, a, likely, to); |
1057 break; | 1055 break; |
1058 } | 1056 } |
1059 | 1057 |
1060 a = optoas(a, nr->type); | 1058 a = optoas(a, nr->type); |
1061 | 1059 |
1062 if(nr->ullman >= UINF) { | 1060 if(nr->ullman >= UINF) { |
1063 tempname(&n1, nl->type); | 1061 tempname(&n1, nl->type); |
1064 tempname(&tmp, nr->type); | 1062 tempname(&tmp, nr->type); |
1065 cgen(nl, &n1); | 1063 cgen(nl, &n1); |
1066 cgen(nr, &tmp); | 1064 cgen(nr, &tmp); |
1067 regalloc(&n2, nr->type, N); | 1065 regalloc(&n2, nr->type, N); |
1068 cgen(&tmp, &n2); | 1066 cgen(&tmp, &n2); |
1069 goto cmp; | 1067 goto cmp; |
1070 } | 1068 } |
1071 | 1069 |
1072 tempname(&n1, nl->type); | 1070 tempname(&n1, nl->type); |
1073 cgen(nl, &n1); | 1071 cgen(nl, &n1); |
1074 | 1072 |
1075 if(smallintconst(nr)) { | 1073 if(smallintconst(nr)) { |
1076 gins(optoas(OCMP, nr->type), &n1, nr); | 1074 gins(optoas(OCMP, nr->type), &n1, nr); |
1077 » » » patch(gbranch(a, nr->type), to); | 1075 » » » patch(gbranch(a, nr->type, likely), to); |
1078 break; | 1076 break; |
1079 } | 1077 } |
1080 | 1078 |
1081 tempname(&tmp, nr->type); | 1079 tempname(&tmp, nr->type); |
1082 cgen(nr, &tmp); | 1080 cgen(nr, &tmp); |
1083 regalloc(&n2, nr->type, N); | 1081 regalloc(&n2, nr->type, N); |
1084 gmove(&tmp, &n2); | 1082 gmove(&tmp, &n2); |
1085 | 1083 |
1086 cmp: | 1084 cmp: |
1087 gins(optoas(OCMP, nr->type), &n1, &n2); | 1085 gins(optoas(OCMP, nr->type), &n1, &n2); |
1088 » » patch(gbranch(a, nr->type), to); | 1086 » » patch(gbranch(a, nr->type, likely), to); |
1089 regfree(&n2); | 1087 regfree(&n2); |
1090 break; | 1088 break; |
1091 } | 1089 } |
1092 } | 1090 } |
1093 | 1091 |
1094 /* | 1092 /* |
1095 * n is on stack, either local variable | 1093 * n is on stack, either local variable |
1096 * or return value from function call. | 1094 * or return value from function call. |
1097 * return n's offset from SP. | 1095 * return n's offset from SP. |
1098 */ | 1096 */ |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+ | 1248 gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+ |
1251 q--; | 1249 q--; |
1252 } | 1250 } |
1253 while(c > 0) { | 1251 while(c > 0) { |
1254 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ | 1252 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ |
1255 c--; | 1253 c--; |
1256 } | 1254 } |
1257 } | 1255 } |
1258 } | 1256 } |
1259 | 1257 |
LEFT | RIGHT |