Changeset 408 in dev for trunk/abdev/BasicCompiler64
- Timestamp:
- Mar 2, 2008, 5:40:44 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abdev/BasicCompiler64/Compile_Statement.cpp
r402 r408 669 669 std::vector<SelectSchedule> selectSchedules; 670 670 671 void OpcodeSelect( const char *lpszParms ){ 671 void OpcodeSelect( const char *lpszParms ) 672 { 672 673 extern HANDLE hHeap; 673 674 extern char *basbuf; … … 677 678 int reg1=REG_RAX; 678 679 Type type1; 679 if( !NumOpe(®1,lpszParms,Type(), type1 ) ){ 680 return; 681 } 680 bool result = NumOpe(®1,lpszParms,Type(), type1 ); 682 681 683 682 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) ); 684 683 685 if( selectSchedules.back().typeSize < sizeof(long) ){ 686 selectSchedules.back().typeSize = sizeof(long); 687 } 688 689 if(type1.IsDouble()){ 690 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 691 pobj_sf->push(reg1,sizeof(double)); 692 } 693 else if(type1.IsSingle()){ 694 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 695 pobj_sf->push(reg1,sizeof(float)); 696 } 697 else{ 698 ExtendTypeTo64(type1.GetBasicType(),reg1); 699 700 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 701 pobj_sf->push(reg1); 702 } 703 704 for(i=cp;;i++){ 705 if(basbuf[i]=='\0'){ 706 selectSchedules.pop_back(); 707 SetError(22,"Select",cp); 708 return; 709 } 710 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){ 711 for(i2=0;;i++){ 712 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++; 713 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){ 714 i2--; 715 if(i2==0) break; 684 if( result ) 685 { 686 if( selectSchedules.back().typeSize < sizeof(long) ){ 687 selectSchedules.back().typeSize = sizeof(long); 688 } 689 690 if(type1.IsDouble()){ 691 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 692 pobj_sf->push(reg1,sizeof(double)); 693 } 694 else if(type1.IsSingle()){ 695 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 696 pobj_sf->push(reg1,sizeof(float)); 697 } 698 else{ 699 ExtendTypeTo64(type1.GetBasicType(),reg1); 700 701 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 702 pobj_sf->push(reg1); 703 } 704 705 for(i=cp;;i++){ 706 if(basbuf[i]=='\0'){ 707 selectSchedules.pop_back(); 708 SetError(22,"Select",cp); 709 return; 710 } 711 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){ 712 for(i2=0;;i++){ 713 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++; 714 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){ 715 i2--; 716 if(i2==0) break; 717 } 716 718 } 717 } 718 continue; 719 } 720 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break; 721 722 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){ 723 NowCaseCp=i; 724 725 i++; 726 while(1){ 727 for(i++,i2=0;;i++,i2++){ 728 if(basbuf[i]=='\"'){ 729 i3=GetStringInQuotation(temporary+i2,basbuf+i); 730 i+=i3-1; 731 i2+=i3-1; 732 continue; 719 continue; 720 } 721 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break; 722 723 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){ 724 NowCaseCp=i; 725 726 i++; 727 while(1){ 728 for(i++,i2=0;;i++,i2++){ 729 if(basbuf[i]=='\"'){ 730 i3=GetStringInQuotation(temporary+i2,basbuf+i); 731 i+=i3-1; 732 i2+=i3-1; 733 continue; 734 } 735 if(basbuf[i]=='('){ 736 i3=GetStringInPare(temporary+i2,basbuf+i); 737 i+=i3-1; 738 i2+=i3-1; 739 continue; 740 } 741 if(basbuf[i]=='['){ 742 i3=GetStringInBracket(temporary+i2,basbuf+i); 743 i+=i3-1; 744 i2+=i3-1; 745 continue; 746 } 747 748 if(IsCommandDelimitation(basbuf[i])){ 749 temporary[i2]=0; 750 break; 751 } 752 if(basbuf[i]==','){ 753 temporary[i2]=0; 754 break; 755 } 756 757 temporary[i2]=basbuf[i]; 733 758 } 734 if(basbuf[i]=='('){ 735 i3=GetStringInPare(temporary+i2,basbuf+i); 736 i+=i3-1; 737 i2+=i3-1; 738 continue; 739 } 740 if(basbuf[i]=='['){ 741 i3=GetStringInBracket(temporary+i2,basbuf+i); 742 i+=i3-1; 743 i2+=i3-1; 744 continue; 745 } 746 747 if(IsCommandDelimitation(basbuf[i])){ 748 temporary[i2]=0; 749 break; 750 } 751 if(basbuf[i]==','){ 752 temporary[i2]=0; 753 break; 754 } 755 756 temporary[i2]=basbuf[i]; 757 } 758 759 //エラー用 760 i2=cp; 761 cp=NowCaseCp; 762 763 int reg2=REG_RDX; 764 Type type2; 765 if( !NumOpe(®2,temporary,type1,type2) ){ 766 return; 767 } 768 769 cp=i2; 770 771 if(type1.IsObject()){ 772 std::vector<const UserProc *> subs; 773 type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs ); 774 if( subs.size() == 0 ){ 759 760 //エラー用 761 i2=cp; 762 cp=NowCaseCp; 763 764 int reg2=REG_RDX; 765 Type type2; 766 if( !NumOpe(®2,temporary,type1,type2) ){ 775 767 return; 776 768 } 777 769 778 Parameters params; 779 params.push_back( new Parameter( "", Type( type2 ) ) ); 780 781 //オーバーロードを解決 782 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL); 783 784 delete params[0]; 785 786 if(!pUserProc){ 787 //エラー 788 return; 789 } 790 791 792 //実体オブジェクト 793 if(reg2!=REG_RDX){ 794 //mov rdx,reg2 795 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2); 796 } 797 798 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照 799 pobj_sf->ref(REG_RCX); 800 801 //call operator_proc ※ ==演算子 802 compiler.codeGenerator.op_call(pUserProc); 803 804 //test rax,rax 805 compiler.codeGenerator.op_test(REG_RAX,REG_RAX); 806 807 //jne ... 808 selectSchedules.back().casePertialSchedules.push_back( 809 compiler.codeGenerator.op_jne( 0, sizeof(long), true ) 810 ); 811 } 812 else{ 813 if(type1.IsDouble()){ 814 int xmm_reg; 815 if(IsXmmReg(reg2)) xmm_reg=reg2; 816 else xmm_reg=REG_XMM5; 817 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2); 818 819 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照 820 pobj_sf->ref(REG_XMM4,sizeof(double)); 821 822 //comiss xmm_reg1,xmm_reg2 823 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4); 824 } 825 else if(type1.IsSingle()){ 826 int xmm_reg; 827 if(IsXmmReg(reg2)) xmm_reg=reg2; 828 else xmm_reg=REG_XMM5; 829 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2); 830 831 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照 832 pobj_sf->ref(REG_XMM4,sizeof(float)); 833 834 //comiss xmm_reg1,xmm_reg2 835 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4); 770 cp=i2; 771 772 if(type1.IsObject()){ 773 std::vector<const UserProc *> subs; 774 type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs ); 775 if( subs.size() == 0 ){ 776 return; 777 } 778 779 Parameters params; 780 params.push_back( new Parameter( "", Type( type2 ) ) ); 781 782 //オーバーロードを解決 783 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL); 784 785 delete params[0]; 786 787 if(!pUserProc){ 788 //エラー 789 return; 790 } 791 792 793 //実体オブジェクト 794 if(reg2!=REG_RDX){ 795 //mov rdx,reg2 796 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2); 797 } 798 799 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照 800 pobj_sf->ref(REG_RCX); 801 802 //call operator_proc ※ ==演算子 803 compiler.codeGenerator.op_call(pUserProc); 804 805 //test rax,rax 806 compiler.codeGenerator.op_test(REG_RAX,REG_RAX); 807 808 //jne ... 809 selectSchedules.back().casePertialSchedules.push_back( 810 compiler.codeGenerator.op_jne( 0, sizeof(long), true ) 811 ); 836 812 } 837 813 else{ 838 //その他整数型 839 840 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1); 841 842 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照 843 pobj_sf->ref(REG_R14); 844 845 //cmp reg2,r14 846 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14); 814 if(type1.IsDouble()){ 815 int xmm_reg; 816 if(IsXmmReg(reg2)) xmm_reg=reg2; 817 else xmm_reg=REG_XMM5; 818 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2); 819 820 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照 821 pobj_sf->ref(REG_XMM4,sizeof(double)); 822 823 //comiss xmm_reg1,xmm_reg2 824 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4); 825 } 826 else if(type1.IsSingle()){ 827 int xmm_reg; 828 if(IsXmmReg(reg2)) xmm_reg=reg2; 829 else xmm_reg=REG_XMM5; 830 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2); 831 832 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照 833 pobj_sf->ref(REG_XMM4,sizeof(float)); 834 835 //comiss xmm_reg1,xmm_reg2 836 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4); 837 } 838 else{ 839 //その他整数型 840 841 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1); 842 843 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照 844 pobj_sf->ref(REG_R14); 845 846 //cmp reg2,r14 847 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14); 848 } 849 850 //je ... 851 selectSchedules.back().casePertialSchedules.push_back( 852 compiler.codeGenerator.op_je( 0, sizeof(long), true ) 853 ); 847 854 } 848 855 849 //je ... 850 selectSchedules.back().casePertialSchedules.push_back( 851 compiler.codeGenerator.op_je( 0, sizeof(long), true ) 852 ); 856 if(basbuf[i]!=',') break; 853 857 } 854 855 if(basbuf[i]!=',') break; 856 } 857 } 858 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){ 859 //jmp ... 860 selectSchedules.back().casePertialSchedules.push_back( 861 compiler.codeGenerator.op_jmp( 0, sizeof(long), true ) 862 ); 863 } 864 } 865 866 //スタックフレームを1スペースだけ解除 867 pobj_sf->pop(REG_NON); 858 } 859 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){ 860 //jmp ... 861 selectSchedules.back().casePertialSchedules.push_back( 862 compiler.codeGenerator.op_jmp( 0, sizeof(long), true ) 863 ); 864 } 865 } 866 867 //スタックフレームを1スペースだけ解除 868 pobj_sf->pop(REG_NON); 869 } 868 870 869 871 //レキシカルスコープをレベルアップ
Note:
See TracChangeset
for help on using the changeset viewer.