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

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