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

Last change on this file since 250 was 250, checked in by dai_9181, 17 years ago

Selectステートメントのスケジュール機構をリファクタリング

File size: 6.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 // 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
29
30// 分岐関連
31void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
32{
33 bool isSuccessful = false;
34
[248]35 PertialSchedules::iterator it = pertialSchedules.begin();
[239]36 while( it != pertialSchedules.end() )
37 {
38 if( (*it) == pPertialSchedule )
39 {
[241]40 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
41
42 extern int obp;
43 long newValueOld = obp - (pPertialSchedule->GetObpOld()+pPertialSchedule->GetTypeSize());
44
[239]45 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
46 {
[241]47 if( newValue < -128 || 127 < newValue )
48 {
49 // 範囲外
50 SetError();
51 }
[239]52
[241]53 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
54
[239]55 // TODO: 未完成(用が無くなったら消す)
[241]56 pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), (char)newValueOld );
[239]57 }
[241]58 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
59 {
60 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
61
62 // TODO: 未完成(用が無くなったら消す)
63 pNativeCode->OverwriteOld( pPertialSchedule->GetObpOld(), newValueOld );
64 }
[239]65 else
66 {
67 SetError();
68 }
69
[245]70 it = pertialSchedules.erase( it );
[239]71 delete pPertialSchedule;
72
73 isSuccessful = true;
74 }
75 else
76 {
77 it++;
78 }
79 }
80
81 if( isSuccessful == false )
82 {
83 SetError();
84 }
85}
[248]86const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]87{
[241]88 long beginCodePos = pNativeCode->GetSize();
89 {
90 // TODO: 未完成
91 extern int obp;
92 beginCodePos = obp;
93 }
[239]94
[241]95 if( opcode == (char)0xEB )
96 {
97 // jmp命令のとき
98 if( op_size == sizeof(char) )
99 {
100 pNativeCode->Put( (char)opcode );
101 }
102 else if( op_size == sizeof(long) )
103 {
104 pNativeCode->Put( (char)0xE9 );
105 }
106 else
107 {
108 SetError();
109 }
110 }
111 else
112 {
113 if( op_size == sizeof(char) )
114 {
115 pNativeCode->Put( (char)((char)0x70 | opcode) );
116 }
117 else if( op_size == sizeof(long) )
118 {
119 pNativeCode->Put( (char)0x0F );
120 pNativeCode->Put( (char)((char)0x80 | opcode) );
121 }
122 else
123 {
124 SetError();
125 }
126 }
127
[245]128 const PertialSchedule *pPertialSchedule = NULL;
[239]129 if( isPertialSchedule )
130 {
131 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
132 pPertialSchedule = pertialSchedules[pertialSchedules.size()-1];
133 }
134
[241]135 if( isSelfOpcodeOffset )
136 {
137 // 自分自身の命令サイズを考慮する場合
138 //offset += ( pNativeCode->GetSize() - beginCodePos ) + op_size;
139
140 // TODO: 未完成
141 extern int obp;
142 offset -= ( obp - beginCodePos ) + op_size;
143 }
144
[239]145 if( op_size == sizeof(char) )
146 {
147 pNativeCode->Put( (char)offset );
148 }
149 else if( op_size == sizeof(long) )
150 {
151 pNativeCode->Put( offset );
152 }
153 else
154 {
155 SetError();
156 }
157
158 return pPertialSchedule;
159}
[250]160const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]161{
[250]162 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]163}
[250]164const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]165{
[250]166 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]167}
[250]168const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]169{
[250]170 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]171}
[250]172const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]173{
[250]174 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]175}
[250]176const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]177{
[250]178 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]179}
[250]180const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]181{
[250]182 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]183}
[250]184const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]185{
[250]186 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]187}
[250]188const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]189{
[250]190 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]191}
[250]192const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]193{
[250]194 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]195}
[250]196const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]197{
[250]198 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]199}
[248]200const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]201{
[241]202 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]203}
[241]204void CodeGenerator::op_jmp_continue()
205{
206 //op_jmp( GetContinueCodePos()-(pNativeCode->GetSize()+sizeof(long)), sizeof(long) );
207
208 // TODO: 未完成(OpBuffer/obp廃止が整ったら上記のコードを有効にすべし)
209
210 if( GetContinueCodePosOld() == -1 )
211 {
212 SetError(12,"Continue",cp);
213 return;
214 }
215
216 extern int obp;
217 op_jmp( GetContinueCodePosOld()-obp, sizeof(long), false, true );
218}
[247]219void CodeGenerator::op_jmp_exitsub()
220{
221 // オペコード
222 pNativeCode->Put( (char)0xE9 );
223
224 exitSubCodePositions.push_back( pNativeCode->GetSize() );
225
226 extern int obp;
227 _exitSubCodePositions_ObpOld.push_back( obp );
228
229 pNativeCode->Put( (long)0 );
230}
[246]231void CodeGenerator::op_jmp_goto_schedule( const GotoLabelSchedule &gotoLabelSchedule )
232{
233 // オペコード
234 pNativeCode->Put( (char)0xE9 );
235
236 gotoLabelSchedules.push_back( gotoLabelSchedule );
237
238 pNativeCode->Put( (long)0 );
239}
Note: See TracBrowser for help on using the repository browser.