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
RevLine 
[239]1#include "stdafx.h"
2
3#include <CodeGenerator.h>
4
5
[247]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
[239]21void CodeGenerator::CheckUnresolveSchedule()
22{
23 if( pertialSchedules.size() > 0 )
24 {
25 SetError();
26 }
27}
28
[251]29void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, long newValue )
30{
31 bool isSuccessful = false;
[239]32
[251]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;
[253]67 break;
[251]68 }
69 else
70 {
71 it++;
72 }
73 }
74
75 if( isSuccessful == false )
76 {
77 SetError();
78 }
79}
80
[253]81void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
82{
83 bool isSuccessful = false;
[251]84
[253]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
[239]127// 分岐関連
128void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
129{
130 bool isSuccessful = false;
131
[248]132 PertialSchedules::iterator it = pertialSchedules.begin();
[239]133 while( it != pertialSchedules.end() )
134 {
135 if( (*it) == pPertialSchedule )
136 {
[241]137 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
138
139 extern int obp;
140 long newValueOld = obp - (pPertialSchedule->GetObpOld()+pPertialSchedule->GetTypeSize());
141
[239]142 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
143 {
[241]144 if( newValue < -128 || 127 < newValue )
145 {
146 // 範囲外
147 SetError();
148 }
[239]149
[241]150 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
151
[239]152 // TODO: 未完成(用が無くなったら消す)
[241]153 pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), (char)newValueOld );
[239]154 }
[241]155 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
156 {
157 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
158
159 // TODO: 未完成(用が無くなったら消す)
160 pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), newValueOld );
161 }
[239]162 else
163 {
164 SetError();
165 }
166
[245]167 it = pertialSchedules.erase( it );
[239]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}
[248]183const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]184{
[241]185 long beginCodePos = pNativeCode->GetSize();
186 {
187 // TODO: 未完成
188 extern int obp;
189 beginCodePos = obp;
190 }
[239]191
[241]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
[245]225 const PertialSchedule *pPertialSchedule = NULL;
[239]226 if( isPertialSchedule )
227 {
228 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
[251]229 pPertialSchedule = pertialSchedules.back();
[239]230 }
231
[241]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
[239]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}
[250]257const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]258{
[250]259 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]260}
[250]261const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]262{
[250]263 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]264}
[250]265const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]266{
[250]267 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]268}
[250]269const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]270{
[250]271 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]272}
[250]273const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]274{
[250]275 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]276}
[250]277const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]278{
[250]279 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]280}
[250]281const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]282{
[250]283 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]284}
[250]285const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]286{
[250]287 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]288}
[250]289const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]290{
[250]291 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]292}
[250]293const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]294{
[250]295 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]296}
[248]297const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]298{
[241]299 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]300}
[241]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}
[247]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}
[253]328void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
[246]329{
330 // オペコード
331 pNativeCode->Put( (char)0xE9 );
332
[253]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 );
[246]343
[253]344 pertialSchedules.push_back( pGotoLabelSchedule );
345
[246]346 pNativeCode->Put( (long)0 );
347}
Note: See TracBrowser for help on using the repository browser.