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

Last change on this file since 253 was 253, checked in by dai_9181, 17 years ago
File size: 9.1 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 //op_jmp( GetContinueCodePos()-(pNativeCode->GetSize()+sizeof(long)), sizeof(long) );
304
305 // TODO: 未完成(OpBuffer/obp廃止が整ったら上記のコードを有効にすべし)
306
307 if( GetContinueCodePosOld() == -1 )
308 {
309 SetError(12,"Continue",cp);
310 return;
311 }
312
313 extern int obp;
314 op_jmp( GetContinueCodePosOld()-obp, sizeof(long), false, true );
315}
316void CodeGenerator::op_jmp_exitsub()
317{
318 // オペコード
319 pNativeCode->Put( (char)0xE9 );
320
321 exitSubCodePositions.push_back( pNativeCode->GetSize() );
322
323 extern int obp;
324 _exitSubCodePositions_ObpOld.push_back( obp );
325
326 pNativeCode->Put( (long)0 );
327}
328void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
329{
330 // オペコード
331 pNativeCode->Put( (char)0xE9 );
332
333 const GotoLabelSchedule *pGotoLabelSchedule = NULL;
334 if( name.size() == 0 )
335 {
336 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
337 }
338 else
339 {
340 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
341 }
342 gotoLabelSchedules.push_back( pGotoLabelSchedule );
343
344 pertialSchedules.push_back( pGotoLabelSchedule );
345
346 pNativeCode->Put( (long)0 );
347}
Note: See TracBrowser for help on using the repository browser.