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

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

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

File size: 9.7 KB
Line 
1#include "stdafx.h"
2
3#include <CodeGenerator.h>
4
5#ifdef _AMD64_
6#include "../../BasicCompiler64/opcode.h"
7#else
8#include "../../BasicCompiler32/opcode.h"
9#endif
10
11
12void CodeGenerator::ResolveExitSubSchedule()
13{
14 BOOST_FOREACH( long exitSubCodePosition, exitSubCodePositions )
15 {
16 pNativeCode->Overwrite( exitSubCodePosition, (long)( pNativeCode->GetSize()-(exitSubCodePosition+sizeof(long)) ) );
17 }
18}
19
20void CodeGenerator::CheckUnresolveSchedule()
21{
22 if( pertialSchedules.size() > 0 )
23 {
24 compiler.errorMessenger.OutputFatalError();
25 }
26}
27
28void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, _int64 newValue )
29{
30 bool isSuccessful = false;
31
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 // 範囲外
42 compiler.errorMessenger.OutputFatalError();
43 }
44
45 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
46 }
47 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
48 {
49 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), static_cast<long>(newValue) );
50 }
51 else if( pPertialSchedule->GetTypeSize() == sizeof(_int64) )
52 {
53 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
54 }
55 else
56 {
57 compiler.errorMessenger.OutputFatalError();
58 }
59
60 it = pertialSchedules.erase( it );
61 delete pPertialSchedule;
62
63 isSuccessful = true;
64 break;
65 }
66 else
67 {
68 it++;
69 }
70 }
71
72 if( isSuccessful == false )
73 {
74 compiler.errorMessenger.OutputFatalError();
75 }
76}
77
78void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
79{
80 bool isSuccessful = false;
81
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 {
96 compiler.errorMessenger.OutputFatalError();
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 {
113 compiler.errorMessenger.OutputFatalError();
114 }
115}
116
117
118// 分岐関連
119void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
120{
121 bool isSuccessful = false;
122
123 PertialSchedules::iterator it = pertialSchedules.begin();
124 while( it != pertialSchedules.end() )
125 {
126 if( (*it) == pPertialSchedule )
127 {
128 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
129
130 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
131 {
132 if( newValue < -128 || 127 < newValue )
133 {
134 // 範囲外
135 compiler.errorMessenger.OutputFatalError();
136 }
137
138 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
139 }
140 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
141 {
142 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
143 }
144 else
145 {
146 compiler.errorMessenger.OutputFatalError();
147 }
148
149 it = pertialSchedules.erase( it );
150 delete pPertialSchedule;
151
152 isSuccessful = true;
153 }
154 else
155 {
156 it++;
157 }
158 }
159
160 if( isSuccessful == false )
161 {
162 compiler.errorMessenger.OutputFatalError();
163 }
164}
165const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
166{
167 long beginCodePos = pNativeCode->GetSize();
168
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 {
182 compiler.errorMessenger.OutputFatalError();
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 {
198 compiler.errorMessenger.OutputFatalError();
199 }
200 }
201
202 const PertialSchedule *pPertialSchedule = NULL;
203 if( isPertialSchedule )
204 {
205 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
206 pPertialSchedule = pertialSchedules.back();
207 }
208
209 if( isSelfOpcodeOffset )
210 {
211 // 自分自身の命令サイズを考慮する場合
212 offset -= ( pNativeCode->GetSize() - beginCodePos ) + op_size;
213 }
214
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 {
225 compiler.errorMessenger.OutputFatalError();
226 }
227
228 return pPertialSchedule;
229}
230const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
231{
232 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
233}
234const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
235{
236 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
237}
238const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
239{
240 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
241}
242const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
243{
244 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
245}
246const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
247{
248 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
249}
250const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
251{
252 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
253}
254const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
255{
256 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
257}
258const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
259{
260 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
261}
262const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
263{
264 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
265}
266const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
267{
268 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
269}
270const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
271{
272 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
273}
274void CodeGenerator::op_jmp_continue()
275{
276 if( GetContinueCodePos() == -1 )
277 {
278 compiler.errorMessenger.Output(12,"Continue",cp);
279 return;
280 }
281 op_jmp( GetContinueCodePos() - pNativeCode->GetSize(), sizeof(long), false, true );
282}
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}
292void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
293{
294 // オペコード
295 pNativeCode->Put( (char)0xE9 );
296
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 );
307
308 pertialSchedules.push_back( pGotoLabelSchedule );
309
310 pNativeCode->Put( (long)0 );
311}
312
313void CodeGenerator::op_AddNeedFreeTempStructure( int reg )
314{
315#ifdef _AMD64_
316 //////////////////////////////////////////////////////
317 ///// レジスタ資源のバックアップ
318 { BACKUP_REGISTER_RESOURCE
319 //////////////////////////////////////////////////////
320
321 //mov rcx,reg
322 op_mov_RR( REG_RCX, reg );
323
324 //call _System_AddNeedFreeTempStructure
325 extern const UserProc *pSub_System_AddNeedFreeTempStructure;
326 op_call( pSub_System_AddNeedFreeTempStructure );
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.