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

Last change on this file since 318 was 276, checked in by dai_9181, 17 years ago
File size: 7.7 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
[239]14void CodeGenerator::CheckUnresolveSchedule()
15{
16 if( pertialSchedules.size() > 0 )
17 {
18 SetError();
19 }
20}
21
[251]22void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, long newValue )
23{
24 bool isSuccessful = false;
[239]25
[251]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;
[253]54 break;
[251]55 }
56 else
57 {
58 it++;
59 }
60 }
61
62 if( isSuccessful == false )
63 {
64 SetError();
65 }
66}
67
[253]68void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
69{
70 bool isSuccessful = false;
[251]71
[253]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
[239]108// 分岐関連
109void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
110{
111 bool isSuccessful = false;
112
[248]113 PertialSchedules::iterator it = pertialSchedules.begin();
[239]114 while( it != pertialSchedules.end() )
115 {
116 if( (*it) == pPertialSchedule )
117 {
[241]118 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
119
[239]120 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
121 {
[241]122 if( newValue < -128 || 127 < newValue )
123 {
124 // 範囲外
125 SetError();
126 }
[239]127
[241]128 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
[239]129 }
[241]130 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
131 {
132 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
133 }
[239]134 else
135 {
136 SetError();
137 }
138
[245]139 it = pertialSchedules.erase( it );
[239]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}
[248]155const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]156{
[241]157 long beginCodePos = pNativeCode->GetSize();
[239]158
[241]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
[245]192 const PertialSchedule *pPertialSchedule = NULL;
[239]193 if( isPertialSchedule )
194 {
195 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
[251]196 pPertialSchedule = pertialSchedules.back();
[239]197 }
198
[241]199 if( isSelfOpcodeOffset )
200 {
201 // 自分自身の命令サイズを考慮する場合
[276]202 offset -= ( pNativeCode->GetSize() - beginCodePos ) + op_size;
[241]203 }
204
[239]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}
[250]220const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]221{
[250]222 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]223}
[250]224const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]225{
[250]226 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]227}
[250]228const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]229{
[250]230 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]231}
[250]232const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]233{
[250]234 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]235}
[250]236const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]237{
[250]238 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]239}
[250]240const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]241{
[250]242 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]243}
[250]244const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]245{
[250]246 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]247}
[250]248const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]249{
[250]250 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]251}
[250]252const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]253{
[250]254 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]255}
[250]256const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]257{
[250]258 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]259}
[248]260const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]261{
[241]262 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]263}
[241]264void CodeGenerator::op_jmp_continue()
265{
[254]266 if( GetContinueCodePos() == -1 )
[241]267 {
268 SetError(12,"Continue",cp);
269 return;
270 }
[254]271 op_jmp( GetContinueCodePos() - pNativeCode->GetSize(), sizeof(long), false, true );
[241]272}
[247]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}
[253]282void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
[246]283{
284 // オペコード
285 pNativeCode->Put( (char)0xE9 );
286
[253]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 );
[246]297
[253]298 pertialSchedules.push_back( pGotoLabelSchedule );
299
[246]300 pNativeCode->Put( (long)0 );
301}
Note: See TracBrowser for help on using the repository browser.