Mercurial > hg > CbC > old > device
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 *)≪ 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 *)≪ 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 |