source: dev/trunk/abdev/BasicCompiler_Common/src/CommonCodeGenerator.cpp@ 254

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