source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/CommonCodeGenerator.cpp@ 484

Last change on this file since 484 was 484, checked in by dai_9181, 16 years ago

プロジェクトのリネーム中

File size: 9.7 KB
RevLine 
[239]1#include "stdafx.h"
2
3#include <CodeGenerator.h>
4
[436]5#ifdef _AMD64_
6#include "../../BasicCompiler64/opcode.h"
7#else
[484]8#include "../../compiler_x86/opcode.h"
[436]9#endif
[239]10
[436]11
[247]12void CodeGenerator::ResolveExitSubSchedule()
13{
14 BOOST_FOREACH( long exitSubCodePosition, exitSubCodePositions )
15 {
16 pNativeCode->Overwrite( exitSubCodePosition, (long)( pNativeCode->GetSize()-(exitSubCodePosition+sizeof(long)) ) );
17 }
18}
19
[239]20void CodeGenerator::CheckUnresolveSchedule()
21{
22 if( pertialSchedules.size() > 0 )
23 {
[465]24 compiler.errorMessenger.OutputFatalError();
[239]25 }
26}
27
[357]28void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, _int64 newValue )
[251]29{
30 bool isSuccessful = false;
[239]31
[251]32 PertialSchedules::iterator it = pertialSchedules.begin();
33 while( it != pertialSchedules.end() )
34 {
35 if( (*it) == pPertialSchedule )
36 {
37 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
38 {
39 if( newValue < -128 || 127 < newValue )
40 {
41 // 範囲外
[465]42 compiler.errorMessenger.OutputFatalError();
[251]43 }
44
45 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
46 }
47 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
48 {
[357]49 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), static_cast<long>(newValue) );
50 }
51 else if( pPertialSchedule->GetTypeSize() == sizeof(_int64) )
52 {
[251]53 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
54 }
55 else
56 {
[465]57 compiler.errorMessenger.OutputFatalError();
[251]58 }
59
60 it = pertialSchedules.erase( it );
61 delete pPertialSchedule;
62
63 isSuccessful = true;
[253]64 break;
[251]65 }
66 else
67 {
68 it++;
69 }
70 }
71
72 if( isSuccessful == false )
73 {
[465]74 compiler.errorMessenger.OutputFatalError();
[251]75 }
76}
77
[253]78void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
79{
80 bool isSuccessful = false;
[251]81
[253]82 PertialSchedules::iterator it = pertialSchedules.begin();
83 while( it != pertialSchedules.end() )
84 {
85 if( (*it) == pPertialSchedule )
86 {
87 if( pPertialSchedule->GetTypeSize() == sizeof(long) )
88 {
89 pNativeCode->Overwrite(
90 pPertialSchedule->GetCodePos(),
91 pNativeCode->GetLong(pPertialSchedule->GetCodePos()) + offset
92 );
93 }
94 else
95 {
[465]96 compiler.errorMessenger.OutputFatalError();
[253]97 }
98
99 it = pertialSchedules.erase( it );
100 delete pPertialSchedule;
101
102 isSuccessful = true;
103 break;
104 }
105 else
106 {
107 it++;
108 }
109 }
110
111 if( isSuccessful == false )
112 {
[465]113 compiler.errorMessenger.OutputFatalError();
[253]114 }
115}
116
117
[239]118// 分岐関連
119void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
120{
121 bool isSuccessful = false;
122
[248]123 PertialSchedules::iterator it = pertialSchedules.begin();
[239]124 while( it != pertialSchedules.end() )
125 {
126 if( (*it) == pPertialSchedule )
127 {
[241]128 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
129
[239]130 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
131 {
[241]132 if( newValue < -128 || 127 < newValue )
133 {
134 // 範囲外
[465]135 compiler.errorMessenger.OutputFatalError();
[241]136 }
[239]137
[241]138 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
[239]139 }
[241]140 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
141 {
142 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
143 }
[239]144 else
145 {
[465]146 compiler.errorMessenger.OutputFatalError();
[239]147 }
148
[245]149 it = pertialSchedules.erase( it );
[239]150 delete pPertialSchedule;
151
152 isSuccessful = true;
153 }
154 else
155 {
156 it++;
157 }
158 }
159
160 if( isSuccessful == false )
161 {
[465]162 compiler.errorMessenger.OutputFatalError();
[239]163 }
164}
[248]165const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]166{
[241]167 long beginCodePos = pNativeCode->GetSize();
[239]168
[241]169 if( opcode == (char)0xEB )
170 {
171 // jmp命令のとき
172 if( op_size == sizeof(char) )
173 {
174 pNativeCode->Put( (char)opcode );
175 }
176 else if( op_size == sizeof(long) )
177 {
178 pNativeCode->Put( (char)0xE9 );
179 }
180 else
181 {
[465]182 compiler.errorMessenger.OutputFatalError();
[241]183 }
184 }
185 else
186 {
187 if( op_size == sizeof(char) )
188 {
189 pNativeCode->Put( (char)((char)0x70 | opcode) );
190 }
191 else if( op_size == sizeof(long) )
192 {
193 pNativeCode->Put( (char)0x0F );
194 pNativeCode->Put( (char)((char)0x80 | opcode) );
195 }
196 else
197 {
[465]198 compiler.errorMessenger.OutputFatalError();
[241]199 }
200 }
201
[245]202 const PertialSchedule *pPertialSchedule = NULL;
[239]203 if( isPertialSchedule )
204 {
205 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
[251]206 pPertialSchedule = pertialSchedules.back();
[239]207 }
208
[241]209 if( isSelfOpcodeOffset )
210 {
211 // 自分自身の命令サイズを考慮する場合
[276]212 offset -= ( pNativeCode->GetSize() - beginCodePos ) + op_size;
[241]213 }
214
[239]215 if( op_size == sizeof(char) )
216 {
217 pNativeCode->Put( (char)offset );
218 }
219 else if( op_size == sizeof(long) )
220 {
221 pNativeCode->Put( offset );
222 }
223 else
224 {
[465]225 compiler.errorMessenger.OutputFatalError();
[239]226 }
227
228 return pPertialSchedule;
229}
[250]230const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]231{
[250]232 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]233}
[250]234const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]235{
[250]236 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]237}
[250]238const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]239{
[250]240 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]241}
[250]242const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]243{
[250]244 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]245}
[250]246const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]247{
[250]248 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]249}
[250]250const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]251{
[250]252 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]253}
[250]254const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]255{
[250]256 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]257}
[250]258const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]259{
[250]260 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]261}
[250]262const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]263{
[250]264 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]265}
[250]266const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]267{
[250]268 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]269}
[248]270const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]271{
[241]272 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]273}
[241]274void CodeGenerator::op_jmp_continue()
275{
[254]276 if( GetContinueCodePos() == -1 )
[241]277 {
[465]278 compiler.errorMessenger.Output(12,"Continue",cp);
[241]279 return;
280 }
[254]281 op_jmp( GetContinueCodePos() - pNativeCode->GetSize(), sizeof(long), false, true );
[241]282}
[247]283void CodeGenerator::op_jmp_exitsub()
284{
285 // オペコード
286 pNativeCode->Put( (char)0xE9 );
287
288 exitSubCodePositions.push_back( pNativeCode->GetSize() );
289
290 pNativeCode->Put( (long)0 );
291}
[253]292void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
[246]293{
294 // オペコード
295 pNativeCode->Put( (char)0xE9 );
296
[253]297 const GotoLabelSchedule *pGotoLabelSchedule = NULL;
298 if( name.size() == 0 )
299 {
300 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
301 }
302 else
303 {
304 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
305 }
306 gotoLabelSchedules.push_back( pGotoLabelSchedule );
[246]307
[253]308 pertialSchedules.push_back( pGotoLabelSchedule );
309
[246]310 pNativeCode->Put( (long)0 );
311}
[435]312
313void CodeGenerator::op_AddNeedFreeTempStructure( int reg )
314{
315#ifdef _AMD64_
316 //////////////////////////////////////////////////////
317 ///// レジスタ資源のバックアップ
318 { BACKUP_REGISTER_RESOURCE
319 //////////////////////////////////////////////////////
320
[436]321 //mov rcx,reg
322 op_mov_RR( REG_RCX, reg );
[435]323
[436]324 //call _System_AddNeedFreeTempStructure
325 extern const UserProc *pSub_System_AddNeedFreeTempStructure;
326 op_call( pSub_System_AddNeedFreeTempStructure );
[435]327
328 /////////////////////////////////////////////
329 ////// レジスタ資源を復元
330 RESTORE_REGISTER_RESOURCE
331 }////////////////////////////////////////////
332#else
333
334 //push useReg(引き続き利用するため、退避しておく)
335 compiler.codeGenerator.op_push( reg );
336
337 //push useReg
338 compiler.codeGenerator.op_push( reg );
339
340 //call _System_AddNeedFreeTempStructure
341 extern const UserProc *pSub_System_AddNeedFreeTempStructure;
342 compiler.codeGenerator.op_call( pSub_System_AddNeedFreeTempStructure );
343
344 //pop useReg(復元する)
345 compiler.codeGenerator.op_pop( reg );
346#endif
347
348 isNeedFreeTempStructureInCurrentStep = true;
349}
350void CodeGenerator::op_FreeTempStructure()
351{
352 if( !isNeedFreeTempStructureInCurrentStep )
353 {
354 // 解放の必要はない
355 return;
356 }
357
358 // call _System_FreeTempStructure
359 extern const UserProc *pSub_System_FreeTempStructure;
360 op_call( pSub_System_FreeTempStructure );
361
362 isNeedFreeTempStructureInCurrentStep = false;
363}
Note: See TracBrowser for help on using the repository browser.