Mercurial > hg > CbC > old > device
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&® == ireg) { | 2379 if (ireg&® == 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&®s[regv_h(lreg)]==USING_REG) { | 2387 if (regv_h(lreg)>reg&®s[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&®s[regv_l(lreg)]==USING_REG) { | 2395 if (regv_h(lreg)>reg&®s[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&® == freg) { | 2407 if (freg&® == 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,®_arg,&freg_arg); | 2630 increment_function_arg(e3,&nargs,®_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,®_arg,&freg_arg), | 2671 increment_function_arg(e3,&nargs,®_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,®_arg,&freg_arg), | 2692 increment_function_arg(e3,&nargs,®_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&®!=RET_LREGISTER) | 6092 if (reg!=USE_CREG&®!=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&®!=RET_LREGISTER) | 6102 if (reg!=USE_CREG&®!=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&®!=RET_LREGISTER) | 6112 if (reg!=USE_CREG&®!=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&®!=RET_LREGISTER) | 6122 if (reg!=USE_CREG&®!=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&®!=RET_FREGISTER) | 6132 if (reg!=USE_CREG&®!=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&®!=RET_FREGISTER) | 6143 if (reg!=USE_CREG&®!=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 |