source: dev/trunk/abdev/BasicCompiler32/increment.cpp@ 330

Last change on this file since 330 was 329, checked in by dai_9181, 17 years ago

"obj+=value" など、オブジェクトに対する代入演算の構文を "obj=obj+value" と置換して解釈するようにした。

File size: 5.1 KB
RevLine 
[206]1#include "stdafx.h"
2
[225]3#include <Compiler.h>
4
[3]5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
[329]8void IncDec(int idCalc, const char *lpszLeft, const char *lpszRight)
9{
10 Type varType;
11 if( GetVarType( lpszLeft, varType, false ) )
12 {
13 if( varType.IsObject() )
14 {
15 // オブジェクトが対象だったとき
16 char temporary[8192];
17 char calcStr[32];
18 GetCalcName( idCalc, calcStr );
19 sprintf( temporary, "%s=%s %s %s", lpszLeft, lpszLeft, calcStr, lpszRight );
20 SetEscapeSequenceFormat( temporary );
21 KillStringSpaces( temporary );
22 OpcodeCalc( temporary );
23 return;
24 }
25 }
[3]26
27 ///////////////////////////
28 // 変数アドレスを取得
29 ///////////////////////////
[75]30 RELATIVE_VAR VarRelativeVar;
[11]31 if(!GetVarOffsetReadWrite(
[3]32 lpszLeft,
33 &VarRelativeVar,
[75]34 varType)) return;
[3]35
36 if(IsUse_ecx(&VarRelativeVar)){
37 //push ecx
[225]38 compiler.codeGenerator.op_push(REG_ECX);
[3]39 }
40
41
42 ///////////////////////////////////
43 // レジスタへ変数の内容をコピー
44 ///////////////////////////////////
45
[75]46 if( varType.IsReal() ){
[3]47 //実数
[75]48 SetReg_RealVariable(varType.GetBasicType(),&VarRelativeVar);
[3]49 }
50 else{
51 //整数
[290]52 SetReg_WholeVariable(varType,&VarRelativeVar,REG_EAX);
[3]53 }
54
55
[75]56 if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&&
[3]57 (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){
58 ////////////////////////////////////////////
59 // 整数型のインクリメント・デクリメント
60 ////////////////////////////////////////////
61
[75]62 if( varType.Is64() ){
[3]63 if(idCalc==CALC_ADDITION){
64 //64ビット インクリメント
65
66 //add eax,1
[225]67 compiler.codeGenerator.op_add_RV8(REG_EAX,1);
[3]68
69 //adc edx,0
[225]70 compiler.codeGenerator.op_adc_RV8(REG_EDX,0);
[3]71 }
72 else if(idCalc==CALC_SUBTRACTION){
73 //64ビット デクリメント
74
75 //sub eax,1
[225]76 compiler.codeGenerator.op_sub_RV8(REG_EAX,1);
[3]77
78 //sbb edx,0
[225]79 compiler.codeGenerator.op_sbb_RV8(REG_EDX,0);
[3]80 }
81 }
82 else{
83 if(idCalc==CALC_ADDITION){
84 //インクリメント
[225]85 compiler.codeGenerator.op_inc(REG_EAX);
[3]86 }
87 else if(idCalc==CALC_SUBTRACTION){
88 //デクリメント
[225]89 compiler.codeGenerator.op_dec(REG_EAX);
[3]90 }
91 }
92 }
93 else{
94 //変数オフセットを一時退避
95 //push ecx
[225]96 compiler.codeGenerator.op_push(REG_ECX);
[3]97
[75]98 if( varType.IsDouble() ){
[3]99 //sub esp,8
[225]100 compiler.codeGenerator.op_sub_esp(8);
[3]101
102 //fstp qword ptr[esp]
[225]103 compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP);
[3]104 }
[75]105 else if( varType.IsSingle() ){
[3]106 //sub esp,4
[225]107 compiler.codeGenerator.op_sub_esp(4);
[3]108
109 //fstp dword ptr[esp]
[225]110 compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP);
[3]111 }
[75]112 else if( varType.Is64() ){
[3]113 //push edx
[225]114 compiler.codeGenerator.op_push(REG_EDX);
[3]115
116 //push eax
[225]117 compiler.codeGenerator.op_push(REG_EAX);
[3]118 }
119 else{
120 //push eax
[225]121 compiler.codeGenerator.op_push(REG_EAX);
[3]122 }
123
[75]124 Type calcType;
125 if( !NumOpe(lpszRight,varType,calcType) ){
126 return;
127 }
[3]128
[75]129 if( varType.IsDouble() ) ChangeTypeToDouble(calcType.GetBasicType());
130 else if( varType.IsSingle() ) ChangeTypeToSingle(calcType.GetBasicType());
[290]131 else ChangeTypeToWhole( calcType, varType );
[3]132
[75]133 int type_stack[255],sp;
[3]134 LONG_PTR index_stack[255];
[75]135 type_stack[0]=varType.GetBasicType();
136 type_stack[1]=varType.GetBasicType();
137 index_stack[0]=varType.GetIndex();
138 index_stack[1]=varType.GetIndex();
[3]139 sp=2;
140
141 switch(idCalc){
142 case CALC_XOR:
[75]143 Calc_Xor(type_stack,index_stack,&sp);
[3]144 break;
145 case CALC_OR:
[75]146 Calc_Or(type_stack,index_stack,&sp);
[3]147 break;
148 case CALC_AND:
[75]149 Calc_And(type_stack,index_stack,&sp);
[3]150 break;
151 case CALC_SHL:
[75]152 Calc_SHL(type_stack,&sp);
[3]153 break;
154 case CALC_SHR:
[75]155 Calc_SHR(type_stack,&sp);
[3]156 break;
157 case CALC_ADDITION:
158 case CALC_SUBTRACTION:
159 case CALC_PRODUCT:
[75]160 CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp);
[3]161 break;
162 case CALC_MOD:
[75]163 Calc_Mod(type_stack,&sp);
[3]164 break;
165 case CALC_QUOTIENT:
[75]166 Calc_Divide(type_stack,&sp,varType.GetBasicType());
[3]167 break;
168 case CALC_INTQUOTIENT:
[75]169 Calc_IntDivide(type_stack,index_stack,&sp);
[3]170 break;
171 case CALC_POWER:
[75]172 Calc_Power(type_stack,&sp);
[3]173 break;
174 }
175
176
[75]177 if( varType.IsDouble() ){
[3]178 //fld qword ptr[esp]
[225]179 compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP);
[3]180
181 //add esp,8
[225]182 compiler.codeGenerator.op_add_esp(8);
[3]183 }
[75]184 else if( varType.IsSingle() ){
[3]185 //fld dword ptr[esp]
[225]186 compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP);
[3]187
188 //add esp,4
[225]189 compiler.codeGenerator.op_add_esp(4);
[3]190 }
[75]191 else if( varType.Is64() ){
[3]192 //pop eax
[225]193 compiler.codeGenerator.op_pop(REG_EAX);
[3]194
195 //pop edx
[225]196 compiler.codeGenerator.op_pop(REG_EDX);
[3]197 }
198 else{
199 //pop eax
[225]200 compiler.codeGenerator.op_pop(REG_EAX);
[3]201 }
202
203
204 //変数オフセットを復元
205 //pop ecx
[225]206 compiler.codeGenerator.op_pop(REG_ECX);
[3]207 }
208
209
210 /////////////////////////////////////////////////
211 // レジスタの内容を変数にコピー
212 /////////////////////////////////////////////////
213
214 if(IsUse_ecx(&VarRelativeVar)){
215 //pop ecx
[225]216 compiler.codeGenerator.op_pop(REG_ECX);
[3]217 }
218
[290]219 SetVariableFromEax(varType,varType.GetBasicType(),&VarRelativeVar);
[3]220}
Note: See TracBrowser for help on using the repository browser.