comparison mc-code-powerpc.c @ 206:4170cefb48f6

*** empty log message ***
author kono
date Thu, 15 Apr 2004 07:25:38 +0900
parents a50f90d0b63a
children 8a3516f6eb66
comparison
equal deleted inserted replaced
205:a50f90d0b63a 206:4170cefb48f6
48 /* floating point registers */ 48 /* floating point registers */
49 49
50 static int freg_sp; /* floating point REGister Stack-Pointer */ 50 static int freg_sp; /* floating point REGister Stack-Pointer */
51 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ 51 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
52 52
53 static int lreg_sp; /* longlong REGister Stack-Pointer */
54 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
55
53 #define REG_fp 1 56 #define REG_fp 1
54 #define REG_sp 30 57 #define REG_sp 30
55 #define REG_VAR_BASE 29 58 #define REG_VAR_BASE 29
56 #define REG_VAR_MIN 18 59 #define REG_VAR_MIN 18
57 #define MIN_TMP_REG 3 60 #define MIN_TMP_REG 3
62 #define FREG_VAR_BASE 31 65 #define FREG_VAR_BASE 31
63 #define FREG_VAR_MIN 20 66 #define FREG_VAR_MIN 20
64 #define MIN_TMP_FREG 1 67 #define MIN_TMP_FREG 1
65 #define MAX_TMP_FREG 14 68 #define MAX_TMP_FREG 14
66 69
67 #define RET_REGISTER 3 70 #define RET_REGISTER regv[3]
68 #define RET_FREGISTER (1+FREG_OFFSET) 71 #define RET_FREGISTER regv[(1+FREG_OFFSET)]
69 #define RET_LREGISTER_L 4 /* low word */ 72 #define RET_LREGISTER_L 4 /* low word */
70 #define RET_LREGISTER_H 3 /* high word */ 73 #define RET_LREGISTER_H 3 /* high word */
74 static int lreg_ret;
75 #define RET_LREGISTER lreg_ret
71 76
72 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ 77 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/
73 int MAX_FREGISTER=31; 78 int MAX_FREGISTER=31;
74 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ 79 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/
75 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ 80 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/
81 int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; 86 int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG;
82 int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; 87 int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG;
83 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; 88 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG;
84 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; 89 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG;
85 90
86 #define CREG_REGISTER MAX_TMP_REG
87 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET)
88
89 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; 91 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER];
92 static int regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER];
90 93
91 static int *regs = powerpc_regs; 94 static int *regs = powerpc_regs;
95
96 #define CREG_REGISTER regv[MAX_TMP_REG]
97 #define FREG_FREGISTER regv[MAX_TMP_FREG+FREG_OFFSET]
98
92 99
93 static int max_reg_var, max_freg_var; 100 static int max_reg_var, max_freg_var;
94 101
95 static char *reg_name[] = { 102 static char *reg_name[] = {
96 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", 103 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9",
120 if (lreg) { 127 if (lreg) {
121 free_register(lreg); lreg = 0; 128 free_register(lreg); lreg = 0;
122 } 129 }
123 if (!is_int_reg(i)) { 130 if (!is_int_reg(i)) {
124 if (!ireg) ireg = get_register(); 131 if (!ireg) ireg = get_register();
125 i = lreg; 132 i = ireg;
126 } 133 }
127 return i; 134 return i;
128 } 135 }
129 136
130 int use_float(int i) { 137 int use_float(int i) {
131 if (!is_float_reg(i)) i = freg; 138 if (!is_float_reg(i)) i = freg;
132 if (!regs[i]) regs[i]=1; 139 if (!regs[cadr(i)]) regs[cadr(i)]=1;
133 return i; 140 return i;
134 } 141 }
135 142
136 int use_double(int i) { 143 int use_double(int i) {
137 if (!is_float_reg(i)) i = freg; 144 if (!is_float_reg(i)) i = freg;
138 if (!regs[i]) regs[i]=1; 145 if (!regs[cadr(i)]) regs[cadr(i)]=1;
139 return i; 146 return i;
140 } 147 }
141 148
142 int use_longlong(int i) { 149 int use_longlong(int i) {
143 if (ireg) { 150 if (ireg) {
159 166
160 167
161 static char * fload(int d); 168 static char * fload(int d);
162 static int code_d1(double d); 169 static int code_d1(double d);
163 static int code_d2(double d); 170 static int code_d2(double d);
171 #endif
172 #if LONGLONG_CODE
173 static int code_l1(long long ll);
174 static int code_l2(long long ll);
164 #endif 175 #endif
165 176
166 static void code_save_stacks(); 177 static void code_save_stacks();
167 static void code_save_input_registers(); 178 static void code_save_input_registers();
168 static void clear_ptr_cache_reg(int r); 179 static void clear_ptr_cache_reg(int r);
323 } 334 }
324 335
325 void 336 void
326 code_init(void) 337 code_init(void)
327 { 338 {
339 int i;
328 macro_define("__ppc__ 1\n"); 340 macro_define("__ppc__ 1\n");
329 macro_define("__BIG_ENDIAN__ 1\n"); 341 macro_define("__BIG_ENDIAN__ 1\n");
330 // macro_define("_BSD_CT_RUNE_T_ int\n"); 342 // macro_define("_BSD_CT_RUNE_T_ int\n");
331 macro_define("__STDC__ 1\n"); 343 macro_define("__STDC__ 1\n");
332 init_ptr_cache(); 344 init_ptr_cache();
345 lreg_ret = glist3(LREGISTER, RET_LREGISTER_L,RET_LREGISTER_H);
346 for(i=0;i<MAX_REGISTER;i++) { regv[i]=glist2(REGISTER,i); }
347 for(i=0;i<MAX_FREGISTER;i++) { regv[i+FREG_OFFSET]=glist2(DREGISTER,i+FREG_OFFSET); }
333 } 348 }
334 349
335 void 350 void
336 gexpr_code_init(void){ 351 gexpr_code_init(void){
337 #if 0 352 #if 0
421 { /* 使われていないレジスタを調べる */ 436 { /* 使われていないレジスタを調べる */
422 int i,reg; 437 int i,reg;
423 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { 438 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
424 if (regs[i]) continue; /* 使われている */ 439 if (regs[i]) continue; /* 使われている */
425 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 440 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
426 return glist2(REGISTER,i); /* その場所を表す番号を返す */ 441 return regv[i]; /* その場所を表す番号を返す */
427 } 442 }
428 /* PTR_CACHE をつぶす */ 443 /* PTR_CACHE をつぶす */
429 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { 444 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
430 if (regs[i]==PTRC_REG) { 445 if (regs[i]==PTRC_REG) {
431 clear_ptr_cache_reg(i); 446 clear_ptr_cache_reg(i);
432 } else 447 } else
433 continue; 448 continue;
434 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 449 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
435 return glist2(REGISTER,i); /* その場所を表す番号を返す */ 450 return regv[i]; /* その場所を表す番号を返す */
436 } 451 }
437 /* search register stack */ 452 /* search register stack */
438 for(i=0;i<reg_sp;i++) { 453 for(i=0;i<reg_sp;i++) {
439 if ((reg=reg_stack[i])>=0) { 454 if ((reg=reg_stack[i])>=0) {
440 code_assign_lvar( 455 code_assign_lvar(
441 (reg_stack[i]=new_lvar(size_of_int)),reg,0); 456 (reg_stack[i]=new_lvar(size_of_int)),reg,0);
442 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; 457 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
443 return reg; 458 return reg;
444 } 459 }
445 } 460 }
461 #if LONGLONG_CODE
462 /* search register stack */
463 for(i=0;i<lreg_sp;i++) {
464 if ((reg=lreg_stack[i])>=0) {
465 code_assign_lvar(
466 (lreg_stack[i]=new_lvar(size_of_longlong)),reg,0);
467 lreg_stack[i]= lreg_stack[i]-REG_LVAR_OFFSET;
468 free_register(reg);
469 return get_register();
470 }
471 }
472 #endif
446 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 473 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
447 reg =REG_VAR_BASE-i; 474 reg =REG_VAR_BASE-i;
448 if (! regs[reg]) { /* 使われていないなら */ 475 if (! regs[reg]) { /* 使われていないなら */
449 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ 476 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
450 if (i>max_reg_var) max_reg_var=i; 477 if (i>max_reg_var) max_reg_var=i;
451 return glist2(REGISTER,reg); /* その場所を表す番号を返す */ 478 return regv[reg]; /* その場所を表す番号を返す */
452 } 479 }
453 } 480 }
454 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ 481 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
455 error(HPERR); return creg; 482 error(HPERR); return creg;
456 } 483 }
467 { /* 使われていないレジスタを調べる */ 494 { /* 使われていないレジスタを調べる */
468 int i,reg; 495 int i,reg;
469 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { 496 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) {
470 if (regs[i]) continue; /* 使われている */ 497 if (regs[i]) continue; /* 使われている */
471 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 498 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
472 return glist2(DREGISTER,i); /* その場所を表す番号を返す */ 499 return regv[i]; /* その場所を表す番号を返す */
473 } 500 }
474 /* search register stack */ 501 /* search register stack */
475 for(i=0;i<freg_sp;i++) { 502 for(i=0;i<freg_sp;i++) {
476 if ((reg=freg_stack[i])>=0) { 503 if ((reg=freg_stack[i])>=0) {
477 code_dassign_lvar( 504 code_dassign_lvar(
483 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { 510 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) {
484 reg =FREG_VAR_BASE-i+FREG_OFFSET; 511 reg =FREG_VAR_BASE-i+FREG_OFFSET;
485 if (! regs[reg]) { /* 使われていないなら */ 512 if (! regs[reg]) { /* 使われていないなら */
486 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ 513 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
487 if (i>max_freg_var) max_freg_var=i; 514 if (i>max_freg_var) max_freg_var=i;
488 return glist2(DREGISTER,reg); /* その場所を表す番号を返す */ 515 return regv[reg]; /* その場所を表す番号を返す */
489 } 516 }
490 } 517 }
491 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ 518 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
492 error(REG_ERR); return freg; 519 error(REG_ERR); return freg;
493 } 520 }
497 { /* レジスタから値を取り出す */ 524 { /* レジスタから値を取り出す */
498 return freg_stack[--freg_sp]; 525 return freg_stack[--freg_sp];
499 } 526 }
500 #endif 527 #endif
501 528
502 #if LONGLONG_CODE
503 int 529 int
504 get_lregister() 530 get_lregister()
505 { 531 {
506 int h,l,h0,l0; 532 int h,l,h0,l0;
507 h = get_register(); h0 = cadr(h); 533 h = get_register(); h0 = cadr(h);
508 l = get_register(); l0 = cadr(l); 534 l = get_register(); l0 = cadr(l);
509 free_glist2(h); free_glist2(l);
510 return glist3(LREGISTER,l0,h0); 535 return glist3(LREGISTER,l0,h0);
511 } 536 }
512 537
513 int 538 int
514 get_lregister_var(NMTBL *n) 539 get_lregister_var(NMTBL *n)
515 { 540 {
541 int i,j;
542 int max_reg_var_save=max_reg_var;
543 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
544 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
545 /* そのレジスタを使うことを宣言し */
546 regs[REG_VAR_BASE-i]=USING_REG;
547 if (i>max_reg_var) max_reg_var=i;
548 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) {
549 if (! regs[REG_VAR_BASE-j]) { /* 使われていないなら */
550 /* そのレジスタを使うことを宣言し */
551 regs[REG_VAR_BASE-j]=USING_REG;
552 if (j>max_reg_var) max_reg_var=j;
553 /* その場所を表す番号を返す */
554 return list3(LREGISTER,
555 glist3(LREGISTER,REG_VAR_BASE-j,REG_VAR_BASE-i),
556 (int)n);
557 }
558 }
559 /* ひとつしかなかった */
560 regs[REG_VAR_BASE-i]=0;
561 max_reg_var=max_reg_var_save;
562 }
563 }
516 return list2(LVAR,new_lvar(size_of_longlong)); 564 return list2(LVAR,new_lvar(size_of_longlong));
517 } 565 }
518 #endif
519 566
520 void 567 void
521 emit_pop_free(int xreg) 568 emit_pop_free(int xreg)
522 { 569 {
523 if (xreg>=0) 570 if (xreg>=0)
524 free_register(xreg); 571 free_register(xreg);
525 } 572 }
526 573
527 void 574 void
528 free_register(int i) { /* いらなくなったレジスタを開放 */ 575 free_register(int i) { /* いらなくなったレジスタを開放 */
529 if (i<0||MAX_FREGISTER+FREG_OFFSET<i) error(-1); 576 int j;
530 regs[i]=0; 577 if (i==0) return;
578 j = cadr(i); regs[j]=0;
579 if (car(i)==LREGISTER) {
580 j = caddr(i); regs[j]=0;
581 free_glist3(i);
582 }
531 } 583 }
532 584
533 int 585 int
534 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) 586 get_input_dregister_var(int i,NMTBL *n,int is_code,int d)
535 { 587 {
538 i = FREG_VAR_BASE-i+FREG_OFFSET; 590 i = FREG_VAR_BASE-i+FREG_OFFSET;
539 } else { 591 } else {
540 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; 592 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0;
541 i = i+MIN_TMP_FREG+FREG_OFFSET; 593 i = i+MIN_TMP_FREG+FREG_OFFSET;
542 } 594 }
543 return list3(DREGISTER,glist2(DREGISTER,i),(int)n); 595 return list3(DREGISTER,regv[i],(int)n);
544 } 596 }
545 597
546 int 598 int
547 get_input_lregister_var(int i,NMTBL *n,int is_code) 599 get_input_lregister_var(int i,NMTBL *n,int is_code)
600 {
601 if (is_code) {
602 if(!(i+1<REG_VAR_BASE-REG_VAR_MIN)) return 0;
603 i = REG_VAR_BASE-i;
604 } else {
605 if (i<0||i+1>=MAX_INPUT_REGISTER_VAR) return 0;
606 i = i+MIN_TMP_REG;
607 }
608 return list3(LREGISTER,list3(LREGISTER,i+1,i),(int)n);
609 }
610
611 int
612 get_input_register_var(int i,NMTBL *n,int is_code)
548 { 613 {
549 if (is_code) { 614 if (is_code) {
550 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; 615 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
551 i = REG_VAR_BASE-i; 616 i = REG_VAR_BASE-i;
552 } else { 617 } else {
553 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; 618 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
554 i = i+MIN_TMP_REG; 619 i = i+MIN_TMP_REG;
555 } 620 }
556 return list3(LREGISTER,glist3(LREGISTER,i+1,i),(int)n); 621 return list3(REGISTER,regv[i],(int)n);
557 }
558
559 int
560 get_input_register_var(int i,NMTBL *n,int is_code)
561 {
562 if (is_code) {
563 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
564 i = REG_VAR_BASE-i;
565 } else {
566 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
567 i = i+MIN_TMP_REG;
568 }
569 return list3(REGISTER,glist2(REGISTER,i),(int)n);
570 } 622 }
571 623
572 /* double register case? */ 624 /* double register case? */
573 625
574 int 626 int
579 i = REG_VAR_BASE-i; 631 i = REG_VAR_BASE-i;
580 } else { 632 } else {
581 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; 633 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0;
582 i = i+MIN_TMP_REG; 634 i = i+MIN_TMP_REG;
583 } 635 }
584 return list3(REGISTER,glist2(REGISTER,i),(int)n); 636 return list3(REGISTER,regv[i],(int)n);
585 } 637 }
586 638
587 int 639 int
588 free_register_count(int d) 640 free_register_count(int d)
589 { 641 {
615 667
616 void 668 void
617 free_all_register(void) 669 free_all_register(void)
618 { 670 {
619 int i; 671 int i;
672 #if LONGLONG_CODE
673 if (lreg) free_register(lreg);
674 lreg = 0;
675 #endif
620 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; } 676 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; }
621 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; } 677 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; }
622 #if FLOAT_CODE 678 #if FLOAT_CODE
623 freg = get_dregister(1); 679 freg = get_dregister(1);
624 set_freg(FREG_FREGISTER,0); 680 set_freg(FREG_FREGISTER,0);
635 int i; 691 int i;
636 #endif 692 #endif
637 if (chk) return; 693 if (chk) return;
638 if (!lsrc) return; 694 if (!lsrc) return;
639 printf("# %d: %s:",lineno,s); 695 printf("# %d: %s:",lineno,s);
640 printf(" creg=%s fgreg=%s",register_name(creg),fregister_name(freg)); 696 if (ireg) printf(" creg=%s",register_name(ireg));
697 if (freg) printf(" freg=%s",fregister_name(freg));
698 if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg),
699 lregister_name_low(lreg));
641 #if 0 700 #if 0
642 printf("\n# regs:"); 701 printf("\n# regs:");
643 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } 702 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); }
644 printf("\n# freg:"); 703 printf("\n# freg:");
645 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } 704 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); }
658 free_register(reg_stack[--reg_sp]); 717 free_register(reg_stack[--reg_sp]);
659 } 718 }
660 while(freg_sp > 0) { 719 while(freg_sp > 0) {
661 free_register(freg_stack[--freg_sp]); 720 free_register(freg_stack[--freg_sp]);
662 } 721 }
722 while(lreg_sp > 0) {
723 free_register(lreg_stack[--lreg_sp]);
724 }
663 text_mode(); 725 text_mode();
664 gexpr_code_init(); 726 gexpr_code_init();
665 register_usage("gexpr_init"); 727 register_usage("gexpr_init");
666 } 728 }
667 729
685 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ 747 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
686 /* そのレジスタを使うことを宣言し */ 748 /* そのレジスタを使うことを宣言し */
687 regs[REG_VAR_BASE-i]=USING_REG; 749 regs[REG_VAR_BASE-i]=USING_REG;
688 if (i>max_reg_var) max_reg_var=i; 750 if (i>max_reg_var) max_reg_var=i;
689 /* その場所を表す番号を返す */ 751 /* その場所を表す番号を返す */
690 return list3(REGISTER,REG_VAR_BASE-i,(int)n); 752 return list3(REGISTER,glist2(REGISTER,REG_VAR_BASE-i),(int)n);
691 } 753 }
692 } 754 }
693 return list2(LVAR,new_lvar(size_of_int)); 755 return list2(LVAR,new_lvar(size_of_int));
694 }
695
696 int
697 fregister_var(int r) {
698 return r;
699 } 756 }
700 757
701 int 758 int
702 get_dregister_var(NMTBL *n,int d) 759 get_dregister_var(NMTBL *n,int d)
703 { 760 {
705 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { 762 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) {
706 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ 763 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */
707 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ 764 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/
708 if (i>max_freg_var) max_freg_var=i; 765 if (i>max_freg_var) max_freg_var=i;
709 /* その場所を表す番号を返す */ 766 /* その場所を表す番号を返す */
710 return list3(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); 767 return list3(DREGISTER,
768 glist2(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET),(int)n);
711 } 769 }
712 } 770 }
713 return list2(LVAR,new_lvar(size_of_double)); 771 return list2(LVAR,new_lvar(size_of_double));
714 } 772 }
715 773
744 if (type==INT) { 802 if (type==INT) {
745 xreg = reg_stack[reg_sp]; 803 xreg = reg_stack[reg_sp];
746 if (xreg<= -REG_LVAR_OFFSET) { 804 if (xreg<= -REG_LVAR_OFFSET) {
747 return list2(LVAR,REG_LVAR_OFFSET+xreg); 805 return list2(LVAR,REG_LVAR_OFFSET+xreg);
748 } else { 806 } else {
749 return list2(REGISTER,xreg); 807 return xreg;
750 } 808 }
751 } else { 809 } else {
752 xreg = freg_stack[freg_sp]; 810 xreg = freg_stack[freg_sp];
753 if (xreg<= -REG_LVAR_OFFSET) { 811 if (xreg<= -REG_LVAR_OFFSET) {
754 return list2(LVAR,REG_LVAR_OFFSET+xreg); 812 return list2(LVAR,REG_LVAR_OFFSET+xreg);
755 } else { 813 } else {
756 return list2(DREGISTER,xreg); 814 return xreg;
757 } 815 }
758 } 816 }
759 return xreg; 817 return xreg;
760 } 818 }
761 819
821 cadr(p1)=0; /* remove the last one */ 879 cadr(p1)=0; /* remove the last one */
822 cadr(p) = ptr_cache; /* connect current queue to the last one */ 880 cadr(p) = ptr_cache; /* connect current queue to the last one */
823 ptr_cache = p; /* now the last one is the top */ 881 ptr_cache = p; /* now the last one is the top */
824 if (!caddr(p)) { 882 if (!caddr(p)) {
825 if((r=get_register())) { 883 if((r=get_register())) {
826 caddr(p)=r; regs[r]=PTRC_REG; 884 caddr(p)=r; regs[cadr(r)]=PTRC_REG;
827 } else { 885 } else {
828 error(-1); 886 error(-1);
829 r=creg; /* this can't happen */ 887 r=creg; /* this can't happen */
830 } 888 }
831 car(p)=g; 889 car(p)=g;
1267 void 1325 void
1268 set_creg(int reg,int mode) 1326 set_creg(int reg,int mode)
1269 { 1327 {
1270 if (reg!=creg) { 1328 if (reg!=creg) {
1271 clear_ptr_cache_reg(reg); 1329 clear_ptr_cache_reg(reg);
1272 if (reg!=ireg && mode) 1330 if (ireg && reg!=ireg && mode) {
1273 printf("\tmr %s,%s\n",register_name(reg),register_name(ireg)); 1331 printf("\tmr %s,%s\n",register_name(reg),register_name(ireg));
1332 }
1274 free_register(creg); 1333 free_register(creg);
1275 creg = ireg = reg; 1334 regs[cadr(creg)]=USING_REG;
1276 regs[creg]=1; 1335 }
1277 } 1336 creg = ireg = reg;
1278 if (ireg!=creg) error(-1);
1279 ireg = reg;
1280 } 1337 }
1281 1338
1282 void 1339 void
1283 set_freg(int reg,int mode) 1340 set_freg(int reg,int mode)
1284 { 1341 {
1285 if (reg!=creg) { 1342 if (reg!=creg) {
1286 if (reg!=freg && mode) { 1343 if (reg!=freg && mode) {
1287 printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg)); 1344 printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
1288 } 1345 }
1289 free_register(creg); 1346 free_register(creg);
1290 creg = freg = reg; 1347 regs[cadr(freg)]=USING_REG;
1291 regs[freg]=1; 1348 }
1292 } 1349 creg = freg = reg;
1293 if (freg!=creg) error(-1);
1294 freg = reg;
1295 } 1350 }
1296 1351
1297 void 1352 void
1298 set_lreg(int reg,int mode) 1353 set_lreg(int reg,int mode)
1299 { 1354 {
1355 if (reg!=creg) {
1356 if (reg!=lreg && mode) {
1357 printf("\tmr %s,%s\n",
1358 lregister_name_low(reg),lregister_name_low(lreg));
1359 printf("\tmr %s,%s\n",
1360 lregister_name_high(reg),lregister_name_high(lreg));
1361 }
1362 regs[cadr(lreg)]=USING_REG;
1363 regs[caddr(lreg)]=USING_REG;
1364 free_register(creg);
1365 }
1366 creg = lreg = reg;
1300 } 1367 }
1301 1368
1302 void 1369 void
1303 use_var(int arg) 1370 use_var(int arg)
1304 { 1371 {
1305 if (car(arg)==REGISTER) 1372 if (car(arg)==REGISTER)
1306 regs[cadr(arg)]=USING_REG; 1373 regs[cadr(arg)]=USING_REG;
1307 else if (car(arg)==DREGISTER) 1374 else if (car(arg)==DREGISTER)
1308 regs[cadr(arg)]=USING_REG; 1375 regs[cadr(arg)]=USING_REG;
1376 else if (car(arg)==LREGISTER) {
1377 regs[cadr(arg)]=USING_REG;
1378 regs[caddr(arg)]=USING_REG;
1379 }
1309 } 1380 }
1310 1381
1311 void 1382 void
1312 code_save_input_registers() 1383 code_save_input_registers()
1313 { 1384 {
1337 n->dsp = offset; 1408 n->dsp = offset;
1338 t = n->ty; 1409 t = n->ty;
1339 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } 1410 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; }
1340 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } 1411 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; }
1341 else error(-1); 1412 else error(-1);
1413 } else if (tag==LREGISTER) {
1414 /* regs[reg]==INPUT_REG case should be considered */
1415 n->dsp = offset;
1416 t = n->ty;
1417 offset+=size_of_longlong; reg_offset+=2;
1342 } else { 1418 } else {
1343 offset += size(n->ty); 1419 offset += size(n->ty);
1344 continue; 1420 continue;
1345 } 1421 }
1346 n->sc = LVAR; 1422 n->sc = LVAR;
1347 lvar = list2(LVAR,n->dsp); 1423 lvar = list2(LVAR,n->dsp);
1348 g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); 1424 g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t));
1349 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { 1425 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
1350 free_register(reg); 1426 free_register(reg);
1351 } 1427 }
1352 } 1428 }
1353 my_func_args = offset; 1429 my_func_args = offset;
1354 } 1430 }
1432 reg_arg_list = list2(arg,reg_arg_list); 1508 reg_arg_list = list2(arg,reg_arg_list);
1433 g_expr_u(assign_expr0(arg,e4,t,t)); 1509 g_expr_u(assign_expr0(arg,e4,t,t));
1434 nargs ++ ; reg_arg++; 1510 nargs ++ ; reg_arg++;
1435 continue; 1511 continue;
1436 } else if (t==LONGLONG||t==ULONGLONG) { 1512 } else if (t==LONGLONG||t==ULONGLONG) {
1513 if (reg_arg>=MAX_INPUT_REGISTER_VAR) {
1514 arg = list2(LVAR,caller_arg_offset_v(nargs));
1515 } else if (!simple_args(e3) && cadr(e3)) {
1516 arg = get_register_var(0);
1517 arg_assign = list2(
1518 assign_expr0(get_input_lregister_var(reg_arg,0,0),
1519 arg,t,t),
1520 arg_assign);
1521 } else {
1522 arg = get_input_lregister_var(reg_arg,0,0);
1523 }
1524 use_var(arg); /* protect from input register free */
1525 reg_arg_list = list2(arg,reg_arg_list);
1526 g_expr_u(assign_expr0(arg,e4,t,t));
1527 nargs ++ ; reg_arg++;
1528 nargs ++ ; reg_arg++;
1437 continue; 1529 continue;
1438 } else if (t==DOUBLE||t==FLOAT) { 1530 } else if (t==DOUBLE||t==FLOAT) {
1439 if (reg_arg<MAX_INPUT_REGISTER_VAR) { 1531 if (reg_arg<MAX_INPUT_REGISTER_VAR) {
1440 /* sigh... 1532 /* sigh...
1441 printf requies floating value in integer registers 1533 printf requies floating value in integer registers
1452 e4 = list2(DREGISTER,freg); 1544 e4 = list2(DREGISTER,freg);
1453 /* freg should not change until XXX */ 1545 /* freg should not change until XXX */
1454 } 1546 }
1455 r0=get_input_register_var(reg_arg,0,0); 1547 r0=get_input_register_var(reg_arg,0,0);
1456 r1 = reg_arg+1+MIN_TMP_REG; 1548 r1 = reg_arg+1+MIN_TMP_REG;
1457 if (regs[r1]==PTRC_REG) clear_ptr_cache_reg(r1); 1549 if (regs[r1]==PTRC_REG)
1550 clear_ptr_cache_reg(list2(REGISTER,r1));
1458 /* else if (regs[r1]) error(-1); */ 1551 /* else if (regs[r1]) error(-1); */
1459 r1=get_input_register_var_1(reg_arg+1,0,0); 1552 r1=get_input_register_var_1(reg_arg+1,0,0);
1460 1553
1461 use_var(r0); /* protect from input register free */ 1554 use_var(r0); /* protect from input register free */
1462 use_var(r1); /* protect from input register free */ 1555 use_var(r1); /* protect from input register free */
1517 printf("\tmtctr %s\n",jrn); 1610 printf("\tmtctr %s\n",jrn);
1518 printf("\tbctrl\n"); 1611 printf("\tbctrl\n");
1519 } 1612 }
1520 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { 1613 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
1521 arg = car(reg_arg_list); 1614 arg = car(reg_arg_list);
1522 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER) 1615 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER
1616 ||car(arg)==LREGISTER)
1523 free_register(cadr(arg)); 1617 free_register(cadr(arg));
1524 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); 1618 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
1525 } 1619 }
1526 if (ret_type==DOUBLE||ret_type==FLOAT) { 1620 if (ret_type==DOUBLE||ret_type==FLOAT) {
1527 set_freg(RET_FREGISTER,0); 1621 set_freg(RET_FREGISTER,0);
1622 } else if (ret_type==ULONGLONG||ret_type==LONGLONG) {
1623 set_lreg(RET_LREGISTER,0);
1528 } else if (ret_type==VOID) { 1624 } else if (ret_type==VOID) {
1529 } else { 1625 } else {
1530 set_creg(RET_REGISTER,0); 1626 set_creg(RET_REGISTER,0);
1531 } 1627 }
1532 return ret_type; 1628 return ret_type;
1570 { 1666 {
1571 char *crn; 1667 char *crn;
1572 g_expr(e1); 1668 g_expr(e1);
1573 crn=register_name(creg); 1669 crn=register_name(creg);
1574 printf("\tlwz %s,%d(%s)\n",crn,offset,crn); 1670 printf("\tlwz %s,%d(%s)\n",crn,offset,crn);
1575 return INT; 1671 return us?UNSIGNED:INT;
1576 } 1672 }
1577 1673
1578 int 1674 int
1579 code_crindirect(int e1, int offset, int us) 1675 code_crindirect(int e1, int offset, int us)
1580 { 1676 {
1615 g_expr(e1); 1711 g_expr(e1);
1616 crn=register_name(creg); 1712 crn=register_name(creg);
1617 printf("\t%s %s,%d(%s)\n",fload(d), 1713 printf("\t%s %s,%d(%s)\n",fload(d),
1618 fregister_name(freg),offset,crn); 1714 fregister_name(freg),offset,crn);
1619 creg = freg; 1715 creg = freg;
1620 return DOUBLE; 1716 return d?DOUBLE:FLOAT;
1621 } 1717 }
1622 #endif 1718 #endif
1623 1719
1624 #if LONGLONG_CODE 1720 #if LONGLONG_CODE
1625 int 1721 int
1626 code_lrindirect(int e1, int offset, int us) 1722 code_lrindirect(int e1, int offset, int us)
1627 { 1723 {
1628 char *crn; 1724 char *crn;
1629 g_expr(e1); 1725 g_expr(e1);
1630 crn=register_name(creg); 1726 crn=register_name(creg);
1631 return LONGLONG; 1727 if (!lreg) lreg = get_lregister();
1728 printf("\tlwz %s,%d(%s)\n",crn,offset,lregister_name_low(lreg));
1729 printf("\tlwz %s,%d(%s)\n",crn,offset+size_of_int,lregister_name_high(lreg));
1730 creg = lreg;
1731 return us?ULONGLONG:LONGLONG;
1632 } 1732 }
1633 #endif 1733 #endif
1634 1734
1635 1735
1636 void 1736 void
2090 2190
2091 void 2191 void
2092 code_set_return_register(int mode) { 2192 code_set_return_register(int mode) {
2093 if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) { 2193 if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) {
2094 set_freg(RET_FREGISTER,mode); 2194 set_freg(RET_FREGISTER,mode);
2195 } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) {
2196 set_lreg(RET_LREGISTER,mode);
2095 } else if (cadr(fnptr->ty)==VOID) { 2197 } else if (cadr(fnptr->ty)==VOID) {
2096 } else { 2198 } else {
2097 set_creg(RET_REGISTER,mode); 2199 set_creg(RET_REGISTER,mode);
2098 } 2200 }
2099 } 2201 }
2105 2207
2106 void 2208 void
2107 code_set_fixed_creg(int reg,int mode,int type) { 2209 code_set_fixed_creg(int reg,int mode,int type) {
2108 if (type==FLOAT||type==DOUBLE) { 2210 if (type==FLOAT||type==DOUBLE) {
2109 set_freg(reg,mode); 2211 set_freg(reg,mode);
2110 } else if (type==LONGLONG) { 2212 } else if (type==LONGLONG||type==ULONGLONG) {
2111 set_lreg(reg,mode); 2213 set_lreg(reg,mode);
2112 } else { 2214 } else {
2113 set_creg(reg,mode); 2215 set_creg(reg,mode);
2114 } 2216 }
2115 } 2217 }
2138 { 2240 {
2139 int l; 2241 int l;
2140 #if FLOAT_CODE 2242 #if FLOAT_CODE
2141 double d; 2243 double d;
2142 float f; 2244 float f;
2245 #endif
2246 #if LONGLONG_CODE
2247 long long ll;
2143 #endif 2248 #endif
2144 char *name; 2249 char *name;
2145 name = n->nm; 2250 name = n->nm;
2146 if(mode!=GDECL && mode!=STADECL) { 2251 if(mode!=GDECL && mode!=STADECL) {
2147 error(-1); return; 2252 error(-1); return;
2169 } else { 2274 } else {
2170 printf("\t.long %d\n",cadr(e)); 2275 printf("\t.long %d\n",cadr(e));
2171 gpc += size_of_int; 2276 gpc += size_of_int;
2172 } 2277 }
2173 #if LONGLONG_CODE 2278 #if LONGLONG_CODE
2279 } else if(t==LONGLONG||t==ULONGLONG) {
2280 ll = lcadr(e);
2281 printf("\t.long\t0x%x,0x%x\n",code_l2(ll),code_l1(ll));
2174 #endif 2282 #endif
2175 #if FLOAT_CODE 2283 #if FLOAT_CODE
2176 } else if(t==DOUBLE) { 2284 } else if(t==DOUBLE) {
2177 d = dcadr(e); 2285 d = dcadr(e);
2178 printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d)); 2286 printf("\t.long\t0x%x,0x%x\n",code_d2(d),code_d1(d));
2920 void code_lassign_lregister(int e2,int reg) 3028 void code_lassign_lregister(int e2,int reg)
2921 { 3029 {
2922 3030
2923 } 3031 }
2924 3032
3033 static long long ll = 1LL;
3034
3035 static int
3036 code_l1(long long d)
3037 {
3038 int *i = (int *)&ll; int *j = (int *)&d;
3039 return (i[1] == 1)?j[1]:j[0];
3040 }
3041
3042 static int
3043 code_l2(long long d)
3044 {
3045 int *i = (int *)&ll; int *j = (int *)&d;
3046 return (i[1] == 1)?j[0]:j[1];
3047 }
3048
2925 void code_lconst(int e1,int e2) 3049 void code_lconst(int e1,int e2)
2926 { 3050 {
2927 3051
2928 } 3052 }
2929 3053