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

Side by Side Diff: src/pkg/runtime/vlrt_arm.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/pkg/runtime/vlrt_386.c ('k') | src/pkg/strconv/isprint.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Inferno's libkern/vlrt-arm.c
2 // http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-arm.c
3 //
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 // Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vita nuova.com). All rights reserved.
6 // Portions Copyright 2009 The Go Authors. All rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 // THE SOFTWARE.
25
26 #include "../../cmd/ld/textflag.h"
27
28 // declared here to avoid include of runtime.h
29 void runtime·panicstring(char*);
30 void runtime·panicdivide(void);
31
32 typedef unsigned long ulong;
33 typedef unsigned int uint;
34 typedef unsigned short ushort;
35 typedef unsigned char uchar;
36 typedef signed char schar;
37
38 #define SIGN(n) (1UL<<(n-1))
39
40 typedef struct Vlong Vlong;
41 struct Vlong
42 {
43 union
44 {
45 struct
46 {
47 ulong lo;
48 ulong hi;
49 };
50 struct
51 {
52 ushort lols;
53 ushort loms;
54 ushort hils;
55 ushort hims;
56 };
57 };
58 };
59
60 void runtime·abort(void);
61
62 #pragma textflag NOSPLIT
63 void
64 _addv(Vlong *r, Vlong a, Vlong b)
65 {
66 r->lo = a.lo + b.lo;
67 r->hi = a.hi + b.hi;
68 if(r->lo < a.lo)
69 r->hi++;
70 }
71
72 #pragma textflag NOSPLIT
73 void
74 _subv(Vlong *r, Vlong a, Vlong b)
75 {
76 r->lo = a.lo - b.lo;
77 r->hi = a.hi - b.hi;
78 if(r->lo > a.lo)
79 r->hi--;
80 }
81
82 void
83 _d2v(Vlong *y, double d)
84 {
85 union { double d; struct Vlong; } x;
86 ulong xhi, xlo, ylo, yhi;
87 int sh;
88
89 x.d = d;
90
91 xhi = (x.hi & 0xfffff) | 0x100000;
92 xlo = x.lo;
93 sh = 1075 - ((x.hi >> 20) & 0x7ff);
94
95 ylo = 0;
96 yhi = 0;
97 if(sh >= 0) {
98 /* v = (hi||lo) >> sh */
99 if(sh < 32) {
100 if(sh == 0) {
101 ylo = xlo;
102 yhi = xhi;
103 } else {
104 ylo = (xlo >> sh) | (xhi << (32-sh));
105 yhi = xhi >> sh;
106 }
107 } else {
108 if(sh == 32) {
109 ylo = xhi;
110 } else
111 if(sh < 64) {
112 ylo = xhi >> (sh-32);
113 }
114 }
115 } else {
116 /* v = (hi||lo) << -sh */
117 sh = -sh;
118 if(sh <= 11) {
119 ylo = xlo << sh;
120 yhi = (xhi << sh) | (xlo >> (32-sh));
121 } else {
122 /* overflow */
123 yhi = d; /* causes something awful */
124 }
125 }
126 if(x.hi & SIGN(32)) {
127 if(ylo != 0) {
128 ylo = -ylo;
129 yhi = ~yhi;
130 } else
131 yhi = -yhi;
132 }
133
134 y->hi = yhi;
135 y->lo = ylo;
136 }
137
138 void
139 _f2v(Vlong *y, float f)
140 {
141 _d2v(y, f);
142 }
143
144 void
145 runtime·float64toint64(double d, Vlong y)
146 {
147 _d2v(&y, d);
148 }
149
150 void
151 runtime·float64touint64(double d, Vlong y)
152 {
153 _d2v(&y, d);
154 }
155
156 double
157 _ul2d(ulong u)
158 {
159 // compensate for bug in c
160 if(u & SIGN(32)) {
161 u ^= SIGN(32);
162 return 2147483648. + u;
163 }
164 return u;
165 }
166
167 double
168 _v2d(Vlong x)
169 {
170 if(x.hi & SIGN(32)) {
171 if(x.lo) {
172 x.lo = -x.lo;
173 x.hi = ~x.hi;
174 } else
175 x.hi = -x.hi;
176 return -(_ul2d(x.hi)*4294967296. + _ul2d(x.lo));
177 }
178 return x.hi*4294967296. + _ul2d(x.lo);
179 }
180
181 float
182 _v2f(Vlong x)
183 {
184 return _v2d(x);
185 }
186
187 void
188 runtime·int64tofloat64(Vlong y, double d)
189 {
190 d = _v2d(y);
191 USED(&d); // FLUSH
192 }
193
194 void
195 runtime·uint64tofloat64(Vlong y, double d)
196 {
197 d = _ul2d(y.hi)*4294967296. + _ul2d(y.lo);
198 USED(&d); // FLUSH
199 }
200
201 static void
202 dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
203 {
204 ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
205 int i;
206
207 numhi = num.hi;
208 numlo = num.lo;
209 denhi = den.hi;
210 denlo = den.lo;
211
212 /*
213 * get a divide by zero
214 */
215 if(denlo==0 && denhi==0) {
216 runtime·panicdivide();
217 }
218
219 /*
220 * set up the divisor and find the number of iterations needed
221 */
222 if(numhi >= SIGN(32)) {
223 quohi = SIGN(32);
224 quolo = 0;
225 } else {
226 quohi = numhi;
227 quolo = numlo;
228 }
229 i = 0;
230 while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
231 denhi = (denhi<<1) | (denlo>>31);
232 denlo <<= 1;
233 i++;
234 }
235
236 quohi = 0;
237 quolo = 0;
238 for(; i >= 0; i--) {
239 quohi = (quohi<<1) | (quolo>>31);
240 quolo <<= 1;
241 if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
242 t = numlo;
243 numlo -= denlo;
244 if(numlo > t)
245 numhi--;
246 numhi -= denhi;
247 quolo |= 1;
248 }
249 denlo = (denlo>>1) | (denhi<<31);
250 denhi >>= 1;
251 }
252
253 if(q) {
254 q->lo = quolo;
255 q->hi = quohi;
256 }
257 if(r) {
258 r->lo = numlo;
259 r->hi = numhi;
260 }
261 }
262
263 void
264 _divvu(Vlong *q, Vlong n, Vlong d)
265 {
266
267 if(n.hi == 0 && d.hi == 0) {
268 q->hi = 0;
269 q->lo = n.lo / d.lo;
270 return;
271 }
272 dodiv(n, d, q, 0);
273 }
274
275 void
276 runtime·uint64div(Vlong n, Vlong d, Vlong q)
277 {
278 _divvu(&q, n, d);
279 }
280
281 void
282 _modvu(Vlong *r, Vlong n, Vlong d)
283 {
284
285 if(n.hi == 0 && d.hi == 0) {
286 r->hi = 0;
287 r->lo = n.lo % d.lo;
288 return;
289 }
290 dodiv(n, d, 0, r);
291 }
292
293 void
294 runtime·uint64mod(Vlong n, Vlong d, Vlong q)
295 {
296 _modvu(&q, n, d);
297 }
298
299 static void
300 vneg(Vlong *v)
301 {
302
303 if(v->lo == 0) {
304 v->hi = -v->hi;
305 return;
306 }
307 v->lo = -v->lo;
308 v->hi = ~v->hi;
309 }
310
311 void
312 _divv(Vlong *q, Vlong n, Vlong d)
313 {
314 long nneg, dneg;
315
316 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
317 if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
318 // special case: 32-bit -0x80000000 / -1 causes wrong si gn
319 q->lo = 0x80000000;
320 q->hi = 0;
321 return;
322 }
323 q->lo = (long)n.lo / (long)d.lo;
324 q->hi = ((long)q->lo) >> 31;
325 return;
326 }
327 nneg = n.hi >> 31;
328 if(nneg)
329 vneg(&n);
330 dneg = d.hi >> 31;
331 if(dneg)
332 vneg(&d);
333 dodiv(n, d, q, 0);
334 if(nneg != dneg)
335 vneg(q);
336 }
337
338 void
339 runtime·int64div(Vlong n, Vlong d, Vlong q)
340 {
341 _divv(&q, n, d);
342 }
343
344 void
345 _modv(Vlong *r, Vlong n, Vlong d)
346 {
347 long nneg, dneg;
348
349 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
350 r->lo = (long)n.lo % (long)d.lo;
351 r->hi = ((long)r->lo) >> 31;
352 return;
353 }
354 nneg = n.hi >> 31;
355 if(nneg)
356 vneg(&n);
357 dneg = d.hi >> 31;
358 if(dneg)
359 vneg(&d);
360 dodiv(n, d, 0, r);
361 if(nneg)
362 vneg(r);
363 }
364
365 void
366 runtime·int64mod(Vlong n, Vlong d, Vlong q)
367 {
368 _modv(&q, n, d);
369 }
370
371 void
372 _rshav(Vlong *r, Vlong a, int b)
373 {
374 long t;
375
376 t = a.hi;
377 if(b >= 32) {
378 r->hi = t>>31;
379 if(b >= 64) {
380 /* this is illegal re C standard */
381 r->lo = t>>31;
382 return;
383 }
384 r->lo = t >> (b-32);
385 return;
386 }
387 if(b <= 0) {
388 r->hi = t;
389 r->lo = a.lo;
390 return;
391 }
392 r->hi = t >> b;
393 r->lo = (t << (32-b)) | (a.lo >> b);
394 }
395
396 void
397 _rshlv(Vlong *r, Vlong a, int b)
398 {
399 ulong t;
400
401 t = a.hi;
402 if(b >= 32) {
403 r->hi = 0;
404 if(b >= 64) {
405 /* this is illegal re C standard */
406 r->lo = 0;
407 return;
408 }
409 r->lo = t >> (b-32);
410 return;
411 }
412 if(b <= 0) {
413 r->hi = t;
414 r->lo = a.lo;
415 return;
416 }
417 r->hi = t >> b;
418 r->lo = (t << (32-b)) | (a.lo >> b);
419 }
420
421 #pragma textflag NOSPLIT
422 void
423 _lshv(Vlong *r, Vlong a, int b)
424 {
425 if(b >= 32) {
426 r->lo = 0;
427 if(b >= 64) {
428 /* this is illegal re C standard */
429 r->hi = 0;
430 return;
431 }
432 r->hi = a.lo << (b-32);
433 return;
434 }
435 if(b <= 0) {
436 r->lo = a.lo;
437 r->hi = a.hi;
438 return;
439 }
440 r->lo = a.lo << b;
441 r->hi = (a.lo >> (32-b)) | (a.hi << b);
442 }
443
444 void
445 _andv(Vlong *r, Vlong a, Vlong b)
446 {
447 r->hi = a.hi & b.hi;
448 r->lo = a.lo & b.lo;
449 }
450
451 void
452 _orv(Vlong *r, Vlong a, Vlong b)
453 {
454 r->hi = a.hi | b.hi;
455 r->lo = a.lo | b.lo;
456 }
457
458 void
459 _xorv(Vlong *r, Vlong a, Vlong b)
460 {
461 r->hi = a.hi ^ b.hi;
462 r->lo = a.lo ^ b.lo;
463 }
464
465 void
466 _vpp(Vlong *l, Vlong *r)
467 {
468
469 l->hi = r->hi;
470 l->lo = r->lo;
471 r->lo++;
472 if(r->lo == 0)
473 r->hi++;
474 }
475
476 void
477 _vmm(Vlong *l, Vlong *r)
478 {
479
480 l->hi = r->hi;
481 l->lo = r->lo;
482 if(r->lo == 0)
483 r->hi--;
484 r->lo--;
485 }
486
487 void
488 _ppv(Vlong *l, Vlong *r)
489 {
490
491 r->lo++;
492 if(r->lo == 0)
493 r->hi++;
494 l->hi = r->hi;
495 l->lo = r->lo;
496 }
497
498 void
499 _mmv(Vlong *l, Vlong *r)
500 {
501
502 if(r->lo == 0)
503 r->hi--;
504 r->lo--;
505 l->hi = r->hi;
506 l->lo = r->lo;
507 }
508
509 #pragma textflag NOSPLIT
510 void
511 _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
512 {
513 Vlong t, u;
514
515 u = *ret;
516 switch(type) {
517 default:
518 runtime·abort();
519 break;
520
521 case 1: /* schar */
522 t.lo = *(schar*)lv;
523 t.hi = t.lo >> 31;
524 fn(&u, t, rv);
525 *(schar*)lv = u.lo;
526 break;
527
528 case 2: /* uchar */
529 t.lo = *(uchar*)lv;
530 t.hi = 0;
531 fn(&u, t, rv);
532 *(uchar*)lv = u.lo;
533 break;
534
535 case 3: /* short */
536 t.lo = *(short*)lv;
537 t.hi = t.lo >> 31;
538 fn(&u, t, rv);
539 *(short*)lv = u.lo;
540 break;
541
542 case 4: /* ushort */
543 t.lo = *(ushort*)lv;
544 t.hi = 0;
545 fn(&u, t, rv);
546 *(ushort*)lv = u.lo;
547 break;
548
549 case 9: /* int */
550 t.lo = *(int*)lv;
551 t.hi = t.lo >> 31;
552 fn(&u, t, rv);
553 *(int*)lv = u.lo;
554 break;
555
556 case 10: /* uint */
557 t.lo = *(uint*)lv;
558 t.hi = 0;
559 fn(&u, t, rv);
560 *(uint*)lv = u.lo;
561 break;
562
563 case 5: /* long */
564 t.lo = *(long*)lv;
565 t.hi = t.lo >> 31;
566 fn(&u, t, rv);
567 *(long*)lv = u.lo;
568 break;
569
570 case 6: /* ulong */
571 t.lo = *(ulong*)lv;
572 t.hi = 0;
573 fn(&u, t, rv);
574 *(ulong*)lv = u.lo;
575 break;
576
577 case 7: /* vlong */
578 case 8: /* uvlong */
579 fn(&u, *(Vlong*)lv, rv);
580 *(Vlong*)lv = u;
581 break;
582 }
583 *ret = u;
584 }
585
586 void
587 _p2v(Vlong *ret, void *p)
588 {
589 long t;
590
591 t = (ulong)p;
592 ret->lo = t;
593 ret->hi = 0;
594 }
595
596 void
597 _sl2v(Vlong *ret, long sl)
598 {
599 long t;
600
601 t = sl;
602 ret->lo = t;
603 ret->hi = t >> 31;
604 }
605
606 void
607 _ul2v(Vlong *ret, ulong ul)
608 {
609 long t;
610
611 t = ul;
612 ret->lo = t;
613 ret->hi = 0;
614 }
615
616 #pragma textflag NOSPLIT
617 void
618 _si2v(Vlong *ret, int si)
619 {
620 ret->lo = (long)si;
621 ret->hi = (long)si >> 31;
622 }
623
624 void
625 _ui2v(Vlong *ret, uint ui)
626 {
627 long t;
628
629 t = ui;
630 ret->lo = t;
631 ret->hi = 0;
632 }
633
634 void
635 _sh2v(Vlong *ret, long sh)
636 {
637 long t;
638
639 t = (sh << 16) >> 16;
640 ret->lo = t;
641 ret->hi = t >> 31;
642 }
643
644 void
645 _uh2v(Vlong *ret, ulong ul)
646 {
647 long t;
648
649 t = ul & 0xffff;
650 ret->lo = t;
651 ret->hi = 0;
652 }
653
654 void
655 _sc2v(Vlong *ret, long uc)
656 {
657 long t;
658
659 t = (uc << 24) >> 24;
660 ret->lo = t;
661 ret->hi = t >> 31;
662 }
663
664 void
665 _uc2v(Vlong *ret, ulong ul)
666 {
667 long t;
668
669 t = ul & 0xff;
670 ret->lo = t;
671 ret->hi = 0;
672 }
673
674 long
675 _v2sc(Vlong rv)
676 {
677 long t;
678
679 t = rv.lo & 0xff;
680 return (t << 24) >> 24;
681 }
682
683 long
684 _v2uc(Vlong rv)
685 {
686
687 return rv.lo & 0xff;
688 }
689
690 long
691 _v2sh(Vlong rv)
692 {
693 long t;
694
695 t = rv.lo & 0xffff;
696 return (t << 16) >> 16;
697 }
698
699 long
700 _v2uh(Vlong rv)
701 {
702
703 return rv.lo & 0xffff;
704 }
705
706 long
707 _v2sl(Vlong rv)
708 {
709
710 return rv.lo;
711 }
712
713 long
714 _v2ul(Vlong rv)
715 {
716
717 return rv.lo;
718 }
719
720 #pragma textflag NOSPLIT
721 long
722 _v2si(Vlong rv)
723 {
724
725 return rv.lo;
726 }
727
728 long
729 _v2ui(Vlong rv)
730 {
731
732 return rv.lo;
733 }
734
735 int
736 _testv(Vlong rv)
737 {
738 return rv.lo || rv.hi;
739 }
740
741 int
742 _eqv(Vlong lv, Vlong rv)
743 {
744 return lv.lo == rv.lo && lv.hi == rv.hi;
745 }
746
747 int
748 _nev(Vlong lv, Vlong rv)
749 {
750 return lv.lo != rv.lo || lv.hi != rv.hi;
751 }
752
753 int
754 _ltv(Vlong lv, Vlong rv)
755 {
756 return (long)lv.hi < (long)rv.hi ||
757 (lv.hi == rv.hi && lv.lo < rv.lo);
758 }
759
760 int
761 _lev(Vlong lv, Vlong rv)
762 {
763 return (long)lv.hi < (long)rv.hi ||
764 (lv.hi == rv.hi && lv.lo <= rv.lo);
765 }
766
767 int
768 _gtv(Vlong lv, Vlong rv)
769 {
770 return (long)lv.hi > (long)rv.hi ||
771 (lv.hi == rv.hi && lv.lo > rv.lo);
772 }
773
774 #pragma textflag NOSPLIT
775 int
776 _gev(Vlong lv, Vlong rv)
777 {
778 return (long)lv.hi > (long)rv.hi ||
779 (lv.hi == rv.hi && lv.lo >= rv.lo);
780 }
781
782 int
783 _lov(Vlong lv, Vlong rv)
784 {
785 return lv.hi < rv.hi ||
786 (lv.hi == rv.hi && lv.lo < rv.lo);
787 }
788
789 int
790 _lsv(Vlong lv, Vlong rv)
791 {
792 return lv.hi < rv.hi ||
793 (lv.hi == rv.hi && lv.lo <= rv.lo);
794 }
795
796 int
797 _hiv(Vlong lv, Vlong rv)
798 {
799 return lv.hi > rv.hi ||
800 (lv.hi == rv.hi && lv.lo > rv.lo);
801 }
802
803 int
804 _hsv(Vlong lv, Vlong rv)
805 {
806 return lv.hi > rv.hi ||
807 (lv.hi == rv.hi && lv.lo >= rv.lo);
808 }
OLDNEW
« no previous file with comments | « src/pkg/runtime/vlrt_386.c ('k') | src/pkg/strconv/isprint.go » ('j') | no next file with comments »

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