comparison mc-code-powerpc.c @ 880:5313ed059cee

no tabs in source
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 03 Apr 2014 10:43:01 +0900
parents a97cd8b97434
children 8bdd5061cb8f
comparison
equal deleted inserted replaced
879:528595192871 880:5313ed059cee
88 __arg = __ap->float_first; \\\n\ 88 __arg = __ap->float_first; \\\n\
89 __ap->float_first = __ap->float_first+8; \\\n\ 89 __ap->float_first = __ap->float_first+8; \\\n\
90 if (__ap->float_first==__ap->float_last) \\\n\ 90 if (__ap->float_first==__ap->float_last) \\\n\
91 __ap->float_first = __ap->stack_top;\\\n\ 91 __ap->float_first = __ap->stack_top;\\\n\
92 } else { \\\n\ 92 } else { \\\n\
93 if (__builtin_types_compatible_p(type,long long)) { \\\n\ 93 if (__builtin_types_compatible_p(type,long long)) { \\\n\
94 if (__ap->arg==__ap->top+4) __ap->arg += 4; \\\n\ 94 if (__ap->arg==__ap->top+4) __ap->arg += 4; \\\n\
95 __arg = __ap->arg; \\\n\ 95 __arg = __ap->arg; \\\n\
96 __ap->arg += 8; \\\n\ 96 __ap->arg += 8; \\\n\
97 if (__ap->arg==__ap->top+16+16) \\\n\ 97 if (__ap->arg==__ap->top+16+16) \\\n\
98 __ap->arg = __ap->stack_top; \\\n\ 98 __ap->arg = __ap->stack_top; \\\n\
99 } else { \\\n\ 99 } else { \\\n\
100 __arg = __ap->arg; \\\n\ 100 __arg = __ap->arg; \\\n\
101 __ap->arg = __ap->arg+sizeof(type); \\\n\ 101 __ap->arg = __ap->arg+sizeof(type); \\\n\
102 if (__ap->arg==__ap->long_last) \\\n\ 102 if (__ap->arg==__ap->long_last) \\\n\
103 __ap->arg = __ap->stack_top; \\\n\ 103 __ap->arg = __ap->stack_top; \\\n\
104 } \\\n\ 104 } \\\n\
105 } \\\n\ 105 } \\\n\
106 *((type *)(__arg)); \\\n\ 106 *((type *)(__arg)); \\\n\
107 }) \\\n\ 107 }) \\\n\
108 \n" 108 \n"
109 109
377 #define use_int(reg) if (reg==USE_CREG) reg=use_int0() 377 #define use_int(reg) if (reg==USE_CREG) reg=use_int0()
378 static 378 static
379 int use_int0() { 379 int use_int0() {
380 int i = creg; 380 int i = creg;
381 if (!i||!ireg||!is_int_reg(i)) { 381 if (!i||!ireg||!is_int_reg(i)) {
382 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; } 382 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; }
383 if (!ireg) ireg = get_register(); 383 if (!ireg) ireg = get_register();
384 // else if (ireg!=i) free_register(i); 384 // else if (ireg!=i) free_register(i);
385 i = ireg; 385 i = ireg;
386 } 386 }
387 if (!regs[i]) regs[i]=USING_REG; 387 if (!regs[i]) regs[i]=USING_REG;
388 creg = i; 388 creg = i;
389 return i; 389 return i;
390 } 390 }
394 394
395 static 395 static
396 int use_longlong0() { 396 int use_longlong0() {
397 int i = creg; 397 int i = creg;
398 if (!is_longlong_reg(i)) { 398 if (!is_longlong_reg(i)) {
399 if (ireg) { if (regs[ireg]!=REG_VAR) free_register(ireg); ireg=0; } 399 if (ireg) { if (regs[ireg]!=REG_VAR) free_register(ireg); ireg=0; }
400 if (!lreg||!regs[lreg]) lreg = get_lregister(); 400 if (!lreg||!regs[lreg]) lreg = get_lregister();
401 // else if (lreg!=i) free_register(i); 401 // else if (lreg!=i) free_register(i);
402 i = lreg; 402 i = lreg;
403 } 403 }
404 if (!regv_l(i)) regv_l(i) = get_register(); 404 if (!regv_l(i)) regv_l(i) = get_register();
405 if (!regv_h(i)) regv_h(i) = get_register(); 405 if (!regv_h(i)) regv_h(i) = get_register();
406 if (!regs[i]) regs[i]=USING_REG; 406 if (!regs[i]) regs[i]=USING_REG;
407 if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG; 407 if (!regs[regv_l(i)]) regs[regv_l(i)]=USING_REG;
416 #define use_float(d,reg) if (reg==USE_CREG) reg=d?use_double0():use_float0() 416 #define use_float(d,reg) if (reg==USE_CREG) reg=d?use_double0():use_float0()
417 static 417 static
418 int use_float0() { 418 int use_float0() {
419 int i = creg; 419 int i = creg;
420 if (!is_float_reg(i)) { 420 if (!is_float_reg(i)) {
421 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; } 421 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; }
422 if (!freg) freg = get_dregister(0); 422 if (!freg) freg = get_dregister(0);
423 else if (freg!=i) if (regs[i]!=REG_VAR) free_register(i); 423 else if (freg!=i) if (regs[i]!=REG_VAR) free_register(i);
424 i = freg; 424 i = freg;
425 } 425 }
426 if (!regs[i]) regs[i]=USING_REG; 426 if (!regs[i]) regs[i]=USING_REG;
427 creg = i; 427 creg = i;
428 return i; 428 return i;
429 } 429 }
430 static 430 static
431 int use_double0() { 431 int use_double0() {
432 int i = creg; 432 int i = creg;
433 if (!is_float_reg(i)) { 433 if (!is_float_reg(i)) {
434 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; } 434 if (lreg) { if (regs[lreg]!=REG_VAR) free_register(lreg); lreg = 0; }
435 if (!freg) freg = get_dregister(1); 435 if (!freg) freg = get_dregister(1);
436 else if (freg!=i) if (regs[i]!=REG_VAR) free_register(i); 436 else if (freg!=i) if (regs[i]!=REG_VAR) free_register(i);
437 i = freg; 437 i = freg;
438 } 438 }
439 if (!regs[i]) regs[i]=USING_REG; 439 if (!regs[i]) regs[i]=USING_REG;
440 creg = i; 440 creg = i;
441 return i; 441 return i;
442 } 442 }
563 { 563 {
564 #if 0 564 #if 0
565 int l; 565 int l;
566 #endif 566 #endif
567 int lvar_offsetv = 567 int lvar_offsetv =
568 round16(-disp+max_func_args*SIZE_OF_INT)+func_disp_offset; 568 round16(-disp+max_func_args*SIZE_OF_INT)+func_disp_offset;
569 int r1_offsetv = round16(lvar_offsetv-reg_save); 569 int r1_offsetv = round16(lvar_offsetv-reg_save);
570 570
571 printf(".set %s%d,%d\n",lpfx,lvar_offset_label,r1_offsetv-lvar_offsetv); 571 printf(".set %s%d,%d\n",lpfx,lvar_offset_label,r1_offsetv-lvar_offsetv);
572 if (r1_offsetv-lvar_offsetv > 65000) error(-1); 572 if (r1_offsetv-lvar_offsetv > 65000) error(-1);
573 // too large function arguments? 573 // too large function arguments?
574 printf(".set %s%d,%d\n",lpfx,r1_offset_label,r1_offsetv); 574 printf(".set %s%d,%d\n",lpfx,r1_offset_label,r1_offsetv);
575 if (max_func_arg_label) { 575 if (max_func_arg_label) {
576 printf(".set %s%d,%d\n",lpfx,max_func_arg_label, 576 printf(".set %s%d,%d\n",lpfx,max_func_arg_label,
577 round16(max_func_args*SIZE_OF_INT)+24); 577 round16(max_func_args*SIZE_OF_INT)+24);
578 max_func_arg_label = 0; 578 max_func_arg_label = 0;
579 } 579 }
580 580
581 #if 0 581 #if 0
582 printf("## reg_save %d\n",reg_save); 582 printf("## reg_save %d\n",reg_save);
583 printf("## function %s\n",fnptr->nm); 583 printf("## function %s\n",fnptr->nm);
606 static void 606 static void
607 lvar(int l) 607 lvar(int l)
608 { 608 {
609 char *rn; 609 char *rn;
610 if (!large_offset_reg) { 610 if (!large_offset_reg) {
611 if (is_code(fnptr)) { 611 if (is_code(fnptr)) {
612 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 612 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
613 printf("lo16(%d)(r1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 613 printf("lo16(%d)(r1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
614 } else 614 } else
615 printf("lo16(%d)(r30)\n",CODE_LVAR(l)); 615 printf("lo16(%d)(r30)\n",CODE_LVAR(l));
616 } else if (l<0) { /* local variable */ 616 } else if (l<0) { /* local variable */
617 printf("lo16(%d)(r30)\n",FUNC_LVAR(l)); 617 printf("lo16(%d)(r30)\n",FUNC_LVAR(l));
618 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 618 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
619 printf("lo16(%d)(r1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); 619 printf("lo16(%d)(r1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET));
620 } else { /* callee's arguments */ 620 } else { /* callee's arguments */
621 printf("lo16(%d+%s%d)(r30)\n",CALLEE_ARG(l),lpfx,lvar_offset_label); 621 printf("lo16(%d+%s%d)(r30)\n",CALLEE_ARG(l),lpfx,lvar_offset_label);
622 } 622 }
623 } else { 623 } else {
624 rn = register_name(large_offset_reg); 624 rn = register_name(large_offset_reg);
625 if (is_code(fnptr)) { 625 if (is_code(fnptr)) {
626 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 626 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
627 printf("lo16(%d)(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn); 627 printf("lo16(%d)(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn);
655 if (is_code(fnptr)) { 655 if (is_code(fnptr)) {
656 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 656 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
657 if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) { 657 if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) {
658 rn=register_name(large_offset_reg=get_register()); 658 rn=register_name(large_offset_reg=get_register());
659 printf("\taddis %s,r1,ha16(%d)\n",rn, 659 printf("\taddis %s,r1,ha16(%d)\n",rn,
660 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 660 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
661 } 661 }
662 } else { 662 } else {
663 if (LARGE_OFFSET(CODE_LVAR(l))) { 663 if (LARGE_OFFSET(CODE_LVAR(l))) {
664 rn=register_name(large_offset_reg=get_register()); 664 rn=register_name(large_offset_reg=get_register());
665 printf("\taddis %s,r30,ha16(%d)\n",rn,CODE_LVAR(l)); 665 printf("\taddis %s,r30,ha16(%d)\n",rn,CODE_LVAR(l));
677 } 677 }
678 } else { /* callee's arguments */ 678 } else { /* callee's arguments */
679 if (LARGE_OFFSET(CALLEE_ARG(l))) { 679 if (LARGE_OFFSET(CALLEE_ARG(l))) {
680 rn=register_name(large_offset_reg=get_register()); 680 rn=register_name(large_offset_reg=get_register());
681 printf("\taddis %s,r30,ha16(%d+%s%d)\n", 681 printf("\taddis %s,r30,ha16(%d+%s%d)\n",
682 rn,CALLEE_ARG(l),lpfx,lvar_offset_label); 682 rn,CALLEE_ARG(l),lpfx,lvar_offset_label);
683 } 683 }
684 } 684 }
685 } 685 }
686 686
687 #else /* PS3 */ 687 #else /* PS3 */
689 static void 689 static void
690 lvar(int l) 690 lvar(int l)
691 { 691 {
692 char *rn; 692 char *rn;
693 if (!large_offset_reg) { 693 if (!large_offset_reg) {
694 if (is_code(fnptr)) { 694 if (is_code(fnptr)) {
695 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 695 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
696 printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 696 printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
697 } else 697 } else
698 printf("%d@l(%d)\n",CODE_LVAR(l),REG_fp); 698 printf("%d@l(%d)\n",CODE_LVAR(l),REG_fp);
699 } else if (l<0) { /* local variable */ 699 } else if (l<0) { /* local variable */
700 printf("%d@l(%d)\n",FUNC_LVAR(l),REG_fp); 700 printf("%d@l(%d)\n",FUNC_LVAR(l),REG_fp);
701 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 701 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
702 printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); 702 printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET));
703 } else { /* callee's arguments */ 703 } else { /* callee's arguments */
704 printf("%d+%s%d@l(%d)\n",CALLEE_ARG(l),lpfx,lvar_offset_label,REG_fp) ; 704 printf("%d+%s%d@l(%d)\n",CALLEE_ARG(l),lpfx,lvar_offset_label,REG_fp) ;
705 } 705 }
706 } else { 706 } else {
707 rn = register_name(large_offset_reg); 707 rn = register_name(large_offset_reg);
708 if (is_code(fnptr)) { 708 if (is_code(fnptr)) {
709 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 709 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
710 printf("%d@l(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn); 710 printf("%d@l(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn);
738 if (is_code(fnptr)) { 738 if (is_code(fnptr)) {
739 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 739 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
740 if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) { 740 if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) {
741 rn=register_name(large_offset_reg=get_register()); 741 rn=register_name(large_offset_reg=get_register());
742 printf("\taddis %s,1,%d@ha\n",rn, 742 printf("\taddis %s,1,%d@ha\n",rn,
743 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 743 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
744 } 744 }
745 } else { 745 } else {
746 if (LARGE_OFFSET(CODE_LVAR(l))) { 746 if (LARGE_OFFSET(CODE_LVAR(l))) {
747 rn=register_name(large_offset_reg=get_register()); 747 rn=register_name(large_offset_reg=get_register());
748 printf("\taddis %s,%d,%d@ha\n",rn,REG_fp,CODE_LVAR(l)); 748 printf("\taddis %s,%d,%d@ha\n",rn,REG_fp,CODE_LVAR(l));
845 if (dots && (in || !parse_mode)) { 845 if (dots && (in || !parse_mode)) {
846 type = INT; 846 type = INT;
847 mode = LDECL; 847 mode = LDECL;
848 stmode = 0; 848 stmode = 0;
849 n = def(lsearch("__my_va_list",0),0); 849 n = def(lsearch("__my_va_list",0),0);
850 n->dsp = 0; // first argument 850 n->dsp = 0; // first argument
851 } 851 }
852 if (in) return; 852 if (in) return;
853 853
854 while (args) { 854 while (args) {
855 /* process in reverse order */ 855 /* process in reverse order */
856 n = ncadddr(args); 856 n = ncadddr(args);
857 type = n->ty; 857 type = n->ty;
858 int sz = size(type); 858 int sz = size(type);
859 offset = code_arg_alignment(offset,n,type,sz,is_code0); 859 offset = code_arg_alignment(offset,n,type,sz,is_code0);
860 if (scalar(type)) { 860 if (scalar(type)) {
861 if ((reg = get_input_register_var(reg_var,n,is_code0))) { 861 if ((reg = get_input_register_var(reg_var,n,is_code0))) {
862 n->sc = REGISTER; 862 n->sc = REGISTER;
863 n->dsp = cadr(reg); 863 n->dsp = cadr(reg);
864 regs[n->dsp]= INPUT_REG; 864 regs[n->dsp]= INPUT_REG;
865 reg_var++; 865 reg_var++;
866 arg_offset_v += (caddr(args)=SIZE_OF_INT); 866 arg_offset_v += (caddr(args)=SIZE_OF_INT);
867 } 867 }
868 } else if (type==FLOAT) { 868 } else if (type==FLOAT) {
869 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { 869 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) {
870 n->sc = DREGISTER; 870 n->sc = DREGISTER;
871 n->dsp = cadr(reg); 871 n->dsp = cadr(reg);
872 regs[n->dsp]= INPUT_REG; 872 regs[n->dsp]= INPUT_REG;
873 freg_var++; 873 freg_var++;
874 arg_offset_v += (caddr(args)=size(type)); 874 arg_offset_v += (caddr(args)=size(type));
875 } 875 }
876 } else if (type==DOUBLE) { 876 } else if (type==DOUBLE) {
877 if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { 877 if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) {
878 n->sc = DREGISTER; 878 n->sc = DREGISTER;
879 n->dsp = cadr(reg); 879 n->dsp = cadr(reg);
880 regs[n->dsp]= INPUT_REG; 880 regs[n->dsp]= INPUT_REG;
881 freg_var++; 881 freg_var++;
882 arg_offset_v += (caddr(args)=size(type)); 882 arg_offset_v += (caddr(args)=size(type));
883 } 883 }
884 } else if (type==LONGLONG||type==ULONGLONG) { 884 } else if (type==LONGLONG||type==ULONGLONG) {
885 if ((reg = get_input_lregister_var(reg_var,n,is_code0))) { 885 if ((reg = get_input_lregister_var(reg_var,n,is_code0))) {
886 n->sc = LREGISTER; 886 n->sc = LREGISTER;
887 n->dsp = cadr(reg); 887 n->dsp = cadr(reg);
888 regs[i=n->dsp]= INPUT_REG; 888 regs[i=n->dsp]= INPUT_REG;
889 regs[regv_l(i)]= INPUT_REG; 889 regs[regv_l(i)]= INPUT_REG;
890 regs[regv_h(i)]= INPUT_REG; 890 regs[regv_h(i)]= INPUT_REG;
891 reg_var+=2; 891 reg_var+=2;
892 arg_offset_v += (caddr(args)=size(type)); 892 arg_offset_v += (caddr(args)=size(type));
893 } 893 }
894 } 894 }
895 args = cadr(args); 895 args = cadr(args);
896 } 896 }
897 if (is_function(fnptr)) { 897 if (is_function(fnptr)) {
898 #ifndef __APPLE__ 898 #ifndef __APPLE__
899 if (dots) { 899 if (dots) {
900 arg_offset_v = 900 arg_offset_v =
901 MAX_INPUT_REGISTER_VAR*SIZE_OF_INT + 901 MAX_INPUT_REGISTER_VAR*SIZE_OF_INT +
902 MAX_INPUT_DREGISTER_VAR*SIZE_OF_DOUBLE; 902 MAX_INPUT_DREGISTER_VAR*SIZE_OF_DOUBLE;
903 } 903 }
904 printf(".set %s%d, %d\n",lpfx, arg_offset_label, 904 printf(".set %s%d, %d\n",lpfx, arg_offset_label,
905 arg_offset_v+ arg_offset); 905 arg_offset_v+ arg_offset);
906 #endif 906 #endif
907 code_save_input_registers(dots); 907 code_save_input_registers(dots);
908 } 908 }
909 } 909 }
910 910
911 911
912 int 912 int
913 get_register(void) 913 get_register(void)
914 { /* 使われていないレジスタを調べる */ 914 { /* 使われていないレジスタを調べる */
915 int i,j,reg; 915 int i,j,reg;
916 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { 916 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
917 if (regs[i]) continue; /* 使われている */ 917 if (regs[i]) continue; /* 使われている */
918 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 918 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
919 return i; /* その場所を表す番号を返す */ 919 return i; /* その場所を表す番号を返す */
920 } 920 }
921 /* PTR_CACHE をつぶす */ 921 /* PTR_CACHE をつぶす */
922 if ((i=last_ptr_cache())) { 922 if ((i=last_ptr_cache())) {
923 clear_ptr_cache_reg(i); 923 clear_ptr_cache_reg(i);
924 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 924 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
925 return i; /* その場所を表す番号を返す */ 925 return i; /* その場所を表す番号を返す */
926 } 926 }
927 /* search register stack */ 927 /* search register stack */
928 for(i=0;i<reg_sp;i++) { 928 for(i=0;i<reg_sp;i++) {
929 if ((reg=reg_stack[i])>=0) { 929 if ((reg=reg_stack[i])>=0) {
930 code_assign_lvar( 930 code_assign_lvar(
931 (j=new_lvar(SIZE_OF_INT)),reg,0); 931 (j=new_lvar(SIZE_OF_INT)),reg,0);
932 reg_stack[i]= j-REG_LVAR_OFFSET; 932 reg_stack[i]= j-REG_LVAR_OFFSET;
933 return reg; 933 return reg;
934 } 934 }
935 } 935 }
936 #if LONGLONG_CODE 936 #if LONGLONG_CODE
937 /* search register stack */ 937 /* search register stack */
938 for(i=0;i<lreg_sp;i++) { 938 for(i=0;i<lreg_sp;i++) {
939 if ((reg=lreg_stack[i])>=0) { 939 if ((reg=lreg_stack[i])>=0) {
940 code_lassign_lvar( 940 code_lassign_lvar(
941 (j=new_lvar(SIZE_OF_LONGLONG)),reg); 941 (j=new_lvar(SIZE_OF_LONGLONG)),reg);
942 lreg_stack[i]= j-REG_LVAR_OFFSET; 942 lreg_stack[i]= j-REG_LVAR_OFFSET;
943 free_register(reg); 943 free_register(reg);
944 return get_register(); 944 return get_register();
945 } 945 }
946 } 946 }
947 #endif 947 #endif
948 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 948 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
949 reg =REG_VAR_BASE-i; 949 reg =REG_VAR_BASE-i;
950 if (! regs[reg]) { /* 使われていないなら */ 950 if (! regs[reg]) { /* 使われていないなら */
951 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ 951 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
952 if (i>max_reg_var) max_reg_var=i; 952 if (i>max_reg_var) max_reg_var=i;
953 return reg; /* その場所を表す番号を返す */ 953 return reg; /* その場所を表す番号を返す */
954 } 954 }
955 } 955 }
956 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ 956 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
957 error(RGERR); return creg; 957 error(RGERR); return creg;
958 } 958 }
977 int 977 int
978 get_dregister(int d) 978 get_dregister(int d)
979 { /* 使われていないレジスタを調べる */ 979 { /* 使われていないレジスタを調べる */
980 int i,reg; 980 int i,reg;
981 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { 981 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) {
982 if (regs[i]) continue; /* 使われている */ 982 if (regs[i]) continue; /* 使われている */
983 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ 983 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
984 return i; /* その場所を表す番号を返す */ 984 return i; /* その場所を表す番号を返す */
985 } 985 }
986 /* search register stack */ 986 /* search register stack */
987 for(i=0;i<freg_sp;i++) { 987 for(i=0;i<freg_sp;i++) {
988 if ((reg=freg_stack[i])>=0) { 988 if ((reg=freg_stack[i])>=0) {
989 code_dassign_lvar( 989 code_dassign_lvar(
990 (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1); 990 (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1);
991 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; 991 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
992 return reg; 992 return reg;
993 } 993 }
994 } 994 }
995 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { 995 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) {
996 reg =FREG_VAR_BASE-i+FREG_OFFSET; 996 reg =FREG_VAR_BASE-i+FREG_OFFSET;
997 if (! regs[reg]) { /* 使われていないなら */ 997 if (! regs[reg]) { /* 使われていないなら */
998 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ 998 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
999 if (i>max_freg_var) max_freg_var=i; 999 if (i>max_freg_var) max_freg_var=i;
1000 return reg; /* その場所を表す番号を返す */ 1000 return reg; /* その場所を表す番号を返す */
1001 } 1001 }
1002 } 1002 }
1003 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ 1003 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
1004 error(REG_ERR); return freg; 1004 error(REG_ERR); return freg;
1005 } 1005 }
1025 int 1025 int
1026 get_lregister0() 1026 get_lregister0()
1027 { 1027 {
1028 int i; 1028 int i;
1029 for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { 1029 for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
1030 if (regs[i]==0) { 1030 if (regs[i]==0) {
1031 return i; 1031 return i;
1032 } 1032 }
1033 } 1033 }
1034 return -1; 1034 return -1;
1035 } 1035 }
1036 1036
1037 static int 1037 static int
1038 get_lregister1(int n,int m) 1038 get_lregister1(int n,int m)
1039 { 1039 {
1040 int i; 1040 int i;
1041 #if 1 1041 #if 1
1042 for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { 1042 for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
1043 if (regv_l(i)==n && regv_h(i)==m) { 1043 if (regv_l(i)==n && regv_h(i)==m) {
1044 return i; 1044 return i;
1045 } 1045 }
1046 } 1046 }
1047 #endif 1047 #endif
1048 return get_lregister0(); 1048 return get_lregister0();
1049 } 1049 }
1050 1050
1055 int i; 1055 int i;
1056 // we should not have this, but powerpc's function 1056 // we should not have this, but powerpc's function
1057 // lost some input register variables. 1057 // lost some input register variables.
1058 #if 1 1058 #if 1
1059 for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { 1059 for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
1060 if (regs[i]) { 1060 if (regs[i]) {
1061 if(!regv_l(i) && !regv_h(i)) { 1061 if(!regv_l(i) && !regv_h(i)) {
1062 regs[i]=0; 1062 regs[i]=0;
1063 // printf("## cleanup lreg 0 %d\n",i); 1063 // printf("## cleanup lreg 0 %d\n",i);
1064 } else if(!regs[regv_l(i)] && !regs[regv_h(i)]) { 1064 } else if(!regs[regv_l(i)] && !regs[regv_h(i)]) {
1065 free_register(i); 1065 free_register(i);
1066 // printf("## cleanup lreg 1 %d\n",i); 1066 // printf("## cleanup lreg 1 %d\n",i);
1067 } 1067 }
1068 } 1068 }
1069 } 1069 }
1070 #endif 1070 #endif
1071 } 1071 }
1072 1072
1073 int 1073 int
1079 h = get_register(); 1079 h = get_register();
1080 if (h==-1) return -1; 1080 if (h==-1) return -1;
1081 regv_h(i) = h; 1081 regv_h(i) = h;
1082 l = get_register(); 1082 l = get_register();
1083 if (l==-1) { 1083 if (l==-1) {
1084 if (regs[h]!=REG_VAR) free_register(h); 1084 if (regs[h]!=REG_VAR) free_register(h);
1085 if (regs[i]!=REG_VAR) free_register(i); 1085 if (regs[i]!=REG_VAR) free_register(i);
1086 return -1; 1086 return -1;
1087 } 1087 }
1088 regv_l(i) = l; 1088 regv_l(i) = l;
1089 if (!regs[i]) regs[i]=USING_REG; 1089 if (!regs[i]) regs[i]=USING_REG;
1090 // printf("## get_lregister %d %s %s\n",i, lregister_name_high(i), lregister_name_low(i)); 1090 // printf("## get_lregister %d %s %s\n",i, lregister_name_high(i), lregister_name_low(i));
1091 return i; 1091 return i;
1097 int i,j,ll; 1097 int i,j,ll;
1098 int max_reg_var_save=max_reg_var; 1098 int max_reg_var_save=max_reg_var;
1099 ll = get_lregister0(); 1099 ll = get_lregister0();
1100 if (ll==-1) goto not_found; 1100 if (ll==-1) goto not_found;
1101 if (regs[ll]==0) { 1101 if (regs[ll]==0) {
1102 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 1102 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
1103 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ 1103 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
1104 /* そのレジスタを使うことを宣言し */ 1104 /* そのレジスタを使うことを宣言し */
1105 regs[REG_VAR_BASE-i]=USING_REG; 1105 regs[REG_VAR_BASE-i]=USING_REG;
1106 if (i>max_reg_var) max_reg_var=i; 1106 if (i>max_reg_var) max_reg_var=i;
1107 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) { 1107 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) {
1108 if (! regs[REG_VAR_BASE-j]) { 1108 if (! regs[REG_VAR_BASE-j]) {
1109 /* 使われていないなら */ 1109 /* 使われていないなら */
1110 /* そのレジスタを使うことを宣言し */ 1110 /* そのレジスタを使うことを宣言し */
1111 regs[REG_VAR_BASE-j]=REG_VAR; 1111 regs[REG_VAR_BASE-j]=REG_VAR;
1112 if (j>max_reg_var) max_reg_var=j; 1112 if (j>max_reg_var) max_reg_var=j;
1113 /* その場所を表す番号を返す */ 1113 /* その場所を表す番号を返す */
1114 regs[ll]=REG_VAR; 1114 regs[ll]=REG_VAR;
1115 regv_l(ll) = REG_VAR_BASE-j; 1115 regv_l(ll) = REG_VAR_BASE-j;
1116 regv_h(ll) = REG_VAR_BASE-i; 1116 regv_h(ll) = REG_VAR_BASE-i;
1117 return list3n(LREGISTER,ll,n); 1117 return list3n(LREGISTER,ll,n);
1118 } 1118 }
1119 } 1119 }
1120 /* ひとつしかなかった */ 1120 /* ひとつしかなかった */
1121 regs[REG_VAR_BASE-i]=0; 1121 regs[REG_VAR_BASE-i]=0;
1122 max_reg_var=max_reg_var_save; 1122 max_reg_var=max_reg_var_save;
1123 goto not_found; 1123 goto not_found;
1124 } 1124 }
1125 } 1125 }
1126 } 1126 }
1127 not_found: 1127 not_found:
1128 return list3n(LVAR,new_lvar(SIZE_OF_LONGLONG),0); 1128 return list3n(LVAR,new_lvar(SIZE_OF_LONGLONG),0);
1129 } 1129 }
1130 1130
1131 void 1131 void
1132 emit_pop_free(int xreg) 1132 emit_pop_free(int xreg)
1133 { 1133 {
1134 if (xreg>=0 && xreg!=creg && regs[xreg]!=REG_VAR) 1134 if (xreg>=0 && xreg!=creg && regs[xreg]!=REG_VAR)
1135 free_register(xreg); 1135 free_register(xreg);
1136 } 1136 }
1137 1137
1138 void 1138 void
1139 1139
1140 free_register(int i) { /* いらなくなったレジスタを開放 */ 1140 free_register(int i) { /* いらなくなったレジスタを開放 */
1141 // printf("## free_register %d\n",i); 1141 // printf("## free_register %d\n",i);
1142 if (is_longlong_reg(i)) { 1142 if (is_longlong_reg(i)) {
1143 regs[regv_l(i)]=0; 1143 regs[regv_l(i)]=0;
1144 regs[regv_h(i)]=0; 1144 regs[regv_h(i)]=0;
1145 } 1145 }
1146 regs[i]=0; 1146 regs[i]=0;
1147 } 1147 }
1148 1148
1149 extern void 1149 extern void
1154 1154
1155 int 1155 int
1156 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) 1156 get_input_dregister_var(int i,NMTBL *n,int is_code,int d)
1157 { 1157 {
1158 if (is_code) { 1158 if (is_code) {
1159 if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; 1159 if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0;
1160 i = FREG_VAR_BASE-i+FREG_OFFSET; 1160 i = FREG_VAR_BASE-i+FREG_OFFSET;
1161 } else { 1161 } else {
1162 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; 1162 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0;
1163 i = i+MIN_TMP_FREG+FREG_OFFSET; 1163 i = i+MIN_TMP_FREG+FREG_OFFSET;
1164 } 1164 }
1165 return list3n(DREGISTER,i,n); 1165 return list3n(DREGISTER,i,n);
1166 } 1166 }
1167 1167
1168 int 1168 int
1169 get_input_lregister_var(int i,NMTBL *n,int is_code) 1169 get_input_lregister_var(int i,NMTBL *n,int is_code)
1170 { 1170 {
1171 int ll; 1171 int ll;
1172 if (i!=-1) { 1172 if (i!=-1) {
1173 if (is_code) { 1173 if (is_code) {
1174 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; 1174 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
1175 i = REG_VAR_BASE-i; 1175 i = REG_VAR_BASE-i;
1176 } else { 1176 } else {
1177 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; 1177 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
1178 #ifndef __APPLE__ 1178 #ifndef __APPLE__
1179 if (i%2==1) i++; 1179 if (i%2==1) i++;
1180 #endif 1180 #endif
1181 i = i+MIN_TMP_REG; 1181 i = i+MIN_TMP_REG;
1182 } 1182 }
1183 ll = get_lregister1(i,i+1); 1183 ll = get_lregister1(i,i+1);
1184 #if ENDIAN_L==0 1184 #if ENDIAN_L==0
1185 regv_l(ll)=i; 1185 regv_l(ll)=i;
1186 regv_h(ll)=i+1; 1186 regv_h(ll)=i+1;
1187 #else 1187 #else
1188 regv_h(ll)=i; 1188 regv_h(ll)=i;
1189 regv_l(ll)=i+1; 1189 regv_l(ll)=i+1;
1190 #endif 1190 #endif
1191 } else { error(-1); ll=LREG_OFFSET+2; } 1191 } else { error(-1); ll=LREG_OFFSET+2; }
1192 return list3n(LREGISTER,ll,n); 1192 return list3n(LREGISTER,ll,n);
1193 } 1193 }
1194 1194
1195 int 1195 int
1196 get_input_register_var(int i,NMTBL *n,int is_code) 1196 get_input_register_var(int i,NMTBL *n,int is_code)
1197 { 1197 {
1198 if (is_code) { 1198 if (is_code) {
1199 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; 1199 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
1200 i = REG_VAR_BASE-i; 1200 i = REG_VAR_BASE-i;
1201 } else { 1201 } else {
1202 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; 1202 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
1203 i = i+MIN_TMP_REG; 1203 i = i+MIN_TMP_REG;
1204 } 1204 }
1205 return list3n(REGISTER,i,n); 1205 return list3n(REGISTER,i,n);
1206 } 1206 }
1207 1207
1208 /* double register case? */ 1208 /* double register case? */
1209 1209
1210 int 1210 int
1211 get_input_register_var_1(int i,NMTBL *n,int is_code) 1211 get_input_register_var_1(int i,NMTBL *n,int is_code)
1212 { 1212 {
1213 if (is_code) { 1213 if (is_code) {
1214 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; 1214 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
1215 i = REG_VAR_BASE-i; 1215 i = REG_VAR_BASE-i;
1216 } else { 1216 } else {
1217 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; 1217 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0;
1218 i = i+MIN_TMP_REG; 1218 i = i+MIN_TMP_REG;
1219 } 1219 }
1220 return list3n(REGISTER,i,n); 1220 return list3n(REGISTER,i,n);
1221 } 1221 }
1222 1222
1223 int 1223 int
1239 static int 1239 static int
1240 register_full(void) 1240 register_full(void)
1241 { 1241 {
1242 int i; 1242 int i;
1243 for(i=0;i<MAX_REGISTER;i++) { 1243 for(i=0;i<MAX_REGISTER;i++) {
1244 if (! regs[i]) { 1244 if (! regs[i]) {
1245 return 0; 1245 return 0;
1246 } 1246 }
1247 } 1247 }
1248 return 1; 1248 return 1;
1249 } 1249 }
1250 #endif 1250 #endif
1251 1251
1254 { 1254 {
1255 int i; 1255 int i;
1256 // printf("## free_all register\n"); 1256 // printf("## free_all register\n");
1257 #if LONGLONG_CODE 1257 #if LONGLONG_CODE
1258 for(i=0;i<REAL_MAX_LREGISTER;i++) { 1258 for(i=0;i<REAL_MAX_LREGISTER;i++) {
1259 regs[i+LREG_OFFSET]=0; 1259 regs[i+LREG_OFFSET]=0;
1260 regv_l(i+LREG_OFFSET) = 0; 1260 regv_l(i+LREG_OFFSET) = 0;
1261 regv_h(i+LREG_OFFSET) = 0; 1261 regv_h(i+LREG_OFFSET) = 0;
1262 } 1262 }
1263 lreg = 0; 1263 lreg = 0;
1264 // set_lreg(LREG_LREGISTER,0); 1264 // set_lreg(LREG_LREGISTER,0);
1265 #endif 1265 #endif
1266 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; } 1266 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; }
1277 extern int 1277 extern int
1278 code_register_overlap(int s,int t) 1278 code_register_overlap(int s,int t)
1279 { 1279 {
1280 switch(car(s)) { 1280 switch(car(s)) {
1281 case REGISTER: 1281 case REGISTER:
1282 switch(car(t)) { 1282 switch(car(t)) {
1283 case DREGISTER: case FREGISTER: break; 1283 case DREGISTER: case FREGISTER: break;
1284 case REGISTER: 1284 case REGISTER:
1285 if(cadr(s)==cadr(t)) return 1; 1285 if(cadr(s)==cadr(t)) return 1;
1286 break; 1286 break;
1287 case LREGISTER: 1287 case LREGISTER:
1288 if(cadr(s)==regv_l(cadr(t))) return 1; 1288 if(cadr(s)==regv_l(cadr(t))) return 1;
1289 if(cadr(s)==regv_h(cadr(t))) return 1; 1289 if(cadr(s)==regv_h(cadr(t))) return 1;
1290 break; 1290 break;
1291 } 1291 }
1292 break; 1292 break;
1293 case DREGISTER: 1293 case DREGISTER:
1294 case FREGISTER: 1294 case FREGISTER:
1295 switch(car(t)) { 1295 switch(car(t)) {
1296 case REGISTER: case LREGISTER: break; 1296 case REGISTER: case LREGISTER: break;
1297 case DREGISTER: case FREGISTER: 1297 case DREGISTER: case FREGISTER:
1298 if(cadr(s)==cadr(t)) return 1; 1298 if(cadr(s)==cadr(t)) return 1;
1299 break; 1299 break;
1300 } 1300 }
1301 break; 1301 break;
1302 case LREGISTER: 1302 case LREGISTER:
1303 switch(car(t)) { 1303 switch(car(t)) {
1304 case DREGISTER: case FREGISTER: break; 1304 case DREGISTER: case FREGISTER: break;
1305 case REGISTER: 1305 case REGISTER:
1306 if(cadr(t)==regv_l(cadr(s))) return 1; 1306 if(cadr(t)==regv_l(cadr(s))) return 1;
1307 if(cadr(t)==regv_h(cadr(s))) return 1; 1307 if(cadr(t)==regv_h(cadr(s))) return 1;
1308 break; 1308 break;
1309 case LREGISTER: 1309 case LREGISTER:
1310 if(regv_l(cadr(t))==regv_l(cadr(s))) return 1; 1310 if(regv_l(cadr(t))==regv_l(cadr(s))) return 1;
1311 if(regv_l(cadr(t))==regv_h(cadr(s))) return 1; 1311 if(regv_l(cadr(t))==regv_h(cadr(s))) return 1;
1312 if(regv_h(cadr(t))==regv_l(cadr(s))) return 1; 1312 if(regv_h(cadr(t))==regv_l(cadr(s))) return 1;
1313 if(regv_h(cadr(t))==regv_h(cadr(s))) return 1; 1313 if(regv_h(cadr(t))==regv_h(cadr(s))) return 1;
1314 break; 1314 break;
1315 } 1315 }
1316 break; 1316 break;
1317 } 1317 }
1318 return 0; 1318 return 0;
1319 } 1319 }
1320 1320
1321 // int lreg_count; 1321 // int lreg_count;
1330 if (!lsrc) return; 1330 if (!lsrc) return;
1331 printf("## %d: %s:",lineno,s); 1331 printf("## %d: %s:",lineno,s);
1332 if (ireg) printf(" creg=%s",register_name(ireg)); 1332 if (ireg) printf(" creg=%s",register_name(ireg));
1333 if (freg) printf(" freg=%s",fregister_name(freg)); 1333 if (freg) printf(" freg=%s",fregister_name(freg));
1334 if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg), 1334 if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg),
1335 lregister_name_low(lreg)); 1335 lregister_name_low(lreg));
1336 #if 1 1336 #if 1
1337 for(j=0,i=0;i<MAX_REGISTER;i++) if (regs[i]) j++; 1337 for(j=0,i=0;i<MAX_REGISTER;i++) if (regs[i]) j++;
1338 if (j>USAGE_MAX) { 1338 if (j>USAGE_MAX) {
1339 printf("\n## regs(%d):",j); 1339 printf("\n## regs(%d):",j);
1340 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } 1340 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); }
1341 } 1341 }
1342 if (reg_sp>0) { 1342 if (reg_sp>0) {
1343 printf(" stack "); 1343 printf(" stack ");
1344 for(i=reg_sp;i>0;i--) { 1344 for(i=reg_sp;i>0;i--) {
1345 if(reg_stack[i-1]>=0) { 1345 if(reg_stack[i-1]>=0) {
1346 printf(" %s",register_name(reg_stack[i-1])); 1346 printf(" %s",register_name(reg_stack[i-1]));
1347 } else 1347 } else
1348 printf(",%d",reg_stack[i-1]); 1348 printf(",%d",reg_stack[i-1]);
1349 } 1349 }
1350 } 1350 }
1351 for(j=0,i=0;i<MAX_FREGISTER;i++) if (regs[i+FREG_OFFSET]) j++; 1351 for(j=0,i=0;i<MAX_FREGISTER;i++) if (regs[i+FREG_OFFSET]) j++;
1352 if (j>USAGE_MAX) { 1352 if (j>USAGE_MAX) {
1353 printf("\n## freg(%d):",j); 1353 printf("\n## freg(%d):",j);
1354 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } 1354 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); }
1355 } 1355 }
1356 if (freg_sp>0) { 1356 if (freg_sp>0) {
1357 printf(" fstack "); 1357 printf(" fstack ");
1358 for(i=freg_sp;i>0;i--) { 1358 for(i=freg_sp;i>0;i--) {
1359 if(freg_stack[i-1]>=0) { 1359 if(freg_stack[i-1]>=0) {
1360 printf(" %s",fregister_name(freg_stack[i-1])); 1360 printf(" %s",fregister_name(freg_stack[i-1]));
1361 } else 1361 } else
1362 printf(",%d",freg_stack[i-1]); 1362 printf(",%d",freg_stack[i-1]);
1363 } 1363 }
1364 } 1364 }
1365 1365
1366 for(j=0,i=0;i<REAL_MAX_LREGISTER;i++) if (regs[i+LREG_OFFSET]) j++; 1366 for(j=0,i=0;i<REAL_MAX_LREGISTER;i++) if (regs[i+LREG_OFFSET]) j++;
1367 // lreg_count = j; 1367 // lreg_count = j;
1368 if (j>USAGE_MAX) { 1368 if (j>USAGE_MAX) {
1369 printf("\n## lreg(%d):",j); 1369 printf("\n## lreg(%d):",j);
1370 for(i=0;i<REAL_MAX_LREGISTER;i++) { printf("%d",regs[i+LREG_OFFSET]); } 1370 for(i=0;i<REAL_MAX_LREGISTER;i++) { printf("%d",regs[i+LREG_OFFSET]); }
1371 #if 0 1371 #if 0
1372 for(i=0;i<REAL_MAX_LREGISTER;i++) { 1372 for(i=0;i<REAL_MAX_LREGISTER;i++) {
1373 if (regs[i+LREG_OFFSET] && regv_l(i+LREG_OFFSET)) 1373 if (regs[i+LREG_OFFSET] && regv_l(i+LREG_OFFSET))
1374 printf(" %s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET)); 1374 printf(" %s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET));
1375 else if (regv_l(i+LREG_OFFSET)) 1375 else if (regv_l(i+LREG_OFFSET))
1376 printf(" *%s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET)); 1376 printf(" *%s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET));
1377 } 1377 }
1378 #endif 1378 #endif
1379 } 1379 }
1380 if (lreg_sp>0) { 1380 if (lreg_sp>0) {
1381 printf(" lstack "); 1381 printf(" lstack ");
1382 for(i=lreg_sp;i>0;i--) { 1382 for(i=lreg_sp;i>0;i--) {
1383 if(lreg_stack[i-1]>=0) { 1383 if(lreg_stack[i-1]>=0) {
1384 printf(" %s",lregister_name_high(lreg_stack[i-1])); 1384 printf(" %s",lregister_name_high(lreg_stack[i-1]));
1385 printf(",%s",lregister_name_low(lreg_stack[i-1])); 1385 printf(",%s",lregister_name_low(lreg_stack[i-1]));
1386 } else 1386 } else
1387 printf(",%d",lreg_stack[i-1]); 1387 printf(",%d",lreg_stack[i-1]);
1388 } 1388 }
1389 } 1389 }
1390 #endif 1390 #endif
1391 printf("\n"); 1391 printf("\n");
1392 } 1392 }
1393 1393
1394 void 1394 void
1395 1395
1396 gexpr_init(void) 1396 gexpr_init(void)
1397 { 1397 {
1398 while(reg_sp > 0) { 1398 while(reg_sp > 0) {
1399 error(-1); 1399 error(-1);
1400 free_register(reg_stack[--reg_sp]); 1400 free_register(reg_stack[--reg_sp]);
1401 } 1401 }
1402 while(freg_sp > 0) { 1402 while(freg_sp > 0) {
1403 error(-1); 1403 error(-1);
1404 free_register(freg_stack[--freg_sp]); 1404 free_register(freg_stack[--freg_sp]);
1405 } 1405 }
1406 while(lreg_sp > 0) { 1406 while(lreg_sp > 0) {
1407 error(-1); 1407 error(-1);
1408 free_register(lreg_stack[--lreg_sp]); 1408 free_register(lreg_stack[--lreg_sp]);
1409 } 1409 }
1410 use_int0(); 1410 use_int0();
1411 text_mode(0); 1411 text_mode(0);
1412 gexpr_code_init(); 1412 gexpr_code_init();
1413 register_usage("gexpr_init"); 1413 register_usage("gexpr_init");
1430 int 1430 int
1431 get_register_var(NMTBL *n) 1431 get_register_var(NMTBL *n)
1432 { 1432 {
1433 int i; 1433 int i;
1434 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 1434 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
1435 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ 1435 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
1436 /* そのレジスタを使うことを宣言し */ 1436 /* そのレジスタを使うことを宣言し */
1437 regs[REG_VAR_BASE-i]=REG_VAR; 1437 regs[REG_VAR_BASE-i]=REG_VAR;
1438 if (i>max_reg_var) max_reg_var=i; 1438 if (i>max_reg_var) max_reg_var=i;
1439 /* その場所を表す番号を返す */ 1439 /* その場所を表す番号を返す */
1440 return list3n(REGISTER,REG_VAR_BASE-i,n); 1440 return list3n(REGISTER,REG_VAR_BASE-i,n);
1441 } 1441 }
1442 } 1442 }
1443 return list3n(LVAR,new_lvar(SIZE_OF_INT),0); 1443 return list3n(LVAR,new_lvar(SIZE_OF_INT),0);
1444 } 1444 }
1445 1445
1446 int 1446 int
1448 { 1448 {
1449 int i; 1449 int i;
1450 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { 1450 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) {
1451 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ 1451 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */
1452 regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*そのレジスタを使うことを宣言し*/ 1452 regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*そのレジスタを使うことを宣言し*/
1453 if (i>max_freg_var) max_freg_var=i; 1453 if (i>max_freg_var) max_freg_var=i;
1454 /* その場所を表す番号を返す */ 1454 /* その場所を表す番号を返す */
1455 return list3n(DREGISTER, 1455 return list3n(DREGISTER,
1456 FREG_VAR_BASE-i+FREG_OFFSET,n); 1456 FREG_VAR_BASE-i+FREG_OFFSET,n);
1457 } 1457 }
1458 } 1458 }
1459 return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0); 1459 return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0);
1460 } 1460 }
1461 1461
1477 emit_pop(int type) 1477 emit_pop(int type)
1478 { 1478 {
1479 int xreg,reg; 1479 int xreg,reg;
1480 xreg=pop_register(); 1480 xreg=pop_register();
1481 if (xreg<= -REG_LVAR_OFFSET) { 1481 if (xreg<= -REG_LVAR_OFFSET) {
1482 reg = get_register(); 1482 reg = get_register();
1483 code_rlvar(REG_LVAR_OFFSET+xreg,reg); 1483 code_rlvar(REG_LVAR_OFFSET+xreg,reg);
1484 free_lvar(REG_LVAR_OFFSET+xreg); 1484 free_lvar(REG_LVAR_OFFSET+xreg);
1485 xreg = reg; 1485 xreg = reg;
1486 } 1486 }
1487 return xreg; 1487 return xreg;
1488 } 1488 }
1489 1489
1490 #ifdef __APPLE__ 1490 #ifdef __APPLE__
1495 code_ptr_cache_def(int r,NMTBL *nptr) 1495 code_ptr_cache_def(int r,NMTBL *nptr)
1496 { 1496 {
1497 char *rrn = register_name(r); 1497 char *rrn = register_name(r);
1498 #ifdef __APPLE__ 1498 #ifdef __APPLE__
1499 if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { 1499 if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) {
1500 printf("\taddis %s,r31,ha16(_%s-L_%d)\n", 1500 printf("\taddis %s,r31,ha16(_%s-L_%d)\n",
1501 rrn,nptr->nm,code_base); 1501 rrn,nptr->nm,code_base);
1502 printf("\tla %s,lo16(_%s-L_%d)(%s)\n", 1502 printf("\tla %s,lo16(_%s-L_%d)(%s)\n",
1503 rrn,nptr->nm,code_base,rrn); 1503 rrn,nptr->nm,code_base,rrn);
1504 } else { 1504 } else {
1505 printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n", 1505 printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n",
1506 rrn,nptr->nm,code_base); 1506 rrn,nptr->nm,code_base);
1507 printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n", 1507 printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n",
1508 rrn,nptr->nm,code_base,rrn); 1508 rrn,nptr->nm,code_base,rrn);
1509 } 1509 }
1510 #else 1510 #else
1511 printf("\tlis %s,%s@ha\n", 1511 printf("\tlis %s,%s@ha\n",
1512 rrn,nptr->nm); 1512 rrn,nptr->nm);
1513 printf("\tla %s,%s@l(%s)\n", 1513 printf("\tla %s,%s@l(%s)\n",
1514 rrn,nptr->nm,rrn); 1514 rrn,nptr->nm,rrn);
1515 #endif 1515 #endif
1516 } 1516 }
1517 1517
1518 static char *cload(int sz) { return sz==1?"lbz":sz==SIZE_OF_SHORT?"lhz":"lwz"; } 1518 static char *cload(int sz) { return sz==1?"lbz":sz==SIZE_OF_SHORT?"lhz":"lwz"; }
1519 static char *cstore(int sz) { return sz==1?"stb":sz==SIZE_OF_SHORT?"sth":"stw"; } 1519 static char *cstore(int sz) { return sz==1?"stb":sz==SIZE_OF_SHORT?"sth":"stw"; }
1521 static void 1521 static void
1522 cext(int sign,int sz,int reg) 1522 cext(int sign,int sz,int reg)
1523 { 1523 {
1524 char *crn = register_name(reg); 1524 char *crn = register_name(reg);
1525 if (sign) { 1525 if (sign) {
1526 if (sz==1) 1526 if (sz==1)
1527 printf("\textsb %s,%s\n",crn,crn); 1527 printf("\textsb %s,%s\n",crn,crn);
1528 else if (sz==SIZE_OF_SHORT) 1528 else if (sz==SIZE_OF_SHORT)
1529 printf("\textsh %s,%s\n",crn,crn); 1529 printf("\textsh %s,%s\n",crn,crn);
1530 } else { 1530 } else {
1531 if (sz==1) 1531 if (sz==1)
1532 printf("\trlwinm %s,%s,0,0xff\n",crn,crn); 1532 printf("\trlwinm %s,%s,0,0xff\n",crn,crn);
1533 else if (sz==SIZE_OF_SHORT) 1533 else if (sz==SIZE_OF_SHORT)
1534 printf("\trlwinm %s,%s,0,0xffff\n",crn,crn); 1534 printf("\trlwinm %s,%s,0,0xffff\n",crn,crn);
1535 } 1535 }
1536 } 1536 }
1537 1537
1538 1538
1539 void 1539 void
1547 code_add(int reg,int offset,int r) 1547 code_add(int reg,int offset,int r)
1548 { 1548 {
1549 char *crn = register_name(reg); 1549 char *crn = register_name(reg);
1550 char *rrn = register_name(r); 1550 char *rrn = register_name(r);
1551 if (offset==0) { 1551 if (offset==0) {
1552 if(r!=reg) 1552 if(r!=reg)
1553 printf("\tmr %s,%s\n",crn,rrn); 1553 printf("\tmr %s,%s\n",crn,rrn);
1554 } else if (LARGE_OFFSET(offset)) { 1554 } else if (LARGE_OFFSET(offset)) {
1555 #ifdef __APPLE__ 1555 #ifdef __APPLE__
1556 printf("\tla %s,lo16(%d)(%s)\n",crn,offset,rrn); 1556 printf("\tla %s,lo16(%d)(%s)\n",crn,offset,rrn);
1557 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); 1557 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset);
1558 #else 1558 #else
1559 printf("\tla %s,%d@l(%s)\n",crn,offset,rrn); 1559 printf("\tla %s,%d@l(%s)\n",crn,offset,rrn);
1560 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); 1560 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset);
1561 #endif 1561 #endif
1562 } else 1562 } else
1563 printf("\taddi %s,%s,%d\n",crn,rrn,offset); 1563 printf("\taddi %s,%s,%d\n",crn,rrn,offset);
1564 } 1564 }
1565 1565
1566 static void 1566 static void
1567 code_ld(char *ld,int reg,int offset,int r) 1567 code_ld(char *ld,int reg,int offset,int r)
1568 { 1568 {
1569 char *crn = register_name(reg); 1569 char *crn = register_name(reg);
1570 char *rrn = register_name(r); 1570 char *rrn = register_name(r);
1571 if (LARGE_OFFSET(offset)) { 1571 if (LARGE_OFFSET(offset)) {
1572 #ifdef __APPLE__ 1572 #ifdef __APPLE__
1573 printf("\taddis %s,%s,ha16(%d)\n",crn,rrn,offset); 1573 printf("\taddis %s,%s,ha16(%d)\n",crn,rrn,offset);
1574 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,crn); 1574 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,crn);
1575 #else 1575 #else
1576 printf("\taddis %s,%s,%d@ha\n",crn,rrn,offset); 1576 printf("\taddis %s,%s,%d@ha\n",crn,rrn,offset);
1577 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,crn); 1577 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,crn);
1578 #endif 1578 #endif
1579 } else 1579 } else
1580 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); 1580 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn);
1581 } 1581 }
1582 1582
1583 static void 1583 static void
1584 code_ldf(char *ld,char *crn,int offset,int r) 1584 code_ldf(char *ld,char *crn,int offset,int r)
1585 { 1585 {
1586 char *rrn = register_name(r); 1586 char *rrn = register_name(r);
1587 int reg; 1587 int reg;
1588 char *lrn; 1588 char *lrn;
1589 if (offset<-32768||32767<offset) { 1589 if (offset<-32768||32767<offset) {
1590 lrn = register_name(reg = get_register()); 1590 lrn = register_name(reg = get_register());
1591 #ifdef __APPLE__ 1591 #ifdef __APPLE__
1592 printf("\taddis %s,%s,ha16(%d)\n",lrn,rrn,offset); 1592 printf("\taddis %s,%s,ha16(%d)\n",lrn,rrn,offset);
1593 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,lrn); 1593 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,lrn);
1594 #else 1594 #else
1595 printf("\taddis %s,%s,%d@ha\n",lrn,rrn,offset); 1595 printf("\taddis %s,%s,%d@ha\n",lrn,rrn,offset);
1596 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,lrn); 1596 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,lrn);
1597 #endif 1597 #endif
1598 free_register(reg); 1598 free_register(reg);
1599 } else 1599 } else
1600 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); 1600 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn);
1601 } 1601 }
1602 1602
1603 void 1603 void
1604 code_gvar(int e1,int reg) { 1604 code_gvar(int e1,int reg) {
1605 use_int(reg); 1605 use_int(reg);
1624 1624
1625 void 1625 void
1626 code_register(int e2,int reg) { 1626 code_register(int e2,int reg) {
1627 use_int(reg); 1627 use_int(reg);
1628 if (reg!=e2) 1628 if (reg!=e2)
1629 printf("\tmr %s,%s\n",register_name(reg),register_name(e2)); 1629 printf("\tmr %s,%s\n",register_name(reg),register_name(e2));
1630 } 1630 }
1631 1631
1632 extern void 1632 extern void
1633 code_i2c(int reg) 1633 code_i2c(int reg)
1634 { 1634 {
1678 code_fname(NMTBL *n,int reg) { 1678 code_fname(NMTBL *n,int reg) {
1679 int r; 1679 int r;
1680 use_int(reg); 1680 use_int(reg);
1681 r = get_ptr_cache(n); 1681 r = get_ptr_cache(n);
1682 if(r!=reg) 1682 if(r!=reg)
1683 printf("\tmr %s,%s\n",register_name(reg),register_name(r)); 1683 printf("\tmr %s,%s\n",register_name(reg),register_name(r));
1684 return; 1684 return;
1685 } 1685 }
1686 1686
1687 void 1687 void
1688 code_label_value(int label,int reg) { 1688 code_label_value(int label,int reg) {
1705 use_int(reg); 1705 use_int(reg);
1706 crn = register_name(reg); 1706 crn = register_name(reg);
1707 // printf("## 0x%08x\n",e2); 1707 // printf("## 0x%08x\n",e2);
1708 #ifdef __APPLE__ 1708 #ifdef __APPLE__
1709 if (-32768<e2&&e2<32768) 1709 if (-32768<e2&&e2<32768)
1710 printf("\tli %s,%d\n",crn,e2); 1710 printf("\tli %s,%d\n",crn,e2);
1711 else if ((e2&0xffff)==0) 1711 else if ((e2&0xffff)==0)
1712 printf("\tlis %s,ha16(%d)\n",crn,e2); 1712 printf("\tlis %s,ha16(%d)\n",crn,e2);
1713 else { 1713 else {
1714 printf("\tlis %s,ha16(%d)\n",crn,e2); 1714 printf("\tlis %s,ha16(%d)\n",crn,e2);
1715 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); 1715 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2);
1716 } 1716 }
1717 #else 1717 #else
1718 if (-32768<e2&&e2<32768) 1718 if (-32768<e2&&e2<32768)
1719 printf("\tli %s,%d\n",crn,e2); 1719 printf("\tli %s,%d\n",crn,e2);
1720 else if ((e2&0xffff)==0) 1720 else if ((e2&0xffff)==0)
1721 printf("\tlis %s,%d@ha\n",crn,e2); 1721 printf("\tlis %s,%d@ha\n",crn,e2);
1722 else { 1722 else {
1723 printf("\tlis %s,%d@ha\n",crn,e2); 1723 printf("\tlis %s,%d@ha\n",crn,e2);
1724 printf("\taddi %s,%s,%d@l\n",crn,crn,e2); 1724 printf("\taddi %s,%s,%d@l\n",crn,crn,e2);
1725 } 1725 }
1726 #endif 1726 #endif
1727 } 1727 }
1728 1728
1729 void 1729 void
1735 1735
1736 void 1736 void
1737 code_not(int creg) { 1737 code_not(int creg) {
1738 use_int(creg); 1738 use_int(creg);
1739 printf("\tnor %s,%s,%s\n", 1739 printf("\tnor %s,%s,%s\n",
1740 register_name(creg), register_name(creg),register_name(creg)); 1740 register_name(creg), register_name(creg),register_name(creg));
1741 } 1741 }
1742 1742
1743 1743
1744 void 1744 void
1745 code_lnot(int creg) { 1745 code_lnot(int creg) {
1755 1755
1756 void 1756 void
1757 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { 1757 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) {
1758 char *xrn,*drn; 1758 char *xrn,*drn;
1759 if (car(e2)==REGISTER) { 1759 if (car(e2)==REGISTER) {
1760 use_int(reg); 1760 use_int(reg);
1761 printf("\taddi %s,%s,%d\n", 1761 printf("\taddi %s,%s,%d\n",
1762 register_name(cadr(e2)),register_name(cadr(e2)), dir); 1762 register_name(cadr(e2)),register_name(cadr(e2)), dir);
1763 if (use && cadr(e2)!=reg) 1763 if (use && cadr(e2)!=reg)
1764 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2))); 1764 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2)));
1765 return; 1765 return;
1766 } 1766 }
1767 g_expr(e2); 1767 g_expr(e2);
1768 if (!is_int_reg(creg)) error(-1); 1768 if (!is_int_reg(creg)) error(-1);
1769 xrn = register_name(creg); 1769 xrn = register_name(creg);
1770 if (reg==USE_CREG) { 1770 if (reg==USE_CREG) {
1771 reg=get_register(); if (!reg) error(-1); 1771 reg=get_register(); if (!reg) error(-1);
1772 drn = register_name(reg); 1772 drn = register_name(reg);
1773 set_ireg(reg,0); 1773 set_ireg(reg,0);
1774 } else { 1774 } else {
1775 drn = register_name(reg); 1775 drn = register_name(reg);
1776 } 1776 }
1777 printf("\t%s %s,0(%s)\n",cload(sz),drn,xrn); 1777 printf("\t%s %s,0(%s)\n",cload(sz),drn,xrn);
1778 if (use) cext(sign,sz,reg); 1778 if (use) cext(sign,sz,reg);
1779 printf("\taddi %s,%s,%d\n",drn,drn,dir); 1779 printf("\taddi %s,%s,%d\n",drn,drn,dir);
1780 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); 1780 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn);
1784 void 1784 void
1785 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { 1785 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) {
1786 char *xrn,*crn,*nrn; 1786 char *xrn,*crn,*nrn;
1787 int nreg; 1787 int nreg;
1788 if (car(e2)==REGISTER) { 1788 if (car(e2)==REGISTER) {
1789 use_int(reg); 1789 use_int(reg);
1790 if (use) 1790 if (use)
1791 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2))); 1791 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2)));
1792 printf("\taddi %s,%s,%d\n", 1792 printf("\taddi %s,%s,%d\n",
1793 register_name(cadr(e2)),register_name(cadr(e2)),dir); 1793 register_name(cadr(e2)),register_name(cadr(e2)),dir);
1794 return; 1794 return;
1795 } 1795 }
1796 g_expr(e2); 1796 g_expr(e2);
1797 if (!is_int_reg(creg)) error(-1); 1797 if (!is_int_reg(creg)) error(-1);
1798 crn = register_name(creg); 1798 crn = register_name(creg);
1799 nreg=get_register(); if (!nreg) error(-1); 1799 nreg=get_register(); if (!nreg) error(-1);
1800 nrn = register_name(nreg); 1800 nrn = register_name(nreg);
1801 if (reg==USE_CREG) { 1801 if (reg==USE_CREG) {
1802 reg=get_register(); if (!reg) error(-1); 1802 reg=get_register(); if (!reg) error(-1);
1803 xrn = register_name(reg); 1803 xrn = register_name(reg);
1804 set_ireg(reg,0); 1804 set_ireg(reg,0);
1805 } else { 1805 } else {
1806 xrn = register_name(reg); 1806 xrn = register_name(reg);
1807 } 1807 }
1808 printf("\t%s %s,0(%s)\n",cload(sz),xrn,crn); 1808 printf("\t%s %s,0(%s)\n",cload(sz),xrn,crn);
1809 if (use) cext(sign,sz,reg); 1809 if (use) cext(sign,sz,reg);
1810 printf("\taddi %s,%s,%d\n",nrn,xrn,dir); 1810 printf("\taddi %s,%s,%d\n",nrn,xrn,dir);
1811 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); 1811 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn);
1864 else if (lrexpr_bool(e1,reg)) return; 1864 else if (lrexpr_bool(e1,reg)) return;
1865 #endif 1865 #endif
1866 1866
1867 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ 1867 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */
1868 if (use) { 1868 if (use) {
1869 use_int(reg); 1869 use_int(reg);
1870 xrn = register_name(reg); 1870 xrn = register_name(reg);
1871 printf("\tli %s,0\n",xrn); 1871 printf("\tli %s,0\n",xrn);
1872 jmp(e3=fwdlabel()); 1872 jmp(e3=fwdlabel());
1873 fwddef(e2); 1873 fwddef(e2);
1874 printf("\tli %s,1\n",xrn); 1874 printf("\tli %s,1\n",xrn);
1875 fwddef(e3); 1875 fwddef(e3);
1876 } else { 1876 } else {
1877 fwddef(e2); 1877 fwddef(e2);
1878 } 1878 }
1879 } 1879 }
1880 1880
1881 #define code_gt(cond) (cond?"gt":"le") 1881 #define code_gt(cond) (cond?"gt":"le")
1882 1882
1893 static void 1893 static void
1894 inc_cmpflag() 1894 inc_cmpflag()
1895 { 1895 {
1896 // gcc use cmpflag 4 and 7, and gcc4 believes flag 4 is preserved. 1896 // gcc use cmpflag 4 and 7, and gcc4 believes flag 4 is preserved.
1897 do { 1897 do {
1898 cmpflag = (cmpflag+1)%8; 1898 cmpflag = (cmpflag+1)%8;
1899 } while (cmpflag!=4 && cmpflag!=7); 1899 } while (cmpflag!=4 && cmpflag!=7);
1900 } 1900 }
1901 1901
1902 #ifdef __APPLE__ 1902 #ifdef __APPLE__
1903 static 1903 static
1973 1973
1974 use_int(creg); 1974 use_int(creg);
1975 lb = emit_string_label(); 1975 lb = emit_string_label();
1976 ascii(n->nm); 1976 ascii(n->nm);
1977 if (output_mode==TEXT_EMIT_MODE) { 1977 if (output_mode==TEXT_EMIT_MODE) {
1978 printf(".text\n"); 1978 printf(".text\n");
1979 } else { 1979 } else {
1980 text_mode(0); 1980 text_mode(0);
1981 } 1981 }
1982 code_label_value(lb,creg); 1982 code_label_value(lb,creg);
1983 set_attr(n,LABEL,lb); 1983 set_attr(n,LABEL,lb);
1984 } 1984 }
1985 1985
2002 int i; 2002 int i;
2003 for(i = e2; i; i = cadr(i)) { 2003 for(i = e2; i; i = cadr(i)) {
2004 ascii(scaddr(i)); 2004 ascii(scaddr(i));
2005 } 2005 }
2006 if (output_mode==TEXT_EMIT_MODE) { 2006 if (output_mode==TEXT_EMIT_MODE) {
2007 printf(".text\n"); 2007 printf(".text\n");
2008 } else { 2008 } else {
2009 text_mode(0); 2009 text_mode(0);
2010 } 2010 }
2011 code_label_value(l,reg); 2011 code_label_value(l,reg);
2012 } 2012 }
2013 2013
2014 #define MAX_COPY_LEN 20 2014 #define MAX_COPY_LEN 20
2022 char *drn; 2022 char *drn;
2023 char *memmove = "memmove"; 2023 char *memmove = "memmove";
2024 int l; 2024 int l;
2025 int dreg = get_register(); if (!dreg) error(-1); 2025 int dreg = get_register(); if (!dreg) error(-1);
2026 2026
2027 drn = register_name(dreg); 2027 drn = register_name(dreg);
2028 use_int(from); 2028 use_int(from);
2029 use_int(to); 2029 use_int(to);
2030 frn = register_name(from); 2030 frn = register_name(from);
2031 trn = register_name(to); 2031 trn = register_name(to);
2032 2032
2033 /* length <0 means upward direction copy */ 2033 /* length <0 means upward direction copy */
2034 switch (length) { 2034 switch (length) {
2035 case 0: break; 2035 case 0: break;
2036 case 1: case -1: 2036 case 1: case -1:
2037 printf("\tlbz %s,%d(%s)\n",drn,offset,frn); 2037 printf("\tlbz %s,%d(%s)\n",drn,offset,frn);
2038 printf("\tstb %s,%d(%s)\n",drn,offset,trn); 2038 printf("\tstb %s,%d(%s)\n",drn,offset,trn);
2039 break; 2039 break;
2040 case 2: case -2: 2040 case 2: case -2:
2041 printf("\tlhz %s,%d(%s)\n",drn,offset,frn); 2041 printf("\tlhz %s,%d(%s)\n",drn,offset,frn);
2042 printf("\tsth %s,%d(%s)\n",drn,offset,trn); 2042 printf("\tsth %s,%d(%s)\n",drn,offset,trn);
2043 break; 2043 break;
2044 case 4: case -4: 2044 case 4: case -4:
2045 printf("\tlwz %s,%d(%s)\n",drn,offset,frn); 2045 printf("\tlwz %s,%d(%s)\n",drn,offset,frn);
2046 printf("\tstw %s,%d(%s)\n",drn,offset,trn); 2046 printf("\tstw %s,%d(%s)\n",drn,offset,trn);
2047 break; 2047 break;
2048 default: 2048 default:
2049 if (length <0) { 2049 if (length <0) {
2050 if (length >= -MAX_COPY_LEN) { 2050 if (length >= -MAX_COPY_LEN) {
2051 free_register(dreg); dreg = 0; 2051 free_register(dreg); dreg = 0;
2052 for(;length<=-4;length+=4,offset-=4) 2052 for(;length<=-4;length+=4,offset-=4)
2053 emit_copy(from,to,-4,offset-4,0,det); 2053 emit_copy(from,to,-4,offset-4,0,det);
2054 for(;length<=-2;length+=2,offset-=2) 2054 for(;length<=-2;length+=2,offset-=2)
2055 emit_copy(from,to,-2,offset-2,0,det); 2055 emit_copy(from,to,-2,offset-2,0,det);
2056 if(length<0) 2056 if(length<0)
2057 emit_copy(from,to,length,offset-1,0,det); 2057 emit_copy(from,to,length,offset-1,0,det);
2058 break; 2058 break;
2059 } 2059 }
2060 } else if (length <=MAX_COPY_LEN) { 2060 } else if (length <=MAX_COPY_LEN) {
2061 free_register(dreg); dreg = 0; 2061 free_register(dreg); dreg = 0;
2062 for(;length>=4;length-=4,offset+=4) 2062 for(;length>=4;length-=4,offset+=4)
2063 emit_copy(from,to,4,offset,0,det); 2063 emit_copy(from,to,4,offset,0,det);
2064 for(;length>=2;length-=2,offset+=2) 2064 for(;length>=2;length-=2,offset+=2)
2065 emit_copy(from,to,2,offset,0,det); 2065 emit_copy(from,to,2,offset,0,det);
2066 if(length>0) 2066 if(length>0)
2067 emit_copy(from,to,length,offset,0,det); 2067 emit_copy(from,to,length,offset,0,det);
2068 break; 2068 break;
2069 } 2069 }
2070 clear_ptr_cache(); 2070 clear_ptr_cache();
2071 code_save_stacks(); 2071 code_save_stacks();
2072 2072
2073 l = list3(3,0,to); 2073 l = list3(3,0,to);
2074 l = list3(4,l,from); 2074 l = list3(4,l,from);
2075 parallel_rassign(l); 2075 parallel_rassign(l);
2076 2076
2077 #ifdef __APPLE__ 2077 #ifdef __APPLE__
2078 printf("\tli r5,%d\n",length>0?length:-length); 2078 printf("\tli r5,%d\n",length>0?length:-length);
2079 /* offset should be ignored */ 2079 /* offset should be ignored */
2080 /* overrap must be allowed */ 2080 /* overrap must be allowed */
2081 printf("\tbl L_%s$stub\n",memmove); 2081 printf("\tbl L_%s$stub\n",memmove);
2082 #else 2082 #else
2083 printf("\tli 5,%d\n",length>0?length:-length); 2083 printf("\tli 5,%d\n",length>0?length:-length);
2084 /* offset should be ignored */ 2084 /* offset should be ignored */
2085 /* overrap must be allowed */ 2085 /* overrap must be allowed */
2086 printf("\tbl %s\n",memmove); 2086 printf("\tbl %s\n",memmove);
2087 #endif 2087 #endif
2088 extern_define(memmove,0,FUNCTION,1); 2088 extern_define(memmove,0,FUNCTION,1);
2089 set_ireg(RET_REGISTER,0); 2089 set_ireg(RET_REGISTER,0);
2090 //if (creg!=to) { 2090 //if (creg!=to) {
2091 // free_register(to); to = creg; 2091 // free_register(to); to = creg;
2092 //} 2092 //}
2093 break; 2093 break;
2094 } 2094 }
2095 if (value) { 2095 if (value) {
2096 /* creg must point top of the destination data */ 2096 /* creg must point top of the destination data */
2097 /* this code is necessary for the value of assignment or function call */ 2097 /* this code is necessary for the value of assignment or function call */
2098 /* otherwise we don't need this */ 2098 /* otherwise we don't need this */
2099 if(creg!=to) { 2099 if(creg!=to) {
2100 free_register(to); 2100 free_register(to);
2101 // set_ireg(to,1); 2101 // set_ireg(to,1);
2102 } 2102 }
2103 } 2103 }
2104 if (dreg) free_register(dreg); 2104 if (dreg) free_register(dreg);
2105 } 2105 }
2106 2106
2107 int 2107 int
2111 int dreg,sreg; char *drn,*crn,*srn; 2111 int dreg,sreg; char *drn,*crn,*srn;
2112 g_expr(e4); 2112 g_expr(e4);
2113 if (!is_int_reg(creg)) error(-1); 2113 if (!is_int_reg(creg)) error(-1);
2114 length=size(t); 2114 length=size(t);
2115 if(length%SIZE_OF_INT) { 2115 if(length%SIZE_OF_INT) {
2116 length += SIZE_OF_INT - (length%SIZE_OF_INT); 2116 length += SIZE_OF_INT - (length%SIZE_OF_INT);
2117 } 2117 }
2118 dreg = get_register(); if (!dreg) error(-1); 2118 dreg = get_register(); if (!dreg) error(-1);
2119 drn = register_name(dreg); 2119 drn = register_name(dreg);
2120 crn = register_name(creg); 2120 crn = register_name(creg);
2121 if (length<MAX_COPY_LEN) { 2121 if (length<MAX_COPY_LEN) {
2122 sreg = get_register(); if (!sreg) error(-1); 2122 sreg = get_register(); if (!sreg) error(-1);
2123 srn = register_name(sreg); 2123 srn = register_name(sreg);
2124 code_lvar(cadr(arg),dreg); 2124 code_lvar(cadr(arg),dreg);
2125 for(count=0;count<length;count+=SIZE_OF_INT) { 2125 for(count=0;count<length;count+=SIZE_OF_INT) {
2126 printf("\tlwz %s,%d(%s)\n",srn,count,crn); 2126 printf("\tlwz %s,%d(%s)\n",srn,count,crn);
2127 printf("\tstw %s,%d(%s)\n",srn,count,drn); 2127 printf("\tstw %s,%d(%s)\n",srn,count,drn);
2128 } 2128 }
2129 free_register(sreg); 2129 free_register(sreg);
2130 free_register(dreg); 2130 free_register(dreg);
2131 return length/SIZE_OF_INT; 2131 return length/SIZE_OF_INT;
2132 } else { 2132 } else {
2133 code_lvar(cadr(arg),dreg); 2133 code_lvar(cadr(arg),dreg);
2134 /* downward direction copy */ 2134 /* downward direction copy */
2135 emit_copy(creg,dreg,length,0,0,1); 2135 emit_copy(creg,dreg,length,0,0,1);
2136 } 2136 }
2137 free_register(dreg); 2137 free_register(dreg);
2138 return length/SIZE_OF_INT; 2138 return length/SIZE_OF_INT;
2139 } 2139 }
2140 2140
2141 static void 2141 static void
2142 set_ireg(int reg,int mode) 2142 set_ireg(int reg,int mode)
2143 { 2143 {
2144 if (!is_int_reg(reg)) error(-1); 2144 if (!is_int_reg(reg)) error(-1);
2145 if (reg!=creg) { 2145 if (reg!=creg) {
2146 clear_ptr_cache_reg(reg); 2146 clear_ptr_cache_reg(reg);
2147 if (ireg && reg!=ireg ) { 2147 if (ireg && reg!=ireg ) {
2148 clear_ptr_cache_reg(ireg); 2148 clear_ptr_cache_reg(ireg);
2149 if (regs[ireg]!=REG_VAR) free_register(ireg); 2149 if (regs[ireg]!=REG_VAR) free_register(ireg);
2150 if (mode) { 2150 if (mode) {
2151 printf("\tmr %s,%s\n",register_name(reg),register_name(ireg)); 2151 printf("\tmr %s,%s\n",register_name(reg),register_name(ireg));
2152 } 2152 }
2153 } 2153 }
2154 if (regs[creg]!=REG_VAR) { 2154 if (regs[creg]!=REG_VAR) {
2155 clear_ptr_cache_reg(creg); 2155 clear_ptr_cache_reg(creg);
2156 free_register(creg); 2156 free_register(creg);
2157 } 2157 }
2158 if (creg==lreg) lreg = 0; 2158 if (creg==lreg) lreg = 0;
2159 regs[reg]=USING_REG; 2159 regs[reg]=USING_REG;
2160 } 2160 }
2161 creg = ireg = reg; 2161 creg = ireg = reg;
2162 } 2162 }
2163 2163
2164 static void 2164 static void
2165 set_freg(int reg,int mode) 2165 set_freg(int reg,int mode)
2166 { 2166 {
2167 if (!is_float_reg(reg)) error(-1); 2167 if (!is_float_reg(reg)) error(-1);
2168 if (reg!=creg) { 2168 if (reg!=creg) {
2169 if (freg && reg!=freg) { 2169 if (freg && reg!=freg) {
2170 free_register(freg); 2170 free_register(freg);
2171 if (mode) { 2171 if (mode) {
2172 printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg)); 2172 printf("\tfmr %s,%s\n",fregister_name(reg),fregister_name(freg));
2173 } 2173 }
2174 } 2174 }
2175 // if (creg!=ireg) free_register(creg); 2175 // if (creg!=ireg) free_register(creg);
2176 regs[reg]=USING_REG; 2176 regs[reg]=USING_REG;
2177 } 2177 }
2178 creg = freg = reg; 2178 creg = freg = reg;
2179 } 2179 }
2180 2180
2181 static void 2181 static void
2182 set_lreg(int reg,int mode) 2182 set_lreg(int reg,int mode)
2183 { 2183 {
2184 if (reg==RET_LREGISTER) { 2184 if (reg==RET_LREGISTER) {
2185 regv_l(reg) = RET_LREGISTER_L; 2185 regv_l(reg) = RET_LREGISTER_L;
2186 regv_h(reg) = RET_LREGISTER_H; 2186 regv_h(reg) = RET_LREGISTER_H;
2187 } 2187 }
2188 if (!is_longlong_reg(reg)) error(-1); 2188 if (!is_longlong_reg(reg)) error(-1);
2189 if (reg!=creg) { 2189 if (reg!=creg) {
2190 if (lreg) { 2190 if (lreg) {
2191 if (reg!=lreg) { 2191 if (reg!=lreg) {
2192 if (mode) { 2192 if (mode) {
2193 printf("\tmr %s,%s\n", 2193 printf("\tmr %s,%s\n",
2194 lregister_name_low(reg),lregister_name_low(lreg)); 2194 lregister_name_low(reg),lregister_name_low(lreg));
2195 printf("\tmr %s,%s\n", 2195 printf("\tmr %s,%s\n",
2196 lregister_name_high(reg),lregister_name_high(lreg)); 2196 lregister_name_high(reg),lregister_name_high(lreg));
2197 } 2197 }
2198 free_register(lreg); 2198 free_register(lreg);
2199 } 2199 }
2200 if (lreg==creg) creg=0; 2200 if (lreg==creg) creg=0;
2201 } 2201 }
2202 if (creg) free_register(creg); 2202 if (creg) free_register(creg);
2203 regs[reg]=USING_REG; 2203 regs[reg]=USING_REG;
2204 clear_ptr_cache_reg(regv_l(reg)); 2204 clear_ptr_cache_reg(regv_l(reg));
2205 regs[regv_l(reg)]=USING_REG; 2205 regs[regv_l(reg)]=USING_REG;
2206 clear_ptr_cache_reg(regv_h(reg)); 2206 clear_ptr_cache_reg(regv_h(reg));
2207 regs[regv_h(reg)]=USING_REG; 2207 regs[regv_h(reg)]=USING_REG;
2208 creg = lreg = reg; 2208 creg = lreg = reg;
2209 } 2209 }
2210 } 2210 }
2211 2211
2212 static void 2212 static void
2213 set_lreg_operand(int reg,int mode) 2213 set_lreg_operand(int reg,int mode)
2214 { 2214 {
2215 // save_stack,clear_ptr_cache is assumed 2215 // save_stack,clear_ptr_cache is assumed
2216 if (!is_longlong_reg(reg)) { error(-1); return; } 2216 if (!is_longlong_reg(reg)) { error(-1); return; }
2217 if (mode) { 2217 if (mode) {
2218 if (regv_l(reg)!=3) 2218 if (regv_l(reg)!=3)
2219 printf("\tmr %s,%s\n", register_name(3),lregister_name_high(reg)); 2219 printf("\tmr %s,%s\n", register_name(3),lregister_name_high(reg));
2220 if (regv_l(reg)!=4) 2220 if (regv_l(reg)!=4)
2221 printf("\tmr %s,%s\n", register_name(4),lregister_name_low(reg)); 2221 printf("\tmr %s,%s\n", register_name(4),lregister_name_low(reg));
2222 } 2222 }
2223 } 2223 }
2224 2224
2225 static void 2225 static void
2226 set_lreg_operand1(int reg,int mode) 2226 set_lreg_operand1(int reg,int mode)
2227 { 2227 {
2228 // save_stack,clear_ptr_cache is assumed 2228 // save_stack,clear_ptr_cache is assumed
2229 if (!is_longlong_reg(reg)) { error(-1); return; } 2229 if (!is_longlong_reg(reg)) { error(-1); return; }
2230 if (mode) { 2230 if (mode) {
2231 if (regv_l(reg)!=5) 2231 if (regv_l(reg)!=5)
2232 printf("\tmr %s,%s\n", register_name(5),lregister_name_high(reg)); 2232 printf("\tmr %s,%s\n", register_name(5),lregister_name_high(reg));
2233 if (regv_l(reg)!=6) 2233 if (regv_l(reg)!=6)
2234 printf("\tmr %s,%s\n", register_name(6),lregister_name_low(reg)); 2234 printf("\tmr %s,%s\n", register_name(6),lregister_name_low(reg));
2235 } 2235 }
2236 } 2236 }
2237 2237
2238 static void 2238 static void
2239 use_reg(int arg) 2239 use_reg(int arg)
2240 { 2240 {
2241 // printf("## use reg %d\n",arg); 2241 // printf("## use reg %d\n",arg);
2242 if (arg<0||arg> REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ REAL_MAX_LREGISTER) 2242 if (arg<0||arg> REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ REAL_MAX_LREGISTER)
2243 error(-1); 2243 error(-1);
2244 clear_ptr_cache_reg(arg); 2244 clear_ptr_cache_reg(arg);
2245 regs[arg]=USING_REG; 2245 regs[arg]=USING_REG;
2246 if (is_longlong_reg(arg)) { 2246 if (is_longlong_reg(arg)) {
2247 clear_ptr_cache_reg(regv_l(arg)); 2247 clear_ptr_cache_reg(regv_l(arg));
2248 regs[regv_l(arg)]=USING_REG; 2248 regs[regv_l(arg)]=USING_REG;
2249 clear_ptr_cache_reg(regv_h(arg)); 2249 clear_ptr_cache_reg(regv_h(arg));
2250 regs[regv_h(arg)]=USING_REG; 2250 regs[regv_h(arg)]=USING_REG;
2251 } 2251 }
2252 } 2252 }
2253 2253
2254 /* 2254 /*
2255 store input argument into stack 2255 store input argument into stack
2279 type = stype; mode = smode; 2279 type = stype; mode = smode;
2280 } 2280 }
2281 2281
2282 2282
2283 for(args = fnptr->dsp;args;args = cadr(args)) { 2283 for(args = fnptr->dsp;args;args = cadr(args)) {
2284 n = ncadddr(args); 2284 n = ncadddr(args);
2285 tag = n->sc; 2285 tag = n->sc;
2286 reg = n->dsp; 2286 reg = n->dsp;
2287 if (!n||n==&null_nptr) error(REG_ERR); 2287 if (!n||n==&null_nptr) error(REG_ERR);
2288 if (tag==REGISTER) { 2288 if (tag==REGISTER) {
2289 n->dsp = offset; 2289 n->dsp = offset;
2290 offset+=SIZE_OF_INT; 2290 offset+=SIZE_OF_INT;
2291 t = INT; 2291 t = INT;
2292 reg += reg_offset; /* for duplicated floating point argument */ 2292 reg += reg_offset; /* for duplicated floating point argument */
2293 reg_var++; 2293 reg_var++;
2294 } else if (tag==DREGISTER) { 2294 } else if (tag==DREGISTER) {
2295 n->dsp = offset; 2295 n->dsp = offset;
2296 t = n->ty; 2296 t = n->ty;
2297 #ifdef __APPLE__ 2297 #ifdef __APPLE__
2298 if(t==FLOAT) { offset+=SIZE_OF_FLOAT; reg_offset+=1; } 2298 if(t==FLOAT) { offset+=SIZE_OF_FLOAT; reg_offset+=1; }
2299 else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; } 2299 else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; }
2300 else error(-1); 2300 else error(-1);
2301 reg_var += 2; 2301 reg_var += 2;
2302 #else 2302 #else
2303 if(t==FLOAT) { offset+=SIZE_OF_FLOAT; } 2303 if(t==FLOAT) { offset+=SIZE_OF_FLOAT; }
2304 else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; } 2304 else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; }
2305 else error(-1); 2305 else error(-1);
2306 #endif 2306 #endif
2307 } else if (tag==LREGISTER) { 2307 } else if (tag==LREGISTER) {
2308 n->dsp = offset; 2308 n->dsp = offset;
2309 t = n->ty; 2309 t = n->ty;
2310 offset+=SIZE_OF_LONGLONG; 2310 offset+=SIZE_OF_LONGLONG;
2311 reg_offset+=2; 2311 reg_offset+=2;
2312 reg_var += 2; 2312 reg_var += 2;
2313 } else { 2313 } else {
2314 // n->dsp = offset; this is no allowed becase of arg reorder 2314 // n->dsp = offset; this is no allowed becase of arg reorder
2315 offset += size(n->ty); 2315 offset += size(n->ty);
2316 continue; 2316 continue;
2317 } 2317 }
2318 n->sc = LVAR; 2318 n->sc = LVAR;
2319 g_expr_u(assign_expr0( 2319 g_expr_u(assign_expr0(
2320 list3n(LVAR,n->dsp,0),list3n(tag,reg,n),n->ty,t)); 2320 list3n(LVAR,n->dsp,0),list3n(tag,reg,n),n->ty,t));
2321 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { 2321 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
2322 free_register(reg); 2322 free_register(reg);
2323 } 2323 }
2324 } 2324 }
2325 if (dots) { 2325 if (dots) {
2326 while ((reg = get_input_register_var(reg_var,0,0))) { 2326 while ((reg = get_input_register_var(reg_var,0,0))) {
2327 g_expr_u(assign_expr0( 2327 g_expr_u(assign_expr0(
2328 list3n(LVAR,offset,0),reg,INT,INT)); 2328 list3n(LVAR,offset,0),reg,INT,INT));
2329 offset+=SIZE_OF_INT; 2329 offset+=SIZE_OF_INT;
2330 reg_var++; 2330 reg_var++;
2331 } 2331 }
2332 #ifndef __APPLE__ 2332 #ifndef __APPLE__
2333 int skip = fwdlabel(); 2333 int skip = fwdlabel();
2334 int freg_var = 0; 2334 int freg_var = 0;
2335 printf("\tbne 1,%s%d\n",lpfx,skip); 2335 printf("\tbne 1,%s%d\n",lpfx,skip);
2336 while ((reg = get_input_dregister_var(freg_var,0,0,1))) { 2336 while ((reg = get_input_dregister_var(freg_var,0,0,1))) {
2337 g_expr_u(assign_expr0( 2337 g_expr_u(assign_expr0(
2338 list3n(LVAR,offset,0),reg,DOUBLE,DOUBLE)); 2338 list3n(LVAR,offset,0),reg,DOUBLE,DOUBLE));
2339 offset+=SIZE_OF_DOUBLE; 2339 offset+=SIZE_OF_DOUBLE;
2340 freg_var++; 2340 freg_var++;
2341 } 2341 }
2342 fwddef(skip); 2342 fwddef(skip);
2343 #endif 2343 #endif
2344 } 2344 }
2345 my_func_args = offset; 2345 my_func_args = offset;
2346 } 2346 }
2347 2347
2348 int 2348 int
2349 not_simple_p(int e3) 2349 not_simple_p(int e3)
2350 { 2350 {
2351 switch (e3) { 2351 switch (e3) {
2352 case FUNCTION: case CONV: case LCALL: case STASS: 2352 case FUNCTION: case CONV: case LCALL: case STASS:
2353 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: 2353 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
2354 case LDIV: case LUDIV: case LMOD: case LUMOD: case LASSOP: case ALLOCA: 2354 case LDIV: case LUDIV: case LMOD: case LUMOD: case LASSOP: case ALLOCA:
2355 case INLINE: 2355 case INLINE:
2356 return 1; 2356 return 1;
2357 } 2357 }
2358 return 0; 2358 return 0;
2359 } 2359 }
2360 2360
2367 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT) 2367 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT)
2368 2368
2369 /* 2369 /*
2370 use input register as current register 2370 use input register as current register
2371 なんで、こんなに複雑なんだ? 2371 なんで、こんなに複雑なんだ?
2372 むしろ、INPUT_REG みたいな mark をいれたら? 2372 むしろ、INPUT_REG みたいな mark をいれたら?
2373 */ 2373 */
2374 2374
2375 static void 2375 static void
2376 use_input_reg(int reg,int mode) 2376 use_input_reg(int reg,int mode)
2377 { 2377 {
2378 if (is_int_reg(reg)) { 2378 if (is_int_reg(reg)) {
2379 if (ireg&&reg == ireg) { 2379 if (ireg&&reg == ireg) {
2380 if (creg==ireg) creg = 0; 2380 if (creg==ireg) creg = 0;
2381 ireg = 0; 2381 ireg = 0;
2382 } 2382 }
2383 if (lreg) { 2383 if (lreg) {
2384 // free_regsiter(lreg) でいいんじゃないの? 2384 // free_regsiter(lreg) でいいんじゃないの?
2385 if (regv_l(lreg)==reg) { 2385 if (regv_l(lreg)==reg) {
2386 regs[lreg]=0; 2386 regs[lreg]=0;
2387 if (regv_h(lreg)>reg&&regs[regv_h(lreg)]==USING_REG) { 2387 if (regv_h(lreg)>reg&&regs[regv_h(lreg)]==USING_REG) {
2388 free_register(regv_h(lreg)); 2388 free_register(regv_h(lreg));
2389 } 2389 }
2390 if (creg==lreg) creg = ireg; 2390 if (creg==lreg) creg = ireg;
2391 free_register(lreg); 2391 free_register(lreg);
2392 lreg = 0; 2392 lreg = 0;
2393 } else if (regv_h(lreg)==reg) { 2393 } else if (regv_h(lreg)==reg) {
2394 regs[lreg]=0; 2394 regs[lreg]=0;
2395 if (regv_h(lreg)>reg&&regs[regv_l(lreg)]==USING_REG) { 2395 if (regv_h(lreg)>reg&&regs[regv_l(lreg)]==USING_REG) {
2396 free_register(regv_l(lreg)); 2396 free_register(regv_l(lreg));
2397 } 2397 }
2398 if (creg==lreg) creg = ireg; 2398 if (creg==lreg) creg = ireg;
2399 free_register(lreg); 2399 free_register(lreg);
2400 lreg = 0; 2400 lreg = 0;
2401 } 2401 }
2402 } 2402 }
2403 } else if (is_longlong_reg(reg)) { 2403 } else if (is_longlong_reg(reg)) {
2404 use_input_reg(regv_h(reg),mode); 2404 use_input_reg(regv_h(reg),mode);
2405 use_input_reg(regv_l(reg),mode); 2405 use_input_reg(regv_l(reg),mode);
2406 } else if (is_float_reg(reg)) { 2406 } else if (is_float_reg(reg)) {
2407 if (freg&&reg == freg) { 2407 if (freg&&reg == freg) {
2408 if (creg==freg) creg = ireg; 2408 if (creg==freg) creg = ireg;
2409 freg = 0; 2409 freg = 0;
2410 } 2410 }
2411 } 2411 }
2412 if (mode) use_reg(reg); 2412 if (mode) use_reg(reg);
2413 } 2413 }
2414 2414
2415 static int 2415 static int
2416 compute_complex_arg(int e3,int reg_arg_list,int arg) { 2416 compute_complex_arg(int e3,int reg_arg_list,int arg) {
2417 int t=caddr(e3); 2417 int t=caddr(e3);
2418 int e4 = car(e3); 2418 int e4 = car(e3);
2419 reg_arg_list = list2(arg,reg_arg_list); 2419 reg_arg_list = list2(arg,reg_arg_list);
2420 if (car(arg)==REGISTER||car(arg)==DREGISTER|| 2420 if (car(arg)==REGISTER||car(arg)==DREGISTER||
2421 car(arg)==FREGISTER||car(arg)==LREGISTER) 2421 car(arg)==FREGISTER||car(arg)==LREGISTER)
2422 use_input_reg(cadr(arg),1); 2422 use_input_reg(cadr(arg),1);
2423 g_expr_u(assign_expr0(arg,e4,t,t)); 2423 g_expr_u(assign_expr0(arg,e4,t,t));
2424 car(e3) = arg; 2424 car(e3) = arg;
2425 return reg_arg_list; 2425 return reg_arg_list;
2426 } 2426 }
2427 2427
2430 static void 2430 static void
2431 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { 2431 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) {
2432 int nargs=0,reg_arg=0,freg_arg=0; 2432 int nargs=0,reg_arg=0,freg_arg=0;
2433 int t=type_value(caddr(e3)); 2433 int t=type_value(caddr(e3));
2434 if (t>=0&&(car(t)==BIT_FIELD)) { 2434 if (t>=0&&(car(t)==BIT_FIELD)) {
2435 t = type_value(cadr(t)); 2435 t = type_value(cadr(t));
2436 } 2436 }
2437 if(scalar(t)) { 2437 if(scalar(t)) {
2438 nargs ++ ; reg_arg++; 2438 nargs ++ ; reg_arg++;
2439 } else if (t==LONGLONG||t==ULONGLONG) { 2439 } else if (t==LONGLONG||t==ULONGLONG) {
2440 nargs ++ ; reg_arg++; 2440 nargs ++ ; reg_arg++;
2441 nargs ++ ; reg_arg++; 2441 nargs ++ ; reg_arg++;
2442 } else if (t==FLOAT) { 2442 } else if (t==FLOAT) {
2443 if (*preg_arg<MAX_INPUT_REGISTER_VAR) { 2443 if (*preg_arg<MAX_INPUT_REGISTER_VAR) {
2444 reg_arg += 1; 2444 reg_arg += 1;
2445 } 2445 }
2446 freg_arg++; 2446 freg_arg++;
2447 nargs += size(t)/SIZE_OF_INT; 2447 nargs += size(t)/SIZE_OF_INT;
2448 } else if (t==DOUBLE) { 2448 } else if (t==DOUBLE) {
2449 if (*preg_arg<MAX_INPUT_REGISTER_VAR) { 2449 if (*preg_arg<MAX_INPUT_REGISTER_VAR) {
2450 reg_arg += 2; 2450 reg_arg += 2;
2451 } 2451 }
2452 nargs += size(t)/SIZE_OF_INT; 2452 nargs += size(t)/SIZE_OF_INT;
2453 freg_arg++; 2453 freg_arg++;
2454 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { 2454 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
2455 nargs += round4(size(t))/SIZE_OF_INT; 2455 nargs += round4(size(t))/SIZE_OF_INT;
2456 } else { 2456 } else {
2457 error(TYERR); 2457 error(TYERR);
2458 nargs ++ ; 2458 nargs ++ ;
2459 } 2459 }
2460 *pnargs += nargs; 2460 *pnargs += nargs;
2461 *preg_arg += reg_arg; 2461 *preg_arg += reg_arg;
2462 *pfreg_arg += freg_arg; 2462 *pfreg_arg += freg_arg;
2463 } 2463 }
2465 static void 2465 static void
2466 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { 2466 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) {
2467 int nargs=0,reg_arg=0,freg_arg=0; 2467 int nargs=0,reg_arg=0,freg_arg=0;
2468 int t=type_value(caddr(e3)); 2468 int t=type_value(caddr(e3));
2469 if (t>=0&&(car(t)==BIT_FIELD)) { 2469 if (t>=0&&(car(t)==BIT_FIELD)) {
2470 t = type_value(cadr(t)); 2470 t = type_value(cadr(t));
2471 } 2471 }
2472 if(scalar(t)) { 2472 if(scalar(t)) {
2473 reg_arg++; 2473 reg_arg++;
2474 if (*preg_arg>=MAX_INPUT_REGISTER_VAR) nargs ++ ; 2474 if (*preg_arg>=MAX_INPUT_REGISTER_VAR) nargs ++ ;
2475 } else if (t==LONGLONG||t==ULONGLONG) { 2475 } else if (t==LONGLONG||t==ULONGLONG) {
2476 if (*preg_arg%2==1) reg_arg++; // alignment 2476 if (*preg_arg%2==1) reg_arg++; // alignment
2477 if (*pnargs%2==1) nargs++; // alignment 2477 if (*pnargs%2==1) nargs++; // alignment
2478 reg_arg++; reg_arg++; 2478 reg_arg++; reg_arg++;
2479 if (*preg_arg+1>=MAX_INPUT_REGISTER_VAR) nargs += 2; 2479 if (*preg_arg+1>=MAX_INPUT_REGISTER_VAR) nargs += 2;
2480 } else if (t==FLOAT) { 2480 } else if (t==FLOAT) {
2481 freg_arg++; 2481 freg_arg++;
2482 if (*pfreg_arg>=MAX_INPUT_DREGISTER_VAR) nargs += size(t)/SIZE_OF_INT; 2482 if (*pfreg_arg>=MAX_INPUT_DREGISTER_VAR) nargs += size(t)/SIZE_OF_INT;
2483 } else if (t==DOUBLE) { 2483 } else if (t==DOUBLE) {
2484 freg_arg++; 2484 freg_arg++;
2485 if (*pfreg_arg>=MAX_INPUT_DREGISTER_VAR) nargs += round4(size(t))/SIZE_OF_INT; 2485 if (*pfreg_arg>=MAX_INPUT_DREGISTER_VAR) nargs += round4(size(t))/SIZE_OF_INT;
2486 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { 2486 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
2487 nargs += round4(size(t))/SIZE_OF_INT; 2487 nargs += round4(size(t))/SIZE_OF_INT;
2488 } else { 2488 } else {
2489 error(TYERR); 2489 error(TYERR);
2490 nargs ++ ; 2490 nargs ++ ;
2491 } 2491 }
2492 *pnargs += nargs; 2492 *pnargs += nargs;
2493 *preg_arg += reg_arg; 2493 *preg_arg += reg_arg;
2494 *pfreg_arg += freg_arg; 2494 *pfreg_arg += freg_arg;
2495 } 2495 }
2509 static int 2509 static int
2510 get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg) 2510 get_input_arg(int t,int mode,int nargs,int reg_arg,int freg_arg)
2511 { 2511 {
2512 t = type_value(t); 2512 t = type_value(t);
2513 if (t>=0&&(car(t)==BIT_FIELD)) { 2513 if (t>=0&&(car(t)==BIT_FIELD)) {
2514 t = type_value(cadr(t)); 2514 t = type_value(cadr(t));
2515 } 2515 }
2516 if(scalar(t)) { 2516 if(scalar(t)) {
2517 if (mode==AS_SAVE) { 2517 if (mode==AS_SAVE) {
2518 return get_register_var(0); 2518 return get_register_var(0);
2519 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) { 2519 } else if (reg_arg>=MAX_INPUT_REGISTER_VAR) {
2520 return list3n(LVAR,caller_arg_offset_v(nargs),0); 2520 return list3n(LVAR,caller_arg_offset_v(nargs),0);
2521 } else { 2521 } else {
2522 int e = get_input_register_var(reg_arg,0,0); 2522 int e = get_input_register_var(reg_arg,0,0);
2523 clear_ptr_cache_reg(cadr(e)); 2523 clear_ptr_cache_reg(cadr(e));
2524 return e; 2524 return e;
2525 } 2525 }
2526 } else if (t==LONGLONG||t==ULONGLONG) { 2526 } else if (t==LONGLONG||t==ULONGLONG) {
2527 if (mode==AS_SAVE) { 2527 if (mode==AS_SAVE) {
2528 return get_lregister_var(0); 2528 return get_lregister_var(0);
2529 } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) { 2529 } else if (reg_arg+1>=MAX_INPUT_REGISTER_VAR) {
2530 return list3n(LVAR,caller_arg_offset_v(nargs),0); 2530 return list3n(LVAR,caller_arg_offset_v(nargs),0);
2531 } else { 2531 } else {
2532 int e = get_input_lregister_var(reg_arg,0,0); 2532 int e = get_input_lregister_var(reg_arg,0,0);
2533 clear_ptr_cache_reg(regv_l(cadr(e))); 2533 clear_ptr_cache_reg(regv_l(cadr(e)));
2534 clear_ptr_cache_reg(regv_h(cadr(e))); 2534 clear_ptr_cache_reg(regv_h(cadr(e)));
2535 return e; 2535 return e;
2536 } 2536 }
2537 } else if (t==FLOAT) { 2537 } else if (t==FLOAT) {
2538 if (mode==AS_SAVE) { 2538 if (mode==AS_SAVE) {
2539 return get_dregister_var(0,0); 2539 return get_dregister_var(0,0);
2540 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { 2540 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
2541 return list3n(LVAR,caller_arg_offset_v(nargs),0); 2541 return list3n(LVAR,caller_arg_offset_v(nargs),0);
2542 } else 2542 } else
2543 return get_input_dregister_var(freg_arg,0,0,0); 2543 return get_input_dregister_var(freg_arg,0,0,0);
2544 } else if (t==DOUBLE) { 2544 } else if (t==DOUBLE) {
2545 if (mode==AS_SAVE) { 2545 if (mode==AS_SAVE) {
2546 return get_dregister_var(0,1); 2546 return get_dregister_var(0,1);
2547 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { 2547 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) {
2548 return list3n(LVAR,caller_arg_offset_v(nargs),0); 2548 return list3n(LVAR,caller_arg_offset_v(nargs),0);
2549 } else 2549 } else
2550 return get_input_dregister_var(freg_arg,0,0,1); 2550 return get_input_dregister_var(freg_arg,0,0,1);
2551 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { 2551 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
2552 if (mode==AS_SAVE) { 2552 if (mode==AS_SAVE) {
2553 return get_register_var(0); 2553 return get_register_var(0);
2554 } else 2554 } else
2555 return list3n(LVAR,caller_arg_offset_v(nargs),0); 2555 return list3n(LVAR,caller_arg_offset_v(nargs),0);
2556 } else { 2556 } else {
2557 error(-1); 2557 error(-1);
2558 return get_register_var(0); 2558 return get_register_var(0);
2559 } 2559 }
2560 } 2560 }
2561 2561
2562 int 2562 int
2563 function(int e1) 2563 function(int e1)
2577 ret_type = function_type(cadddr(e1),&dots); 2577 ret_type = function_type(cadddr(e1),&dots);
2578 if (caddr(cadddr(e1))==0) dots=1; 2578 if (caddr(cadddr(e1))==0) dots=1;
2579 2579
2580 arg_assign = 0; 2580 arg_assign = 0;
2581 e2 = cadr(e1); 2581 e2 = cadr(e1);
2582 if (car(e2) == FNAME) { 2582 if (car(e2) == FNAME) {
2583 fn=ncaddr(e2); 2583 fn=ncaddr(e2);
2584 } else { 2584 } else {
2585 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case 2585 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case
2586 jmp = get_register_var(0); 2586 jmp = get_register_var(0);
2587 if (car(jmp)!=REGISTER) error(-1); 2587 if (car(jmp)!=REGISTER) error(-1);
2588 reg_arg_list = list2(jmp,reg_arg_list); 2588 reg_arg_list = list2(jmp,reg_arg_list);
2589 if (!simple_arg(e2)) { 2589 if (!simple_arg(e2)) {
2590 g_expr_u(assign_expr0(jmp,e2,INT,INT)); 2590 g_expr_u(assign_expr0(jmp,e2,INT,INT));
2591 } else 2591 } else
2592 arg_assign = list2(assign_expr0(jmp,e2,INT,INT),arg_assign); 2592 arg_assign = list2(assign_expr0(jmp,e2,INT,INT),arg_assign);
2593 } 2593 }
2594 /* first we execute complex argument to avoid interaction with 2594 /* first we execute complex argument to avoid interaction with
2595 input variables */ 2595 input variables */
2596 stargs = 0; 2596 stargs = 0;
2597 complex_ = 0; 2597 complex_ = 0;
2598 nargs = reg_arg = freg_arg = 0; 2598 nargs = reg_arg = freg_arg = 0;
2599 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { 2599 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {
2600 t=caddr(e3); 2600 t=caddr(e3);
2601 if ((e5= !simple_arg(car(e3)))) { 2601 if ((e5= !simple_arg(car(e3)))) {
2602 if (complex_) { 2602 if (complex_) {
2603 arg = get_input_arg(caddr(complex_),AS_SAVE, 2603 arg = get_input_arg(caddr(complex_),AS_SAVE,
2604 pnargs,preg_arg,pfreg_arg); 2604 pnargs,preg_arg,pfreg_arg);
2605 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); 2605 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg);
2606 } 2606 }
2607 pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg; 2607 pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
2608 complex_ = e3; 2608 complex_ = e3;
2609 } 2609 }
2610 if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { 2610 if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
2611 // The struct should be pushed after complex arguments. 2611 // The struct should be pushed after complex arguments.
2612 if (e5) { // compute address only, complex_ is me now. Clear it. 2612 if (e5) { // compute address only, complex_ is me now. Clear it.
2613 complex_ = 0; 2613 complex_ = 0;
2614 e4 = car(e3); 2614 e4 = car(e3);
2615 if (car(e4)==RSTRUCT) e4 = cadr(e4); 2615 if (car(e4)==RSTRUCT) e4 = cadr(e4);
2616 else if (car(e4)==INDIRECT) e4 = cadr(e4); 2616 else if (car(e4)==INDIRECT) e4 = cadr(e4);
2617 if (!simple_arg(e4)) { 2617 if (!simple_arg(e4)) {
2618 // Calculate complex struct address here. 2618 // Calculate complex struct address here.
2619 // If simple, leave it. 2619 // If simple, leave it.
2620 arg = get_register_var(0); 2620 arg = get_register_var(0);
2621 g_expr_u(assign_expr0(arg,e4,INT,INT)); 2621 g_expr_u(assign_expr0(arg,e4,INT,INT));
2622 car(e3)=arg; 2622 car(e3)=arg;
2623 reg_arg_list = list2(arg,reg_arg_list); 2623 reg_arg_list = list2(arg,reg_arg_list);
2624 if (car(arg)==REGISTER) use_input_reg(cadr(arg),1); 2624 if (car(arg)==REGISTER) use_input_reg(cadr(arg),1);
2625 else car(e3) = rvalue_t(arg,INT); 2625 else car(e3) = rvalue_t(arg,INT);
2626 } 2626 }
2627 } 2627 }
2628 stargs = list4(e3,stargs,nargs,reg_arg); 2628 stargs = list4(e3,stargs,nargs,reg_arg);
2629 } 2629 }
2630 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg); 2630 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg);
2631 } 2631 }
2632 2632
2633 /* now all input register vars are free */ 2633 /* now all input register vars are free */
2634 code_save_stacks(); 2634 code_save_stacks();
2635 // set_lreg(LREG_LREGISTER,0); 2635 // set_lreg(LREG_LREGISTER,0);
2655 arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0); 2655 arg = get_input_arg(t,AS_ARG,caddr(stargs),cadddr(stargs),0);
2656 push_struct(e4,t,arg); 2656 push_struct(e4,t,arg);
2657 car(e3)=0; // done 2657 car(e3)=0; // done
2658 } 2658 }
2659 } else { 2659 } else {
2660 // last complex argument can use input register 2660 // last complex argument can use input register
2661 if (complex_) { 2661 if (complex_) {
2662 arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg); 2662 arg = get_input_arg(caddr(complex_),AS_ARG,pnargs,preg_arg,pfreg_arg);
2663 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg); 2663 reg_arg_list = compute_complex_arg(complex_,reg_arg_list,arg);
2664 } 2664 }
2665 } 2665 }
2666 2666
2667 nargs = reg_arg = freg_arg = 0; 2667 nargs = reg_arg = freg_arg = 0;
2668 // calc stack arguments first, it may requires extra registers, 2668 // calc stack arguments first, it may requires extra registers,
2669 // and we can still use input registers now. 2669 // and we can still use input registers now.
2670 for (e3 = e1; e3; 2670 for (e3 = e1; e3;
2671 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg), 2671 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
2672 e3 = cadr(e3)) { 2672 e3 = cadr(e3)) {
2673 if (!(e4=car(e3))) continue; 2673 if (!(e4=car(e3))) continue;
2674 t=caddr(e3); 2674 t=caddr(e3);
2675 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); 2675 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg);
2676 if (car(arg)!=LVAR) continue; 2676 if (car(arg)!=LVAR) continue;
2677 g_expr_u(assign_expr0(arg,e4,t,t)); 2677 g_expr_u(assign_expr0(arg,e4,t,t));
2678 if (t==LONGLONG||t==ULONGLONG) { 2678 if (t==LONGLONG||t==ULONGLONG) {
2679 if (reg_arg+1==MAX_INPUT_REGISTER_VAR) { 2679 if (reg_arg+1==MAX_INPUT_REGISTER_VAR) {
2680 // half register, half memory case 2680 // half register, half memory case
2681 arg_assign = list2( 2681 arg_assign = list2(
2682 assign_expr0(r0=get_input_register_var(reg_arg,0,0), 2682 assign_expr0(r0=get_input_register_var(reg_arg,0,0),
2683 arg,INT,INT), 2683 arg,INT,INT),
2684 arg_assign); 2684 arg_assign);
2685 use_input_reg(cadr(r0),1); 2685 use_input_reg(cadr(r0),1);
2686 } 2686 }
2687 } 2687 }
2688 car(e3)=0; // done 2688 car(e3)=0; // done
2689 } 2689 }
2690 nargs = reg_arg = freg_arg = 0; 2690 nargs = reg_arg = freg_arg = 0;
2691 for (e3 = e1; e3; 2691 for (e3 = e1; e3;
2692 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg), 2692 increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
2693 e3 = cadr(e3)) { 2693 e3 = cadr(e3)) {
2694 if (!(e4=car(e3))) continue; 2694 if (!(e4=car(e3))) continue;
2695 t=type_value(caddr(e3)); 2695 t=type_value(caddr(e3));
2696 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); 2696 arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg);
2697 if(scalar(t)) { 2697 if(scalar(t)) {
2698 reg_arg_list = list2(arg,reg_arg_list); 2698 reg_arg_list = list2(arg,reg_arg_list);
2699 /* protect from input register free */ 2699 /* protect from input register free */
2700 if (car(arg)==REGISTER) { 2700 if (car(arg)==REGISTER) {
2701 set_ireg(cadr(arg),0); 2701 set_ireg(cadr(arg),0);
2702 g_expr_u(assign_expr0(arg,e4,t,t)); 2702 g_expr_u(assign_expr0(arg,e4,t,t));
2703 use_input_reg(cadr(arg),1); 2703 use_input_reg(cadr(arg),1);
2704 } else 2704 } else
2705 g_expr_u(assign_expr0(arg,e4,t,t)); 2705 g_expr_u(assign_expr0(arg,e4,t,t));
2706 } else if (t==LONGLONG||t==ULONGLONG) { 2706 } else if (t==LONGLONG||t==ULONGLONG) {
2707 if (reg_arg+1==MAX_INPUT_REGISTER_VAR) { 2707 if (reg_arg+1==MAX_INPUT_REGISTER_VAR) {
2708 // half register, half memory case 2708 // half register, half memory case
2709 // put whole long long anyway 2709 // put whole long long anyway
2710 arg_assign = list2( 2710 arg_assign = list2(
2711 assign_expr0(r0=get_input_register_var(reg_arg,0,0), 2711 assign_expr0(r0=get_input_register_var(reg_arg,0,0),
2712 arg,INT,INT), 2712 arg,INT,INT),
2713 arg_assign); 2713 arg_assign);
2714 use_input_reg(cadr(r0),1); 2714 use_input_reg(cadr(r0),1);
2715 reg_arg_list = list2(r0,reg_arg_list); 2715 reg_arg_list = list2(r0,reg_arg_list);
2716 } else { 2716 } else {
2717 if (car(arg)==LREGISTER) { 2717 if (car(arg)==LREGISTER) {
2718 use_input_reg(cadr(arg),1); 2718 use_input_reg(cadr(arg),1);
2719 } 2719 }
2720 } 2720 }
2721 reg_arg_list = list2(arg,reg_arg_list); 2721 reg_arg_list = list2(arg,reg_arg_list);
2722 g_expr_u(assign_expr0(arg,e4,t,t)); 2722 g_expr_u(assign_expr0(arg,e4,t,t));
2723 } else if (t==DOUBLE||t==FLOAT) { 2723 } else if (t==DOUBLE||t==FLOAT) {
2724 #ifdef __APPLE__ 2724 #ifdef __APPLE__
2725 if (reg_arg<MAX_INPUT_REGISTER_VAR) { 2725 if (reg_arg<MAX_INPUT_REGISTER_VAR) {
2726 /* sigh... 2726 /* sigh...
2727 printf requires floating value in integer registers 2727 printf requires floating value in integer registers
2728 */ 2728 */
2729 if (dots) { 2729 if (dots) {
2730 int r1; 2730 int r1;
2731 if (car(e4)==DRLVAR) { 2731 if (car(e4)==DRLVAR) {
2732 special_lvar = cadr(e4); 2732 special_lvar = cadr(e4);
2733 e5 = list3n(LVAR,special_lvar,0); 2733 e5 = list3n(LVAR,special_lvar,0);
2734 } else { 2734 } else {
2735 special_lvar = new_lvar(SIZE_OF_DOUBLE); 2735 special_lvar = new_lvar(SIZE_OF_DOUBLE);
2736 g_expr(assign_expr0( 2736 g_expr(assign_expr0(
2737 (e5=list3n(LVAR,special_lvar,0)),e4,DOUBLE,t)); 2737 (e5=list3n(LVAR,special_lvar,0)),e4,DOUBLE,t));
2738 reg_arg_list = list2(e5,reg_arg_list); 2738 reg_arg_list = list2(e5,reg_arg_list);
2739 e4 = list2(DREGISTER,freg); 2739 e4 = list2(DREGISTER,freg);
2740 /* freg should not change until XXX */ 2740 /* freg should not change until XXX */
2741 } 2741 }
2742 r0=get_input_register_var(reg_arg,0,0); 2742 r0=get_input_register_var(reg_arg,0,0);
2743 r1 = reg_arg+1+MIN_TMP_REG; 2743 r1 = reg_arg+1+MIN_TMP_REG;
2744 if (regs[r1]==PTRC_REG) 2744 if (regs[r1]==PTRC_REG)
2745 clear_ptr_cache_reg(list2(REGISTER,r1)); 2745 clear_ptr_cache_reg(list2(REGISTER,r1));
2746 /* else if (regs[r1]) error(-1); */ 2746 /* else if (regs[r1]) error(-1); */
2747 r1=get_input_register_var_1(reg_arg+1,0,0); 2747 r1=get_input_register_var_1(reg_arg+1,0,0);
2748 use_input_reg(cadr(r0),1); /* protect from input register free */ 2748 use_input_reg(cadr(r0),1); /* protect from input register free */
2749 use_input_reg(cadr(r1),1); /* protect from input register free */ 2749 use_input_reg(cadr(r1),1); /* protect from input register free */
2750 reg_arg_list = list2(r0,reg_arg_list); 2750 reg_arg_list = list2(r0,reg_arg_list);
2751 reg_arg_list = list2(r1,reg_arg_list); 2751 reg_arg_list = list2(r1,reg_arg_list);
2752 arg_assign = list2( assign_expr0(r0,e5,INT,INT), arg_assign); 2752 arg_assign = list2( assign_expr0(r0,e5,INT,INT), arg_assign);
2753 arg_assign = list2( assign_expr0(r1, 2753 arg_assign = list2( assign_expr0(r1,
2754 list3n(LVAR,special_lvar+SIZE_OF_INT,0), 2754 list3n(LVAR,special_lvar+SIZE_OF_INT,0),
2755 INT,INT), arg_assign); 2755 INT,INT), arg_assign);
2756 } 2756 }
2757 } 2757 }
2758 if (dots && (freg_arg*8+reg_arg*4)>=32 && freg_arg<MAX_INPUT_DREGISTER_VAR) { 2758 if (dots && (freg_arg*8+reg_arg*4)>=32 && freg_arg<MAX_INPUT_DREGISTER_VAR) {
2759 /* 2759 /*
2760 it requires integer register and floating register and 2760 it requires integer register and floating register and
2761 stack value. 2761 stack value.
2762 */ 2762 */
2763 arg_assign = list2( 2763 arg_assign = list2(
2764 assign_expr0(list3n(LVAR,caller_arg_offset_v(nargs),0), 2764 assign_expr0(list3n(LVAR,caller_arg_offset_v(nargs),0),
2765 get_input_dregister_var(freg_arg,0,0,1),t,t), 2765 get_input_dregister_var(freg_arg,0,0,1),t,t),
2766 arg_assign); 2766 arg_assign);
2767 } 2767 }
2768 #endif 2768 #endif
2769 reg_arg_list = list2(arg,reg_arg_list); 2769 reg_arg_list = list2(arg,reg_arg_list);
2770 if (car(arg)==DREGISTER) { 2770 if (car(arg)==DREGISTER) {
2771 set_freg(cadr(arg),0); 2771 set_freg(cadr(arg),0);
2772 g_expr_u(assign_expr0(arg,e4,t,t)); 2772 g_expr_u(assign_expr0(arg,e4,t,t));
2773 use_input_reg(cadr(arg),1); 2773 use_input_reg(cadr(arg),1);
2774 } else 2774 } else
2775 g_expr_u(assign_expr0(arg,e4,t,t)); 2775 g_expr_u(assign_expr0(arg,e4,t,t));
2776 } 2776 }
2777 // structs are finished 2777 // structs are finished
2778 } 2778 }
2779 if (max_func_args<nargs) max_func_args=nargs; 2779 if (max_func_args<nargs) max_func_args=nargs;
2780 for(;arg_assign;arg_assign=cadr(arg_assign)) { 2780 for(;arg_assign;arg_assign=cadr(arg_assign)) {
2781 g_expr_u(car(arg_assign)); 2781 g_expr_u(car(arg_assign));
2782 } 2782 }
2783 clear_ptr_cache(); 2783 clear_ptr_cache();
2784 #ifndef __APPLE__ 2784 #ifndef __APPLE__
2785 if (dots) { 2785 if (dots) {
2786 if (freg_arg) { 2786 if (freg_arg) {
2787 // variadic function has floating value in register 2787 // variadic function has floating value in register
2788 printf("\tcreqv 6,6,6\n"); 2788 printf("\tcreqv 6,6,6\n");
2789 } else { 2789 } else {
2790 // printf("\tcrxor 6,6,6\n"); // for value in stack 2790 // printf("\tcrxor 6,6,6\n"); // for value in stack
2791 } 2791 }
2792 } 2792 }
2793 #endif 2793 #endif
2794 if (car(e2) == FNAME) { 2794 if (car(e2) == FNAME) {
2795 #ifdef __APPLE__ 2795 #ifdef __APPLE__
2796 printf("\tbl\tL_%s$stub\n",fn->nm); 2796 printf("\tbl\tL_%s$stub\n",fn->nm);
2797 #else 2797 #else
2798 printf("\tbl\t%s\n",fn->nm); 2798 printf("\tbl\t%s\n",fn->nm);
2799 #endif 2799 #endif
2800 } else { 2800 } else {
2801 jrn = register_name(cadr(jmp)); 2801 jrn = register_name(cadr(jmp));
2802 printf("\tmtctr %s\n",jrn); 2802 printf("\tmtctr %s\n",jrn);
2803 printf("\tbctrl\n"); 2803 printf("\tbctrl\n");
2804 } 2804 }
2805 free_register_var(reg_arg_list); 2805 free_register_var(reg_arg_list);
2806 if (ret_type==DOUBLE||ret_type==FLOAT) { 2806 if (ret_type==DOUBLE||ret_type==FLOAT) {
2807 set_freg(RET_FREGISTER,0); 2807 set_freg(RET_FREGISTER,0);
2808 } else if (ret_type==ULONGLONG||ret_type==LONGLONG) { 2808 } else if (ret_type==ULONGLONG||ret_type==LONGLONG) {
2809 set_lreg(RET_LREGISTER,0); 2809 set_lreg(RET_LREGISTER,0);
2810 use_reg(RET_LREGISTER); 2810 use_reg(RET_LREGISTER);
2811 } else if (ret_type==VOID) { 2811 } else if (ret_type==VOID) {
2812 } else { 2812 } else {
2813 set_ireg(RET_REGISTER,0); 2813 set_ireg(RET_REGISTER,0);
2814 } 2814 }
2815 cleanup_lregister0(); 2815 cleanup_lregister0();
2816 return ret_type; 2816 return ret_type;
2817 } 2817 }
2818 2818
2953 lload(int creg,int reg,int offset) 2953 lload(int creg,int reg,int offset)
2954 { 2954 {
2955 char *crn = register_name(creg); 2955 char *crn = register_name(creg);
2956 #ifdef __APPLE__ 2956 #ifdef __APPLE__
2957 if (LARGE_OFFSET(offset)) { 2957 if (LARGE_OFFSET(offset)) {
2958 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); 2958 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset);
2959 } 2959 }
2960 #if ENDIAN_L==0 2960 #if ENDIAN_L==0
2961 if (creg!=regv_l(reg)) { 2961 if (creg!=regv_l(reg)) {
2962 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset,crn); 2962 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset,crn);
2963 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); 2963 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
2964 } else { 2964 } else {
2965 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); 2965 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
2966 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset,crn); 2966 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset,crn);
2967 } 2967 }
2968 #else 2968 #else
2969 if (creg!=regv_h(reg)) { 2969 if (creg!=regv_h(reg)) {
2970 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); 2970 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn);
2971 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); 2971 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
2972 } else { 2972 } else {
2973 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); 2973 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
2974 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); 2974 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn);
2975 } 2975 }
2976 #endif 2976 #endif
2977 #else 2977 #else
2978 if (LARGE_OFFSET(offset)) { 2978 if (LARGE_OFFSET(offset)) {
2979 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); 2979 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset);
2980 } 2980 }
2981 #if ENDIAN_L==0 2981 #if ENDIAN_L==0
2982 if (creg!=regv_l(reg)) { 2982 if (creg!=regv_l(reg)) {
2983 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); 2983 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn);
2984 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); 2984 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
2985 } else { 2985 } else {
2986 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); 2986 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn);
2987 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); 2987 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn);
2988 } 2988 }
2989 #else 2989 #else
2990 if (creg!=regv_h(reg)) { 2990 if (creg!=regv_h(reg)) {
2991 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); 2991 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn);
2992 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); 2992 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
2993 } else { 2993 } else {
2994 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); 2994 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn);
2995 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); 2995 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn);
2996 } 2996 }
2997 #endif 2997 #endif
2998 2998
2999 #endif 2999 #endif
3000 } 3000 }
3016 3016
3017 void 3017 void
3018 code_assign_gvar(int e2,int creg,int byte) { 3018 code_assign_gvar(int e2,int creg,int byte) {
3019 use_int(creg); 3019 use_int(creg);
3020 code_ldf(cstore(byte),register_name(creg),cadr(e2), 3020 code_ldf(cstore(byte),register_name(creg),cadr(e2),
3021 get_ptr_cache(ncaddr(e2))); 3021 get_ptr_cache(ncaddr(e2)));
3022 } 3022 }
3023 3023
3024 void 3024 void
3025 code_assign_lvar(int e2,int creg,int byte) { 3025 code_assign_lvar(int e2,int creg,int byte) {
3026 char *crn; 3026 char *crn;
3033 3033
3034 void 3034 void
3035 code_assign_register(int e2,int byte,int creg) { 3035 code_assign_register(int e2,int byte,int creg) {
3036 use_int(creg); 3036 use_int(creg);
3037 if (e2!=creg) 3037 if (e2!=creg)
3038 printf("\tmr %s,%s\n",register_name(e2),register_name(creg)); 3038 printf("\tmr %s,%s\n",register_name(e2),register_name(creg));
3039 } 3039 }
3040 3040
3041 void 3041 void
3042 code_assign(int e2,int byte,int creg) { 3042 code_assign(int e2,int byte,int creg) {
3043 char *drn; 3043 char *drn;
3070 ld_indexx(byte,0,creg,ireg,sign); 3070 ld_indexx(byte,0,creg,ireg,sign);
3071 tosop(op,ireg,xreg); 3071 tosop(op,ireg,xreg);
3072 emit_pop_free(xreg); 3072 emit_pop_free(xreg);
3073 xreg = emit_pop(0); /* pop e3 value */ 3073 xreg = emit_pop(0); /* pop e3 value */
3074 printf("\t%s %s,0(%s)\n",cstore(byte), 3074 printf("\t%s %s,0(%s)\n",cstore(byte),
3075 register_name(ireg),register_name(xreg)); 3075 register_name(ireg),register_name(xreg));
3076 emit_pop_free(xreg); 3076 emit_pop_free(xreg);
3077 } 3077 }
3078 3078
3079 int 3079 int
3080 tosop_operand_safe_p(int op) 3080 tosop_operand_safe_p(int op)
3090 char *orn,*crn,*drn; 3090 char *orn,*crn,*drn;
3091 // creg = creg op oreg 3091 // creg = creg op oreg
3092 3092
3093 use_int(creg); 3093 use_int(creg);
3094 if(oreg==-1) { 3094 if(oreg==-1) {
3095 error(-1); 3095 error(-1);
3096 } else if (oreg<= -REG_LVAR_OFFSET) { 3096 } else if (oreg<= -REG_LVAR_OFFSET) {
3097 ox = get_register(); if (ox<0) error(-1); 3097 ox = get_register(); if (ox<0) error(-1);
3098 code_rlvar(oreg+REG_LVAR_OFFSET,ox); 3098 code_rlvar(oreg+REG_LVAR_OFFSET,ox);
3099 free_lvar(oreg+REG_LVAR_OFFSET); 3099 free_lvar(oreg+REG_LVAR_OFFSET);
3100 oreg = ox; 3100 oreg = ox;
3101 } 3101 }
3102 3102
3103 switch(op) { 3103 switch(op) {
3104 case LSHIFT: 3104 case LSHIFT:
3105 case ULSHIFT: 3105 case ULSHIFT:
3106 shift("slw",creg,oreg); 3106 shift("slw",creg,oreg);
3107 if(ox!=-1) free_register(ox); 3107 if(ox!=-1) free_register(ox);
3108 return; 3108 return;
3109 case RSHIFT: 3109 case RSHIFT:
3110 shift("sraw",creg,oreg); 3110 shift("sraw",creg,oreg);
3111 if(ox!=-1) free_register(ox); 3111 if(ox!=-1) free_register(ox);
3112 return; 3112 return;
3113 case URSHIFT: 3113 case URSHIFT:
3114 shift("srw",creg,oreg); 3114 shift("srw",creg,oreg);
3115 if(ox!=-1) free_register(ox); 3115 if(ox!=-1) free_register(ox);
3116 return; 3116 return;
3117 } 3117 }
3118 orn = register_name(oreg); 3118 orn = register_name(oreg);
3119 crn = register_name(creg); 3119 crn = register_name(creg);
3120 switch(op) { 3120 switch(op) {
3121 case ADD: 3121 case ADD:
3122 printf("\tadd %s,%s,%s\n",crn,crn,orn); 3122 printf("\tadd %s,%s,%s\n",crn,crn,orn);
3123 break; 3123 break;
3124 case SUB: 3124 case SUB:
3125 printf("\tsub %s,%s,%s\n",crn,crn,orn); 3125 printf("\tsub %s,%s,%s\n",crn,crn,orn);
3126 break; 3126 break;
3127 case CMP: 3127 case CMP:
3128 inc_cmpflag(); 3128 inc_cmpflag();
3129 printf("\tcmpw %s,%s,%s\n",crname(cmpflag),crn,orn); 3129 printf("\tcmpw %s,%s,%s\n",crname(cmpflag),crn,orn);
3130 break; 3130 break;
3131 case UCMP: 3131 case UCMP:
3132 inc_cmpflag(); 3132 inc_cmpflag();
3133 printf("\tcmplw %s,%s,%s\n",crname(cmpflag),crn,orn); 3133 printf("\tcmplw %s,%s,%s\n",crname(cmpflag),crn,orn);
3134 break; 3134 break;
3135 case BAND: 3135 case BAND:
3136 printf("\tand %s,%s,%s\n",crn,crn,orn); 3136 printf("\tand %s,%s,%s\n",crn,crn,orn);
3137 break; 3137 break;
3138 case EOR: 3138 case EOR:
3139 printf("\txor %s,%s,%s\n",crn,crn,orn); 3139 printf("\txor %s,%s,%s\n",crn,crn,orn);
3140 break; 3140 break;
3141 case BOR: 3141 case BOR:
3142 printf("\tor %s,%s,%s\n",crn,crn,orn); 3142 printf("\tor %s,%s,%s\n",crn,crn,orn);
3143 break; 3143 break;
3144 case MUL: 3144 case MUL:
3145 printf("\tmullw %s,%s,%s\n",crn,crn,orn); 3145 printf("\tmullw %s,%s,%s\n",crn,crn,orn);
3146 break; 3146 break;
3147 case UMUL: 3147 case UMUL:
3148 printf("\tmullw %s,%s,%s\n",crn,crn,orn); 3148 printf("\tmullw %s,%s,%s\n",crn,crn,orn);
3149 break; 3149 break;
3150 case DIV: 3150 case DIV:
3151 printf("\tdivw %s,%s,%s\n",crn,crn,orn); 3151 printf("\tdivw %s,%s,%s\n",crn,crn,orn);
3152 break; 3152 break;
3153 case UDIV: 3153 case UDIV:
3154 printf("\tdivwu %s,%s,%s\n",crn,crn,orn); 3154 printf("\tdivwu %s,%s,%s\n",crn,crn,orn);
3155 break; 3155 break;
3156 case MOD: 3156 case MOD:
3157 dx=get_register(); 3157 dx=get_register();
3158 drn = register_name(dx); 3158 drn = register_name(dx);
3159 printf("\tdivw %s,%s,%s\n",drn,crn,orn); 3159 printf("\tdivw %s,%s,%s\n",drn,crn,orn);
3160 printf("\tmullw %s,%s,%s\n",drn,drn,orn); 3160 printf("\tmullw %s,%s,%s\n",drn,drn,orn);
3161 printf("\tsubf %s,%s,%s\n",crn,drn,crn); 3161 printf("\tsubf %s,%s,%s\n",crn,drn,crn);
3162 break; 3162 break;
3163 case UMOD: 3163 case UMOD:
3164 dx=get_register(); 3164 dx=get_register();
3165 drn = register_name(dx); 3165 drn = register_name(dx);
3166 printf("\tdivwu %s,%s,%s\n",drn,crn,orn); 3166 printf("\tdivwu %s,%s,%s\n",drn,crn,orn);
3167 printf("\tmullw %s,%s,%s\n",drn,drn,orn); 3167 printf("\tmullw %s,%s,%s\n",drn,drn,orn);
3168 printf("\tsubf %s,%s,%s\n",crn,drn,crn); 3168 printf("\tsubf %s,%s,%s\n",crn,drn,crn);
3169 break; 3169 break;
3170 default: 3170 default:
3171 error(-1); 3171 error(-1);
3172 } 3172 }
3173 if(dx!=-1) free_register(dx); 3173 if(dx!=-1) free_register(dx);
3174 if(ox!=-1) free_register(ox); 3174 if(ox!=-1) free_register(ox);
3175 } 3175 }
3176 3176
3194 v = cadr(v); 3194 v = cadr(v);
3195 3195
3196 switch(op) { 3196 switch(op) {
3197 case LSHIFT: 3197 case LSHIFT:
3198 case ULSHIFT: 3198 case ULSHIFT:
3199 printf("\tslwi %s,%s,%d\n",crn,crn,v); 3199 printf("\tslwi %s,%s,%d\n",crn,crn,v);
3200 return; 3200 return;
3201 case DIV: 3201 case DIV:
3202 v = ilog(v); 3202 v = ilog(v);
3203 case RSHIFT: 3203 case RSHIFT:
3204 printf("\tsrawi %s,%s,%d\n",crn,crn,v); 3204 printf("\tsrawi %s,%s,%d\n",crn,crn,v);
3205 return; 3205 return;
3206 case UDIV: 3206 case UDIV:
3207 v = ilog(v); 3207 v = ilog(v);
3208 case URSHIFT: 3208 case URSHIFT:
3209 printf("\tsrwi %s,%s,%d\n",crn,crn,v); 3209 printf("\tsrwi %s,%s,%d\n",crn,crn,v);
3210 return; 3210 return;
3211 case ADD: 3211 case ADD:
3212 #ifdef __APPLE__ 3212 #ifdef __APPLE__
3213 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v); 3213 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v);
3214 #else 3214 #else
3215 printf("\taddi %s,%s,%d@l\n",crn,crn,v); 3215 printf("\taddi %s,%s,%d@l\n",crn,crn,v);
3216 #endif 3216 #endif
3217 break; 3217 break;
3218 case SUB: 3218 case SUB:
3219 #ifdef __APPLE__ 3219 #ifdef __APPLE__
3220 printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v); 3220 printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v);
3221 #else 3221 #else
3222 printf("\taddi %s,%s,-%d@l\n",crn,crn,v); 3222 printf("\taddi %s,%s,-%d@l\n",crn,crn,v);
3223 #endif 3223 #endif
3224 break; 3224 break;
3225 case CMP: 3225 case CMP:
3226 inc_cmpflag(); 3226 inc_cmpflag();
3227 #ifdef __APPLE__ 3227 #ifdef __APPLE__
3228 printf("\tcmpwi %s,%s,lo16(%d)\n",crname(cmpflag),crn,v); 3228 printf("\tcmpwi %s,%s,lo16(%d)\n",crname(cmpflag),crn,v);
3229 #else 3229 #else
3230 printf("\tcmpwi %s,%s,%d@l\n",crname(cmpflag),crn,v); 3230 printf("\tcmpwi %s,%s,%d@l\n",crname(cmpflag),crn,v);
3231 #endif 3231 #endif
3232 break; 3232 break;
3233 case UCMP: 3233 case UCMP:
3234 inc_cmpflag(); 3234 inc_cmpflag();
3235 #ifdef __APPLE__ 3235 #ifdef __APPLE__
3236 printf("\tcmplwi %s,%s,lo16(%d)\n",crname(cmpflag),crn,v); 3236 printf("\tcmplwi %s,%s,lo16(%d)\n",crname(cmpflag),crn,v);
3237 #else 3237 #else
3238 printf("\tcmplwi %s,%s,%d@l\n",crname(cmpflag),crn,v); 3238 printf("\tcmplwi %s,%s,%d@l\n",crname(cmpflag),crn,v);
3239 #endif 3239 #endif
3240 break; 3240 break;
3241 case EOR: 3241 case EOR:
3242 #ifdef __APPLE__ 3242 #ifdef __APPLE__
3243 printf("\txori %s,%s,lo16(%d)\n",crn,crn,v); 3243 printf("\txori %s,%s,lo16(%d)\n",crn,crn,v);
3244 #else 3244 #else
3245 printf("\txori %s,%s,%d@l\n",crn,crn,v); 3245 printf("\txori %s,%s,%d@l\n",crn,crn,v);
3246 #endif 3246 #endif
3247 break; 3247 break;
3248 case BOR: 3248 case BOR:
3249 #ifdef __APPLE__ 3249 #ifdef __APPLE__
3250 printf("\tori %s,%s,lo16(%d)\n",crn,crn,v); 3250 printf("\tori %s,%s,lo16(%d)\n",crn,crn,v);
3251 #else 3251 #else
3252 printf("\tori %s,%s,%d@l\n",crn,crn,v); 3252 printf("\tori %s,%s,%d@l\n",crn,crn,v);
3253 #endif 3253 #endif
3254 break; 3254 break;
3255 case MUL: 3255 case MUL:
3256 case UMUL: 3256 case UMUL:
3257 if ((l=ilog(v))) { 3257 if ((l=ilog(v))) {
3258 printf("\tslwi %s,%s,%d\n",crn,crn,l); 3258 printf("\tslwi %s,%s,%d\n",crn,crn,l);
3259 } else 3259 } else
3260 #ifdef __APPLE__ 3260 #ifdef __APPLE__
3261 printf("\tmulli %s,%s,lo16(%d)\n",crn,crn,v); 3261 printf("\tmulli %s,%s,lo16(%d)\n",crn,crn,v);
3262 #else 3262 #else
3263 printf("\tmulli %s,%s,%d@l\n",crn,crn,v); 3263 printf("\tmulli %s,%s,%d@l\n",crn,crn,v);
3264 #endif 3264 #endif
3265 break; 3265 break;
3266 default: 3266 default:
3267 error(-1); 3267 error(-1);
3268 } 3268 }
3269 } 3269 }
3270 3270
3271 void 3271 void
3272 shift(char *op, int creg, int reg) 3272 shift(char *op, int creg, int reg)
3278 printf("\t%s %s,%s,%s\n",op,crn,crn,rrn); 3278 printf("\t%s %s,%s,%s\n",op,crn,crn,rrn);
3279 } 3279 }
3280 3280
3281 void 3281 void
3282 ld_indexx(int byte, int n, int xreg,int creg, int sign) 3282 ld_indexx(int byte, int n, int xreg,int creg, int sign)
3283 { 3283 {
3284 char *crn; 3284 char *crn;
3285 use_int(creg); 3285 use_int(creg);
3286 crn = register_name(creg); 3286 crn = register_name(creg);
3287 printf("\t%s %s,%d(%s)\n",cload(byte),register_name(creg),n, 3287 printf("\t%s %s,%d(%s)\n",cload(byte),register_name(creg),n,
3288 register_name(xreg)); 3288 register_name(xreg));
3289 cext(sign,byte,creg); 3289 cext(sign,byte,creg);
3290 } 3290 }
3291 3291
3292 int 3292 int
3293 code_csvalue() 3293 code_csvalue()
3300 { 3300 {
3301 int reg,regsv; 3301 int reg,regsv;
3302 /* used in dosiwtch() */ 3302 /* used in dosiwtch() */
3303 inc_cmpflag(); 3303 inc_cmpflag();
3304 if (-32767<e&&e<32767) { 3304 if (-32767<e&&e<32767) {
3305 printf("\tcmpwi %s,%s,%d\n",crname(cmpflag),register_name(csreg),e); 3305 printf("\tcmpwi %s,%s,%d\n",crname(cmpflag),register_name(csreg),e);
3306 jcond(label,cond); 3306 jcond(label,cond);
3307 } else { 3307 } else {
3308 regsv = regs[csreg]; regs[csreg]=USING_REG; 3308 regsv = regs[csreg]; regs[csreg]=USING_REG;
3309 reg = get_register(); 3309 reg = get_register();
3310 regs[csreg]= regsv; 3310 regs[csreg]= regsv;
3311 code_const(e,reg); 3311 code_const(e,reg);
3312 printf("\tcmpw %s,%s,%s\n",crname(cmpflag),register_name(csreg),register_name(reg)); 3312 printf("\tcmpw %s,%s,%s\n",crname(cmpflag),register_name(csreg),register_name(reg));
3313 jcond(label,cond); 3313 jcond(label,cond);
3314 free_register(reg); 3314 free_register(reg);
3315 } 3315 }
3316 } 3316 }
3317 3317
3318 void 3318 void
3319 code_opening(char *filename) 3319 code_opening(char *filename)
3384 g_expr(list3((t==INT?CMP:UCMP),cadr(e1),caddr(e1))); 3384 g_expr(list3((t==INT?CMP:UCMP),cadr(e1),caddr(e1)));
3385 use_int(reg); 3385 use_int(reg);
3386 rn = register_name(reg); 3386 rn = register_name(reg);
3387 t = CRBITSIZ*cmpflag; 3387 t = CRBITSIZ*cmpflag;
3388 if (eq>0) { 3388 if (eq>0) {
3389 printf("\tcror %d,%d,%d\n",t+flag-1,t+eq-1,t+flag-1); 3389 printf("\tcror %d,%d,%d\n",t+flag-1,t+eq-1,t+flag-1);
3390 } 3390 }
3391 if (neg>0) { 3391 if (neg>0) {
3392 neg = t+neg-1, 3392 neg = t+neg-1,
3393 printf("\tcrnor %d,%d,%d\n",neg,neg,neg); 3393 printf("\tcrnor %d,%d,%d\n",neg,neg,neg);
3394 } 3394 }
3395 printf("\tmfcr %s\n",rn); 3395 printf("\tmfcr %s\n",rn);
3396 printf("\trlwinm %s,%s,%d,1\n",rn,rn,t+flag); 3396 printf("\trlwinm %s,%s,%d,1\n",rn,rn,t+flag);
3397 return 1; 3397 return 1;
3398 } 3398 }
3431 3431
3432 static void 3432 static void
3433 jcond(int l, char cond) 3433 jcond(int l, char cond)
3434 { 3434 {
3435 if (cond==LT) { 3435 if (cond==LT) {
3436 printf("\tb%s %s,%s%d\n",code_ge(0),crname(cmpflag),lpfx,l); 3436 printf("\tb%s %s,%s%d\n",code_ge(0),crname(cmpflag),lpfx,l);
3437 } else if (cond==1||cond==0) { 3437 } else if (cond==1||cond==0) {
3438 printf("\tb%s %s,%s%d\n",cond?"ne":"eq",crname(cmpflag),lpfx,l); 3438 printf("\tb%s %s,%s%d\n",cond?"ne":"eq",crname(cmpflag),lpfx,l);
3439 } else error(-1); 3439 } else error(-1);
3440 } 3440 }
3441 3441
3442 void 3442 void
3443 jmp(int l) 3443 jmp(int l)
3454 void 3454 void
3455 code_enter(char *name) 3455 code_enter(char *name)
3456 { 3456 {
3457 #ifdef __APPLE__ 3457 #ifdef __APPLE__
3458 if (output_mode!=TEXT_EMIT_MODE) 3458 if (output_mode!=TEXT_EMIT_MODE)
3459 text_mode(0); 3459 text_mode(0);
3460 else 3460 else
3461 printf("\t.align 2\n"); 3461 printf("\t.align 2\n");
3462 if (stmode!=STATIC) 3462 if (stmode!=STATIC)
3463 printf(".globl _%s\n",name); 3463 printf(".globl _%s\n",name);
3464 #ifdef DOT_SIZE 3464 #ifdef DOT_SIZE
3465 printf("\t.type\t%s,@function\n",name); 3465 printf("\t.type\t%s,@function\n",name);
3466 #endif 3466 #endif
3467 printf("_%s:\n",name); 3467 printf("_%s:\n",name);
3468 code_disp_label=fwdlabel(); 3468 code_disp_label=fwdlabel();
3477 printf("\tmflr r31\n"); 3477 printf("\tmflr r31\n");
3478 max_func_args = 0; 3478 max_func_args = 0;
3479 clear_ptr_cache(); 3479 clear_ptr_cache();
3480 #else 3480 #else
3481 if (output_mode!=TEXT_EMIT_MODE) 3481 if (output_mode!=TEXT_EMIT_MODE)
3482 text_mode(0); 3482 text_mode(0);
3483 else 3483 else
3484 printf("\t.align 2\n"); 3484 printf("\t.align 2\n");
3485 if (stmode!=STATIC) 3485 if (stmode!=STATIC)
3486 printf(".globl %s\n",name); 3486 printf(".globl %s\n",name);
3487 #ifdef DOT_SIZE 3487 #ifdef DOT_SIZE
3488 printf("\t.type\t%s,@function\n",name); 3488 printf("\t.type\t%s,@function\n",name);
3489 #endif 3489 #endif
3490 printf("%s:\n",name); 3490 printf("%s:\n",name);
3491 code_disp_label=fwdlabel(); 3491 code_disp_label=fwdlabel();
3516 disp&= -SIZE_OF_INT; 3516 disp&= -SIZE_OF_INT;
3517 r1_offsetv = -disp+max_func_args*SIZE_OF_INT -code_disp_offset0 +8+32+48; 3517 r1_offsetv = -disp+max_func_args*SIZE_OF_INT -code_disp_offset0 +8+32+48;
3518 #ifdef __APPLE__ 3518 #ifdef __APPLE__
3519 printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv); 3519 printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv);
3520 if (max_func_arg_label) { 3520 if (max_func_arg_label) {
3521 printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); 3521 printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24);
3522 max_func_arg_label = 0; 3522 max_func_arg_label = 0;
3523 } 3523 }
3524 #else 3524 #else
3525 printf(".set .LC%d,%d\n",code_disp_label,-r1_offsetv); 3525 printf(".set .LC%d,%d\n",code_disp_label,-r1_offsetv);
3526 if (max_func_arg_label) { 3526 if (max_func_arg_label) {
3527 printf(".set .LC%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); 3527 printf(".set .LC%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24);
3528 max_func_arg_label = 0; 3528 max_func_arg_label = 0;
3529 } 3529 }
3530 #endif 3530 #endif
3531 local_table(); 3531 local_table();
3532 // free_all_register(); 3532 // free_all_register();
3533 } 3533 }
3535 void 3535 void
3536 enter(char *name) 3536 enter(char *name)
3537 { 3537 {
3538 #ifdef __APPLE__ 3538 #ifdef __APPLE__
3539 if (output_mode!=TEXT_EMIT_MODE) 3539 if (output_mode!=TEXT_EMIT_MODE)
3540 text_mode(0); 3540 text_mode(0);
3541 else 3541 else
3542 printf("\t.align 2\n"); 3542 printf("\t.align 2\n");
3543 if (stmode!=STATIC) 3543 if (stmode!=STATIC)
3544 printf(".globl %s%s\n",npfx,name); 3544 printf(".globl %s%s\n",npfx,name);
3545 /* 3545 /*
3546 printf("\t.type\t%s,@function\n",name); 3546 printf("\t.type\t%s,@function\n",name);
3547 */ 3547 */
3548 printf("%s%s:\n",npfx,name); 3548 printf("%s%s:\n",npfx,name);
3549 code_setup=fwdlabel(); 3549 code_setup=fwdlabel();
3564 printf("\tstwux r1,r1,r31\n"); 3564 printf("\tstwux r1,r1,r31\n");
3565 #endif 3565 #endif
3566 printf("\tmflr r31\n"); 3566 printf("\tmflr r31\n");
3567 #else 3567 #else
3568 if (output_mode!=TEXT_EMIT_MODE) 3568 if (output_mode!=TEXT_EMIT_MODE)
3569 text_mode(0); 3569 text_mode(0);
3570 else 3570 else
3571 printf("\t.align 2\n"); 3571 printf("\t.align 2\n");
3572 if (stmode!=STATIC) 3572 if (stmode!=STATIC)
3573 printf(".globl %s%s\n",npfx,name); 3573 printf(".globl %s%s\n",npfx,name);
3574 /* 3574 /*
3575 printf("\t.type\t%s,@function\n",name); 3575 printf("\t.type\t%s,@function\n",name);
3576 */ 3576 */
3577 printf("%s:\n",name); 3577 printf("%s:\n",name);
3578 control = 1; 3578 control = 1;
3605 3605
3606 int 3606 int
3607 reg_save_offset() 3607 reg_save_offset()
3608 { 3608 {
3609 return -( 3609 return -(
3610 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*SIZE_OF_INT+ 3610 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*SIZE_OF_INT+
3611 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_DOUBLE 3611 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_DOUBLE
3612 ); 3612 );
3613 } 3613 }
3614 3614
3615 void 3615 void
3616 code_label_call(int l) 3616 code_label_call(int l)
3617 { 3617 {
3618 #ifdef __APPLE__ 3618 #ifdef __APPLE__
3619 printf("\tbl\tL_%d\n",l); 3619 printf("\tbl\tL_%d\n",l);
3620 #else 3620 #else
3621 printf("\tbl\t.LC%d\n",l); 3621 printf("\tbl\t.LC%d\n",l);
3622 #endif 3622 #endif
3623 } 3623 }
3624 3624
3625 void 3625 void
3626 code_ret() 3626 code_ret()
3627 { 3627 {
3628 printf("\tblr\n"); 3628 printf("\tblr\n");
3629 } 3629 }
3630 3630
3631 #ifndef __APPLE__ 3631 #ifndef __APPLE__
3632 static int saveFP_used=0; 3632 static int saveFP_used=0;
3633 static char *saveFP_lib[] = { 3633 static char *saveFP_lib[] = {
3679 3679
3680 static void 3680 static void
3681 make_return_continuation() 3681 make_return_continuation()
3682 { 3682 {
3683 #if R1SAVE 3683 #if R1SAVE
3684 retcont1 = fwdlabel(); 3684 retcont1 = fwdlabel();
3685 #endif 3685 #endif
3686 fwddef(retcont); 3686 fwddef(retcont);
3687 if (cadr(fnptr->ty)==FLOAT||cadr(fnptr->ty)==DOUBLE) { 3687 if (cadr(fnptr->ty)==FLOAT||cadr(fnptr->ty)==DOUBLE) {
3688 printf("\tfmr %s,%s\n",fregister_name(1),fregister_name(31)); 3688 printf("\tfmr %s,%s\n",fregister_name(1),fregister_name(31));
3689 printf("\tmr %s,%s\n",register_name(30),register_name(28)); 3689 printf("\tmr %s,%s\n",register_name(30),register_name(28));
3690 } else if (cadr(fnptr->ty)>0&&( 3690 } else if (cadr(fnptr->ty)>0&&(
3691 car(cadr(fnptr->ty))==STRUCT || 3691 car(cadr(fnptr->ty))==STRUCT ||
3692 car(cadr(fnptr->ty))==UNION)) { 3692 car(cadr(fnptr->ty))==UNION)) {
3693 int sz = size(cadr(fnptr->ty)); 3693 int sz = size(cadr(fnptr->ty));
3694 #ifdef __APPLE__ 3694 #ifdef __APPLE__
3695 printf("\tli r7,%d\n",sz); 3695 printf("\tli r7,%d\n",sz);
3696 printf("\tsubl r6,r7,r30\n"); 3696 printf("\tsubl r6,r7,r30\n");
3697 printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*SIZE_OF_INT); 3697 printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*SIZE_OF_INT);
3698 // emit_copy(6,3,sz,0,1,1); 3698 // emit_copy(6,3,sz,0,1,1);
3699 #else 3699 #else
3700 printf("\tli 7,%d\n",sz); 3700 printf("\tli 7,%d\n",sz);
3701 printf("\tsubl 6,7,%d\n",REG_fp); 3701 printf("\tsubl 6,7,%d\n",REG_fp);
3702 printf("\tlwz 3,%d@l(%d)\n",(my_func_args-1)*SIZE_OF_INT,REG_fp); 3702 printf("\tlwz 3,%d@l(%d)\n",(my_func_args-1)*SIZE_OF_INT,REG_fp);
3703 // emit_copy(6,3,sz,0,1,1); 3703 // emit_copy(6,3,sz,0,1,1);
3704 #endif 3704 #endif
3705 printf("\tmr %s,%s\n",register_name(30),register_name(28)); 3705 printf("\tmr %s,%s\n",register_name(30),register_name(28));
3706 } else if (cadr(fnptr->ty)!=VOID) { 3706 } else if (cadr(fnptr->ty)!=VOID) {
3707 printf("\tmr %s,%s\n",register_name(3),register_name(29)); 3707 printf("\tmr %s,%s\n",register_name(3),register_name(29));
3708 printf("\tmr %s,%s\n",register_name(30),register_name(28)); 3708 printf("\tmr %s,%s\n",register_name(30),register_name(28));
3709 } 3709 }
3710 #if R1SAVE 3710 #if R1SAVE
3711 jmp(retcont1); 3711 jmp(retcont1);
3712 #else 3712 #else
3713 #endif 3713 #endif
3714 } 3714 }
3715 3715
3716 void 3716 void
3723 3723
3724 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; 3724 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3;
3725 reg_save = reg_save_offset(); 3725 reg_save = reg_save_offset();
3726 3726
3727 if (control) { 3727 if (control) {
3728 code_set_return_register(1); 3728 code_set_return_register(1);
3729 } 3729 }
3730 if (retcont) { 3730 if (retcont) {
3731 if (control) jmp(retlabel); 3731 if (control) jmp(retlabel);
3732 make_return_continuation(); 3732 make_return_continuation();
3733 } 3733 }
3734 fwddef(retlabel); 3734 fwddef(retlabel);
3735 #if R1SAVE 3735 #if R1SAVE
3736 printf("\tlwz %s,0(%s)\n",register_name(1),register_name(1)); 3736 printf("\tlwz %s,0(%s)\n",register_name(1),register_name(1));
3737 if (retcont) { 3737 if (retcont) {
3738 fwddef(retcont1); 3738 fwddef(retcont1);
3739 } 3739 }
3740 #else 3740 #else
3741 #ifdef __APPLE__ 3741 #ifdef __APPLE__
3742 printf("\taddi r1,r30,lo16(L_%d)\n",lvar_offset_label); 3742 printf("\taddi r1,r30,lo16(L_%d)\n",lvar_offset_label);
3743 #else 3743 #else
3744 printf("\taddi 1,%d,%s%d@l\n",REG_fp,lpfx,lvar_offset_label); 3744 printf("\taddi 1,%d,%s%d@l\n",REG_fp,lpfx,lvar_offset_label);
3745 #endif 3745 #endif
3746 #endif 3746 #endif
3747 if (max_freg_var>=0) { 3747 if (max_freg_var>=0) {
3748 #ifdef __APPLE__ 3748 #ifdef __APPLE__
3749 printf("\tlmw r%d,%d(%s)\n", 3749 printf("\tlmw r%d,%d(%s)\n",
3750 REG_VAR_BASE-max_reg_var,reg_save,register_name(1)); 3750 REG_VAR_BASE-max_reg_var,reg_save,register_name(1));
3751 freg_save = 72-(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*4; 3751 freg_save = 72-(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*4;
3752 printf("\tb restFP+%d ; restore f%d-f31\n", 3752 printf("\tb restFP+%d ; restore f%d-f31\n",
3753 freg_save, 3753 freg_save,
3754 FREG_VAR_BASE-max_freg_var); 3754 FREG_VAR_BASE-max_freg_var);
3755 #else 3755 #else
3756 printf("\tlmw %d,%d(%s)\n", 3756 printf("\tlmw %d,%d(%s)\n",
3757 REG_VAR_BASE-max_reg_var,reg_save,register_name(1)); 3757 REG_VAR_BASE-max_reg_var,reg_save,register_name(1));
3758 freg_save = 72-(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*4; 3758 freg_save = 72-(REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*4;
3759 printf("\tb .restFP+%d # restore f%d-f31\n", 3759 printf("\tb .restFP+%d # restore f%d-f31\n",
3760 freg_save, 3760 freg_save,
3761 FREG_VAR_BASE-max_freg_var); 3761 FREG_VAR_BASE-max_freg_var);
3762 #endif 3762 #endif
3763 } else { 3763 } else {
3764 #ifdef __APPLE__ 3764 #ifdef __APPLE__
3765 printf("\tlwz r0,8(r1)\n"); 3765 printf("\tlwz r0,8(r1)\n");
3766 printf("\tmtlr r0\n"); 3766 printf("\tmtlr r0\n");
3767 printf("\tlmw r%d,%d(r1)\n", 3767 printf("\tlmw r%d,%d(r1)\n",
3768 REG_VAR_BASE-max_reg_var,reg_save); 3768 REG_VAR_BASE-max_reg_var,reg_save);
3769 #else 3769 #else
3770 printf("\tlmw %d,%d(1)\n", 3770 printf("\tlmw %d,%d(1)\n",
3771 REG_VAR_BASE-max_reg_var,reg_save); 3771 REG_VAR_BASE-max_reg_var,reg_save);
3772 printf("\tlwz %s,4(1)\n",register_name(0)); 3772 printf("\tlwz %s,4(1)\n",register_name(0));
3773 printf("\tlwz 1,0(1)\n"); 3773 printf("\tlwz 1,0(1)\n");
3774 printf("\tmtlr %s\n",register_name(0)); 3774 printf("\tmtlr %s\n",register_name(0));
3775 #endif 3775 #endif
3776 code_ret(); 3776 code_ret();
3777 } 3777 }
3778 3778
3779 disp &= -SIZE_OF_INT; 3779 disp &= -SIZE_OF_INT;
3780 fwddef(code_setup); 3780 fwddef(code_setup);
3781 #ifdef __APPLE__ 3781 #ifdef __APPLE__
3782 printf("\tstmw %s,%d(%s)\n", 3782 printf("\tstmw %s,%d(%s)\n",
3783 register_name(REG_VAR_BASE-max_reg_var),reg_save,register_name(1)); 3783 register_name(REG_VAR_BASE-max_reg_var),reg_save,register_name(1));
3784 printf("\tstw %s,8(%s)\n",register_name(0),register_name(1)); 3784 printf("\tstw %s,8(%s)\n",register_name(0),register_name(1));
3785 #else 3785 #else
3786 printf("\tstmw %s,%d(%s)\n", 3786 printf("\tstmw %s,%d(%s)\n",
3787 register_name(REG_VAR_BASE-max_reg_var),reg_save,register_name(1)); 3787 register_name(REG_VAR_BASE-max_reg_var),reg_save,register_name(1));
3788 printf("\tstw %s,4(%s)\n",register_name(0),register_name(1)); 3788 printf("\tstw %s,4(%s)\n",register_name(0),register_name(1));
3789 #endif 3789 #endif
3790 if (max_freg_var>=0) { 3790 if (max_freg_var>=0) {
3791 #ifdef __APPLE__ 3791 #ifdef __APPLE__
3792 printf("\tb saveFP+%d ; save f%d-f31\n", 3792 printf("\tb saveFP+%d ; save f%d-f31\n",
3793 freg_save, 3793 freg_save,
3794 FREG_VAR_BASE-max_freg_var); 3794 FREG_VAR_BASE-max_freg_var);
3795 #else 3795 #else
3796 saveFP_used = 1; 3796 saveFP_used = 1;
3797 printf("\tb .saveFP+%d # save f%d-f31\n", 3797 printf("\tb .saveFP+%d # save f%d-f31\n",
3798 freg_save, 3798 freg_save,
3799 FREG_VAR_BASE-max_freg_var); 3799 FREG_VAR_BASE-max_freg_var);
3800 #endif 3800 #endif
3801 } else { 3801 } else {
3802 printf("\tblr\n"); 3802 printf("\tblr\n");
3803 } 3803 }
3804 3804
3805 code_offset_set(); 3805 code_offset_set();
3806 local_table(); 3806 local_table();
3807 labelno++; 3807 labelno++;
3810 3810
3811 3811
3812 int 3812 int
3813 code_set_return_register(int mode) { 3813 code_set_return_register(int mode) {
3814 if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) { 3814 if (cadr(fnptr->ty)==DOUBLE||cadr(fnptr->ty)==FLOAT) {
3815 set_freg(RET_FREGISTER,mode); 3815 set_freg(RET_FREGISTER,mode);
3816 return freg; 3816 return freg;
3817 } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) { 3817 } else if (cadr(fnptr->ty)==LONGLONG||cadr(fnptr->ty)==ULONGLONG) {
3818 set_lreg(RET_LREGISTER,mode); 3818 set_lreg(RET_LREGISTER,mode);
3819 return lreg; 3819 return lreg;
3820 } else if (cadr(fnptr->ty)==VOID) { 3820 } else if (cadr(fnptr->ty)==VOID) {
3821 return 0; 3821 return 0;
3822 } else { 3822 } else {
3823 set_ireg(RET_REGISTER,mode); 3823 set_ireg(RET_REGISTER,mode);
3824 return ireg; 3824 return ireg;
3825 } 3825 }
3826 } 3826 }
3827 3827
3828 int 3828 int
3829 code_get_fixed_creg(int reg,int type) { 3829 code_get_fixed_creg(int reg,int type) {
3831 } 3831 }
3832 3832
3833 void 3833 void
3834 code_set_fixed_creg(int reg,int mode,int type) { 3834 code_set_fixed_creg(int reg,int mode,int type) {
3835 if (type==FLOAT||type==DOUBLE) { 3835 if (type==FLOAT||type==DOUBLE) {
3836 set_freg(reg,mode); 3836 set_freg(reg,mode);
3837 } else if (type==LONGLONG||type==ULONGLONG) { 3837 } else if (type==LONGLONG||type==ULONGLONG) {
3838 set_lreg(reg,mode); 3838 set_lreg(reg,mode);
3839 // use_reg(reg); 3839 // use_reg(reg);
3840 } else { 3840 } else {
3841 set_ireg(reg,mode); 3841 set_ireg(reg,mode);
3842 } 3842 }
3843 } 3843 }
3844 3844
3845 void 3845 void
3846 gen_gdecl(char *n, int gpc) 3846 gen_gdecl(char *n, int gpc)
3847 { 3847 {
3848 /* 3848 /*
3849 if (stmode!=STATIC) 3849 if (stmode!=STATIC)
3850 printf(".globl _%s\n",n); 3850 printf(".globl _%s\n",n);
3851 */ 3851 */
3852 } 3852 }
3853 3853
3854 extern void 3854 extern void
3855 ascii(char *s) 3855 ascii(char *s)
3859 printf("\t.ascii \""); 3859 printf("\t.ascii \"");
3860 #else 3860 #else
3861 printf("\t.string \""); 3861 printf("\t.string \"");
3862 #endif 3862 #endif
3863 while(*s) { 3863 while(*s) {
3864 if (*s=='\n') 3864 if (*s=='\n')
3865 printf("%cn",92); 3865 printf("%cn",92);
3866 else if (*s<' ') 3866 else if (*s<' ')
3867 printf("%c%03o",92,*s); 3867 printf("%c%03o",92,*s);
3868 else if (*s=='\\') 3868 else if (*s=='\\')
3869 printf("\\\\"); 3869 printf("\\\\");
3870 else if (*s==34) 3870 else if (*s==34)
3871 printf("%c%c",92,34); 3871 printf("%c%c",92,34);
3872 else 3872 else
3873 printf("%c",*s); 3873 printf("%c",*s);
3874 s++; 3874 s++;
3875 } 3875 }
3876 printf("\\0%c\n\t.align 2\n",34); 3876 printf("\\0%c\n\t.align 2\n",34);
3877 } 3877 }
3878 3878
3879 extern int 3879 extern int
3919 void 3919 void
3920 emit_global(NMTBL *n,int a,int e) 3920 emit_global(NMTBL *n,int a,int e)
3921 { 3921 {
3922 int t = type_value(n->ty); 3922 int t = type_value(n->ty);
3923 if (e>0 && car(e)==STRING && t>0 && car(t)==ARRAY && 3923 if (e>0 && car(e)==STRING && t>0 && car(t)==ARRAY &&
3924 (type_value(cadr(t))==CHAR||type_value(cadr(t))==UCHAR)) { 3924 (type_value(cadr(t))==CHAR||type_value(cadr(t))==UCHAR)) {
3925 cstring_mode(); 3925 cstring_mode();
3926 } else 3926 } else
3927 data_mode(n->nm); 3927 data_mode(n->nm);
3928 if (n && n->sc!=STATIC) 3928 if (n && n->sc!=STATIC)
3929 printf("\t.globl\t%s%s\n",npfx,n->nm); 3929 printf("\t.globl\t%s%s\n",npfx,n->nm);
3930 printf("%s%s:\n",npfx,n->nm); 3930 printf("%s%s:\n",npfx,n->nm);
3931 } 3931 }
3932 3932
3933 extern void 3933 extern void
3934 emit_space(int sp) 3934 emit_space(int sp)
3999 extern void 3999 extern void
4000 emit_address(char *s,int offset) 4000 emit_address(char *s,int offset)
4001 { 4001 {
4002 data_mode(0); 4002 data_mode(0);
4003 if (offset) 4003 if (offset)
4004 printf("\t.long %s%s+%d\n",npfx,s,offset); 4004 printf("\t.long %s%s+%d\n",npfx,s,offset);
4005 else 4005 else
4006 printf("\t.long %s%s\n",npfx,s); 4006 printf("\t.long %s%s\n",npfx,s);
4007 } 4007 }
4008 4008
4009 extern void 4009 extern void
4010 emit_label(int labelno) 4010 emit_label(int labelno)
4011 { 4011 {
4020 int lb; 4020 int lb;
4021 #endif 4021 #endif
4022 if (mode==GDECL) { 4022 if (mode==GDECL) {
4023 #ifdef DOT_SIZE 4023 #ifdef DOT_SIZE
4024 #ifdef __APPLE__ 4024 #ifdef __APPLE__
4025 data_mode(0); 4025 data_mode(0);
4026 lb=fwdlabel(); 4026 lb=fwdlabel();
4027 printf("%s%d:\n",lpfx,lb); 4027 printf("%s%d:\n",lpfx,lb);
4028 printf("\t.size\t%s,%s%d-%%ss\n",n->nm,lb,lpfx,npfx,n->nm); 4028 printf("\t.size\t%s,%s%d-%%ss\n",n->nm,lb,lpfx,npfx,n->nm);
4029 #else 4029 #else
4030 data_mode(0); 4030 data_mode(0);
4031 lb=fwdlabel(); 4031 lb=fwdlabel();
4032 printf(".LC%d:\n",lb); 4032 printf(".LC%d:\n",lb);
4033 printf("\t.size\t%s,%s%d-%s%s\n",n->nm,lb,lpfx,npfx,n->nm); 4033 printf("\t.size\t%s,%s%d-%s%s\n",n->nm,lb,lpfx,npfx,n->nm);
4034 #endif 4034 #endif
4035 #endif 4035 #endif
4036 } 4036 }
4037 } 4037 }
4038 4038
4044 int init; char *extrn; 4044 int init; char *extrn;
4045 init=0; 4045 init=0;
4046 global_list = reversen(global_list); 4046 global_list = reversen(global_list);
4047 text_mode(0); 4047 text_mode(0);
4048 for(n = global_list;n!=&null_nptr;n = n->next) { 4048 for(n = global_list;n!=&null_nptr;n = n->next) {
4049 if ((n->sc == GVAR) && n->dsp != -1) { 4049 if ((n->sc == GVAR) && n->dsp != -1) {
4050 /* n->dsp = -1 means initialized global */ 4050 /* n->dsp = -1 means initialized global */
4051 if (init==0) { 4051 if (init==0) {
4052 // data_mode(0); 4052 // data_mode(0);
4053 text_mode(0); 4053 text_mode(0);
4054 printf("\t.align 3\n"); 4054 printf("\t.align 3\n");
4055 init=1; 4055 init=1;
4056 } 4056 }
4057 int align; 4057 int align;
4058 if ((align=attr_value(n,ALIGNED))) { 4058 if ((align=attr_value(n,ALIGNED))) {
4059 int a = ilog(caddr(align)); 4059 int a = ilog(caddr(align));
4060 printf(".comm %s%s,%d,%d\n",npfx,n->nm,size(n->ty),a); 4060 printf(".comm %s%s,%d,%d\n",npfx,n->nm,size(n->ty),a);
4061 } else if (size(n->ty)>1) { 4061 } else if (size(n->ty)>1) {
4062 printf(".comm %s%s,%d,2\n",npfx,n->nm,size(n->ty)); 4062 printf(".comm %s%s,%d,2\n",npfx,n->nm,size(n->ty));
4063 } else 4063 } else
4064 printf(".comm %s%s,%d\n",npfx,n->nm,size(n->ty)); 4064 printf(".comm %s%s,%d\n",npfx,n->nm,size(n->ty));
4065 } else if ((n->sc==STATIC) && n->dsp != -1) { 4065 } else if ((n->sc==STATIC) && n->dsp != -1) {
4066 /* n->dsp = -1 means initialized global */ 4066 /* n->dsp = -1 means initialized global */
4067 if (is_code(n)||is_function(n)) continue; 4067 if (is_code(n)||is_function(n)) continue;
4068 if (init==0) { 4068 if (init==0) {
4069 text_mode(0); 4069 text_mode(0);
4070 printf("\t.align 8\n"); 4070 printf("\t.align 8\n");
4071 // data_mode(0); 4071 // data_mode(0);
4072 init=1; 4072 init=1;
4073 } 4073 }
4074 printf(".lcomm %s%s,%d\n",npfx,n->nm,size(n->ty)); 4074 printf(".lcomm %s%s,%d\n",npfx,n->nm,size(n->ty));
4075 } 4075 }
4076 } 4076 }
4077 for(n = global_list;n!=&null_nptr;n = n->next) { 4077 for(n = global_list;n!=&null_nptr;n = n->next) {
4078 if (is_code(n)||is_function(n)) { 4078 if (is_code(n)||is_function(n)) {
4079 extrn = n->nm; 4079 extrn = n->nm;
4080 if (n->sc==EXTRN1) { 4080 if (n->sc==EXTRN1) {
4081 data_mode(0); 4081 data_mode(0);
4082 printf(".picsymbol_stub\n"); 4082 printf(".picsymbol_stub\n");
4083 printf("L_%s$stub:\n",extrn); 4083 printf("L_%s$stub:\n",extrn);
4084 printf("\t.indirect_symbol _%s\n",extrn); 4084 printf("\t.indirect_symbol _%s\n",extrn);
4085 printf("\tmflr r0\n"); 4085 printf("\tmflr r0\n");
4086 printf("\tbcl 20,31,L0$_%s\n",extrn); 4086 printf("\tbcl 20,31,L0$_%s\n",extrn);
4095 printf(".data\n"); 4095 printf(".data\n");
4096 printf(".lazy_symbol_pointer\n"); 4096 printf(".lazy_symbol_pointer\n");
4097 printf("L_%s$lazy_ptr:\n",extrn); 4097 printf("L_%s$lazy_ptr:\n",extrn);
4098 printf("\t.indirect_symbol _%s\n",extrn); 4098 printf("\t.indirect_symbol _%s\n",extrn);
4099 printf("\t.long dyld_stub_binding_helper\n"); 4099 printf("\t.long dyld_stub_binding_helper\n");
4100 } else if (n->sc==STATIC) { 4100 } else if (n->sc==STATIC) {
4101 text_mode(0); 4101 text_mode(0);
4102 printf("\t.set L_%s$stub,_%s\n",extrn,extrn); 4102 printf("\t.set L_%s$stub,_%s\n",extrn,extrn);
4103 data_mode(0); 4103 data_mode(0);
4104 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",extrn,extrn); 4104 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",extrn,extrn);
4105 } 4105 }
4106 } 4106 }
4107 } 4107 }
4108 init=0; 4108 init=0;
4109 for(n = global_list;n!=&null_nptr;n = n->next) { 4109 for(n = global_list;n!=&null_nptr;n = n->next) {
4110 if (n->sc == GVAR) { 4110 if (n->sc == GVAR) {
4111 if (init==0) { 4111 if (init==0) {
4112 printf(".data\n"); 4112 printf(".data\n");
4113 init=1; 4113 init=1;
4114 } 4114 }
4115 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",n->nm,n->nm); 4115 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",n->nm,n->nm);
4116 } 4116 }
4117 } 4117 }
4118 init = 0; 4118 init = 0;
4119 for(n = global_list;n!=&null_nptr;n = n->next) { 4119 for(n = global_list;n!=&null_nptr;n = n->next) {
4120 if ((is_code(n)||is_function(n))&& 4120 if ((is_code(n)||is_function(n))&&
4121 !has_attr(n,FNAME)) // not used as value 4121 !has_attr(n,FNAME)) // not used as value
4122 continue; 4122 continue;
4123 if (n->sc==EXTRN1) { 4123 if (n->sc==EXTRN1) {
4124 if(init==0) { 4124 if(init==0) {
4125 printf(".data\n"); 4125 printf(".data\n");
4126 printf(".non_lazy_symbol_pointer\n"); 4126 printf(".non_lazy_symbol_pointer\n");
4127 init=1; 4127 init=1;
4128 } 4128 }
4129 printf("L_%s$non_lazy_ptr:\n",n->nm); 4129 printf("L_%s$non_lazy_ptr:\n",n->nm);
4130 printf("\t.indirect_symbol _%s\n",n->nm); 4130 printf("\t.indirect_symbol _%s\n",n->nm);
4131 printf("\t.long\t0\n"); 4131 printf("\t.long\t0\n");
4132 } 4132 }
4133 } 4133 }
4134 } 4134 }
4135 #else 4135 #else
4136 4136
4137 static void 4137 static void
4138 comm(NMTBL *n) 4138 comm(NMTBL *n)
4139 { 4139 {
4140 int align = 1; 4140 int align = 1;
4141 if ((align=attr_value(n,ALIGNED))) { 4141 if ((align=attr_value(n,ALIGNED))) {
4142 align = ilog(caddr(align)); 4142 align = ilog(caddr(align));
4143 } else { 4143 } else {
4144 if (size(n->ty)>4) 4144 if (size(n->ty)>4)
4145 align = 2; 4145 align = 2;
4146 else if (size(n->ty)>4) 4146 else if (size(n->ty)>4)
4147 align = 0; 4147 align = 0;
4148 switch(n->ty) { 4148 switch(n->ty) {
4149 case DOUBLE: 4149 case DOUBLE:
4150 case LONGLONG: 4150 case LONGLONG:
4151 case ULONGLONG: 4151 case ULONGLONG:
4152 align = 8; break; 4152 align = 8; break;
4153 case INT: 4153 case INT:
4154 case UNSIGNED: 4154 case UNSIGNED:
4155 case FLOAT: 4155 case FLOAT:
4156 align = 4; break; 4156 align = 4; break;
4157 case SHORT: 4157 case SHORT:
4158 case USHORT: 4158 case USHORT:
4159 align = 2; break; 4159 align = 2; break;
4160 } 4160 }
4161 } 4161 }
4162 printf("\t.comm %s,%d,%d\n",n->nm,size(n->ty),align); 4162 printf("\t.comm %s,%d,%d\n",n->nm,size(n->ty),align);
4163 } 4163 }
4164 4164
4165 void 4165 void
4198 NMTBL *n; 4198 NMTBL *n;
4199 int init; 4199 int init;
4200 init=0; 4200 init=0;
4201 /* static local variables */ 4201 /* static local variables */
4202 for(n = local_static_list;n!=&null_nptr;n = n->next) { 4202 for(n = local_static_list;n!=&null_nptr;n = n->next) {
4203 if (n->sc == STATIC) { 4203 if (n->sc == STATIC) {
4204 if (init==0) { 4204 if (init==0) {
4205 data_mode(0); 4205 data_mode(0);
4206 init=1; 4206 init=1;
4207 } 4207 }
4208 if (n->dsp != -1) /* initialized static */ 4208 if (n->dsp != -1) /* initialized static */
4209 printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); 4209 printf(".lcomm _%s,%d\n",n->nm,size(n->ty));
4210 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",n->nm,n->nm); 4210 printf("L_%s$non_lazy_ptr:\n\t.long\t_%s\n",n->nm,n->nm);
4211 } 4211 }
4212 } 4212 }
4213 } 4213 }
4214 #else 4214 #else
4215 void 4215 void
4216 local_table(void) 4216 local_table(void)
4218 NMTBL *n; 4218 NMTBL *n;
4219 int init; 4219 int init;
4220 init=0; 4220 init=0;
4221 /* static local variables */ 4221 /* static local variables */
4222 for(n = local_static_list;n!=&null_nptr;n = n->next) { 4222 for(n = local_static_list;n!=&null_nptr;n = n->next) {
4223 if (n->sc == STATIC) { 4223 if (n->sc == STATIC) {
4224 if (init==0) { 4224 if (init==0) {
4225 data_mode(0); 4225 data_mode(0);
4226 init=1; 4226 init=1;
4227 } 4227 }
4228 if (n->dsp != -1) /* initialized static */ 4228 if (n->dsp != -1) /* initialized static */
4229 printf(".lcomm %s,%d\n",n->nm,size(n->ty)); 4229 printf(".lcomm %s,%d\n",n->nm,size(n->ty));
4230 } 4230 }
4231 } 4231 }
4232 } 4232 }
4233 #endif 4233 #endif
4234 4234
4235 void 4235 void
4247 4247
4248 void 4248 void
4249 text_mode(int align) 4249 text_mode(int align)
4250 { 4250 {
4251 if (output_mode!=TEXT_EMIT_MODE) { 4251 if (output_mode!=TEXT_EMIT_MODE) {
4252 printf(".text\n"); 4252 printf(".text\n");
4253 printf("\t.align 2\n"); 4253 printf("\t.align 2\n");
4254 output_mode = TEXT_EMIT_MODE; 4254 output_mode = TEXT_EMIT_MODE;
4255 } 4255 }
4256 } 4256 }
4257 4257
4258 void 4258 void
4259 data_mode(char *name) 4259 data_mode(char *name)
4260 { 4260 {
4261 if (output_mode!=DATA_EMIT_MODE) { 4261 if (output_mode!=DATA_EMIT_MODE) {
4262 printf(".data\n"); 4262 printf(".data\n");
4263 output_mode = DATA_EMIT_MODE; 4263 output_mode = DATA_EMIT_MODE;
4264 } 4264 }
4265 /* 4265 /*
4266 if (name) 4266 if (name)
4267 printf("\t.type\t%s,@object\n",name); 4267 printf("\t.type\t%s,@object\n",name);
4268 */ 4268 */
4269 } 4269 }
4270 4270
4271 #if FLOAT_CODE 4271 #if FLOAT_CODE
4272 4272
4328 void 4328 void
4329 code_dregister(int e2,int freg,int d) 4329 code_dregister(int e2,int freg,int d)
4330 { 4330 {
4331 use_float(d,freg); 4331 use_float(d,freg);
4332 if (freg!=e2) { 4332 if (freg!=e2) {
4333 if (is_int_reg(e2)) error(-1); 4333 if (is_int_reg(e2)) error(-1);
4334 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); 4334 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2));
4335 } 4335 }
4336 } 4336 }
4337 4337
4338 void 4338 void
4339 code_dassign_gvar(int e2,int freg,int d) 4339 code_dassign_gvar(int e2,int freg,int d)
4340 { 4340 {
4341 use_float(d,freg); 4341 use_float(d,freg);
4342 code_ldf(fstore(d),fregister_name(freg),cadr(e2), 4342 code_ldf(fstore(d),fregister_name(freg),cadr(e2),
4343 get_ptr_cache(ncaddr(e2))); 4343 get_ptr_cache(ncaddr(e2)));
4344 } 4344 }
4345 4345
4346 void 4346 void
4347 code_dassign_lvar(int e2,int freg,int d) 4347 code_dassign_lvar(int e2,int freg,int d)
4348 { 4348 {
4361 4361
4362 void 4362 void
4363 code_dassign_dregister(int e2,int d,int freg) { 4363 code_dassign_dregister(int e2,int d,int freg) {
4364 use_float(d,freg); 4364 use_float(d,freg);
4365 if (e2!=freg) { 4365 if (e2!=freg) {
4366 printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg)); 4366 printf("\tfmr %s,%s\n",fregister_name(e2),fregister_name(freg));
4367 } 4367 }
4368 } 4368 }
4369 4369
4370 static double d0 = 1.0; 4370 static double d0 = 1.0;
4371 4371
4396 long d = (long) arg; 4396 long d = (long) arg;
4397 printf(" \t.data\n\t.align 3\n"); 4397 printf(" \t.data\n\t.align 3\n");
4398 printf("%s%d:\n",lpfx,lb); 4398 printf("%s%d:\n",lpfx,lb);
4399 if (d) { 4399 if (d) {
4400 #if ENDIAN_D==0 4400 #if ENDIAN_D==0
4401 printf("\t.long\t0x%x,0x%x\n",code_d1(value->d),code_d2(value->d)); 4401 printf("\t.long\t0x%x,0x%x\n",code_d1(value->d),code_d2(value->d));
4402 #else 4402 #else
4403 printf("\t.long\t0x%x,0x%x\n",code_d2(value->d),code_d1(value->d)); 4403 printf("\t.long\t0x%x,0x%x\n",code_d2(value->d),code_d1(value->d));
4404 #endif 4404 #endif
4405 } else { 4405 } else {
4406 printf("\t.long\t0x%x\n",code_f(value->f)); 4406 printf("\t.long\t0x%x\n",code_f(value->f));
4407 } 4407 }
4408 if (output_mode==TEXT_EMIT_MODE) { 4408 if (output_mode==TEXT_EMIT_MODE) {
4409 printf(".text\n"); 4409 printf(".text\n");
4410 } else { 4410 } else {
4411 text_mode(0); 4411 text_mode(0);
4412 } 4412 }
4413 } 4413 }
4414 4414
4415 /* load double / float const 4415 /* load double / float const
4416 we should keep what constant we have create 4416 we should keep what constant we have create
4425 int r; 4425 int r;
4426 char *rrn,*frn; 4426 char *rrn,*frn;
4427 use_float(d,freg); 4427 use_float(d,freg);
4428 frn = fregister_name(freg); 4428 frn = fregister_name(freg);
4429 if (value.d==0.0) { 4429 if (value.d==0.0) {
4430 float_zero_lib_used=1; 4430 float_zero_lib_used=1;
4431 r = get_ptr_cache(&float_zero); 4431 r = get_ptr_cache(&float_zero);
4432 rrn = register_name(r); 4432 rrn = register_name(r);
4433 printf("\tlfs %s,0(%s)\n",frn,rrn); 4433 printf("\tlfs %s,0(%s)\n",frn,rrn);
4434 return; 4434 return;
4435 } 4435 }
4436 if (value.d==1.0) { 4436 if (value.d==1.0) {
4437 float_one_lib_used=1; 4437 float_one_lib_used=1;
4438 r = get_ptr_cache(&float_one); 4438 r = get_ptr_cache(&float_one);
4439 rrn = register_name(r); 4439 rrn = register_name(r);
4440 printf("\tlfs %s,0(%s)\n",frn,rrn); 4440 printf("\tlfs %s,0(%s)\n",frn,rrn);
4441 return; 4441 return;
4442 } 4442 }
4443 if (d) { 4443 if (d) {
4444 sz = sizeof(double); 4444 sz = sizeof(double);
4445 } else { 4445 } else {
4446 sz = sizeof(float); 4446 sz = sizeof(float);
4452 4452
4453 rrn = register_name((r=get_register())); 4453 rrn = register_name((r=get_register()));
4454 // use_reg(r); // to clear ptr cache 4454 // use_reg(r); // to clear ptr cache
4455 code_label_value(lb,r); 4455 code_label_value(lb,r);
4456 if (d) { 4456 if (d) {
4457 printf("\tlfd %s,0(%s)\n",frn,rrn); 4457 printf("\tlfd %s,0(%s)\n",frn,rrn);
4458 } else { 4458 } else {
4459 printf("\tlfs %s,0(%s)\n",frn,rrn); 4459 printf("\tlfs %s,0(%s)\n",frn,rrn);
4460 } 4460 }
4461 free_register(r); 4461 free_register(r);
4462 } 4462 }
4463 4463
4464 void 4464 void
4496 printf(" \t.data\n\t.align 3\n"); 4496 printf(" \t.data\n\t.align 3\n");
4497 lb=fwdlabel(); 4497 lb=fwdlabel();
4498 printf("L_%d:\n",lb); 4498 printf("L_%d:\n",lb);
4499 if (d) { 4499 if (d) {
4500 #if ENDIAN_D==0 4500 #if ENDIAN_D==0
4501 printf("\t.long\t0x%x,0x%x\n",0,0x7ff00000); 4501 printf("\t.long\t0x%x,0x%x\n",0,0x7ff00000);
4502 #else 4502 #else
4503 printf("\t.long\t0x%x,0x%x\n",0x7ff00000,0); 4503 printf("\t.long\t0x%x,0x%x\n",0x7ff00000,0);
4504 #endif 4504 #endif
4505 } else { 4505 } else {
4506 printf("\t.long\t0x%x\n",0x7f800000); 4506 printf("\t.long\t0x%x\n",0x7f800000);
4507 } 4507 }
4508 if (output_mode==TEXT_EMIT_MODE) { 4508 if (output_mode==TEXT_EMIT_MODE) {
4509 printf(".text\n"); 4509 printf(".text\n");
4510 } else { 4510 } else {
4511 text_mode(0); 4511 text_mode(0);
4512 } 4512 }
4513 code_label_value(lb,r); 4513 code_label_value(lb,r);
4514 if (d) { 4514 if (d) {
4515 printf("\tlfd %s,0(%s)\n",frn,rrn); 4515 printf("\tlfd %s,0(%s)\n",frn,rrn);
4516 } else { 4516 } else {
4517 printf("\tlfs %s,0(%s)\n",frn,rrn); 4517 printf("\tlfs %s,0(%s)\n",frn,rrn);
4518 } 4518 }
4519 free_register(r); 4519 free_register(r);
4520 } 4520 }
4521 4521
4522 void 4522 void
4785 void 4785 void
4786 code_drgvar(int e2,int d,int freg) 4786 code_drgvar(int e2,int d,int freg)
4787 { 4787 {
4788 use_float(d,freg); 4788 use_float(d,freg);
4789 code_ldf(fload(d),fregister_name(freg),cadr(e2), 4789 code_ldf(fload(d),fregister_name(freg),cadr(e2),
4790 get_ptr_cache(ncaddr(e2))); 4790 get_ptr_cache(ncaddr(e2)));
4791 } 4791 }
4792 4792
4793 4793
4794 void 4794 void
4795 code_drlvar(int e2,int d,int freg) 4795 code_drlvar(int e2,int d,int freg)
4808 4808
4809 use_float(d,reg); 4809 use_float(d,reg);
4810 frn=fregister_name(reg); 4810 frn=fregister_name(reg);
4811 4811
4812 code_ldf(fload(1),grn,cadr(e2), 4812 code_ldf(fload(1),grn,cadr(e2),
4813 get_ptr_cache(ncaddr(e2))); 4813 get_ptr_cache(ncaddr(e2)));
4814 inc_cmpflag(); 4814 inc_cmpflag();
4815 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn); 4815 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn);
4816 free_register(g); 4816 free_register(g);
4817 jcond(label,cond); 4817 jcond(label,cond);
4818 } 4818 }
4863 case DDIV: opn="fdiv"; break; 4863 case DDIV: opn="fdiv"; break;
4864 case FMUL: 4864 case FMUL:
4865 case DMUL: opn="fmul"; break; 4865 case DMUL: opn="fmul"; break;
4866 case FCMP: 4866 case FCMP:
4867 case DCMP: 4867 case DCMP:
4868 inc_cmpflag(); 4868 inc_cmpflag();
4869 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn); 4869 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn);
4870 if (ox!=-1) free_register(ox); 4870 if (ox!=-1) free_register(ox);
4871 return; 4871 return;
4872 case FCMPGE: 4872 case FCMPGE:
4873 case DCMPGE: 4873 case DCMPGE:
4874 inc_cmpflag(); 4874 inc_cmpflag();
4875 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn); 4875 printf("\tfcmpu %s,%s,%s\n",crname(cmpflag),frn,grn);
4876 if (ox!=-1) free_register(ox); 4876 if (ox!=-1) free_register(ox);
4877 return; 4877 return;
4878 default: 4878 default:
4879 error(-1); return; 4879 error(-1); return;
4880 } 4880 }
4881 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); 4881 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
4882 if (ox!=-1) free_register(ox); 4882 if (ox!=-1) free_register(ox);
4883 } 4883 }
4884 4884
4926 code_dpreinc(int e1,int e2,int d,int reg) { 4926 code_dpreinc(int e1,int e2,int d,int reg) {
4927 char *frn,*crn,*grn; 4927 char *frn,*crn,*grn;
4928 int g; 4928 int g;
4929 4929
4930 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { 4930 if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
4931 crn=register_name(cadr(e2)); 4931 crn=register_name(cadr(e2));
4932 grn = fregister_name(g = code_dload_1(d)); 4932 grn = fregister_name(g = code_dload_1(d));
4933 if (reg==USE_CREG) { 4933 if (reg==USE_CREG) {
4934 reg=get_dregister(d); if (!reg) error(-1); 4934 reg=get_dregister(d); if (!reg) error(-1);
4935 set_freg(reg,0); 4935 set_freg(reg,0);
4936 } 4936 }
4937 frn=fregister_name(reg); 4937 frn=fregister_name(reg);
4938 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",crn,crn,grn); 4938 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",crn,crn,grn);
4939 if (use && reg!=cadr(e2)) 4939 if (use && reg!=cadr(e2))
4940 printf("\tfmr %s,%s\n",frn,crn); 4940 printf("\tfmr %s,%s\n",frn,crn);
4941 } else { 4941 } else {
4942 g_expr(e2); 4942 g_expr(e2);
4943 if (!is_int_reg(creg)) error(-1); 4943 if (!is_int_reg(creg)) error(-1);
4944 crn=register_name(ireg); 4944 crn=register_name(ireg);
4945 if (reg==USE_CREG) { 4945 if (reg==USE_CREG) {
4946 reg=get_dregister(d); if (!reg) error(-1); 4946 reg=get_dregister(d); if (!reg) error(-1);
4947 set_freg(reg,0); 4947 set_freg(reg,0);
4948 } 4948 }
4949 frn=fregister_name(reg); 4949 frn=fregister_name(reg);
4950 grn = fregister_name(g = code_dload_1(d)); 4950 grn = fregister_name(g = code_dload_1(d));
4951 printf("\t%s %s,0(%s)\n",fload(d),frn,crn); 4951 printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
4952 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",frn,frn,grn); 4952 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",frn,frn,grn);
4953 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); 4953 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn);
4954 } 4954 }
4955 free_register(g); 4955 free_register(g);
4956 } 4956 }
4957 4957
4958 void 4958 void
4959 code_dpostinc(int e1,int e2,int d,int reg) { 4959 code_dpostinc(int e1,int e2,int d,int reg) {
4960 char *frn,*crn,*grn; 4960 char *frn,*crn,*grn;
4961 int g; 4961 int g;
4962 4962
4963 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { 4963 if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
4964 crn=register_name(cadr(e2)); 4964 crn=register_name(cadr(e2));
4965 grn = fregister_name(g = code_dload_1(d)); 4965 grn = fregister_name(g = code_dload_1(d));
4966 if (reg==USE_CREG) { 4966 if (reg==USE_CREG) {
4967 reg=get_dregister(d); if (!reg) error(-1); 4967 reg=get_dregister(d); if (!reg) error(-1);
4968 set_freg(reg,0); 4968 set_freg(reg,0);
4969 } 4969 }
4970 frn=fregister_name(reg); 4970 frn=fregister_name(reg);
4971 if (use && reg!=cadr(e2)) 4971 if (use && reg!=cadr(e2))
4972 printf("\tfmr %s,%s\n",frn,crn); 4972 printf("\tfmr %s,%s\n",frn,crn);
4973 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",crn,crn,grn); 4973 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",crn,crn,grn);
4974 } else { 4974 } else {
4975 g_expr(e2); 4975 g_expr(e2);
4976 if (!is_int_reg(creg)) error(-1); 4976 if (!is_int_reg(creg)) error(-1);
4977 crn=register_name(ireg); 4977 crn=register_name(ireg);
4978 if (reg==USE_CREG) { 4978 if (reg==USE_CREG) {
4979 reg=get_dregister(d); if (!reg) error(-1); 4979 reg=get_dregister(d); if (!reg) error(-1);
4980 set_freg(reg,0); 4980 set_freg(reg,0);
4981 } 4981 }
4982 frn=fregister_name(reg); 4982 frn=fregister_name(reg);
4983 grn = fregister_name(g = code_dload_1(d)); 4983 grn = fregister_name(g = code_dload_1(d));
4984 printf("\t%s %s,0(%s)\n",fload(d),frn,crn); 4984 printf("\t%s %s,0(%s)\n",fload(d),frn,crn);
4985 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",grn,frn,grn); 4985 printf("\t%s %s,%s,%s\n",(caddr(e1)>0)?"fadd":"fsub",grn,frn,grn);
4986 printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); 4986 printf("\t%s %s,0(%s)\n",fstore(d),grn,crn);
4987 } 4987 }
4988 free_register(g); 4988 free_register(g);
4989 } 4989 }
4990 4990
4991 static int 4991 static int
5005 g_expr(list3(DCMP,cadr(e1),caddr(e1))); 5005 g_expr(list3(DCMP,cadr(e1),caddr(e1)));
5006 use_int(reg); 5006 use_int(reg);
5007 rn = register_name(reg); 5007 rn = register_name(reg);
5008 t = CRBITSIZ*cmpflag; 5008 t = CRBITSIZ*cmpflag;
5009 if (eq>0) { 5009 if (eq>0) {
5010 printf("\tcror %d,%d,%d\n",t+flag-1,t+eq-1,t+flag-1); 5010 printf("\tcror %d,%d,%d\n",t+flag-1,t+eq-1,t+flag-1);
5011 } 5011 }
5012 if (neg>0) { 5012 if (neg>0) {
5013 neg = t+neg-1, 5013 neg = t+neg-1,
5014 printf("\tcrnor %d,%d,%d\n",neg,neg,neg); 5014 printf("\tcrnor %d,%d,%d\n",neg,neg,neg);
5015 } 5015 }
5016 printf("\tmfcr %s\n",rn); 5016 printf("\tmfcr %s\n",rn);
5017 printf("\trlwinm %s,%s,%d,1\n",rn,rn,t+flag); 5017 printf("\trlwinm %s,%s,%d,1\n",rn,rn,t+flag);
5018 return 1; 5018 return 1;
5019 } 5019 }
5020 5020
5021 int 5021 int
5022 drexpr(int e1, int e2,int l1, int op,int cond) 5022 drexpr(int e1, int e2,int l1, int op,int cond)
5023 { 5023 {
5024 if (!cond) { 5024 if (!cond) {
5025 switch(op) { 5025 switch(op) {
5026 case FOP+GT: 5026 case FOP+GT:
5027 return drexpr(e2,e1,l1,FOP+GE,1); 5027 return drexpr(e2,e1,l1,FOP+GE,1);
5028 case FOP+GE: 5028 case FOP+GE:
5029 return drexpr(e2,e1,l1,FOP+GT,1); 5029 return drexpr(e2,e1,l1,FOP+GT,1);
5030 case FOP+EQ: 5030 case FOP+EQ:
5031 op=FOP+NEQ; break; 5031 op=FOP+NEQ; break;
5032 case FOP+NEQ: 5032 case FOP+NEQ:
5033 op=FOP+EQ; break; 5033 op=FOP+EQ; break;
5034 case DOP+GT: 5034 case DOP+GT:
5035 return drexpr(e2,e1,l1,DOP+GE,1); 5035 return drexpr(e2,e1,l1,DOP+GE,1);
5036 case DOP+GE: 5036 case DOP+GE:
5037 return drexpr(e2,e1,l1,DOP+GT,1); 5037 return drexpr(e2,e1,l1,DOP+GT,1);
5038 case DOP+EQ: 5038 case DOP+EQ:
5039 op=DOP+NEQ; break; 5039 op=DOP+NEQ; break;
5040 case DOP+NEQ: 5040 case DOP+NEQ:
5041 op=DOP+EQ; break; 5041 op=DOP+EQ; break;
5042 } 5042 }
5043 } 5043 }
5044 g_expr(list3(DCMP, e1,e2)); 5044 g_expr(list3(DCMP, e1,e2));
5045 switch(op) { 5045 switch(op) {
5046 case DOP+GT: case FOP+GT: 5046 case DOP+GT: case FOP+GT:
5047 printf("\tbgt\t%s,%s%d\n",crname(cmpflag),lpfx,l1); 5047 printf("\tbgt\t%s,%s%d\n",crname(cmpflag),lpfx,l1);
5048 break; 5048 break;
5049 case DOP+GE: case FOP+GE: 5049 case DOP+GE: case FOP+GE:
5050 printf("\tbge\t%s,%s%d\n",crname(cmpflag),lpfx,l1); 5050 printf("\tbge\t%s,%s%d\n",crname(cmpflag),lpfx,l1);
5051 break; 5051 break;
5052 case DOP+EQ: case FOP+EQ: 5052 case DOP+EQ: case FOP+EQ:
5053 printf("\tbeq\t%s,%s%d\n",crname(cmpflag),lpfx,l1); 5053 printf("\tbeq\t%s,%s%d\n",crname(cmpflag),lpfx,l1);
5054 break; 5054 break;
5055 case DOP+NEQ: case FOP+NEQ: 5055 case DOP+NEQ: case FOP+NEQ:
5056 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,l1); 5056 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,l1);
5057 break; 5057 break;
5058 } 5058 }
5059 return l1; 5059 return l1;
5060 } 5060 }
5061 5061
5062 int emit_dpop(int d) 5062 int emit_dpop(int d)
5063 { 5063 {
5064 int xreg,reg; 5064 int xreg,reg;
5065 xreg=pop_fregister(); 5065 xreg=pop_fregister();
5066 if (xreg<= -REG_LVAR_OFFSET) { 5066 if (xreg<= -REG_LVAR_OFFSET) {
5067 reg = get_dregister(d); 5067 reg = get_dregister(d);
5068 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); 5068 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg);
5069 free_lvar(REG_LVAR_OFFSET+xreg); 5069 free_lvar(REG_LVAR_OFFSET+xreg);
5070 xreg=reg; 5070 xreg=reg;
5071 } 5071 }
5072 return xreg; 5072 return xreg;
5073 } 5073 }
5074 5074
5075 void 5075 void
5076 emit_dpop_free(int e1,int d) 5076 emit_dpop_free(int e1,int d)
5077 { 5077 {
5078 if (e1>=0 && e1!=creg && regs[e1]!=REG_VAR) 5078 if (e1>=0 && e1!=creg && regs[e1]!=REG_VAR)
5079 free_register(e1); 5079 free_register(e1);
5080 } 5080 }
5081 5081
5082 void 5082 void
5083 emit_dpush(int d) 5083 emit_dpush(int d)
5084 { 5084 {
5099 static void 5099 static void
5100 lmove(int to,int from) // to <= from 5100 lmove(int to,int from) // to <= from
5101 { 5101 {
5102 int tmp; 5102 int tmp;
5103 if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) { 5103 if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) {
5104 tmp = get_register(); 5104 tmp = get_register();
5105 printf("\tmr %s,%s\n",register_name(tmp),lregister_name_low(from)); 5105 printf("\tmr %s,%s\n",register_name(tmp),lregister_name_low(from));
5106 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from)); 5106 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from));
5107 printf("\tmr %s,%s\n",lregister_name_low(to),register_name(tmp)); 5107 printf("\tmr %s,%s\n",lregister_name_low(to),register_name(tmp));
5108 free_register(tmp); 5108 free_register(tmp);
5109 } else if (regv_h(to)==regv_l(from)) { 5109 } else if (regv_h(to)==regv_l(from)) {
5110 printf("\tmr %s,%s\n",lregister_name_low(to),lregister_name_low(from)); 5110 printf("\tmr %s,%s\n",lregister_name_low(to),lregister_name_low(from));
5111 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from)); 5111 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from));
5112 } else { 5112 } else {
5113 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from)); 5113 printf("\tmr %s,%s\n",lregister_name_high(to),lregister_name_high(from));
5114 printf("\tmr %s,%s\n",lregister_name_low(to),lregister_name_low(from)); 5114 printf("\tmr %s,%s\n",lregister_name_low(to),lregister_name_low(from));
5115 } 5115 }
5116 } 5116 }
5117 5117
5118 static void 5118 static void
5119 pcond(char *s,int cmpflag,int l1) 5119 pcond(char *s,int cmpflag,int l1)
5156 l2 = fwdlabel(); 5156 l2 = fwdlabel();
5157 // cond==0 jump on false condtion ( if(x) => rexpr(.. cond=0 ...) ) 5157 // cond==0 jump on false condtion ( if(x) => rexpr(.. cond=0 ...) )
5158 switch(op+(!cond)*BNOT) { 5158 switch(op+(!cond)*BNOT) {
5159 case LOP+GT: 5159 case LOP+GT:
5160 case LOP+GE: 5160 case LOP+GE:
5161 pcond(code_gt(1),cr0,1?l1:l2); 5161 pcond(code_gt(1),cr0,1?l1:l2);
5162 pcond(code_eq(0),cr0,1?l2:l1); 5162 pcond(code_eq(0),cr0,1?l2:l1);
5163 break; 5163 break;
5164 case LOP+UGT: 5164 case LOP+UGT:
5165 case LOP+UGE: 5165 case LOP+UGE:
5166 pcond(code_ugt(1),cr0,1?l1:l2); 5166 pcond(code_ugt(1),cr0,1?l1:l2);
5167 pcond(code_eq(0), cr0,1?l2:l1); 5167 pcond(code_eq(0), cr0,1?l2:l1);
5168 break; 5168 break;
5169 case LOP+EQ: 5169 case LOP+EQ:
5170 pcond(code_eq(0),cr0,(1?l2:l1)); 5170 pcond(code_eq(0),cr0,(1?l2:l1));
5171 pcond(code_eq(cond),cr1,l1); 5171 pcond(code_eq(cond),cr1,l1);
5172 break; 5172 break;
5173 case LOP+NEQ: 5173 case LOP+NEQ:
5174 pcond(code_eq(0),cr0,(1?l1:l2)); 5174 pcond(code_eq(0),cr0,(1?l1:l2));
5175 pcond(code_eq(!1),cr1,l1); 5175 pcond(code_eq(!1),cr1,l1);
5176 break; 5176 break;
5177 case LOP+GT+BNOT: 5177 case LOP+GT+BNOT:
5178 case LOP+GE+BNOT: 5178 case LOP+GE+BNOT:
5179 pcond(code_gt(1),cr0,0?l1:l2); 5179 pcond(code_gt(1),cr0,0?l1:l2);
5180 pcond(code_eq(0),cr0,0?l2:l1); 5180 pcond(code_eq(0),cr0,0?l2:l1);
5181 break; 5181 break;
5182 case LOP+UGT+BNOT: 5182 case LOP+UGT+BNOT:
5183 case LOP+UGE+BNOT: 5183 case LOP+UGE+BNOT:
5184 pcond(code_ugt(1),cr0,0?l1:l2); 5184 pcond(code_ugt(1),cr0,0?l1:l2);
5185 pcond(code_eq(0), cr0,0?l2:l1); 5185 pcond(code_eq(0), cr0,0?l2:l1);
5186 break; 5186 break;
5187 case LOP+EQ+BNOT: 5187 case LOP+EQ+BNOT:
5188 pcond(code_eq(0),cr0,(0?l2:l1)); 5188 pcond(code_eq(0),cr0,(0?l2:l1));
5189 pcond(code_eq(0),cr1,l1); 5189 pcond(code_eq(0),cr1,l1);
5190 break; 5190 break;
5191 case LOP+NEQ+BNOT: 5191 case LOP+NEQ+BNOT:
5192 pcond(code_eq(0),cr0,(0?l1:l2)); 5192 pcond(code_eq(0),cr0,(0?l1:l2));
5193 pcond(code_eq(!0),cr1,l1); 5193 pcond(code_eq(!0),cr1,l1);
5194 break; 5194 break;
5195 default: 5195 default:
5196 error(-1); 5196 error(-1);
5197 } 5197 }
5198 switch(op+BNOT*(!cond)) { 5198 switch(op+BNOT*(!cond)) {
5199 case LOP+GT: pcond(code_gt(1), cr1,l1); break; 5199 case LOP+GT: pcond(code_gt(1), cr1,l1); break;
5200 case LOP+GE: pcond(code_ge(1), cr1,l1); break; 5200 case LOP+GE: pcond(code_ge(1), cr1,l1); break;
5201 case LOP+UGT: pcond(code_ugt(1), cr1,l1); break; 5201 case LOP+UGT: pcond(code_ugt(1), cr1,l1); break;
5227 void 5227 void
5228 code_lregister(int e2,int reg) 5228 code_lregister(int e2,int reg)
5229 { 5229 {
5230 use_longlong(reg); 5230 use_longlong(reg);
5231 if (reg!=e2) { 5231 if (reg!=e2) {
5232 lmove(reg,e2); 5232 lmove(reg,e2);
5233 } 5233 }
5234 } 5234 }
5235 5235
5236 void 5236 void
5237 code_cmp_lregister(int reg,int label,int cond) 5237 code_cmp_lregister(int reg,int label,int cond)
5238 { 5238 {
5239 use_longlong(reg); 5239 use_longlong(reg);
5240 printf("\tor %s,%s,%s\n", 5240 printf("\tor %s,%s,%s\n",
5241 lregister_name_low(reg), 5241 lregister_name_low(reg),
5242 lregister_name_low(reg), 5242 lregister_name_low(reg),
5243 lregister_name_high(reg)); 5243 lregister_name_high(reg));
5244 inc_cmpflag(); 5244 inc_cmpflag();
5245 printf("\tcmpwi %s,%s,0\n",crname(cmpflag),lregister_name_low(reg)); 5245 printf("\tcmpwi %s,%s,0\n",crname(cmpflag),lregister_name_low(reg));
5246 jcond(label,cond); 5246 jcond(label,cond);
5247 } 5247 }
5248 5248
5318 void 5318 void
5319 code_lassign_lregister(int e2,int reg) 5319 code_lassign_lregister(int e2,int reg)
5320 { 5320 {
5321 use_longlong(reg); 5321 use_longlong(reg);
5322 if (e2!=reg) { 5322 if (e2!=reg) {
5323 lmove(e2,reg); 5323 lmove(e2,reg);
5324 } 5324 }
5325 } 5325 }
5326 5326
5327 static long long ll0 = 1LL; 5327 static long long ll0 = 1LL;
5328 5328
5356 void 5356 void
5357 code_lneg(int creg) 5357 code_lneg(int creg)
5358 { 5358 {
5359 use_longlong(creg); 5359 use_longlong(creg);
5360 printf("\tsubfic %s,%s,0\n", 5360 printf("\tsubfic %s,%s,0\n",
5361 lregister_name_low(creg),lregister_name_low(creg)); 5361 lregister_name_low(creg),lregister_name_low(creg));
5362 printf("\tsubfze %s,%s\n", 5362 printf("\tsubfze %s,%s\n",
5363 lregister_name_high(creg),lregister_name_high(creg)); 5363 lregister_name_high(creg),lregister_name_high(creg));
5364 } 5364 }
5365 5365
5366 void 5366 void
5367 code_lrgvar(int e1,int creg) 5367 code_lrgvar(int e1,int creg)
5368 { 5368 {
5653 clear_ptr_cache(); 5653 clear_ptr_cache();
5654 asld_lib_used = 1; 5654 asld_lib_used = 1;
5655 set_lreg_operand(reg,1); 5655 set_lreg_operand(reg,1);
5656 set_lreg(RET_LREGISTER,0); 5656 set_lreg(RET_LREGISTER,0);
5657 if (regv_l(oreg)!=5) { 5657 if (regv_l(oreg)!=5) {
5658 printf("\tmr %s,%s\n", 5658 printf("\tmr %s,%s\n",
5659 register_name(5), 5659 register_name(5),
5660 lregister_name_low(oreg)); 5660 lregister_name_low(oreg));
5661 } 5661 }
5662 printf("\tbl .asld__\n"); 5662 printf("\tbl .asld__\n");
5663 } 5663 }
5664 5664
5665 static void 5665 static void
5669 clear_ptr_cache(); 5669 clear_ptr_cache();
5670 asrd_lib_used = 1; 5670 asrd_lib_used = 1;
5671 set_lreg_operand(reg,1); 5671 set_lreg_operand(reg,1);
5672 set_lreg(RET_LREGISTER,0); 5672 set_lreg(RET_LREGISTER,0);
5673 if (regv_l(oreg)!=5) { 5673 if (regv_l(oreg)!=5) {
5674 printf("\tmr %s,%s\n", 5674 printf("\tmr %s,%s\n",
5675 register_name(5), 5675 register_name(5),
5676 lregister_name_low(oreg)); 5676 lregister_name_low(oreg));
5677 } 5677 }
5678 printf("\tbl .asrd__\n"); 5678 printf("\tbl .asrd__\n");
5679 } 5679 }
5680 5680
5681 static void 5681 static void
5685 clear_ptr_cache(); 5685 clear_ptr_cache();
5686 lsrd_lib_used = 1; 5686 lsrd_lib_used = 1;
5687 set_lreg_operand(reg,1); 5687 set_lreg_operand(reg,1);
5688 set_lreg(RET_LREGISTER,0); 5688 set_lreg(RET_LREGISTER,0);
5689 if (regv_l(oreg)!=5) { 5689 if (regv_l(oreg)!=5) {
5690 printf("\tmr %s,%s\n", 5690 printf("\tmr %s,%s\n",
5691 register_name(5), 5691 register_name(5),
5692 lregister_name_low(oreg)); 5692 lregister_name_low(oreg));
5693 } 5693 }
5694 printf("\tbl .lsrd__\n"); 5694 printf("\tbl .lsrd__\n");
5695 } 5695 }
5696 5696
5697 static void 5697 static void
5752 char *orn_l,*crn_l,*drn_l; 5752 char *orn_l,*crn_l,*drn_l;
5753 // creg = creg op oreg 5753 // creg = creg op oreg
5754 5754
5755 use_longlong(reg); 5755 use_longlong(reg);
5756 if(oreg==-1) { 5756 if(oreg==-1) {
5757 error(-1); 5757 error(-1);
5758 } else if (oreg<= -REG_LVAR_OFFSET) { 5758 } else if (oreg<= -REG_LVAR_OFFSET) {
5759 ox = get_lregister(); if (ox<0) error(-1); 5759 ox = get_lregister(); if (ox<0) error(-1);
5760 use_reg(ox); 5760 use_reg(ox);
5761 code_lrlvar(oreg+REG_LVAR_OFFSET,ox); 5761 code_lrlvar(oreg+REG_LVAR_OFFSET,ox);
5762 oreg = ox; 5762 oreg = ox;
5763 } 5763 }
5764 5764
5765 switch(op) { 5765 switch(op) {
5766 case LLSHIFT: 5766 case LLSHIFT:
5767 case LULSHIFT: 5767 case LULSHIFT:
5768 code_asld_lib(reg,oreg); // ___ashldi3$stub 5768 code_asld_lib(reg,oreg); // ___ashldi3$stub
5769 check_lreg(reg); 5769 check_lreg(reg);
5770 if(ox!=-1) free_register(ox); 5770 if(ox!=-1) free_register(ox);
5771 return; 5771 return;
5772 case LRSHIFT: 5772 case LRSHIFT:
5773 code_asrd_lib(reg,oreg); // ___ashrdi3$stub 5773 code_asrd_lib(reg,oreg); // ___ashrdi3$stub
5774 check_lreg(reg); 5774 check_lreg(reg);
5775 if(ox!=-1) free_register(ox); 5775 if(ox!=-1) free_register(ox);
5776 return; 5776 return;
5777 case LURSHIFT: 5777 case LURSHIFT:
5778 code_lsrd_lib(reg,oreg); // ___lshrdi3$stub 5778 code_lsrd_lib(reg,oreg); // ___lshrdi3$stub
5779 check_lreg(reg); 5779 check_lreg(reg);
5780 if(ox!=-1) free_register(ox); 5780 if(ox!=-1) free_register(ox);
5781 return; 5781 return;
5782 } 5782 }
5783 orn_h = lregister_name_high(oreg); 5783 orn_h = lregister_name_high(oreg);
5784 orn_l = lregister_name_low(oreg); 5784 orn_l = lregister_name_low(oreg);
5785 crn_h = lregister_name_high(reg); 5785 crn_h = lregister_name_high(reg);
5786 crn_l = lregister_name_low(reg); 5786 crn_l = lregister_name_low(reg);
5787 switch(op) { 5787 switch(op) {
5788 case LADD: 5788 case LADD:
5789 printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l); 5789 printf("\taddc %s,%s,%s\n",crn_l,crn_l,orn_l);
5790 printf("\tadde %s,%s,%s\n",crn_h,crn_h,orn_h); 5790 printf("\tadde %s,%s,%s\n",crn_h,crn_h,orn_h);
5791 break; 5791 break;
5792 case LSUB: 5792 case LSUB:
5793 printf("\tsubfc %s,%s,%s\n",crn_l,orn_l,crn_l); 5793 printf("\tsubfc %s,%s,%s\n",crn_l,orn_l,crn_l);
5794 printf("\tsubfe %s,%s,%s\n",crn_h,orn_h,crn_h); 5794 printf("\tsubfe %s,%s,%s\n",crn_h,orn_h,crn_h);
5795 break; 5795 break;
5796 case LCMP: 5796 case LCMP:
5797 error(-1); 5797 error(-1);
5798 break; 5798 break;
5799 case LBAND: 5799 case LBAND:
5800 printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l); 5800 printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l);
5801 printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h); 5801 printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h);
5802 break; 5802 break;
5803 case LEOR: 5803 case LEOR:
5804 printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l); 5804 printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l);
5805 printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h); 5805 printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h);
5806 break; 5806 break;
5807 case LBOR: 5807 case LBOR:
5808 printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l); 5808 printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l);
5809 printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h); 5809 printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h);
5810 break; 5810 break;
5811 case LMUL: 5811 case LMUL:
5812 case LUMUL: 5812 case LUMUL:
5813 // code_save_stacks(); 5813 // code_save_stacks();
5814 // clear_ptr_cache(); 5814 // clear_ptr_cache();
5815 dx=get_lregister(); if (dx<0) error(-1); 5815 dx=get_lregister(); if (dx<0) error(-1);
5816 use_reg(dx); 5816 use_reg(dx);
5817 drn_l = lregister_name_low(dx); 5817 drn_l = lregister_name_low(dx);
5818 drn_h = lregister_name_high(dx); 5818 drn_h = lregister_name_high(dx);
5819 /* 5819 /*
5820 drn_l = l32( crn_l * orn_l); 5820 drn_l = l32( crn_l * orn_l);
5821 drn_h = h32( crn_l * orn_l); 5821 drn_h = h32( crn_l * orn_l);
5822 crn_h = l32( crn_h * orn_l); 5822 crn_h = l32( crn_h * orn_l);
5823 drn_h = drn_h + crn_h; 5823 drn_h = drn_h + crn_h;
5824 crn_l = l32( crn_l * orn_h); 5824 crn_l = l32( crn_l * orn_h);
5825 crn_h = drn_h + crn_l; 5825 crn_h = drn_h + crn_l;
5826 crn_l = drn_l; 5826 crn_l = drn_l;
5827 */ 5827 */
5828 printf("\tmulhwu %s,%s,%s\n",drn_h,crn_l,orn_l); 5828 printf("\tmulhwu %s,%s,%s\n",drn_h,crn_l,orn_l);
5829 printf("\tmullw %s,%s,%s\n", drn_l,crn_l,orn_l); 5829 printf("\tmullw %s,%s,%s\n", drn_l,crn_l,orn_l);
5830 printf("\tmullw %s,%s,%s\n", crn_h,crn_h,orn_l); 5830 printf("\tmullw %s,%s,%s\n", crn_h,crn_h,orn_l);
5831 printf("\tadd %s,%s,%s\n", drn_h,drn_h,crn_h); 5831 printf("\tadd %s,%s,%s\n", drn_h,drn_h,crn_h);
5832 printf("\tmullw %s,%s,%s\n", crn_l,orn_h,crn_l); 5832 printf("\tmullw %s,%s,%s\n", crn_l,orn_h,crn_l);
5833 printf("\tadd %s,%s,%s\n", crn_h,drn_h,crn_l); 5833 printf("\tadd %s,%s,%s\n", crn_h,drn_h,crn_l);
5834 printf("\tmr %s,%s\n", crn_l,drn_l); 5834 printf("\tmr %s,%s\n", crn_l,drn_l);
5835 break; 5835 break;
5836 case LDIV: 5836 case LDIV:
5837 code_ldiv_lib(reg,oreg); // ___divdi3$stub 5837 code_ldiv_lib(reg,oreg); // ___divdi3$stub
5838 if (!creg_mode) check_lreg(reg); 5838 if (!creg_mode) check_lreg(reg);
5839 break; 5839 break;
5840 case LUDIV: 5840 case LUDIV:
5841 code_ludiv_lib(reg,oreg); // ___udivdi3$stub 5841 code_ludiv_lib(reg,oreg); // ___udivdi3$stub
5842 if (!creg_mode) check_lreg(reg); 5842 if (!creg_mode) check_lreg(reg);
5843 break; 5843 break;
5844 case LMOD: 5844 case LMOD:
5845 code_lmod_lib(reg,oreg); // ___moddi3$stub 5845 code_lmod_lib(reg,oreg); // ___moddi3$stub
5846 if (!creg_mode) check_lreg(reg); 5846 if (!creg_mode) check_lreg(reg);
5847 break; 5847 break;
5848 case LUMOD: 5848 case LUMOD:
5849 code_lumod_lib(reg,oreg); // ___umoddi3$stub 5849 code_lumod_lib(reg,oreg); // ___umoddi3$stub
5850 if (!creg_mode) check_lreg(reg); 5850 if (!creg_mode) check_lreg(reg);
5851 break; 5851 break;
5852 default: 5852 default:
5853 error(-1); 5853 error(-1);
5854 } 5854 }
5855 if(ox!=-1) free_register(ox); 5855 if(ox!=-1) free_register(ox);
5856 if(dx!=-1) free_register(dx); 5856 if(dx!=-1) free_register(dx);
5857 } 5857 }
5858 5858
5859 int 5859 int
5860 code_lconst_op_p(int op,int e) 5860 code_lconst_op_p(int op,int e)
5861 { 5861 {
5862 int v; 5862 int v;
5863 if (car(e)==LCONST) { 5863 if (car(e)==LCONST) {
5864 if (!(-32766<lcadr(e)&&lcadr(e)<32767)) return 0; 5864 if (!(-32766<lcadr(e)&&lcadr(e)<32767)) return 0;
5865 v = lcadr(e); 5865 v = lcadr(e);
5866 } else if (car(e)==CONST) { 5866 } else if (car(e)==CONST) {
5867 if (!(-32766<cadr(e)&&cadr(e)<32767)) return 0; 5867 if (!(-32766<cadr(e)&&cadr(e)<32767)) return 0;
5868 v = cadr(e); 5868 v = cadr(e);
5869 } else return 0; 5869 } else return 0;
5870 5870
5871 switch(op) { 5871 switch(op) {
5872 case LMUL: case LUMUL: case LUDIV: 5872 case LMUL: case LUMUL: case LUDIV:
5873 // case LDIV: 5873 // case LDIV:
5874 return ilog(v); 5874 return ilog(v);
5875 case LLSHIFT: 5875 case LLSHIFT:
5876 case LULSHIFT: 5876 case LULSHIFT:
5877 case LRSHIFT: 5877 case LRSHIFT:
5878 case LURSHIFT: 5878 case LURSHIFT:
5879 return (0<=v&&v<=64); 5879 return (0<=v&&v<=64);
5880 case LADD: 5880 case LADD:
5881 case LSUB: 5881 case LSUB:
5882 return 1; 5882 return 1;
5883 case LBOR: 5883 case LBOR:
5884 return (v>0); 5884 return (v>0);
5885 default: 5885 default:
5886 return 0; 5886 return 0;
5887 } 5887 }
5888 } 5888 }
5889 5889
5890 void 5890 void
5891 loprtc(int op,int creg,int e) 5891 loprtc(int op,int creg,int e)
5906 switch(op) { 5906 switch(op) {
5907 case LMUL: case LUMUL: 5907 case LMUL: case LUMUL:
5908 v=ilog(v); 5908 v=ilog(v);
5909 case LLSHIFT: 5909 case LLSHIFT:
5910 case LULSHIFT: 5910 case LULSHIFT:
5911 if (v==0) return; 5911 if (v==0) return;
5912 if (v==32) { 5912 if (v==32) {
5913 code_register(regv_l(creg),regv_h(creg)); 5913 code_register(regv_l(creg),regv_h(creg));
5914 code_const(0,regv_l(creg)); 5914 code_const(0,regv_l(creg));
5915 return; 5915 return;
5916 } else if (v>31) { 5916 } else if (v>31) {
5917 printf("\tslwi %s,%s,%d\n",crn_h,crn_l,v-32); 5917 printf("\tslwi %s,%s,%d\n",crn_h,crn_l,v-32);
5918 code_const(0,regv_l(creg)); 5918 code_const(0,regv_l(creg));
5919 return; 5919 return;
5920 } 5920 }
5921 greg = get_register(); 5921 greg = get_register();
5922 grn = register_name(greg); 5922 grn = register_name(greg);
5923 use_reg(greg); 5923 use_reg(greg);
5924 printf("\tsrwi %s,%s,%d\n",grn,crn_l,32-v); 5924 printf("\tsrwi %s,%s,%d\n",grn,crn_l,32-v);
5925 printf("\tslwi %s,%s,%d\n",crn_h,crn_h,v); 5925 printf("\tslwi %s,%s,%d\n",crn_h,crn_h,v);
5926 printf("\tor %s,%s,%s\n",crn_h,grn,crn_h); 5926 printf("\tor %s,%s,%s\n",crn_h,grn,crn_h);
5927 printf("\tslwi %s,%s,%d\n",crn_l,crn_l,v); 5927 printf("\tslwi %s,%s,%d\n",crn_l,crn_l,v);
5928 free_register(greg); 5928 free_register(greg);
5929 return; 5929 return;
5930 case LDIV: 5930 case LDIV:
5931 v=ilog(v); 5931 v=ilog(v);
5932 case LRSHIFT: 5932 case LRSHIFT:
5933 if (v==0) return; 5933 if (v==0) return;
5934 if (v==32) { 5934 if (v==32) {
5935 code_register(regv_h(creg),regv_l(creg)); 5935 code_register(regv_h(creg),regv_l(creg));
5936 printf("\tsrawi %s,%s,31\n",crn_h,crn_l); 5936 printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
5937 return; 5937 return;
5938 } else if (v>31) { 5938 } else if (v>31) {
5939 printf("\tsrawi %s,%s,%d\n",crn_l,crn_h,v-32); 5939 printf("\tsrawi %s,%s,%d\n",crn_l,crn_h,v-32);
5940 printf("\tsrawi %s,%s,31\n",crn_h,crn_l); 5940 printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
5941 return; 5941 return;
5942 } 5942 }
5943 greg = get_register(); 5943 greg = get_register();
5944 use_reg(greg); 5944 use_reg(greg);
5945 grn = register_name(greg); 5945 grn = register_name(greg);
5946 printf("\tsrwi %s,%s,%d\n",grn,crn_l,v); 5946 printf("\tsrwi %s,%s,%d\n",grn,crn_l,v);
5947 printf("\tinsrwi %s,%s,%d,0\n",grn,crn_h,v); 5947 printf("\tinsrwi %s,%s,%d,0\n",grn,crn_h,v);
5948 printf("\tsrawi %s,%s,%d\n",crn_h,crn_h,v); 5948 printf("\tsrawi %s,%s,%d\n",crn_h,crn_h,v);
5949 printf("\tmr %s,%s\n",crn_l,grn); 5949 printf("\tmr %s,%s\n",crn_l,grn);
5950 free_register(greg); 5950 free_register(greg);
5951 return; 5951 return;
5952 case LUDIV: 5952 case LUDIV:
5953 v=ilog(v); 5953 v=ilog(v);
5954 case LURSHIFT: 5954 case LURSHIFT:
5955 if (v==0) return; 5955 if (v==0) return;
5956 if (v==32) { 5956 if (v==32) {
5957 code_register(regv_h(creg),regv_l(creg)); 5957 code_register(regv_h(creg),regv_l(creg));
5958 code_const(0,regv_h(creg)); 5958 code_const(0,regv_h(creg));
5959 return; 5959 return;
5960 } else if (v>31) { 5960 } else if (v>31) {
5961 printf("\tsrwi %s,%s,%d\n",crn_l,crn_h,v-32); 5961 printf("\tsrwi %s,%s,%d\n",crn_l,crn_h,v-32);
5962 code_const(0,regv_h(creg)); 5962 code_const(0,regv_h(creg));
5963 return; 5963 return;
5964 } 5964 }
5965 greg = get_register(); 5965 greg = get_register();
5966 use_reg(greg); 5966 use_reg(greg);
5967 grn = register_name(greg); 5967 grn = register_name(greg);
5968 printf("\tslwi %s,%s,%d\n",grn,crn_h,32-v); 5968 printf("\tslwi %s,%s,%d\n",grn,crn_h,32-v);
5969 printf("\tsrwi %s,%s,%d\n",crn_l,crn_l,v); 5969 printf("\tsrwi %s,%s,%d\n",crn_l,crn_l,v);
5970 printf("\tor %s,%s,%s\n",crn_l,grn,crn_l); 5970 printf("\tor %s,%s,%s\n",crn_l,grn,crn_l);
5971 printf("\tsrwi %s,%s,%d\n",crn_h,crn_h,v); 5971 printf("\tsrwi %s,%s,%d\n",crn_h,crn_h,v);
5972 free_register(greg); 5972 free_register(greg);
5973 return; 5973 return;
5974 case LSUB: 5974 case LSUB:
5975 v = -v; 5975 v = -v;
5976 case LADD: 5976 case LADD:
5977 printf("\taddic %s,%s,%d\n",crn_l,crn_l,v); 5977 printf("\taddic %s,%s,%d\n",crn_l,crn_l,v);
5978 if (v<0) 5978 if (v<0)
5979 printf("\taddme %s,%s\n",crn_h,crn_h); 5979 printf("\taddme %s,%s\n",crn_h,crn_h);
5980 else 5980 else
5981 printf("\taddze %s,%s\n",crn_h,crn_h); 5981 printf("\taddze %s,%s\n",crn_h,crn_h);
5982 break; 5982 break;
5983 case LBOR: 5983 case LBOR:
5984 #ifdef __APPLE__ 5984 #ifdef __APPLE__
5985 printf("\tori %s,%s,lo16(%d)\n",crn_l,crn_l,v); 5985 printf("\tori %s,%s,lo16(%d)\n",crn_l,crn_l,v);
5986 #else 5986 #else
5987 printf("\tori %s,%s,%d@l\n",crn_l,crn_l,v); 5987 printf("\tori %s,%s,%d@l\n",crn_l,crn_l,v);
5988 #endif 5988 #endif
5989 break; 5989 break;
5990 default: 5990 default:
5991 error(-1); 5991 error(-1);
5992 } 5992 }
5993 } 5993 }
5994 5994
5995 5995
5996 void 5996 void
6019 crn = register_name(reg0 = ireg); 6019 crn = register_name(reg0 = ireg);
6020 use_longlong(reg); 6020 use_longlong(reg);
6021 crn_h = lregister_name_high(lreg); 6021 crn_h = lregister_name_high(lreg);
6022 crn_l = lregister_name_low(lreg); 6022 crn_l = lregister_name_low(lreg);
6023 if (reg0!=regv_l(lreg)) 6023 if (reg0!=regv_l(lreg))
6024 printf("\tmr %s,%s\n",crn_l,crn); 6024 printf("\tmr %s,%s\n",crn_l,crn);
6025 printf("\tsrawi %s,%s,31\n",crn_h,crn_l); 6025 printf("\tsrawi %s,%s,31\n",crn_h,crn_l);
6026 } 6026 }
6027 6027
6028 void 6028 void
6029 code_i2ull(int reg) 6029 code_i2ull(int reg)
6039 crn = register_name(reg0 = ireg); 6039 crn = register_name(reg0 = ireg);
6040 use_longlong(reg); 6040 use_longlong(reg);
6041 crn_h = lregister_name_high(lreg); 6041 crn_h = lregister_name_high(lreg);
6042 crn_l = lregister_name_low(lreg); 6042 crn_l = lregister_name_low(lreg);
6043 if (reg0!=regv_l(lreg)) 6043 if (reg0!=regv_l(lreg))
6044 printf("\tmr %s,%s\n",crn_l,crn); 6044 printf("\tmr %s,%s\n",crn_l,crn);
6045 printf("\tli %s,0\n",crn_h); 6045 printf("\tli %s,0\n",crn_h);
6046 } 6046 }
6047 6047
6048 void 6048 void
6049 code_u2ull(int creg) 6049 code_u2ull(int creg)
6057 char *crn_l; 6057 char *crn_l;
6058 int reg0; 6058 int reg0;
6059 crn_l = lregister_name_low(reg0=lreg); 6059 crn_l = lregister_name_low(reg0=lreg);
6060 use_int(reg); 6060 use_int(reg);
6061 if (ireg!=regv_l(reg0)) 6061 if (ireg!=regv_l(reg0))
6062 printf("\tmr %s,%s\n",register_name(ireg),crn_l); 6062 printf("\tmr %s,%s\n",register_name(ireg),crn_l);
6063 } 6063 }
6064 6064
6065 void 6065 void
6066 code_ll2u(int creg) 6066 code_ll2u(int creg)
6067 { 6067 {
6088 // fixdfdi$stub 6088 // fixdfdi$stub
6089 set_freg(RET_FREGISTER,1); 6089 set_freg(RET_FREGISTER,1);
6090 extern_conv("__fixdfdi"); 6090 extern_conv("__fixdfdi");
6091 set_lreg(RET_LREGISTER,0); 6091 set_lreg(RET_LREGISTER,0);
6092 if (reg!=USE_CREG&&reg!=RET_LREGISTER) 6092 if (reg!=USE_CREG&&reg!=RET_LREGISTER)
6093 use_longlong(reg); 6093 use_longlong(reg);
6094 } 6094 }
6095 6095
6096 void 6096 void
6097 code_d2ull(int reg) 6097 code_d2ull(int reg)
6098 { 6098 {
6099 set_freg(RET_FREGISTER,1); 6099 set_freg(RET_FREGISTER,1);
6100 extern_conv("__fixunsdfdi"); 6100 extern_conv("__fixunsdfdi");
6101 set_lreg(RET_LREGISTER,0); 6101 set_lreg(RET_LREGISTER,0);
6102 if (reg!=USE_CREG&&reg!=RET_LREGISTER) 6102 if (reg!=USE_CREG&&reg!=RET_LREGISTER)
6103 use_longlong(reg); 6103 use_longlong(reg);
6104 } 6104 }
6105 6105
6106 void 6106 void
6107 code_f2ll(int reg) 6107 code_f2ll(int reg)
6108 { 6108 {
6109 set_freg(RET_FREGISTER,1); 6109 set_freg(RET_FREGISTER,1);
6110 extern_conv("__fixdfdi"); 6110 extern_conv("__fixdfdi");
6111 set_lreg(RET_LREGISTER,0); 6111 set_lreg(RET_LREGISTER,0);
6112 if (reg!=USE_CREG&&reg!=RET_LREGISTER) 6112 if (reg!=USE_CREG&&reg!=RET_LREGISTER)
6113 use_longlong(reg); 6113 use_longlong(reg);
6114 } 6114 }
6115 6115
6116 void 6116 void
6117 code_f2ull(int reg) 6117 code_f2ull(int reg)
6118 { 6118 {
6119 set_freg(RET_FREGISTER,1); 6119 set_freg(RET_FREGISTER,1);
6120 extern_conv("__fixsfdi"); 6120 extern_conv("__fixsfdi");
6121 set_lreg(RET_LREGISTER,0); 6121 set_lreg(RET_LREGISTER,0);
6122 if (reg!=USE_CREG&&reg!=RET_LREGISTER) 6122 if (reg!=USE_CREG&&reg!=RET_LREGISTER)
6123 use_longlong(reg); 6123 use_longlong(reg);
6124 } 6124 }
6125 6125
6126 void 6126 void
6127 code_ll2d(int reg) 6127 code_ll2d(int reg)
6128 { 6128 {
6129 set_lreg(RET_LREGISTER,1); 6129 set_lreg(RET_LREGISTER,1);
6130 extern_conv("__floatdidf"); 6130 extern_conv("__floatdidf");
6131 set_freg(RET_FREGISTER,0); 6131 set_freg(RET_FREGISTER,0);
6132 if (reg!=USE_CREG&&reg!=RET_FREGISTER) 6132 if (reg!=USE_CREG&&reg!=RET_FREGISTER)
6133 use_float(1,reg); 6133 use_float(1,reg);
6134 } 6134 }
6135 6135
6136 6136
6137 void 6137 void
6138 code_ll2f(int reg) 6138 code_ll2f(int reg)
6139 { 6139 {
6140 set_lreg(RET_LREGISTER,1); 6140 set_lreg(RET_LREGISTER,1);
6141 extern_conv("__floatdisf"); 6141 extern_conv("__floatdisf");
6142 set_freg(RET_FREGISTER,0); 6142 set_freg(RET_FREGISTER,0);
6143 if (reg!=USE_CREG&&reg!=RET_FREGISTER) 6143 if (reg!=USE_CREG&&reg!=RET_FREGISTER)
6144 use_float(0,reg); 6144 use_float(0,reg);
6145 } 6145 }
6146 6146
6147 void 6147 void
6148 code_ull2d(int creg) 6148 code_ull2d(int creg)
6149 { 6149 {
6159 6159
6160 static void 6160 static void
6161 ladd(int creg,int reg,int dir) // creg=reg+dir 6161 ladd(int creg,int reg,int dir) // creg=reg+dir
6162 { 6162 {
6163 printf("\taddic %s,%s,%d\n", 6163 printf("\taddic %s,%s,%d\n",
6164 lregister_name_low(creg),lregister_name_low(reg), dir); 6164 lregister_name_low(creg),lregister_name_low(reg), dir);
6165 printf("\tadd%s %s,%s\n", dir>0?"ze":"me", 6165 printf("\tadd%s %s,%s\n", dir>0?"ze":"me",
6166 lregister_name_high(creg),lregister_name_high(reg)); 6166 lregister_name_high(creg),lregister_name_high(reg));
6167 } 6167 }
6168 6168
6169 void 6169 void
6170 code_lpreinc(int e1,int e2,int reg) 6170 code_lpreinc(int e1,int e2,int reg)
6171 { 6171 {
6172 int dreg,xreg; 6172 int dreg,xreg;
6173 int dir=caddr(e1); 6173 int dir=caddr(e1);
6174 if (car(e2)==LREGISTER) { 6174 if (car(e2)==LREGISTER) {
6175 use_longlong(reg); 6175 use_longlong(reg);
6176 ladd(cadr(e2),cadr(e2),dir); 6176 ladd(cadr(e2),cadr(e2),dir);
6177 if (reg!=cadr(e2)) { 6177 if (reg!=cadr(e2)) {
6178 lmove(reg,cadr(e2)); 6178 lmove(reg,cadr(e2));
6179 } 6179 }
6180 return; 6180 return;
6181 } 6181 }
6182 g_expr(e2); 6182 g_expr(e2);
6183 if(!is_int_reg(creg)) error(-1); 6183 if(!is_int_reg(creg)) error(-1);
6184 emit_push(); 6184 emit_push();
6185 if (reg==USE_CREG) { 6185 if (reg==USE_CREG) {
6186 dreg=get_lregister(); if (!dreg) error(-1); 6186 dreg=get_lregister(); if (!dreg) error(-1);
6187 set_lreg(dreg,0); // free old lreg==creg 6187 set_lreg(dreg,0); // free old lreg==creg
6188 } else { 6188 } else {
6189 dreg = reg; 6189 dreg = reg;
6190 } 6190 }
6191 xreg = emit_pop(0); 6191 xreg = emit_pop(0);
6192 lload(xreg,dreg,0); 6192 lload(xreg,dreg,0);
6199 code_lpostinc(int e1,int e2,int reg) 6199 code_lpostinc(int e1,int e2,int reg)
6200 { 6200 {
6201 int dreg,nreg,xreg; 6201 int dreg,nreg,xreg;
6202 int dir=caddr(e1); 6202 int dir=caddr(e1);
6203 if (car(e2)==LREGISTER) { 6203 if (car(e2)==LREGISTER) {
6204 use_longlong(reg); 6204 use_longlong(reg);
6205 if (use && reg!=cadr(e2)) 6205 if (use && reg!=cadr(e2))
6206 lmove(reg,cadr(e2)); 6206 lmove(reg,cadr(e2));
6207 ladd(cadr(e2),cadr(e2),dir); 6207 ladd(cadr(e2),cadr(e2),dir);
6208 return; 6208 return;
6209 } 6209 }
6210 g_expr(e2); 6210 g_expr(e2);
6211 if(!is_int_reg(creg)) error(-1); 6211 if(!is_int_reg(creg)) error(-1);
6212 emit_push(); 6212 emit_push();
6213 nreg=get_lregister(); if (!nreg) error(-1); 6213 nreg=get_lregister(); if (!nreg) error(-1);
6214 if (reg==USE_CREG) { 6214 if (reg==USE_CREG) {
6215 dreg=get_lregister(); if (!dreg) error(-1); 6215 dreg=get_lregister(); if (!dreg) error(-1);
6216 set_lreg(dreg,0); // free old lreg==creg 6216 set_lreg(dreg,0); // free old lreg==creg
6217 } else { 6217 } else {
6218 dreg = reg; 6218 dreg = reg;
6219 } 6219 }
6220 xreg = emit_pop(0); 6220 xreg = emit_pop(0);
6221 lload(xreg,dreg,0); 6221 lload(xreg,dreg,0);
6236 if (!is_int_reg(creg)) error(-1); 6236 if (!is_int_reg(creg)) error(-1);
6237 edx = ireg; 6237 edx = ireg;
6238 emit_push(); 6238 emit_push();
6239 use_longlong(reg); 6239 use_longlong(reg);
6240 if (regv_l(lreg)==edx || regv_h(lreg)==edx) { 6240 if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
6241 // this can't happen 6241 // this can't happen
6242 edx0 = get_register(); if(!edx0) error(-1); 6242 edx0 = get_register(); if(!edx0) error(-1);
6243 printf("## lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx)); 6243 printf("## lassop\n\tmr %s,%s\n",register_name(edx0),register_name(edx));
6244 edx = edx0; 6244 edx = edx0;
6245 } 6245 }
6246 lload(edx0=edx,reg,0); 6246 lload(edx0=edx,reg,0);
6247 ltosop(op,reg,xreg); 6247 ltosop(op,reg,xreg);
6248 use_reg(reg); 6248 use_reg(reg);
6249 edx = emit_pop(0); 6249 edx = emit_pop(0);
6250 code_lassign(edx,reg); 6250 code_lassign(edx,reg);
6251 if (edx0!=-1) 6251 if (edx0!=-1)
6252 free_register(edx0); 6252 free_register(edx0);
6253 emit_pop_free(edx); 6253 emit_pop_free(edx);
6254 emit_lpop_free(xreg); 6254 emit_lpop_free(xreg);
6255 } 6255 }
6256 6256
6257 void 6257 void
6272 for(i=0;i<reg_sp;i++) { 6272 for(i=0;i<reg_sp;i++) {
6273 if ((reg=reg_stack[i])>=0) { 6273 if ((reg=reg_stack[i])>=0) {
6274 code_assign_lvar( 6274 code_assign_lvar(
6275 (reg_stack[i]=new_lvar(SIZE_OF_INT)),reg,0); 6275 (reg_stack[i]=new_lvar(SIZE_OF_INT)),reg,0);
6276 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; 6276 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET;
6277 free_register(reg); 6277 free_register(reg);
6278 } 6278 }
6279 } 6279 }
6280 #if FLOAT_CODE 6280 #if FLOAT_CODE
6281 for(i=0;i<freg_sp;i++) { 6281 for(i=0;i<freg_sp;i++) {
6282 if ((reg=freg_stack[i])>=0) { 6282 if ((reg=freg_stack[i])>=0) {
6283 code_dassign_lvar( 6283 code_dassign_lvar(
6284 (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1); 6284 (freg_stack[i]=new_lvar(SIZE_OF_DOUBLE)),reg,1);
6285 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; 6285 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET;
6286 free_register(reg); 6286 free_register(reg);
6287 } 6287 }
6288 } 6288 }
6289 #endif 6289 #endif
6290 #if LONGLONG_CODE 6290 #if LONGLONG_CODE
6291 for(i=0;i<lreg_sp;i++) { 6291 for(i=0;i<lreg_sp;i++) {
6292 if ((reg=lreg_stack[i])>=0) { 6292 if ((reg=lreg_stack[i])>=0) {
6293 code_lassign_lvar( 6293 code_lassign_lvar(
6294 (lreg_stack[i]=new_lvar(SIZE_OF_LONGLONG)),reg); 6294 (lreg_stack[i]=new_lvar(SIZE_OF_LONGLONG)),reg);
6295 lreg_stack[i]= lreg_stack[i]-REG_LVAR_OFFSET; 6295 lreg_stack[i]= lreg_stack[i]-REG_LVAR_OFFSET;
6296 free_register(reg); 6296 free_register(reg);
6297 } 6297 }
6298 } 6298 }
6299 #endif 6299 #endif
6300 } 6300 }
6301 6301
6302 static void 6302 static void
6303 emit_lib(char *p[]) 6303 emit_lib(char *p[])
6304 { 6304 {
6305 while(*p) { 6305 while(*p) {
6306 printf("%s\n",*p++); 6306 printf("%s\n",*p++);
6307 } 6307 }
6308 } 6308 }
6309 6309
6310 void 6310 void
6311 code_closing() 6311 code_closing()
6361 char *srn = register_name(s=get_register()); 6361 char *srn = register_name(s=get_register());
6362 char *urn; 6362 char *urn;
6363 6363
6364 inc_cmpflag(); 6364 inc_cmpflag();
6365 if (min>32767||min<-32765) { 6365 if (min>32767||min<-32765) {
6366 if (t==csvalue) { 6366 if (t==csvalue) {
6367 code_const(min,s); 6367 code_const(min,s);
6368 printf("\tsub\t%s,%s,%s\n",trn,crn,srn); 6368 printf("\tsub\t%s,%s,%s\n",trn,crn,srn);
6369 } else { 6369 } else {
6370 code_const(min,t); 6370 code_const(min,t);
6371 printf("\tsub\t%s,%s,%s\n",trn,crn,trn); 6371 printf("\tsub\t%s,%s,%s\n",trn,crn,trn);
6372 } 6372 }
6373 } else { 6373 } else {
6374 #ifdef __APPLE__ 6374 #ifdef __APPLE__
6375 printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min); 6375 printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min);
6376 #else 6376 #else
6377 printf("\taddi\t%s,%s,%d@l\n",trn,crn,-min); 6377 printf("\taddi\t%s,%s,%d@l\n",trn,crn,-min);
6378 #endif 6378 #endif
6379 } 6379 }
6380 printf("\tcmplwi %s,%s,%d\n",crname(cmpflag),trn,max-min); 6380 printf("\tcmplwi %s,%s,%d\n",crname(cmpflag),trn,max-min);
6381 printf("\tbgt-\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); 6381 printf("\tbgt-\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel);
6382 inc_cmpflag(); 6382 inc_cmpflag();
6383 switch(delta) { 6383 switch(delta) {
6384 case 1: printf("\tslwi %s,%s,2\n",trn,trn); break; 6384 case 1: printf("\tslwi %s,%s,2\n",trn,trn); break;
6385 case 2: 6385 case 2:
6386 printf("\tli %s,1\n",srn); 6386 printf("\tli %s,1\n",srn);
6387 printf("\tand %s,%s,%s\n",srn,srn,trn); 6387 printf("\tand %s,%s,%s\n",srn,srn,trn);
6388 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); 6388 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn);
6389 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); 6389 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel);
6390 printf("\tslwi %s,%s,1\n",trn,trn); 6390 printf("\tslwi %s,%s,1\n",trn,trn);
6391 break; 6391 break;
6392 case 4: 6392 case 4:
6393 printf("\tli %s,3\n",srn); 6393 printf("\tli %s,3\n",srn);
6394 printf("\tand %s,%s,%s\n",srn,srn,trn); 6394 printf("\tand %s,%s,%s\n",srn,srn,trn);
6395 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); 6395 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn);
6396 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); 6396 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel);
6397 break; 6397 break;
6398 default: 6398 default:
6399 urn = register_name(u=get_register()); 6399 urn = register_name(u=get_register());
6400 printf("\tli %s,%d\n",srn,delta); 6400 printf("\tli %s,%d\n",srn,delta);
6401 printf("\tdivwu %s,%s,%s\n",urn,trn,srn); 6401 printf("\tdivwu %s,%s,%s\n",urn,trn,srn);
6402 printf("\tmullw %s,%s,%s\n",srn,urn,srn); 6402 printf("\tmullw %s,%s,%s\n",srn,urn,srn);
6403 printf("\tsubf %s,%s,%s\n",srn,trn,srn); 6403 printf("\tsubf %s,%s,%s\n",srn,trn,srn);
6404 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); 6404 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn);
6405 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); 6405 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel);
6406 printf("\tslwi %s,%s,2\n",trn,urn); 6406 printf("\tslwi %s,%s,2\n",trn,urn);
6407 } 6407 }
6408 #ifdef __APPLE__ 6408 #ifdef __APPLE__
6409 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n", 6409 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",
6410 srn,l,code_base); 6410 srn,l,code_base);
6411 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n", 6411 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",
6412 srn,l,code_base,srn); 6412 srn,l,code_base,srn);
6413 printf("\tadd %s,%s,%s\n",trn,srn,trn); 6413 printf("\tadd %s,%s,%s\n",trn,srn,trn);
6414 printf("\tlwz r0,0(%s)\n",trn); 6414 printf("\tlwz r0,0(%s)\n",trn);
6415 printf("\tadd r0,r0,%s\n",srn); 6415 printf("\tadd r0,r0,%s\n",srn);
6416 printf("\tmtctr r0\n"); 6416 printf("\tmtctr r0\n");
6417 printf("\tbctr\n"); 6417 printf("\tbctr\n");
6458 6458
6459 static void 6459 static void
6460 emit_asm_operand(int rstr) 6460 emit_asm_operand(int rstr)
6461 { 6461 {
6462 if (car(rstr)==REGISTER) { 6462 if (car(rstr)==REGISTER) {
6463 printf("%s",register_name(cadr(rstr))); 6463 printf("%s",register_name(cadr(rstr)));
6464 } else if (car(rstr)==CONST) { 6464 } else if (car(rstr)==CONST) {
6465 printf("%d",cadr(rstr)); 6465 printf("%d",cadr(rstr));
6466 } else if (car(rstr)==FNAME) { 6466 } else if (car(rstr)==FNAME) {
6467 printf("%s",ncaddr(rstr)->nm); 6467 printf("%s",ncaddr(rstr)->nm);
6468 } else if (car(rstr)==LABEL) { 6468 } else if (car(rstr)==LABEL) {
6469 printf("%s%d:\n",lpfx,cadr(rstr)); 6469 printf("%s%d:\n",lpfx,cadr(rstr));
6470 } else { 6470 } else {
6471 error(-1); 6471 error(-1);
6472 } 6472 }
6473 } 6473 }
6474 6474
6475 /* 6475 /*
6476 prepare asm operands 6476 prepare asm operands
6504 case '+': 6504 case '+':
6505 case '%': 6505 case '%':
6506 case '#': 6506 case '#':
6507 case '*': 6507 case '*':
6508 case '=': 6508 case '=':
6509 // output register 6509 // output register
6510 p++; 6510 p++;
6511 goto retry; 6511 goto retry;
6512 case '&': 6512 case '&':
6513 // earlyclobber 6513 // earlyclobber
6514 p++; 6514 p++;
6515 clobber = 1; 6515 clobber = 1;
6516 goto retry; 6516 goto retry;
6517 case 'b': // address base register (what?) 6517 case 'b': // address base register (what?)
6518 case 'r': 6518 case 'r':
6519 if (mode==ASM_INPUT) { 6519 if (mode==ASM_INPUT) {
6520 for(;repl0;repl0 = cadr(repl0)) { 6520 for(;repl0;repl0 = cadr(repl0)) {
6521 if (car(car(repl0))==REGISTER && caddr(repl0)==0) { 6521 if (car(car(repl0))==REGISTER && caddr(repl0)==0) {
6522 r = cadr(car(repl0)); 6522 r = cadr(car(repl0));
6523 caddr(repl0) = ASM_USED; 6523 caddr(repl0) = ASM_USED;
6524 break; 6524 break;
6525 } 6525 }
6526 } 6526 }
6527 r = get_register(); 6527 r = get_register();
6528 } else { 6528 } else {
6529 r = get_register(); 6529 r = get_register();
6530 } 6530 }
6531 repl = list3(list2(REGISTER,r),repl,clobber); 6531 repl = list3(list2(REGISTER,r),repl,clobber);
6532 break; 6532 break;
6533 case 'm': 6533 case 'm':
6534 repl = list3(list2(0,0),repl,clobber); 6534 repl = list3(list2(0,0),repl,clobber);
6535 break; 6535 break;
6536 case 'i': 6536 case 'i':
6537 if (car(e1)==GVAR) { 6537 if (car(e1)==GVAR) {
6538 e1=list3n(FNAME,0,ncaddr(e1)); 6538 e1=list3n(FNAME,0,ncaddr(e1));
6539 } else if (car(e1)==FNAME) { 6539 } else if (car(e1)==FNAME) {
6540 e1=list3n(FNAME,0,ncaddr(e1)); 6540 e1=list3n(FNAME,0,ncaddr(e1));
6541 } else if (car(e1)==STRING) { 6541 } else if (car(e1)==STRING) {
6542 val = emit_string_label(); 6542 val = emit_string_label();
6543 ascii(ncaddr(e1)->nm); 6543 ascii(ncaddr(e1)->nm);
6544 e1=list2(LABEL,val); 6544 e1=list2(LABEL,val);
6545 } else if (car(e1)==CONST) { 6545 } else if (car(e1)==CONST) {
6546 } else error(-1); 6546 } else error(-1);
6547 repl = list3(e1,repl,clobber); 6547 repl = list3(e1,repl,clobber);
6548 break; 6548 break;
6549 case '0': case '1': case '2': case '3': case '4': 6549 case '0': case '1': case '2': case '3': case '4':
6550 case '5': case '6': case '7': case '8': case '9': 6550 case '5': case '6': case '7': case '8': case '9':
6551 val = 0; 6551 val = 0;
6552 do { val = val*10 + c-'0'; } while (digit(c=*p++)); 6552 do { val = val*10 + c-'0'; } while (digit(c=*p++));
6553 if (val>MAX_ASM_REG) error(-1); // too large register 6553 if (val>MAX_ASM_REG) error(-1); // too large register
6554 if (n-val<0) error(-1); 6554 if (n-val<0) error(-1);
6555 repl = list3(car(nth(n-val-1,repl0)),repl,clobber); 6555 repl = list3(car(nth(n-val-1,repl0)),repl,clobber);
6556 break; 6556 break;
6557 default: 6557 default:
6558 printf("### unknown asm constraint %c\n",c); 6558 printf("### unknown asm constraint %c\n",c);
6559 } 6559 }
6560 return repl; 6560 return repl;
6561 } 6561 }
6562 6562
6563 void 6563 void
6564 code_free_asm_operand(int repl) 6564 code_free_asm_operand(int repl)
6565 { 6565 {
6566 for(;repl;repl=cadr(repl)) { 6566 for(;repl;repl=cadr(repl)) {
6567 if (car(car(repl))==REGISTER) 6567 if (car(car(repl))==REGISTER)
6568 free_register(cadr(car(repl))); 6568 free_register(cadr(car(repl)));
6569 } 6569 }
6570 } 6570 }
6571 6571
6572 6572
6573 extern void 6573 extern void
6579 6579
6580 text_mode(0); 6580 text_mode(0);
6581 c = *asm_str; 6581 c = *asm_str;
6582 if (c!='\t'&&c!=' ') printf("\t"); 6582 if (c!='\t'&&c!=' ') printf("\t");
6583 for(i=0;repl && i<MAX_ASM_REG;i++) { 6583 for(i=0;repl && i<MAX_ASM_REG;i++) {
6584 reg[i] = car(repl); 6584 reg[i] = car(repl);
6585 repl = cadr(repl); 6585 repl = cadr(repl);
6586 } 6586 }
6587 p = asm_str; 6587 p = asm_str;
6588 while((c = *p++)) { 6588 while((c = *p++)) {
6589 if (c=='%') { 6589 if (c=='%') {
6590 c = *p++; 6590 c = *p++;
6591 if (!c) { break; 6591 if (!c) { break;
6592 } else if (c=='%') { 6592 } else if (c=='%') {
6593 printf("%%"); continue; 6593 printf("%%"); continue;
6594 } else if (!digit(c)) { 6594 } else if (!digit(c)) {
6595 printf("%%%c",c); continue; 6595 printf("%%%c",c); continue;
6596 } 6596 }
6597 val = 0; 6597 val = 0;
6598 do { val = val*10 + c-'0'; } while (digit(c=*p++)) ; 6598 do { val = val*10 + c-'0'; } while (digit(c=*p++)) ;
6599 p--; 6599 p--;
6600 if (val>MAX_ASM_REG) error(-1); // too large register 6600 if (val>MAX_ASM_REG) error(-1); // too large register
6601 rstr = reg[val]; 6601 rstr = reg[val];
6602 emit_asm_operand(rstr); 6602 emit_asm_operand(rstr);
6603 } else { 6603 } else {
6604 printf("%c",c); 6604 printf("%c",c);
6605 } 6605 }
6606 } 6606 }
6607 printf("\n"); 6607 printf("\n");
6608 } 6608 }
6609 6609
6610 #endif 6610 #endif
6614 6614
6615 /* bit field alignment calcuration */ 6615 /* bit field alignment calcuration */
6616 6616
6617 static void 6617 static void
6618 set_bitsz(int type,int *pbitpos,int *pbitsize, 6618 set_bitsz(int type,int *pbitpos,int *pbitsize,
6619 int *psign,int *pbitsz,int *palign,int *pl) 6619 int *psign,int *pbitsz,int *palign,int *pl)
6620 { 6620 {
6621 int sign=0,bitsz=0; 6621 int sign=0,bitsz=0;
6622 int align=4,l=0; 6622 int align=4,l=0;
6623 *pbitpos = cadr(caddr(type)); 6623 *pbitpos = cadr(caddr(type));
6624 *pbitsize = caddr(caddr(type)); 6624 *pbitsize = caddr(caddr(type));
6625 switch(cadr(type)) { /* value type */ 6625 switch(cadr(type)) { /* value type */
6626 case INT: sign=1; bitsz=32; align=4;break; 6626 case INT: sign=1; bitsz=32; align=4;break;
6627 case UNSIGNED: bitsz=32; align=4;break; 6627 case UNSIGNED: bitsz=32; align=4;break;
6628 case CHAR: sign=1; bitsz= 8; align=1;break; 6628 case CHAR: sign=1; bitsz= 8; align=1;break;
6629 case UCHAR: bitsz= 8; align=1;break; 6629 case UCHAR: bitsz= 8; align=1;break;
6630 case SHORT: sign=1; bitsz=16; align=2;break; 6630 case SHORT: sign=1; bitsz=16; align=2;break;
6631 case USHORT: sign=1; bitsz=16; align=2;break; 6631 case USHORT: sign=1; bitsz=16; align=2;break;
6632 #ifdef __APPLE__ 6632 #ifdef __APPLE__
6633 case LONGLONG: sign=1; bitsz=64; align=4;l=1; break; 6633 case LONGLONG: sign=1; bitsz=64; align=4;l=1; break;
6634 case ULONGLONG: bitsz=64; align=4;l=1; break; 6634 case ULONGLONG: bitsz=64; align=4;l=1; break;
6635 #else 6635 #else
6636 case LONGLONG: sign=1; bitsz=64; align=8;l=1; break; 6636 case LONGLONG: sign=1; bitsz=64; align=8;l=1; break;
6637 case ULONGLONG: bitsz=64; align=8;l=1; break; 6637 case ULONGLONG: bitsz=64; align=8;l=1; break;
6638 #endif 6638 #endif
6639 default: error(-1); 6639 default: error(-1);
6640 } 6640 }
6641 *psign = sign; 6641 *psign = sign;
6642 *pbitsz = bitsz; 6642 *pbitsz = bitsz;
6663 6663
6664 if (bitsize>bitsz) { error(BTERR); bitsize = bitsz; } 6664 if (bitsize>bitsz) { error(BTERR); bitsize = bitsz; }
6665 6665
6666 /* bfd means previous bit field bit offset */ 6666 /* bfd means previous bit field bit offset */
6667 if (bitpos) { 6667 if (bitpos) {
6668 /* previous field is bit field and spaces may remain */ 6668 /* previous field is bit field and spaces may remain */
6669 /* calc previsous offset */ 6669 /* calc previsous offset */
6670 6670
6671 i= offset-(bitpos+7)/8; 6671 i= offset-(bitpos+7)/8;
6672 6672
6673 for(l = bitpos;l>0;l -= 8,i++) { 6673 for(l = bitpos;l>0;l -= 8,i++) {
6674 if ((i & (align-1))==0 && l+bitsize <= bitsz) { 6674 if ((i & (align-1))==0 && l+bitsize <= bitsz) {
6675 /* alignment is correct and space remains */ 6675 /* alignment is correct and space remains */
6676 *poffset=offset=i; 6676 *poffset=offset=i;
6677 i = l+bitsize; 6677 i = l+bitsize;
6678 *bfd = (i==bitsz)?0:i; 6678 *bfd = (i==bitsz)?0:i;
6679 *sz = (i+7)/8; 6679 *sz = (i+7)/8;
6680 // printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset); 6680 // printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
6681 return l; 6681 return l;
6682 } 6682 }
6683 } 6683 }
6684 } 6684 }
6685 6685
6686 /* first bit-field */ 6686 /* first bit-field */
6687 6687
6688 if ((i=(offset & (align-1)))) { 6688 if ((i=(offset & (align-1)))) {
6689 *poffset = (offset += (align-i)); 6689 *poffset = (offset += (align-i));
6690 } 6690 }
6691 bitpos = 0; 6691 bitpos = 0;
6692 *bfd = (bitsize==bitsz)?0:bitsize; 6692 *bfd = (bitsize==bitsz)?0:bitsize;
6693 *sz = (bitsize+7)/8; 6693 *sz = (bitsize+7)/8;
6694 6694
6708 size = bitsz/8; 6708 size = bitsz/8;
6709 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); 6709 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
6710 /* this implementation returns -1 for int i:1; */ 6710 /* this implementation returns -1 for int i:1; */
6711 if (l==1) { 6711 if (l==1) {
6712 #if LONGLONG_CODE 6712 #if LONGLONG_CODE
6713 // use_int(adr); 6713 // use_int(adr);
6714 use_longlong(reg); 6714 use_longlong(reg);
6715 lload(adr,reg,0); 6715 lload(adr,reg,0);
6716 /* shift left */ 6716 /* shift left */
6717 if (bitpos) 6717 if (bitpos)
6718 loprtc(LLSHIFT,reg,list2(CONST,bitpos)); 6718 loprtc(LLSHIFT,reg,list2(CONST,bitpos));
6719 /* shift right */ 6719 /* shift right */
6720 if ((i=bitsz-bitsize)) 6720 if ((i=bitsz-bitsize))
6721 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); 6721 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i));
6722 #endif 6722 #endif
6723 } else { 6723 } else {
6724 // use_int(adr); 6724 // use_int(adr);
6725 use_int(reg); 6725 use_int(reg);
6726 #ifdef __APPLE__ 6726 #ifdef __APPLE__
6727 printf("\t%s %s,lo16(%d)(%s)\n",cload(size), 6727 printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
6728 register_name(reg),0,register_name(adr)); 6728 register_name(reg),0,register_name(adr));
6729 #else 6729 #else
6730 printf("\t%s %s,%d@l(%s)\n",cload(size), 6730 printf("\t%s %s,%d@l(%s)\n",cload(size),
6731 register_name(reg),0,register_name(adr)); 6731 register_name(reg),0,register_name(adr));
6732 #endif 6732 #endif
6733 cext(sign,size,reg); 6733 cext(sign,size,reg);
6734 /* shift left */ 6734 /* shift left */
6735 if ((i=bitpos+(32-bitsz))) 6735 if ((i=bitpos+(32-bitsz)))
6736 oprtc(LSHIFT,reg,list2(CONST,i)); 6736 oprtc(LSHIFT,reg,list2(CONST,i));
6737 /* shift right */ 6737 /* shift right */
6738 if ((i=bitsz-bitsize+(32-bitsz))) 6738 if ((i=bitsz-bitsize+(32-bitsz)))
6739 oprtc(sign?RSHIFT:URSHIFT,reg,list2(CONST,i)); 6739 oprtc(sign?RSHIFT:URSHIFT,reg,list2(CONST,i));
6740 } 6740 }
6741 } 6741 }
6742 6742
6743 /* bit field replacement */ 6743 /* bit field replacement */
6744 6744
6745 static void 6745 static void
6746 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn) 6746 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn)
6747 { 6747 {
6748 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); 6748 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
6749 code_const(~mask,tmp); 6749 code_const(~mask,tmp);
6750 printf("\tor %s,%s,%s\n",trn,crn,trn); 6750 printf("\tor %s,%s,%s\n",trn,crn,trn);
6751 /* do conjunction */ 6751 /* do conjunction */
6752 printf("\tand %s,%s,%s\n",lrn,trn,lrn); 6752 printf("\tand %s,%s,%s\n",lrn,trn,lrn);
6753 /* make or-mask */ 6753 /* make or-mask */
6754 code_const(mask,tmp); 6754 code_const(mask,tmp);
6755 printf("\tand %s,%s,%s\n",trn,crn,trn); 6755 printf("\tand %s,%s,%s\n",trn,crn,trn);
6756 /* do disjunction */ 6756 /* do disjunction */
6757 printf("\tor %s,%s,%s\n",crn,trn,lrn); 6757 printf("\tor %s,%s,%s\n",crn,trn,lrn);
6758 } 6758 }
6759 6759
6760 extern void 6760 extern void
6761 code_bit_replace(int adr,int value,int type) 6761 code_bit_replace(int adr,int value,int type)
6762 { 6762 {
6771 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); 6771 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
6772 size = bitsz/8; 6772 size = bitsz/8;
6773 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); 6773 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
6774 if (l) { 6774 if (l) {
6775 #if LONGLONG_CODE 6775 #if LONGLONG_CODE
6776 // use_int(adr); 6776 // use_int(adr);
6777 lvalue = get_lregister(); 6777 lvalue = get_lregister();
6778 lload(adr,lvalue,0); 6778 lload(adr,lvalue,0);
6779 use_longlong(value); 6779 use_longlong(value);
6780 crn = lregister_name_low(value); 6780 crn = lregister_name_low(value);
6781 lrn = lregister_name_low(lvalue); 6781 lrn = lregister_name_low(lvalue);
6782 /* shift left */ 6782 /* shift left */
6783 if ((i=bitsz-bitsize-bitpos)) 6783 if ((i=bitsz-bitsize-bitpos))
6784 loprtc(LLSHIFT,value,list2(CONST,i)); 6784 loprtc(LLSHIFT,value,list2(CONST,i));
6785 trn = register_name(tmp = get_register()); 6785 trn = register_name(tmp = get_register());
6786 if (bitpos+bitsize>=32) { 6786 if (bitpos+bitsize>=32) {
6787 /* make and-mask lower */ 6787 /* make and-mask lower */
6788 mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1); 6788 mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1);
6789 make_mask_and_or(mask,tmp,trn,crn,lrn); 6789 make_mask_and_or(mask,tmp,trn,crn,lrn);
6790 } 6790 }
6791 crn = lregister_name_high(value); 6791 crn = lregister_name_high(value);
6792 lrn = lregister_name_high(lvalue); 6792 lrn = lregister_name_high(lvalue);
6793 if (bitpos<32) { 6793 if (bitpos<32) {
6794 /* make and-mask upper */ 6794 /* make and-mask upper */
6795 mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1); 6795 mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
6796 make_mask_and_or(mask,tmp,trn,crn,lrn); 6796 make_mask_and_or(mask,tmp,trn,crn,lrn);
6797 } 6797 }
6798 code_lassign(adr,value); 6798 code_lassign(adr,value);
6799 free_register(lvalue); 6799 free_register(lvalue);
6800 // free_register(adr); 6800 // free_register(adr);
6801 #endif 6801 #endif
6802 } else { 6802 } else {
6803 // use_int(adr); 6803 // use_int(adr);
6804 use_int(value); 6804 use_int(value);
6805 lvalue = get_register(); 6805 lvalue = get_register();
6806 #ifdef __APPLE__ 6806 #ifdef __APPLE__
6807 printf("\t%s %s,lo16(%d)(%s)\n",cload(size), 6807 printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
6808 register_name(lvalue),0,register_name(adr)); 6808 register_name(lvalue),0,register_name(adr));
6809 #else 6809 #else
6810 printf("\t%s %s,%d@l(%s)\n",cload(size), 6810 printf("\t%s %s,%d@l(%s)\n",cload(size),
6811 register_name(lvalue),0,register_name(adr)); 6811 register_name(lvalue),0,register_name(adr));
6812 #endif 6812 #endif
6813 cext(sign,size,lvalue); 6813 cext(sign,size,lvalue);
6814 crn = register_name(value); 6814 crn = register_name(value);
6815 lrn = register_name(lvalue); 6815 lrn = register_name(lvalue);
6816 /* shift left */ 6816 /* shift left */
6817 if ((i=bitsz-bitsize-bitpos)) 6817 if ((i=bitsz-bitsize-bitpos))
6818 oprtc(LSHIFT,value,list2(CONST,i)); 6818 oprtc(LSHIFT,value,list2(CONST,i));
6819 trn = register_name(tmp = get_register()); 6819 trn = register_name(tmp = get_register());
6820 /* make and-mask */ 6820 /* make and-mask */
6821 mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz)); 6821 mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
6822 make_mask_and_or(mask,tmp,trn,crn,lrn); 6822 make_mask_and_or(mask,tmp,trn,crn,lrn);
6823 free_register(lvalue); 6823 free_register(lvalue);
6824 code_assign(adr,size,value); 6824 code_assign(adr,size,value);
6825 } 6825 }
6826 if (tmp!=-1) free_register(tmp); 6826 if (tmp!=-1) free_register(tmp);
6827 if (use) { 6827 if (use) {
6828 code_bit_field(type,adr,USE_CREG); 6828 code_bit_field(type,adr,USE_CREG);
6829 } 6829 }
6830 } 6830 }
6831 6831
6832 static void 6832 static void
6833 make_mask_and_or_const(int mask,char *crn,int c) 6833 make_mask_and_or_const(int mask,char *crn,int c)
6834 { 6834 {
6835 char *trn; 6835 char *trn;
6836 int tmp = -1; 6836 int tmp = -1;
6837 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask); 6837 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
6838 if ((~mask|c)!=-1) { 6838 if ((~mask|c)!=-1) {
6839 trn = register_name(tmp=get_register()); 6839 trn = register_name(tmp=get_register());
6840 code_const((~mask|c),tmp); 6840 code_const((~mask|c),tmp);
6841 /* do conjunction */ 6841 /* do conjunction */
6842 printf("\tand %s,%s,%s\n",crn,trn,crn); 6842 printf("\tand %s,%s,%s\n",crn,trn,crn);
6843 } 6843 }
6844 /* make or-mask */ 6844 /* make or-mask */
6845 c = mask&c; 6845 c = mask&c;
6846 if (c!=0) { 6846 if (c!=0) {
6847 /* do disjunction */ 6847 /* do disjunction */
6848 if (!((mask&c)&0xffff0000)) { 6848 if (!((mask&c)&0xffff0000)) {
6849 #ifdef __APPLE__ 6849 #ifdef __APPLE__
6850 printf("\tori %s,%s,lo16(%d)\n",crn,crn,c); 6850 printf("\tori %s,%s,lo16(%d)\n",crn,crn,c);
6851 #else 6851 #else
6852 printf("\tori %s,%s,%d@l\n",crn,crn,c); 6852 printf("\tori %s,%s,%d@l\n",crn,crn,c);
6853 #endif 6853 #endif
6854 } else { 6854 } else {
6855 trn = register_name(tmp=get_register()); 6855 trn = register_name(tmp=get_register());
6856 code_const(c,tmp); 6856 code_const(c,tmp);
6857 printf("\tor %s,%s,%s\n",crn,trn,crn); 6857 printf("\tor %s,%s,%s\n",crn,trn,crn);
6858 } 6858 }
6859 } 6859 }
6860 if (tmp!=-1) free_register(tmp); 6860 if (tmp!=-1) free_register(tmp);
6861 } 6861 }
6862 6862
6863 extern void 6863 extern void
6876 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); 6876 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
6877 size = bitsz/8; 6877 size = bitsz/8;
6878 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); 6878 // printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
6879 if (l) { 6879 if (l) {
6880 #if LONGLONG_CODE 6880 #if LONGLONG_CODE
6881 use_int(adr); 6881 use_int(adr);
6882 lvalue = get_lregister(); 6882 lvalue = get_lregister();
6883 lload(adr,lvalue,0); 6883 lload(adr,lvalue,0);
6884 crn = lregister_name_low(lvalue); 6884 crn = lregister_name_low(lvalue);
6885 /* shift left */ 6885 /* shift left */
6886 lc = lcadr(value); 6886 lc = lcadr(value);
6887 if ((i=bitsz-bitsize-bitpos)) 6887 if ((i=bitsz-bitsize-bitpos))
6888 lc <<= i; 6888 lc <<= i;
6889 if (bitpos+bitsize>=32) { 6889 if (bitpos+bitsize>=32) {
6890 /* make and-mask lower */ 6890 /* make and-mask lower */
6891 mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1); 6891 mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1);
6892 make_mask_and_or_const(mask,crn,(int)lc); 6892 make_mask_and_or_const(mask,crn,(int)lc);
6893 } 6893 }
6894 crn = lregister_name_high(lvalue); 6894 crn = lregister_name_high(lvalue);
6895 if (bitpos<32) { 6895 if (bitpos<32) {
6896 /* make and-mask upper */ 6896 /* make and-mask upper */
6897 mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1); 6897 mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
6898 make_mask_and_or_const(mask,crn,(int)(lc>>32)); 6898 make_mask_and_or_const(mask,crn,(int)(lc>>32));
6899 } 6899 }
6900 code_lassign(adr,lvalue); 6900 code_lassign(adr,lvalue);
6901 free_register(lvalue); 6901 free_register(lvalue);
6902 #endif 6902 #endif
6903 } else { 6903 } else {
6904 use_int(adr); 6904 use_int(adr);
6905 lvalue = get_register(); 6905 lvalue = get_register();
6906 #ifdef __APPLE__ 6906 #ifdef __APPLE__
6907 printf("\t%s %s,lo16(%d)(%s)\n",cload(size), 6907 printf("\t%s %s,lo16(%d)(%s)\n",cload(size),
6908 register_name(lvalue),0,register_name(adr)); 6908 register_name(lvalue),0,register_name(adr));
6909 #else 6909 #else
6910 printf("\t%s %s,%d@l(%s)\n",cload(size), 6910 printf("\t%s %s,%d@l(%s)\n",cload(size),
6911 register_name(lvalue),0,register_name(adr)); 6911 register_name(lvalue),0,register_name(adr));
6912 #endif 6912 #endif
6913 cext(sign,size,lvalue); 6913 cext(sign,size,lvalue);
6914 crn = register_name(lvalue); 6914 crn = register_name(lvalue);
6915 /* shift left */ 6915 /* shift left */
6916 c = cadr(value); 6916 c = cadr(value);
6917 if ((i=bitsz-bitsize-bitpos)) 6917 if ((i=bitsz-bitsize-bitpos))
6918 c <<= i; 6918 c <<= i;
6919 /* make and-mask */ 6919 /* make and-mask */
6920 mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz)); 6920 mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
6921 make_mask_and_or_const(mask,crn,c); 6921 make_mask_and_or_const(mask,crn,c);
6922 code_assign(adr,size,lvalue); 6922 code_assign(adr,size,lvalue);
6923 free_register(lvalue); 6923 free_register(lvalue);
6924 } 6924 }
6925 if (use) { 6925 if (use) {
6926 code_bit_field(type,adr,USE_CREG); 6926 code_bit_field(type,adr,USE_CREG);
6927 } 6927 }
6928 } 6928 }
6929 6929
6930 #endif 6930 #endif
6931 6931