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

Side by Side Diff: src/cmd/gc/gen.c

Issue 160200044: [dev.power64] code review 160200044: build: merge default into dev.power64 (Closed)
Patch Set: diff -r be0c14f62257b42485019e9e1db23cf40d2e249f https://code.google.com/p/go Created 10 years, 4 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 | « src/cmd/gc/fmt.c ('k') | src/cmd/gc/go.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 /* 5 /*
6 * portable half of code generator. 6 * portable half of code generator.
7 * mainly statements and control flow. 7 * mainly statements and control flow.
8 */ 8 */
9 9
10 #include <u.h> 10 #include <u.h>
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 * res = s[lo, hi]; 799 * res = s[lo, hi];
800 * n->left is s 800 * n->left is s
801 * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)]) 801 * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)])
802 * caller (cgen) guarantees res is an addable ONAME. 802 * caller (cgen) guarantees res is an addable ONAME.
803 * 803 *
804 * called for OSLICE, OSLICE3, OSLICEARR, OSLICE3ARR, OSLICESTR. 804 * called for OSLICE, OSLICE3, OSLICEARR, OSLICE3ARR, OSLICESTR.
805 */ 805 */
806 void 806 void
807 cgen_slice(Node *n, Node *res) 807 cgen_slice(Node *n, Node *res)
808 { 808 {
809 » Node src, dst, *cap, *len, *offs, *add, *base; 809 » Node src, dst, *cap, *len, *offs, *add, *base, *tmpcap, *tmplen, *cmp, c on;
810 » Prog *p1, *p2;
810 811
811 cap = n->list->n; 812 cap = n->list->n;
812 len = n->list->next->n; 813 len = n->list->next->n;
813 offs = N; 814 offs = N;
814 if(n->list->next->next) 815 if(n->list->next->next)
815 offs = n->list->next->next->n; 816 offs = n->list->next->next->n;
816 817
817 // evaluate base pointer first, because it is the only 818 // evaluate base pointer first, because it is the only
818 // possibly complex expression. once that is evaluated 819 // possibly complex expression. once that is evaluated
819 // and stored, updating the len and cap can be done 820 // and stored, updating the len and cap can be done
820 // without making any calls, so without doing anything that 821 // without making any calls, so without doing anything that
821 // might cause preemption or garbage collection. 822 // might cause preemption or garbage collection.
822 // this makes the whole slice update atomic as far as the 823 // this makes the whole slice update atomic as far as the
823 // garbage collector can see. 824 // garbage collector can see.
824 ········ 825 ········
825 base = temp(types[TUINTPTR]); 826 base = temp(types[TUINTPTR]);
827 tmplen = temp(types[TINT]);
828 if(n->op != OSLICESTR)
829 tmpcap = temp(types[TINT]);
830 else
831 tmpcap = tmplen;
826 832
827 if(isnil(n->left)) { 833 if(isnil(n->left)) {
828 tempname(&src, n->left->type); 834 tempname(&src, n->left->type);
829 cgen(n->left, &src); 835 cgen(n->left, &src);
830 } else 836 } else
831 src = *n->left; 837 src = *n->left;
832 if(n->op == OSLICE || n->op == OSLICE3 || n->op == OSLICESTR) 838 if(n->op == OSLICE || n->op == OSLICE3 || n->op == OSLICESTR)
833 src.xoffset += Array_array; 839 src.xoffset += Array_array;
834 840
835 if(n->op == OSLICEARR || n->op == OSLICE3ARR) { 841 if(n->op == OSLICEARR || n->op == OSLICE3ARR) {
836 if(!isptr[n->left->type->etype]) 842 if(!isptr[n->left->type->etype])
837 fatal("slicearr is supposed to work on pointer: %+N\n", n); 843 fatal("slicearr is supposed to work on pointer: %+N\n", n);
838 cgen(&src, base); 844 cgen(&src, base);
839 cgen_checknil(base); 845 cgen_checknil(base);
840 » » if(offs != N) { 846 » } else {
841 » » » add = nod(OADD, base, offs);
842 » » » typecheck(&add, Erv);
843 » » » cgen(add, base);
844 » » }
845 » } else if(offs == N) {
846 src.type = types[tptr]; 847 src.type = types[tptr];
847 cgen(&src, base); 848 cgen(&src, base);
848 } else {
849 src.type = types[tptr];
850 add = nod(OADDPTR, &src, offs);
851 typecheck(&add, Erv);
852 cgen(add, base);
853 } 849 }
854 ········ 850 ········
855 // committed to the update 851 // committed to the update
856 gvardef(res); 852 gvardef(res);
857 853
854 // compute len and cap.
855 // len = n-i, cap = m-i, and offs = i*width.
856 // computing offs last lets the multiply overwrite i.
857 cgen(len, tmplen);
858 if(n->op != OSLICESTR)
859 cgen(cap, tmpcap);
860
861 // if new cap != 0 { base += add }
862 // This avoids advancing base past the end of the underlying array/strin g,
863 // so that it cannot point at the next object in memory.
864 // If cap == 0, the base doesn't matter except insofar as it is 0 or non -zero.
865 // In essence we are replacing x[i:j:k] where i == j == k
866 // or x[i:j] where i == j == cap(x) with x[0:0:0].
867 if(offs != N) {
868 p1 = gjmp(P);
869 p2 = gjmp(P);
870 patch(p1, pc);
871
872 nodconst(&con, tmpcap->type, 0);
873 cmp = nod(OEQ, tmpcap, &con);
874 typecheck(&cmp, Erv);
875 bgen(cmp, 1, -1, p2);
876
877 add = nod(OADD, base, offs);
878 typecheck(&add, Erv);
879 cgen(add, base);
880
881 patch(p2, pc);
882 }
883
858 // dst.array = src.array [ + lo *width ] 884 // dst.array = src.array [ + lo *width ]
859 dst = *res; 885 dst = *res;
860 dst.xoffset += Array_array; 886 dst.xoffset += Array_array;
861 dst.type = types[tptr]; 887 dst.type = types[tptr];
862 ········
863 cgen(base, &dst); 888 cgen(base, &dst);
864 889
865 // dst.len = hi [ - lo ] 890 // dst.len = hi [ - lo ]
866 dst = *res; 891 dst = *res;
867 dst.xoffset += Array_nel; 892 dst.xoffset += Array_nel;
868 dst.type = types[simtype[TUINT]]; 893 dst.type = types[simtype[TUINT]];
869 » cgen(len, &dst); 894 » cgen(tmplen, &dst);
870 895
871 if(n->op != OSLICESTR) { 896 if(n->op != OSLICESTR) {
872 // dst.cap = cap [ - lo ] 897 // dst.cap = cap [ - lo ]
873 dst = *res; 898 dst = *res;
874 dst.xoffset += Array_cap; 899 dst.xoffset += Array_cap;
875 dst.type = types[simtype[TUINT]]; 900 dst.type = types[simtype[TUINT]];
876 » » cgen(cap, &dst); 901 » » cgen(tmpcap, &dst);
877 } 902 }
878 } 903 }
879 904
880 /* 905 /*
881 * gather series of offsets 906 * gather series of offsets
882 * >=0 is direct addressed field 907 * >=0 is direct addressed field
883 * <0 is pointer to next field (+1) 908 * <0 is pointer to next field (+1)
884 */ 909 */
885 int 910 int
886 dotoffset(Node *n, int64 *oary, Node **nn) 911 dotoffset(Node *n, int64 *oary, Node **nn)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 Node* 990 Node*
966 temp(Type *t) 991 temp(Type *t)
967 { 992 {
968 Node *n; 993 Node *n;
969 ········ 994 ········
970 n = nod(OXXX, N, N); 995 n = nod(OXXX, N, N);
971 tempname(n, t); 996 tempname(n, t);
972 n->sym->def->used = 1; 997 n->sym->def->used = 1;
973 return n->orig; 998 return n->orig;
974 } 999 }
OLDNEW
« no previous file with comments | « src/cmd/gc/fmt.c ('k') | src/cmd/gc/go.h » ('j') | no next file with comments »

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