1 // Derived from Inferno utils/8c/txt.c
2 // http://code.google.com/p/inferno-os/source/browse/utils/8c/txt.c
3 //
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6 // Portions Copyright © 1997-1999 Vita Nuova Limited
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8 // Portions Copyright © 2004,2006 Bruce Ellis
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11 // Portions Copyright © 2009 The Go Authors. All rights reserved.
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a copy
14 // of this software and associated documentation files (the "Software"), to deal
15 // in the Software without restriction, including without limitation the rights
16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 // copies of the Software, and to permit persons to whom the Software is
18 // furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included in
21 // all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 // THE SOFTWARE.
30
31 #include "gg.h"
32
33 // TODO(rsc): Can make this bigger if we move
34 // the text segment up higher in 8l for all GOOS.
35 uint32 unmappedzero = 4096;
36
37 #define CASE(a,b) (((a)<<16)|((b)<<0))
38
39 void
40 clearp(Prog *p)
41 {
42 p->as = AEND;
43 p->from.type = D_NONE;
44 p->from.index = D_NONE;
45 p->to.type = D_NONE;
46 p->to.index = D_NONE;
47 p->loc = pcloc;
48 pcloc++;
49 }
50
51 /*
52 * generate and return proc with p->as = as,
53 * linked into program. pc is next instruction.
54 */
55 Prog*
56 prog(int as)
57 {
58 Prog *p;
59
60 p = pc;
61 pc = mal(sizeof(*pc));
62
63 clearp(pc);
64
65 if(lineno == 0) {
66 if(debug['K'])
67 warn("prog: line 0");
68 }
69
70 p->as = as;
71 p->lineno = lineno;
72 p->link = pc;
73 return p;
74 }
75
76 /*
77 * generate a branch.
78 * t is ignored.
79 */
80 Prog*
81 gbranch(int as, Type *t)
82 {
83 Prog *p;
84
85 p = prog(as);
86 p->to.type = D_BRANCH;
87 p->to.branch = P;
88 return p;
89 }
90
91 /*
92 * patch previous branch to jump to to.
93 */
94 void
95 patch(Prog *p, Prog *to)
96 {
97 if(p->to.type != D_BRANCH)
98 fatal("patch: not a branch");
99 p->to.branch = to;
100 p->to.offset = to->loc;
101 }
102
103 Prog*
104 unpatch(Prog *p)
105 {
106 Prog *q;
107
108 if(p->to.type != D_BRANCH)
109 fatal("unpatch: not a branch");
110 q = p->to.branch;
111 p->to.branch = P;
112 p->to.offset = 0;
113 return q;
114 }
115
116 /*
117 * start a new Prog list.
118 */
119 Plist*
120 newplist(void)
121 {
122 Plist *pl;
123
124 pl = mal(sizeof(*pl));
125 if(plist == nil)
126 plist = pl;
127 else
128 plast->link = pl;
129 plast = pl;
130
131 pc = mal(sizeof(*pc));
132 clearp(pc);
133 pl->firstpc = pc;
134
135 return pl;
136 }
137
138 void
139 clearstk(void)
140 {
141 Plist *pl;
142 Prog *p1, *p2;
143 Node sp, di, cx, con, ax;
144
145 if(plast->firstpc->to.offset <= 0)
146 return;
147
148 // reestablish context for inserting code
149 // at beginning of function.
150 pl = plast;
151 p1 = pl->firstpc;
152 p2 = p1->link;
153 pc = mal(sizeof(*pc));
154 clearp(pc);
155 p1->link = pc;
156
157 // zero stack frame
158 nodreg(&sp, types[tptr], D_SP);
159 nodreg(&di, types[tptr], D_DI);
160 nodreg(&cx, types[TUINT32], D_CX);
161 nodconst(&con, types[TUINT32], p1->to.offset / widthptr);
162 gins(ACLD, N, N);
163 gins(AMOVL, &sp, &di);
164 gins(AMOVL, &con, &cx);
165 nodconst(&con, types[TUINT32], 0);
166 nodreg(&ax, types[TUINT32], D_AX);
167 gins(AMOVL, &con, &ax);
168 gins(AREP, N, N);
169 gins(ASTOSL, N, N);
170
171 // continue with original code.
172 gins(ANOP, N, N)->link = p2;
173 pc = P;
174 }
175
176 void
177 gused(Node *n)
178 {
179 gins(ANOP, n, N); // used
180 }
181
182 Prog*
183 gjmp(Prog *to)
184 {
185 Prog *p;
186
187 p = gbranch(AJMP, T);
188 if(to != P)
189 patch(p, to);
190 return p;
191 }
192
193 void
194 ggloblnod(Node *nam, int32 width)
195 {
196 Prog *p;
197
198 p = gins(AGLOBL, nam, N);
199 p->lineno = nam->lineno;
200 p->to.sym = S;
201 p->to.type = D_CONST;
202 p->to.offset = width;
203 if(nam->readonly)
204 p->from.scale = RODATA;
205 }
206
207 void
208 ggloblsym(Sym *s, int32 width, int dupok)
209 {
210 Prog *p;
211
212 p = gins(AGLOBL, N, N);
213 p->from.type = D_EXTERN;
214 p->from.index = D_NONE;
215 p->from.sym = s;
216 p->to.type = D_CONST;
217 p->to.index = D_NONE;
218 p->to.offset = width;
219 if(dupok)
220 p->from.scale = DUPOK;
221 p->from.scale |= RODATA;
222 }
223
224 int
225 isfat(Type *t)
226 {
227 if(t != T)
228 switch(t->etype) {
229 case TSTRUCT:
230 case TARRAY:
231 case TSTRING:
232 case TINTER: // maybe remove later
233 return 1;
234 }
235 return 0;
236 }
237
238 /*
239 * naddr of func generates code for address of func.
240 * if using opcode that can take address implicitly,
241 * call afunclit to fix up the argument.
242 */
243 void
244 afunclit(Addr *a)
245 {
246 if(a->type == D_ADDR && a->index == D_EXTERN) {
247 a->type = D_EXTERN;
248 a->index = D_NONE;
249 }
250 }
251
252 /*
253 * return Axxx for Oxxx on type t.
254 */
255 int
256 optoas(int op, Type *t)
257 {
258 int a;
259
260 if(t == T)
261 fatal("optoas: t is nil");
262
263 a = AGOK;
264 switch(CASE(op, simtype[t->etype])) {
265 default:
266 fatal("optoas: no entry %O-%T", op, t);
267 break;
268
269 case CASE(OADDR, TPTR32):
270 a = ALEAL;
271 break;
272
273 case CASE(OEQ, TBOOL):
274 case CASE(OEQ, TINT8):
275 case CASE(OEQ, TUINT8):
276 case CASE(OEQ, TINT16):
277 case CASE(OEQ, TUINT16):
278 case CASE(OEQ, TINT32):
279 case CASE(OEQ, TUINT32):
280 case CASE(OEQ, TINT64):
281 case CASE(OEQ, TUINT64):
282 case CASE(OEQ, TPTR32):
283 case CASE(OEQ, TPTR64):
284 case CASE(OEQ, TFLOAT32):
285 case CASE(OEQ, TFLOAT64):
286 a = AJEQ;
287 break;
288
289 case CASE(ONE, TBOOL):
290 case CASE(ONE, TINT8):
291 case CASE(ONE, TUINT8):
292 case CASE(ONE, TINT16):
293 case CASE(ONE, TUINT16):
294 case CASE(ONE, TINT32):
295 case CASE(ONE, TUINT32):
296 case CASE(ONE, TINT64):
297 case CASE(ONE, TUINT64):
298 case CASE(ONE, TPTR32):
299 case CASE(ONE, TPTR64):
300 case CASE(ONE, TFLOAT32):
301 case CASE(ONE, TFLOAT64):
302 a = AJNE;
303 break;
304
305 case CASE(OLT, TINT8):
306 case CASE(OLT, TINT16):
307 case CASE(OLT, TINT32):
308 case CASE(OLT, TINT64):
309 a = AJLT;
310 break;
311
312 case CASE(OLT, TUINT8):
313 case CASE(OLT, TUINT16):
314 case CASE(OLT, TUINT32):
315 case CASE(OLT, TUINT64):
316 a = AJCS;
317 break;
318
319 case CASE(OLE, TINT8):
320 case CASE(OLE, TINT16):
321 case CASE(OLE, TINT32):
322 case CASE(OLE, TINT64):
323 a = AJLE;
324 break;
325
326 case CASE(OLE, TUINT8):
327 case CASE(OLE, TUINT16):
328 case CASE(OLE, TUINT32):
329 case CASE(OLE, TUINT64):
330 a = AJLS;
331 break;
332
333 case CASE(OGT, TINT8):
334 case CASE(OGT, TINT16):
335 case CASE(OGT, TINT32):
336 case CASE(OGT, TINT64):
337 a = AJGT;
338 break;
339
340 case CASE(OGT, TUINT8):
341 case CASE(OGT, TUINT16):
342 case CASE(OGT, TUINT32):
343 case CASE(OGT, TUINT64):
344 case CASE(OLT, TFLOAT32):
345 case CASE(OLT, TFLOAT64):
346 a = AJHI;
347 break;
348
349 case CASE(OGE, TINT8):
350 case CASE(OGE, TINT16):
351 case CASE(OGE, TINT32):
352 case CASE(OGE, TINT64):
353 a = AJGE;
354 break;
355
356 case CASE(OGE, TUINT8):
357 case CASE(OGE, TUINT16):
358 case CASE(OGE, TUINT32):
359 case CASE(OGE, TUINT64):
360 case CASE(OLE, TFLOAT32):
361 case CASE(OLE, TFLOAT64):
362 a = AJCC;
363 break;
364
365 case CASE(OCMP, TBOOL):
366 case CASE(OCMP, TINT8):
367 case CASE(OCMP, TUINT8):
368 a = ACMPB;
369 break;
370
371 case CASE(OCMP, TINT16):
372 case CASE(OCMP, TUINT16):
373 a = ACMPW;
374 break;
375
376 case CASE(OCMP, TINT32):
377 case CASE(OCMP, TUINT32):
378 case CASE(OCMP, TPTR32):
379 a = ACMPL;
380 break;
381
382 case CASE(OAS, TBOOL):
383 case CASE(OAS, TINT8):
384 case CASE(OAS, TUINT8):
385 a = AMOVB;
386 break;
387
388 case CASE(OAS, TINT16):
389 case CASE(OAS, TUINT16):
390 a = AMOVW;
391 break;
392
393 case CASE(OAS, TINT32):
394 case CASE(OAS, TUINT32):
395 case CASE(OAS, TPTR32):
396 a = AMOVL;
397 break;
398
399 case CASE(OADD, TINT8):
400 case CASE(OADD, TUINT8):
401 a = AADDB;
402 break;
403
404 case CASE(OADD, TINT16):
405 case CASE(OADD, TUINT16):
406 a = AADDW;
407 break;
408
409 case CASE(OADD, TINT32):
410 case CASE(OADD, TUINT32):
411 case CASE(OADD, TPTR32):
412 a = AADDL;
413 break;
414
415 case CASE(OSUB, TINT8):
416 case CASE(OSUB, TUINT8):
417 a = ASUBB;
418 break;
419
420 case CASE(OSUB, TINT16):
421 case CASE(OSUB, TUINT16):
422 a = ASUBW;
423 break;
424
425 case CASE(OSUB, TINT32):
426 case CASE(OSUB, TUINT32):
427 case CASE(OSUB, TPTR32):
428 a = ASUBL;
429 break;
430
431 case CASE(OINC, TINT8):
432 case CASE(OINC, TUINT8):
433 a = AINCB;
434 break;
435
436 case CASE(OINC, TINT16):
437 case CASE(OINC, TUINT16):
438 a = AINCW;
439 break;
440
441 case CASE(OINC, TINT32):
442 case CASE(OINC, TUINT32):
443 case CASE(OINC, TPTR32):
444 a = AINCL;
445 break;
446
447 case CASE(ODEC, TINT8):
448 case CASE(ODEC, TUINT8):
449 a = ADECB;
450 break;
451
452 case CASE(ODEC, TINT16):
453 case CASE(ODEC, TUINT16):
454 a = ADECW;
455 break;
456
457 case CASE(ODEC, TINT32):
458 case CASE(ODEC, TUINT32):
459 case CASE(ODEC, TPTR32):
460 a = ADECL;
461 break;
462
463 case CASE(OCOM, TINT8):
464 case CASE(OCOM, TUINT8):
465 a = ANOTB;
466 break;
467
468 case CASE(OCOM, TINT16):
469 case CASE(OCOM, TUINT16):
470 a = ANOTW;
471 break;
472
473 case CASE(OCOM, TINT32):
474 case CASE(OCOM, TUINT32):
475 case CASE(OCOM, TPTR32):
476 a = ANOTL;
477 break;
478
479 case CASE(OMINUS, TINT8):
480 case CASE(OMINUS, TUINT8):
481 a = ANEGB;
482 break;
483
484 case CASE(OMINUS, TINT16):
485 case CASE(OMINUS, TUINT16):
486 a = ANEGW;
487 break;
488
489 case CASE(OMINUS, TINT32):
490 case CASE(OMINUS, TUINT32):
491 case CASE(OMINUS, TPTR32):
492 a = ANEGL;
493 break;
494
495 case CASE(OAND, TINT8):
496 case CASE(OAND, TUINT8):
497 a = AANDB;
498 break;
499
500 case CASE(OAND, TINT16):
501 case CASE(OAND, TUINT16):
502 a = AANDW;
503 break;
504
505 case CASE(OAND, TINT32):
506 case CASE(OAND, TUINT32):
507 case CASE(OAND, TPTR32):
508 a = AANDL;
509 break;
510
511 case CASE(OOR, TINT8):
512 case CASE(OOR, TUINT8):
513 a = AORB;
514 break;
515
516 case CASE(OOR, TINT16):
517 case CASE(OOR, TUINT16):
518 a = AORW;
519 break;
520
521 case CASE(OOR, TINT32):
522 case CASE(OOR, TUINT32):
523 case CASE(OOR, TPTR32):
524 a = AORL;
525 break;
526
527 case CASE(OXOR, TINT8):
528 case CASE(OXOR, TUINT8):
529 a = AXORB;
530 break;
531
532 case CASE(OXOR, TINT16):
533 case CASE(OXOR, TUINT16):
534 a = AXORW;
535 break;
536
537 case CASE(OXOR, TINT32):
538 case CASE(OXOR, TUINT32):
539 case CASE(OXOR, TPTR32):
540 a = AXORL;
541 break;
542
543 case CASE(OLSH, TINT8):
544 case CASE(OLSH, TUINT8):
545 a = ASHLB;
546 break;
547
548 case CASE(OLSH, TINT16):
549 case CASE(OLSH, TUINT16):
550 a = ASHLW;
551 break;
552
553 case CASE(OLSH, TINT32):
554 case CASE(OLSH, TUINT32):
555 case CASE(OLSH, TPTR32):
556 a = ASHLL;
557 break;
558
559 case CASE(ORSH, TUINT8):
560 a = ASHRB;
561 break;
562
563 case CASE(ORSH, TUINT16):
564 a = ASHRW;
565 break;
566
567 case CASE(ORSH, TUINT32):
568 case CASE(ORSH, TPTR32):
569 a = ASHRL;
570 break;
571
572 case CASE(ORSH, TINT8):
573 a = ASARB;
574 break;
575
576 case CASE(ORSH, TINT16):
577 a = ASARW;
578 break;
579
580 case CASE(ORSH, TINT32):
581 a = ASARL;
582 break;
583
584 case CASE(OMUL, TINT8):
585 case CASE(OMUL, TUINT8):
586 a = AIMULB;
587 break;
588
589 case CASE(OMUL, TINT16):
590 case CASE(OMUL, TUINT16):
591 a = AIMULW;
592 break;
593
594 case CASE(OMUL, TINT32):
595 case CASE(OMUL, TUINT32):
596 case CASE(OMUL, TPTR32):
597 a = AIMULL;
598 break;
599
600 case CASE(ODIV, TINT8):
601 case CASE(OMOD, TINT8):
602 a = AIDIVB;
603 break;
604
605 case CASE(ODIV, TUINT8):
606 case CASE(OMOD, TUINT8):
607 a = ADIVB;
608 break;
609
610 case CASE(ODIV, TINT16):
611 case CASE(OMOD, TINT16):
612 a = AIDIVW;
613 break;
614
615 case CASE(ODIV, TUINT16):
616 case CASE(OMOD, TUINT16):
617 a = ADIVW;
618 break;
619
620 case CASE(ODIV, TINT32):
621 case CASE(OMOD, TINT32):
622 a = AIDIVL;
623 break;
624
625 case CASE(ODIV, TUINT32):
626 case CASE(ODIV, TPTR32):
627 case CASE(OMOD, TUINT32):
628 case CASE(OMOD, TPTR32):
629 a = ADIVL;
630 break;
631
632 case CASE(OEXTEND, TINT16):
633 a = ACWD;
634 break;
635
636 case CASE(OEXTEND, TINT32):
637 a = ACDQ;
638 break;
639 }
640 return a;
641 }
642
643 #define FCASE(a, b, c) (((a)<<16)|((b)<<8)|(c))
644 int
645 foptoas(int op, Type *t, int flg)
646 {
647 int et;
648
649 et = simtype[t->etype];
650
651 // If we need Fpop, it means we're working on
652 // two different floating-point registers, not memory.
653 // There the instruction only has a float64 form.
654 if(flg & Fpop)
655 et = TFLOAT64;
656
657 // clear Frev if unneeded
658 switch(op) {
659 case OADD:
660 case OMUL:
661 flg &= ~Frev;
662 break;
663 }
664
665 switch(FCASE(op, et, flg)) {
666 case FCASE(OADD, TFLOAT32, 0):
667 return AFADDF;
668 case FCASE(OADD, TFLOAT64, 0):
669 return AFADDD;
670 case FCASE(OADD, TFLOAT64, Fpop):
671 return AFADDDP;
672
673 case FCASE(OSUB, TFLOAT32, 0):
674 return AFSUBF;
675 case FCASE(OSUB, TFLOAT32, Frev):
676 return AFSUBRF;
677
678 case FCASE(OSUB, TFLOAT64, 0):
679 return AFSUBD;
680 case FCASE(OSUB, TFLOAT64, Frev):
681 return AFSUBRD;
682 case FCASE(OSUB, TFLOAT64, Fpop):
683 return AFSUBDP;
684 case FCASE(OSUB, TFLOAT64, Fpop|Frev):
685 return AFSUBRDP;
686
687 case FCASE(OMUL, TFLOAT32, 0):
688 return AFMULF;
689 case FCASE(OMUL, TFLOAT64, 0):
690 return AFMULD;
691 case FCASE(OMUL, TFLOAT64, Fpop):
692 return AFMULDP;
693
694 case FCASE(ODIV, TFLOAT32, 0):
695 return AFDIVF;
696 case FCASE(ODIV, TFLOAT32, Frev):
697 return AFDIVRF;
698
699 case FCASE(ODIV, TFLOAT64, 0):
700 return AFDIVD;
701 case FCASE(ODIV, TFLOAT64, Frev):
702 return AFDIVRD;
703 case FCASE(ODIV, TFLOAT64, Fpop):
704 return AFDIVDP;
705 case FCASE(ODIV, TFLOAT64, Fpop|Frev):
706 return AFDIVRDP;
707
708 case FCASE(OCMP, TFLOAT32, 0):
709 return AFCOMF;
710 case FCASE(OCMP, TFLOAT32, Fpop):
711 return AFCOMFP;
712 case FCASE(OCMP, TFLOAT64, 0):
713 return AFCOMD;
714 case FCASE(OCMP, TFLOAT64, Fpop):
715 return AFCOMDP;
716 case FCASE(OCMP, TFLOAT64, Fpop2):
717 return AFCOMDPP;
718
719 case FCASE(OMINUS, TFLOAT32, 0):
720 return AFCHS;
721 case FCASE(OMINUS, TFLOAT64, 0):
722 return AFCHS;
723 }
724
725 fatal("foptoas %O %T %#x", op, t, flg);
726 return 0;
727 }
728
729 static int resvd[] =
730 {
731 // D_DI, // for movstring
732 // D_SI, // for movstring
733
734 D_AX, // for divide
735 D_CX, // for shift
736 D_DX, // for divide
737 D_SP, // for stack
738
739 D_BL, // because D_BX can be allocated
740 D_BH,
741 };
742
743 void
744 ginit(void)
745 {
746 int i;
747
748 for(i=0; i<nelem(reg); i++)
749 reg[i] = 1;
750 for(i=D_AL; i<=D_DI; i++)
751 reg[i] = 0;
752 for(i=0; i<nelem(resvd); i++)
753 reg[resvd[i]]++;
754 }
755
756 ulong regpc[D_NONE];
757
758 void
759 gclean(void)
760 {
761 int i;
762
763 for(i=0; i<nelem(resvd); i++)
764 reg[resvd[i]]--;
765
766 for(i=D_AL; i<=D_DI; i++)
767 if(reg[i])
768 yyerror("reg %R left allocated at %ux", i, regpc[i]);
769 }
770
771 int32
772 anyregalloc(void)
773 {
774 int i, j;
775
776 for(i=D_AL; i<=D_DI; i++) {
777 if(reg[i] == 0)
778 goto ok;
779 for(j=0; j<nelem(resvd); j++)
780 if(resvd[j] == i)
781 goto ok;
782 return 1;
783 ok:;
784 }
785 return 0;
786 }
787
788 /*
789 * allocate register of type t, leave in n.
790 * if o != N, o is desired fixed register.
791 * caller must regfree(n).
792 */
793 void
794 regalloc(Node *n, Type *t, Node *o)
795 {
796 int i, et;
797
798 if(t == T)
799 fatal("regalloc: t nil");
800 et = simtype[t->etype];
801
802 switch(et) {
803 case TINT8:
804 case TUINT8:
805 case TINT16:
806 case TUINT16:
807 case TINT32:
808 case TUINT32:
809 case TINT64:
810 case TUINT64:
811 case TPTR32:
812 case TPTR64:
813 case TBOOL:
814 if(o != N && o->op == OREGISTER) {
815 i = o->val.u.reg;
816 if(i >= D_AX && i <= D_DI)
817 goto out;
818 }
819 for(i=D_AX; i<=D_DI; i++)
820 if(reg[i] == 0)
821 goto out;
822
823 fprint(2, "registers allocated at\n");
824 for(i=D_AX; i<=D_DI; i++)
825 fprint(2, "\t%R\t%#ux\n", i, regpc[i]);
826 yyerror("out of fixed registers");
827 goto err;
828
829 case TFLOAT32:
830 case TFLOAT64:
831 i = D_F0;
832 goto out;
833 }
834 yyerror("regalloc: unknown type %T", t);
835 i = 0;
836
837 err:
838 nodreg(n, t, 0);
839 return;
840
841 out:
842 if (i == D_SP)
843 print("alloc SP\n");
844 if(reg[i] == 0) {
845 regpc[i] = (ulong)__builtin_return_address(0);
846 if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) {
847 dump("regalloc-o", o);
848 fatal("regalloc %R", i);
849 }
850 }
851 reg[i]++;
852 nodreg(n, t, i);
853 }
854
855 void
856 regfree(Node *n)
857 {
858 int i;
859
860 if(n->op == ONAME)
861 return;
862 if(n->op != OREGISTER && n->op != OINDREG)
863 fatal("regfree: not a register");
864 i = n->val.u.reg;
865 if(i == D_SP)
866 return;
867 if(i < 0 || i >= sizeof(reg))
868 fatal("regfree: reg out of range");
869 if(reg[i] <= 0)
870 fatal("regfree: reg not allocated");
871 reg[i]--;
872 if(reg[i] == 0 && (i == D_AX || i == D_CX || i == D_DX || i == D_SP))
873 fatal("regfree %R", i);
874 }
875
876 /*
877 * initialize n to be register r of type t.
878 */
879 void
880 nodreg(Node *n, Type *t, int r)
881 {
882 if(t == T)
883 fatal("nodreg: t nil");
884
885 memset(n, 0, sizeof(*n));
886 n->op = OREGISTER;
887 n->addable = 1;
888 ullmancalc(n);
889 n->val.u.reg = r;
890 n->type = t;
891 }
892
893 /*
894 * initialize n to be indirect of register r; n is type t.
895 */
896 void
897 nodindreg(Node *n, Type *t, int r)
898 {
899 nodreg(n, t, r);
900 n->op = OINDREG;
901 }
902
903 Node*
904 nodarg(Type *t, int fp)
905 {
906 Node *n;
907 Type *first;
908 Iter savet;
909
910 // entire argument struct, not just one arg
911 switch(t->etype) {
912 default:
913 fatal("nodarg %T", t);
914
915 case TSTRUCT:
916 if(!t->funarg)
917 fatal("nodarg: TSTRUCT but not funarg");
918 n = nod(ONAME, N, N);
919 n->sym = lookup(".args");
920 n->type = t;
921 first = structfirst(&savet, &t);
922 if(first == nil)
923 fatal("nodarg: bad struct");
924 if(first->width == BADWIDTH)
925 fatal("nodarg: offset not computed for %T", t);
926 n->xoffset = first->width;
927 n->addable = 1;
928 break;
929
930 case TFIELD:
931 n = nod(ONAME, N, N);
932 n->type = t->type;
933 n->sym = t->sym;
934 if(t->width == BADWIDTH)
935 fatal("nodarg: offset not computed for %T", t);
936 n->xoffset = t->width;
937 n->addable = 1;
938 break;
939 }
940
941 switch(fp) {
942 default:
943 fatal("nodarg %T %d", t, fp);
944
945 case 0: // output arg
946 n->op = OINDREG;
947 n->val.u.reg = D_SP;
948 break;
949
950 case 1: // input arg
951 n->class = PPARAM;
952 break;
953 }
954
955 n->typecheck = 1;
956 return n;
957 }
958
959 /*
960 * generate
961 * as $c, reg
962 */
963 void
964 gconreg(int as, vlong c, int reg)
965 {
966 Node n1, n2;
967
968 nodconst(&n1, types[TINT64], c);
969 nodreg(&n2, types[TINT64], reg);
970 gins(as, &n1, &n2);
971 }
972
973 /*
974 * swap node contents
975 */
976 void
977 nswap(Node *a, Node *b)
978 {
979 Node t;
980
981 t = *a;
982 *a = *b;
983 *b = t;
984 }
985
986 /*
987 * return constant i node.
988 * overwritten by next call, but useful in calls to gins.
989 */
990 Node*
991 ncon(uint32 i)
992 {
993 static Node n;
994
995 if(n.type == T)
996 nodconst(&n, types[TUINT32], 0);
997 mpmovecfix(n.val.u.xval, i);
998 return &n;
999 }
1000
1001 /*
1002 * Is this node a memory operand?
1003 */
1004 int
1005 ismem(Node *n)
1006 {
1007 switch(n->op) {
1008 case OLEN:
1009 case OCAP:
1010 case OINDREG:
1011 case ONAME:
1012 case OPARAM:
1013 return 1;
1014 }
1015 return 0;
1016 }
1017
1018 Node sclean[10];
1019 int nsclean;
1020
1021 /*
1022 * n is a 64-bit value. fill in lo and hi to refer to its 32-bit halves.
1023 */
1024 void
1025 split64(Node *n, Node *lo, Node *hi)
1026 {
1027 Node n1;
1028 int64 i;
1029
1030 if(!is64(n->type))
1031 fatal("split64 %T", n->type);
1032
1033 sclean[nsclean].op = OEMPTY;
1034 if(nsclean >= nelem(sclean))
1035 fatal("split64 clean");
1036 nsclean++;
1037 switch(n->op) {
1038 default:
1039 if(!dotaddable(n, &n1)) {
1040 igen(n, &n1, N);
1041 sclean[nsclean-1] = n1;
1042 }
1043 n = &n1;
1044 goto common;
1045 case ONAME:
1046 if(n->class == PPARAMREF) {
1047 cgen(n->heapaddr, &n1);
1048 sclean[nsclean-1] = n1;
1049 // fall through.
1050 n = &n1;
1051 }
1052 goto common;
1053 case OINDREG:
1054 common:
1055 *lo = *n;
1056 *hi = *n;
1057 lo->type = types[TUINT32];
1058 if(n->type->etype == TINT64)
1059 hi->type = types[TINT32];
1060 else
1061 hi->type = types[TUINT32];
1062 hi->xoffset += 4;
1063 break;
1064
1065 case OLITERAL:
1066 convconst(&n1, n->type, &n->val);
1067 i = mpgetfix(n1.val.u.xval);
1068 nodconst(lo, types[TUINT32], (uint32)i);
1069 i >>= 32;
1070 if(n->type->etype == TINT64)
1071 nodconst(hi, types[TINT32], (int32)i);
1072 else
1073 nodconst(hi, types[TUINT32], (uint32)i);
1074 break;
1075 }
1076 }
1077
1078 void
1079 splitclean(void)
1080 {
1081 if(nsclean <= 0)
1082 fatal("splitclean");
1083 nsclean--;
1084 if(sclean[nsclean].op != OEMPTY)
1085 regfree(&sclean[nsclean]);
1086 }
1087
1088 /*
1089 * set up nodes representing fp constants
1090 */
1091 Node zerof;
1092 Node two64f;
1093 Node two63f;
1094
1095 void
1096 bignodes(void)
1097 {
1098 static int did;
1099
1100 if(did)
1101 return;
1102 did = 1;
1103
1104 two64f = *ncon(0);
1105 two64f.type = types[TFLOAT64];
1106 two64f.val.ctype = CTFLT;
1107 two64f.val.u.fval = mal(sizeof *two64f.val.u.fval);
1108 mpmovecflt(two64f.val.u.fval, 18446744073709551616.);
1109
1110 two63f = two64f;
1111 two63f.val.u.fval = mal(sizeof *two63f.val.u.fval);
1112 mpmovecflt(two63f.val.u.fval, 9223372036854775808.);
1113
1114 zerof = two64f;
1115 zerof.val.u.fval = mal(sizeof *zerof.val.u.fval);
1116 mpmovecflt(zerof.val.u.fval, 0);
1117 }
1118
1119 void
1120 memname(Node *n, Type *t)
1121 {
1122 tempname(n, t);
1123 strcpy(namebuf, n->sym->name);
1124 namebuf[0] = '.'; // keep optimizer from registerizing
1125 n->sym = lookup(namebuf);
1126 }
1127
1128 void
1129 gmove(Node *f, Node *t)
1130 {
1131 int a, ft, tt;
1132 Type *cvt;
1133 Node r1, r2, t1, t2, flo, fhi, tlo, thi, con, f0, f1, ax, dx, cx;
1134 Prog *p1, *p2, *p3;
1135
1136 if(debug['M'])
1137 print("gmove %N -> %N\n", f, t);
1138
1139 ft = simsimtype(f->type);
1140 tt = simsimtype(t->type);
1141 cvt = t->type;
1142
1143 if(iscomplex[ft] || iscomplex[tt]) {
1144 complexmove(f, t);
1145 return;
1146 }
1147
1148 // cannot have two integer memory operands;
1149 // except 64-bit, which always copies via registers anyway.
1150 if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
1151 goto hard;
1152
1153 // convert constant to desired type
1154 if(f->op == OLITERAL) {
1155 if(tt == TFLOAT32)
1156 convconst(&con, types[TFLOAT64], &f->val);
1157 else
1158 convconst(&con, t->type, &f->val);
1159 f = &con;
1160 ft = simsimtype(con.type);
1161
1162 // some constants can't move directly to memory.
1163 if(ismem(t)) {
1164 // float constants come from memory.
1165 if(isfloat[tt])
1166 goto hard;
1167 }
1168 }
1169
1170 // value -> value copy, only one memory operand.
1171 // figure out the instruction to use.
1172 // break out of switch for one-instruction gins.
1173 // goto rdst for "destination must be register".
1174 // goto hard for "convert to cvt type first".
1175 // otherwise handle and return.
1176
1177 switch(CASE(ft, tt)) {
1178 default:
1179 goto fatal;
1180
1181 /*
1182 * integer copy and truncate
1183 */
1184 case CASE(TINT8, TINT8): // same size
1185 case CASE(TINT8, TUINT8):
1186 case CASE(TUINT8, TINT8):
1187 case CASE(TUINT8, TUINT8):
1188 a = AMOVB;
1189 break;
1190
1191 case CASE(TINT16, TINT8): // truncate
1192 case CASE(TUINT16, TINT8):
1193 case CASE(TINT32, TINT8):
1194 case CASE(TUINT32, TINT8):
1195 case CASE(TINT16, TUINT8):
1196 case CASE(TUINT16, TUINT8):
1197 case CASE(TINT32, TUINT8):
1198 case CASE(TUINT32, TUINT8):
1199 a = AMOVB;
1200 goto rsrc;
1201
1202 case CASE(TINT64, TINT8): // truncate low word
1203 case CASE(TUINT64, TINT8):
1204 case CASE(TINT64, TUINT8):
1205 case CASE(TUINT64, TUINT8):
1206 split64(f, &flo, &fhi);
1207 nodreg(&r1, t->type, D_AX);
1208 gmove(&flo, &r1);
1209 gins(AMOVB, &r1, t);
1210 splitclean();
1211 return;
1212
1213 case CASE(TINT16, TINT16): // same size
1214 case CASE(TINT16, TUINT16):
1215 case CASE(TUINT16, TINT16):
1216 case CASE(TUINT16, TUINT16):
1217 a = AMOVW;
1218 break;
1219
1220 case CASE(TINT32, TINT16): // truncate
1221 case CASE(TUINT32, TINT16):
1222 case CASE(TINT32, TUINT16):
1223 case CASE(TUINT32, TUINT16):
1224 a = AMOVW;
1225 goto rsrc;
1226
1227 case CASE(TINT64, TINT16): // truncate low word
1228 case CASE(TUINT64, TINT16):
1229 case CASE(TINT64, TUINT16):
1230 case CASE(TUINT64, TUINT16):
1231 split64(f, &flo, &fhi);
1232 nodreg(&r1, t->type, D_AX);
1233 gmove(&flo, &r1);
1234 gins(AMOVW, &r1, t);
1235 splitclean();
1236 return;
1237
1238 case CASE(TINT32, TINT32): // same size
1239 case CASE(TINT32, TUINT32):
1240 case CASE(TUINT32, TINT32):
1241 case CASE(TUINT32, TUINT32):
1242 a = AMOVL;
1243 break;
1244
1245 case CASE(TINT64, TINT32): // truncate
1246 case CASE(TUINT64, TINT32):
1247 case CASE(TINT64, TUINT32):
1248 case CASE(TUINT64, TUINT32):
1249 split64(f, &flo, &fhi);
1250 nodreg(&r1, t->type, D_AX);
1251 gmove(&flo, &r1);
1252 gins(AMOVL, &r1, t);
1253 splitclean();
1254 return;
1255
1256 case CASE(TINT64, TINT64): // same size
1257 case CASE(TINT64, TUINT64):
1258 case CASE(TUINT64, TINT64):
1259 case CASE(TUINT64, TUINT64):
1260 split64(f, &flo, &fhi);
1261 split64(t, &tlo, &thi);
1262 if(f->op == OLITERAL) {
1263 gins(AMOVL, &flo, &tlo);
1264 gins(AMOVL, &fhi, &thi);
1265 } else {
1266 nodreg(&r1, t->type, D_AX);
1267 nodreg(&r2, t->type, D_DX);
1268 gins(AMOVL, &flo, &r1);
1269 gins(AMOVL, &fhi, &r2);
1270 gins(AMOVL, &r1, &tlo);
1271 gins(AMOVL, &r2, &thi);
1272 }
1273 splitclean();
1274 splitclean();
1275 return;
1276
1277 /*
1278 * integer up-conversions
1279 */
1280 case CASE(TINT8, TINT16): // sign extend int8
1281 case CASE(TINT8, TUINT16):
1282 a = AMOVBWSX;
1283 goto rdst;
1284 case CASE(TINT8, TINT32):
1285 case CASE(TINT8, TUINT32):
1286 a = AMOVBLSX;
1287 goto rdst;
1288 case CASE(TINT8, TINT64): // convert via int32
1289 case CASE(TINT8, TUINT64):
1290 cvt = types[TINT32];
1291 goto hard;
1292
1293 case CASE(TUINT8, TINT16): // zero extend uint8
1294 case CASE(TUINT8, TUINT16):
1295 a = AMOVBWZX;
1296 goto rdst;
1297 case CASE(TUINT8, TINT32):
1298 case CASE(TUINT8, TUINT32):
1299 a = AMOVBLZX;
1300 goto rdst;
1301 case CASE(TUINT8, TINT64): // convert via uint32
1302 case CASE(TUINT8, TUINT64):
1303 cvt = types[TUINT32];
1304 goto hard;
1305
1306 case CASE(TINT16, TINT32): // sign extend int16
1307 case CASE(TINT16, TUINT32):
1308 a = AMOVWLSX;
1309 goto rdst;
1310 case CASE(TINT16, TINT64): // convert via int32
1311 case CASE(TINT16, TUINT64):
1312 cvt = types[TINT32];
1313 goto hard;
1314
1315 case CASE(TUINT16, TINT32): // zero extend uint16
1316 case CASE(TUINT16, TUINT32):
1317 a = AMOVWLZX;
1318 goto rdst;
1319 case CASE(TUINT16, TINT64): // convert via uint32
1320 case CASE(TUINT16, TUINT64):
1321 cvt = types[TUINT32];
1322 goto hard;
1323
1324 case CASE(TINT32, TINT64): // sign extend int32
1325 case CASE(TINT32, TUINT64):
1326 split64(t, &tlo, &thi);
1327 nodreg(&flo, tlo.type, D_AX);
1328 nodreg(&fhi, thi.type, D_DX);
1329 gmove(f, &flo);
1330 gins(ACDQ, N, N);
1331 gins(AMOVL, &flo, &tlo);
1332 gins(AMOVL, &fhi, &thi);
1333 splitclean();
1334 return;
1335
1336 case CASE(TUINT32, TINT64): // zero extend uint32
1337 case CASE(TUINT32, TUINT64):
1338 split64(t, &tlo, &thi);
1339 gmove(f, &tlo);
1340 gins(AMOVL, ncon(0), &thi);
1341 splitclean();
1342 return;
1343
1344 /*
1345 * float to integer
1346 */
1347 case CASE(TFLOAT32, TINT16):
1348 case CASE(TFLOAT32, TINT32):
1349 case CASE(TFLOAT32, TINT64):
1350 case CASE(TFLOAT64, TINT16):
1351 case CASE(TFLOAT64, TINT32):
1352 case CASE(TFLOAT64, TINT64):
1353 if(t->op == OREGISTER)
1354 goto hardmem;
1355 nodreg(&r1, types[ft], D_F0);
1356 if(f->op != OREGISTER) {
1357 if(ft == TFLOAT32)
1358 gins(AFMOVF, f, &r1);
1359 else
1360 gins(AFMOVD, f, &r1);
1361 }
1362
1363 // set round to zero mode during conversion
1364 memname(&t1, types[TUINT16]);
1365 memname(&t2, types[TUINT16]);
1366 gins(AFSTCW, N, &t1);
1367 gins(AMOVW, ncon(0xf7f), &t2);
1368 gins(AFLDCW, &t2, N);
1369 if(tt == TINT16)
1370 gins(AFMOVWP, &r1, t);
1371 else if(tt == TINT32)
1372 gins(AFMOVLP, &r1, t);
1373 else
1374 gins(AFMOVVP, &r1, t);
1375 gins(AFLDCW, &t1, N);
1376 return;
1377
1378 case CASE(TFLOAT32, TINT8):
1379 case CASE(TFLOAT32, TUINT16):
1380 case CASE(TFLOAT32, TUINT8):
1381 case CASE(TFLOAT64, TINT8):
1382 case CASE(TFLOAT64, TUINT16):
1383 case CASE(TFLOAT64, TUINT8):
1384 // convert via int32.
1385 tempname(&t1, types[TINT32]);
1386 gmove(f, &t1);
1387 switch(tt) {
1388 default:
1389 fatal("gmove %T", t);
1390 case TINT8:
1391 gins(ACMPL, &t1, ncon(-0x80));
1392 p1 = gbranch(optoas(OLT, types[TINT32]), T);
1393 gins(ACMPL, &t1, ncon(0x7f));
1394 p2 = gbranch(optoas(OGT, types[TINT32]), T);
1395 p3 = gbranch(AJMP, T);
1396 patch(p1, pc);
1397 patch(p2, pc);
1398 gmove(ncon(-0x80), &t1);
1399 patch(p3, pc);
1400 gmove(&t1, t);
1401 break;
1402 case TUINT8:
1403 gins(ATESTL, ncon(0xffffff00), &t1);
1404 p1 = gbranch(AJEQ, T);
1405 gins(AMOVL, ncon(0), &t1);
1406 patch(p1, pc);
1407 gmove(&t1, t);
1408 break;
1409 case TUINT16:
1410 gins(ATESTL, ncon(0xffff0000), &t1);
1411 p1 = gbranch(AJEQ, T);
1412 gins(AMOVL, ncon(0), &t1);
1413 patch(p1, pc);
1414 gmove(&t1, t);
1415 break;
1416 }
1417 return;
1418
1419 case CASE(TFLOAT32, TUINT32):
1420 case CASE(TFLOAT64, TUINT32):
1421 // convert via int64.
1422 tempname(&t1, types[TINT64]);
1423 gmove(f, &t1);
1424 split64(&t1, &tlo, &thi);
1425 gins(ACMPL, &thi, ncon(0));
1426 p1 = gbranch(AJEQ, T);
1427 gins(AMOVL, ncon(0), &tlo);
1428 patch(p1, pc);
1429 gmove(&tlo, t);
1430 splitclean();
1431 return;
1432
1433 case CASE(TFLOAT32, TUINT64):
1434 case CASE(TFLOAT64, TUINT64):
1435 bignodes();
1436 nodreg(&f0, types[ft], D_F0);
1437 nodreg(&f1, types[ft], D_F0 + 1);
1438 nodreg(&ax, types[TUINT16], D_AX);
1439
1440 gmove(f, &f0);
1441
1442 // if 0 > v { answer = 0 }
1443 gmove(&zerof, &f0);
1444 gins(AFUCOMIP, &f0, &f1);
1445 p1 = gbranch(optoas(OGT, types[tt]), T);
1446 // if 1<<64 <= v { answer = 0 too }
1447 gmove(&two64f, &f0);
1448 gins(AFUCOMIP, &f0, &f1);
1449 p2 = gbranch(optoas(OGT, types[tt]), T);
1450 patch(p1, pc);
1451 gins(AFMOVVP, &f0, t); // don't care about t, but will pop the stack
1452 split64(t, &tlo, &thi);
1453 gins(AMOVL, ncon(0), &tlo);
1454 gins(AMOVL, ncon(0), &thi);
1455 splitclean();
1456 p1 = gbranch(AJMP, T);
1457 patch(p2, pc);
1458
1459 // in range; algorithm is:
1460 // if small enough, use native float64 -> int64 conversion.
1461 // otherwise, subtract 2^63, convert, and add it back.
1462
1463 // set round to zero mode during conversion
1464 memname(&t1, types[TUINT16]);
1465 memname(&t2, types[TUINT16]);
1466 gins(AFSTCW, N, &t1);
1467 gins(AMOVW, ncon(0xf7f), &t2);
1468 gins(AFLDCW, &t2, N);
1469
1470 // actual work
1471 gmove(&two63f, &f0);
1472 gins(AFUCOMIP, &f0, &f1);
1473 p2 = gbranch(optoas(OLE, types[tt]), T);
1474 gins(AFMOVVP, &f0, t);
1475 p3 = gbranch(AJMP, T);
1476 patch(p2, pc);
1477 gmove(&two63f, &f0);
1478 gins(AFSUBDP, &f0, &f1);
1479 gins(AFMOVVP, &f0, t);
1480 split64(t, &tlo, &thi);
1481 gins(AXORL, ncon(0x80000000), &thi); // + 2^63
1482 patch(p3, pc);
1483 splitclean();
1484 // restore rounding mode
1485 gins(AFLDCW, &t1, N);
1486
1487 patch(p1, pc);
1488 return;
1489
1490 /*
1491 * integer to float
1492 */
1493 case CASE(TINT16, TFLOAT32):
1494 case CASE(TINT16, TFLOAT64):
1495 case CASE(TINT32, TFLOAT32):
1496 case CASE(TINT32, TFLOAT64):
1497 case CASE(TINT64, TFLOAT32):
1498 case CASE(TINT64, TFLOAT64):
1499 if(t->op != OREGISTER)
1500 goto hard;
1501 if(f->op == OREGISTER) {
1502 cvt = f->type;
1503 goto hardmem;
1504 }
1505 switch(ft) {
1506 case TINT16:
1507 a = AFMOVW;
1508 break;
1509 case TINT32:
1510 a = AFMOVL;
1511 break;
1512 default:
1513 a = AFMOVV;
1514 break;
1515 }
1516 break;
1517
1518 case CASE(TINT8, TFLOAT32):
1519 case CASE(TINT8, TFLOAT64):
1520 case CASE(TUINT16, TFLOAT32):
1521 case CASE(TUINT16, TFLOAT64):
1522 case CASE(TUINT8, TFLOAT32):
1523 case CASE(TUINT8, TFLOAT64):
1524 // convert via int32 memory
1525 cvt = types[TINT32];
1526 goto hardmem;
1527
1528 case CASE(TUINT32, TFLOAT32):
1529 case CASE(TUINT32, TFLOAT64):
1530 // convert via int64 memory
1531 cvt = types[TINT64];
1532 goto hardmem;
1533
1534 case CASE(TUINT64, TFLOAT32):
1535 case CASE(TUINT64, TFLOAT64):
1536 // algorithm is:
1537 // if small enough, use native int64 -> uint64 conversion.
1538 // otherwise, halve (rounding to odd?), convert, and double.
1539 nodreg(&ax, types[TUINT32], D_AX);
1540 nodreg(&dx, types[TUINT32], D_DX);
1541 nodreg(&cx, types[TUINT32], D_CX);
1542 tempname(&t1, f->type);
1543 split64(&t1, &tlo, &thi);
1544 gmove(f, &t1);
1545 gins(ACMPL, &thi, ncon(0));
1546 p1 = gbranch(AJLT, T);
1547 // native
1548 t1.type = types[TINT64];
1549 gmove(&t1, t);
1550 p2 = gbranch(AJMP, T);
1551 // simulated
1552 patch(p1, pc);
1553 gmove(&tlo, &ax);
1554 gmove(&thi, &dx);
1555 p1 = gins(ASHRL, ncon(1), &ax);
1556 p1->from.index = D_DX; // double-width shift DX -> AX
1557 p1->from.scale = 0;
1558 gins(ASETCC, N, &cx);
1559 gins(AORB, &cx, &ax);
1560 gins(ASHRL, ncon(1), &dx);
1561 gmove(&dx, &thi);
1562 gmove(&ax, &tlo);
1563 nodreg(&r1, types[tt], D_F0);
1564 nodreg(&r2, types[tt], D_F0 + 1);
1565 gmove(&t1, &r1); // t1.type is TINT64 now, set above
1566 gins(AFMOVD, &r1, &r1);
1567 gins(AFADDDP, &r1, &r2);
1568 gmove(&r1, t);
1569 patch(p2, pc);
1570 splitclean();
1571 return;
1572
1573 /*
1574 * float to float
1575 */
1576 case CASE(TFLOAT32, TFLOAT32):
1577 case CASE(TFLOAT64, TFLOAT64):
1578 // The way the code generator uses floating-point
1579 // registers, a move from F0 to F0 is intended as a no-op.
1580 // On the x86, it's not: it pushes a second copy of F0
1581 // on the floating point stack. So toss it away here.
1582 // Also, F0 is the *only* register we ever evaluate
1583 // into, so we should only see register/register as F0/F0.
1584 if(ismem(f) && ismem(t))
1585 goto hard;
1586 if(f->op == OREGISTER && t->op == OREGISTER) {
1587 if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
1588 goto fatal;
1589 return;
1590 }
1591 a = AFMOVF;
1592 if(ft == TFLOAT64)
1593 a = AFMOVD;
1594 if(ismem(t)) {
1595 if(f->op != OREGISTER || f->val.u.reg != D_F0)
1596 fatal("gmove %N", f);
1597 a = AFMOVFP;
1598 if(ft == TFLOAT64)
1599 a = AFMOVDP;
1600 }
1601 break;
1602
1603 case CASE(TFLOAT32, TFLOAT64):
1604 if(ismem(f) && ismem(t))
1605 goto hard;
1606 if(f->op == OREGISTER && t->op == OREGISTER) {
1607 if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
1608 goto fatal;
1609 return;
1610 }
1611 if(f->op == OREGISTER)
1612 gins(AFMOVDP, f, t);
1613 else
1614 gins(AFMOVF, f, t);
1615 return;
1616
1617 case CASE(TFLOAT64, TFLOAT32):
1618 if(ismem(f) && ismem(t))
1619 goto hard;
1620 if(f->op == OREGISTER && t->op == OREGISTER) {
1621 tempname(&r1, types[TFLOAT32]);
1622 gins(AFMOVFP, f, &r1);
1623 gins(AFMOVF, &r1, t);
1624 return;
1625 }
1626 if(f->op == OREGISTER)
1627 gins(AFMOVFP, f, t);
1628 else
1629 gins(AFMOVD, f, t);
1630 return;
1631 }
1632
1633 gins(a, f, t);
1634 return;
1635
1636 rsrc:
1637 // requires register source
1638 regalloc(&r1, f->type, t);
1639 gmove(f, &r1);
1640 gins(a, &r1, t);
1641 regfree(&r1);
1642 return;
1643
1644 rdst:
1645 // requires register destination
1646 regalloc(&r1, t->type, t);
1647 gins(a, f, &r1);
1648 gmove(&r1, t);
1649 regfree(&r1);
1650 return;
1651
1652 hard:
1653 // requires register intermediate
1654 regalloc(&r1, cvt, t);
1655 gmove(f, &r1);
1656 gmove(&r1, t);
1657 regfree(&r1);
1658 return;
1659
1660 hardmem:
1661 // requires memory intermediate
1662 tempname(&r1, cvt);
1663 gmove(f, &r1);
1664 gmove(&r1, t);
1665 return;
1666
1667 fatal:
1668 // should not happen
1669 fatal("gmove %N -> %N", f, t);
1670 }
1671
1672 int
1673 samaddr(Node *f, Node *t)
1674 {
1675
1676 if(f->op != t->op)
1677 return 0;
1678
1679 switch(f->op) {
1680 case OREGISTER:
1681 if(f->val.u.reg != t->val.u.reg)
1682 break;
1683 return 1;
1684 }
1685 return 0;
1686 }
1687 /*
1688 * generate one instruction:
1689 * as f, t
1690 */
1691 Prog*
1692 gins(int as, Node *f, Node *t)
1693 {
1694 Prog *p;
1695 Addr af, at;
1696 int w;
1697
1698 if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER)
1699 fatal("gins MOVF reg, reg");
1700
1701 switch(as) {
1702 case AMOVB:
1703 case AMOVW:
1704 case AMOVL:
1705 if(f != N && t != N && samaddr(f, t))
1706 return nil;
1707 }
1708
1709 memset(&af, 0, sizeof af);
1710 memset(&at, 0, sizeof at);
1711 if(f != N)
1712 naddr(f, &af, 1);
1713 if(t != N)
1714 naddr(t, &at, 1);
1715 p = prog(as);
1716 if(f != N)
1717 p->from = af;
1718 if(t != N)
1719 p->to = at;
1720 if(debug['g'])
1721 print("%P\n", p);
1722
1723 w = 0;
1724 switch(as) {
1725 case AMOVB:
1726 w = 1;
1727 break;
1728 case AMOVW:
1729 w = 2;
1730 break;
1731 case AMOVL:
1732 w = 4;
1733 break;
1734 }
1735
1736 if(1 && w != 0 && f != N && (af.width > w || at.width > w)) {
1737 dump("bad width from:", f);
1738 dump("bad width to:", t);
1739 fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
1740 }
1741
1742 return p;
1743 }
1744
1745 static void
1746 checkoffset(Addr *a, int canemitcode)
1747 {
1748 Prog *p;
1749
1750 if(a->offset < unmappedzero)
1751 return;
1752 if(!canemitcode)
1753 fatal("checkoffset %#x, cannot emit code", a->offset);
1754
1755 // cannot rely on unmapped nil page at 0 to catch
1756 // reference with large offset. instead, emit explicit
1757 // test of 0(reg).
1758 p = gins(ATESTB, nodintconst(0), N);
1759 p->to = *a;
1760 p->to.offset = 0;
1761 }
1762
1763 /*
1764 * generate code to compute n;
1765 * make a refer to result.
1766 */
1767 void
1768 naddr(Node *n, Addr *a, int canemitcode)
1769 {
1770 a->scale = 0;
1771 a->index = D_NONE;
1772 a->type = D_NONE;
1773 a->gotype = S;
1774 a->node = N;
1775 if(n == N)
1776 return;
1777
1778 switch(n->op) {
1779 default:
1780 fatal("naddr: bad %O %D", n->op, a);
1781 break;
1782
1783 case OREGISTER:
1784 a->type = n->val.u.reg;
1785 a->sym = S;
1786 break;
1787
1788 case OINDREG:
1789 a->type = n->val.u.reg+D_INDIR;
1790 a->sym = n->sym;
1791 a->offset = n->xoffset;
1792 break;
1793
1794 case OPARAM:
1795 // n->left is PHEAP ONAME for stack parameter.
1796 // compute address of actual parameter on stack.
1797 a->etype = n->left->type->etype;
1798 a->width = n->left->type->width;
1799 a->offset = n->xoffset;
1800 a->sym = n->left->sym;
1801 a->type = D_PARAM;
1802 break;
1803
1804 case ONAME:
1805 a->etype = 0;
1806 a->width = 0;
1807 if(n->type != T) {
1808 a->etype = simtype[n->type->etype];
1809 a->width = n->type->width;
1810 a->gotype = ngotype(n);
1811 }
1812 a->pun = n->pun;
1813 a->offset = n->xoffset;
1814 a->sym = n->sym;
1815 if(a->sym == S)
1816 a->sym = lookup(".noname");
1817 if(n->method) {
1818 if(n->type != T)
1819 if(n->type->sym != S)
1820 if(n->type->sym->pkg != nil)
1821 a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
1822 }
1823
1824 switch(n->class) {
1825 default:
1826 fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
1827 case PEXTERN:
1828 a->type = D_EXTERN;
1829 break;
1830 case PAUTO:
1831 a->type = D_AUTO;
1832 if (n->sym)
1833 a->node = n->orig;
1834 break;
1835 case PPARAM:
1836 case PPARAMOUT:
1837 a->type = D_PARAM;
1838 break;
1839 case PFUNC:
1840 a->index = D_EXTERN;
1841 a->type = D_ADDR;
1842 break;
1843 }
1844 break;
1845
1846 case OLITERAL:
1847 switch(n->val.ctype) {
1848 default:
1849 fatal("naddr: const %lT", n->type);
1850 break;
1851 case CTFLT:
1852 a->type = D_FCONST;
1853 a->dval = mpgetflt(n->val.u.fval);
1854 break;
1855 case CTINT:
1856 a->sym = S;
1857 a->type = D_CONST;
1858 a->offset = mpgetfix(n->val.u.xval);
1859 break;
1860 case CTSTR:
1861 datagostring(n->val.u.sval, a);
1862 break;
1863 case CTBOOL:
1864 a->sym = S;
1865 a->type = D_CONST;
1866 a->offset = n->val.u.bval;
1867 break;
1868 case CTNIL:
1869 a->sym = S;
1870 a->type = D_CONST;
1871 a->offset = 0;
1872 break;
1873 }
1874 break;
1875
1876 case OADDR:
1877 naddr(n->left, a, canemitcode);
1878 if(a->type >= D_INDIR) {
1879 a->type -= D_INDIR;
1880 break;
1881 }
1882 if(a->type == D_EXTERN || a->type == D_STATIC ||
1883 a->type == D_AUTO || a->type == D_PARAM)
1884 if(a->index == D_NONE) {
1885 a->index = a->type;
1886 a->type = D_ADDR;
1887 break;
1888 }
1889 fatal("naddr: OADDR\n");
1890
1891 case OLEN:
1892 // len of string or slice
1893 naddr(n->left, a, canemitcode);
1894 if(a->type == D_CONST && a->offset == 0)
1895 break; // len(nil)
1896 a->etype = TUINT32;
1897 a->offset += Array_nel;
1898 a->width = 4;
1899 if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
1900 checkoffset(a, canemitcode);
1901 break;
1902
1903 case OCAP:
1904 // cap of string or slice
1905 naddr(n->left, a, canemitcode);
1906 if(a->type == D_CONST && a->offset == 0)
1907 break; // cap(nil)
1908 a->etype = TUINT32;
1909 a->offset += Array_cap;
1910 a->width = 4;
1911 if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
1912 checkoffset(a, canemitcode);
1913 break;
1914
1915 // case OADD:
1916 // if(n->right->op == OLITERAL) {
1917 // v = n->right->vconst;
1918 // naddr(n->left, a, canemitcode);
1919 // } else
1920 // if(n->left->op == OLITERAL) {
1921 // v = n->left->vconst;
1922 // naddr(n->right, a, canemitcode);
1923 // } else
1924 // goto bad;
1925 // a->offset += v;
1926 // break;
1927
1928 }
1929 }
1930
1931 int
1932 dotaddable(Node *n, Node *n1)
1933 {
1934 int o, oary[10];
1935 Node *nn;
1936
1937 if(n->op != ODOT)
1938 return 0;
1939
1940 o = dotoffset(n, oary, &nn);
1941 if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
1942 *n1 = *nn;
1943 n1->type = n->type;
1944 n1->xoffset += oary[0];
1945 return 1;
1946 }
1947 return 0;
1948 }
1949
1950 void
1951 sudoclean(void)
1952 {
1953 }
1954
1955 int
1956 sudoaddable(int as, Node *n, Addr *a)
1957 {
1958 return 0;
1959 }