00001
00002
00003
00004
00005 #include <lestes/md/instructions/pi_pi2ge_pi.g.hh>
00006 #include <lestes/md/instructions/pi_operand2ge_operand.g.hh>
00007 #include <lestes/md/instructions/tm_instr.g.hh>
00008 #include <lestes/md/literals/literal_info.g.hh>
00009 #include <lestes/md/types/tm_data_type.g.hh>
00010 #include <lestes/backend_v2/intercode/pi.g.hh>
00011 #include <lestes/backend_v2/structs/pi_operands.g.hh>
00012 #include <lestes/backend_v2/intercode/visitor_pi_pi2pi_operands.g.hh>
00013 #include <lestes/backend_v2/intercode/visitor_pi_pi2id.g.hh>
00014 #include <lestes/backend_v2/debug/debug.hh>
00015 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00016 #include <sstream>
00017 #include <lestes/std/ucn_string.hh>
00018
00019 package(lestes);
00020 package(md);
00021 package(instructions);
00022
00023 using ::lestes::lang::cplus::sem::ss_function_declaration;
00024
00025 using namespace ::lestes::backend_v2::intercode;
00026 using namespace ::lestes::backend_v2::structs;
00027 using namespace ::lestes::backend_v2::debug;
00028 using namespace ::lestes::md::types;
00029 using namespace ::lestes::md::literals;
00030 using namespace ::lestes::msg;
00031
00032 typedef map<ulint,lstring> ulint2lstring__type;
00033 typedef list< srp<pi_mem> > pi_mem_list__type;
00034 typedef list< srp<pi_operand> > pi_operand_list__type;
00035 typedef vector< srp< ::lestes::backend_v2::intercode::ge_pi> > ge_pi_vector__type;
00036 typedef vector< srp < ge_pi > > ge_pi_vector__type;
00037 typedef set< srp < ge_pi > > ge_pi_set__type;
00038
00039 declare_logger(log);
00040 initialize_logger( log, "pi_pi2ge_pi", md_logger );
00041
00042
00043 bool pi_pi2ge_pi::targetmachine__is_instruction_consistent(ptr<tm_instr_base> instr_version, ptr<pi_pi> pi) {
00044 ulint2lstring__type::iterator it = instr_version->properties_get()->find(PROPERTY_TEST_SIGNED);
00045
00046 if ( it!=instr_version->properties_get()->end() ) {
00047
00048
00049
00050
00051
00052
00053
00054 ptr<pi_operands> pi_ops = pi->accept_visitor_pi_pi2pi_operands_gen_base(pi_operands_getter_get());
00055
00056
00057 visitor_pi_pi2id::kind_type pi_id = (visitor_pi_pi2id::kind_type)pi->accept_visitor_pi_pi2ulint_gen_base(pi_id_getter_get());
00058
00059 ptr<tm_data_type_base> type;
00060
00061 switch ( pi_id ) {
00062 case visitor_pi_pi2id::PI_BT:
00063 case visitor_pi_pi2id::PI_BF:
00064 case visitor_pi_pi2id::PI_BG:
00065 case visitor_pi_pi2id::PI_BL:
00066 case visitor_pi_pi2id::PI_BNG:
00067 case visitor_pi_pi2id::PI_BNL: {
00068 ptr<pi_operand> cond = (*pi_ops->operands_input_get())[0];
00069 ptr<pi_pi> cond_origin_cmp = cond->origin_get();
00070 ptr<pi_operands> cmp_ops = cond_origin_cmp->accept_visitor_pi_pi2pi_operands_gen_base(pi_operands_getter_get());
00071 ptr<pi_operand> cmp_op = (*cmp_ops->operands_input_get())[0];
00072 type = cmp_op->type_get();
00073 } break;
00074
00075 case visitor_pi_pi2id::PI_SBG:
00076 case visitor_pi_pi2id::PI_SBL:
00077 case visitor_pi_pi2id::PI_SBNG:
00078 case visitor_pi_pi2id::PI_SBNL:{
00079 ptr<pi_operand> cmp_op = (*pi_ops->operands_input_get())[0];
00080 type = cmp_op->type_get();
00081 } break;
00082
00083 default: {
00084 lassert(false);
00085 }
00086
00087 }
00088
00089 ulint type_id = type->id_get();
00090 if ( it->second=="true" && !( type_id==DT_INT_8S || type_id==DT_INT_16S || type_id==DT_INT_32S ) ) {
00091
00092
00093
00094 return false;
00095 }
00096 }
00097 return true;
00098 }
00099
00100 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_sp(ptr< ::lestes::backend_v2::intercode::pi_sp > pi) {
00101
00102 ptr< ge_pi_vector__type > output = ge_pi_vector__type::create();
00103
00104 ptr<ge_sp> ge = ge_sp::create(NULL,pi);
00105
00106
00107 if ( !pi->psp_get() ) {
00108
00109
00110
00111 ptr<ge_sp> extra_sp = ge_sp::create(NULL,pi);
00112 output->push_back(extra_sp);
00113
00114 ptr<ge_pi> ge_prologue = ge_pi::create(tm_instr::instance(INSTRUCTION_PROLOGUE__1),pi);
00115 ge_prologue->dependencies_get()->insert(extra_sp);
00116 output->push_back(ge_prologue);
00117
00118
00119
00120
00121
00122
00123
00124 ptr<tm_data_type_base> type_32u = tm_dt_simple::instance(DT_INT_32U);
00125 preserved_reg_edi = ge_operand_reg::create(type_32u,ge_prologue,NULL);
00126 ge_prologue->operands_output_get()->push_back(preserved_reg_edi);
00127 preserved_reg_esi = ge_operand_reg::create(type_32u,ge_prologue,NULL);
00128 ge_prologue->operands_output_get()->push_back(preserved_reg_esi);
00129 preserved_reg_ebx = ge_operand_reg::create(type_32u,ge_prologue,NULL);
00130 ge_prologue->operands_output_get()->push_back(preserved_reg_ebx);
00131
00132 ge->dependencies_get()->insert(extra_sp);
00133 ge->dependencies_get()->insert(ge_prologue);
00134 output->push_back(ge);
00135
00136 first_sp_set(ge);
00137 } else if ( !pi->nsp_get() ) {
00138
00139
00140
00141 last_sp_set(ge);
00142 output->push_back(ge);
00143
00144 ptr<ge_pi> ge_epilogue = ge_pi::create(tm_instr::instance(INSTRUCTION_EPILOGUE__1),pi);
00145 ge_epilogue->dependencies_get()->insert(ge);
00146 ge_epilogue->operands_input_get()->push_back(preserved_reg_edi);
00147 ge_epilogue->operands_input_get()->push_back(preserved_reg_esi);
00148 ge_epilogue->operands_input_get()->push_back(preserved_reg_ebx);
00149 output->push_back(ge_epilogue);
00150
00151 ptr<ge_pi> ge_leave = ge_pi::create(tm_instr::instance(INSTRUCTION_LEAVE__1),pi);
00152 ge_leave->dependencies_get()->insert(ge_epilogue);
00153 output->push_back(ge_leave);
00154
00155 ptr<ge_pi> ge_ret = ge_pi::create(tm_instr::instance(INSTRUCTION_RET__1),pi);
00156 ge_ret->dependencies_get()->insert(ge_leave);
00157 output->push_back(ge_ret);
00158
00159 ptr<ge_sp> extra_sp = ge_sp::create(NULL,pi);
00160 extra_sp->dependencies_get()->insert(ge);
00161 extra_sp->dependencies_get()->insert(ge_epilogue);
00162 extra_sp->dependencies_get()->insert(ge_leave);
00163 extra_sp->dependencies_get()->insert(ge_ret);
00164 output->push_back(extra_sp);
00165 } else {
00166 output->push_back(ge);
00167 }
00168
00169 pi_sp2ge_sp_get()->insert(::std::pair<srp<pi_sp>,srp<ge_sp> >(pi,ge));
00170
00171 return output;
00172 }
00173
00174
00175 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_leave(ptr< ::lestes::backend_v2::intercode::pi_leave > pi) {
00176
00177
00178 ptr<ge_pi> ge = ge_pi::create(tm_instr::instance(INSTRUCTION_JMP__1),pi);
00179 ge->jmp_targets_set(vector<srp<ge_sp> >::create());
00180 last_sp_get()->is_jmp_target_set(true);
00181 ge->jmp_targets_get()->push_back(last_sp_get());
00182
00183 ptr< ge_pi_vector__type > output = ge_pi_vector__type::create();
00184 output->push_back(ge);
00185
00186 return output;
00187 }
00188
00189 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_call(ptr< ::lestes::backend_v2::intercode::pi_call > pi) {
00190 log << "visit_pi_call - start\n" << eolog;
00191
00192 ptr< ge_pi_vector__type > output = ge_pi_vector__type::create();
00193
00194 ptr<ge_operand> stack_pointer = get_stack_pointer(pi);
00195
00196 ptr<ge_call> ge = ge_call::create(tm_instr::instance(INSTRUCTION_CALL__1),pi,pi->f_get());
00197
00198
00199 ptr<ge_operand> reg_eax = pi_op2ge_op_convertor_get()->convert(pi->rv_get());
00200 reg_eax->origin_set(ge);
00201 ge->operands_output_get()->push_back(reg_eax);
00202
00203 ptr<tm_data_type_base> type_32u = tm_dt_simple::instance(DT_INT_32U);
00204 ptr<ge_operand> reg_ecx = ge_operand_reg::create(type_32u,ge,NULL);
00205 ge->operands_output_get()->push_back(reg_ecx);
00206
00207 ptr<ge_operand> reg_edx = ge_operand_reg::create(type_32u,ge,NULL);
00208 ge->operands_output_get()->push_back(reg_edx);
00209
00210 int pushed_args = 0;
00211
00212
00213 push_operands(pi,stack_pointer,output);
00214
00215 if ( !pi->type_get()->return_reg_get() ) {
00216
00217 push_operand(pi,pi->rv_get(),stack_pointer,output);
00218 ++pushed_args;
00219 }
00220
00221
00222 if ( output->size()>0 ) {
00223 ptr<ge_pi> last = (*output)[output->size() - 1];
00224 ge->dependencies_get()->insert(last);
00225 }
00226 output->push_back(ge);
00227
00228 pushed_args += pi->args_get()->size();
00229
00230
00231 restore_stack(pi,ge,stack_pointer,pushed_args,output);
00232
00233 log << "visit_pi_call - end\n" << eolog;
00234
00235 return output;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 ptr<ge_operand> pi_pi2ge_pi::get_stack_pointer(ptr<pi_abstract_function_call > pi) {
00245 ptr<ge_pi> ge_psp = (*pi_sp2ge_sp_get())[pi->psp_get().dncast<pi_sp>()];
00246 return ge_operand_reg::create(tm_dt_simple::instance(DT_INT_32U),ge_psp,NULL);
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 void pi_pi2ge_pi::restore_stack(ptr<pi_abstract_function_call > pi, ptr<ge_call> ge, ptr<ge_operand> stack_pointer,ulint argc, ptr< ge_pi_vector__type > output) {
00259 log << "restore_stack - start\n" << eolog;
00260
00261 if ( argc==0 ) {
00262 return;
00263 }
00264
00265 ptr<ge_pi> ge_nsp = (*pi_sp2ge_sp_get())[pi->nsp_get().dncast<pi_sp>()];
00266
00267
00268 ptr<ge_pi> restore = ge_pi::create(tm_instr::instance(INSTRUCTION_ESPADD__1),pi);
00269 restore->dependencies_get()->insert(ge);
00270 restore->operands_input_get()->push_back(stack_pointer);
00271
00272 ptr<tm_data_type_base> type_32u = tm_dt_simple::instance(DT_INT_32U);
00273
00274 ::std::ostringstream oss;
00275 oss << argc*4;
00276
00277 ptr<li_simple> offset_value = li_simple::create(type_32u,ucn_string(oss.str().c_str()));
00278 ptr<ge_operand> offset = ge_operand_imm::create(type_32u,NULL,NULL,offset_value);
00279 restore->operands_input_get()->push_back(offset);
00280
00281 ptr<ge_operand> new_stack_pointer = ge_operand_reg::create(type_32u,restore,NULL);
00282 restore->operands_output_get()->push_back(new_stack_pointer);
00283
00284 ptr<ge_operand> cond = ge_operand_reg::create(tm_dt_simple::instance(DT_COND),restore,NULL);
00285 restore->operands_output_get()->push_back(cond);
00286
00287
00288
00289
00290
00291 ge_nsp->operands_input_get()->push_back(new_stack_pointer);
00292
00293 output->push_back(restore);
00294
00295 log << "restore_stack - end\n" << eolog;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305 void pi_pi2ge_pi::push_operands(ptr<pi_abstract_function_call > pi, ptr<ge_operand>& stack_pointer, ptr< ge_pi_vector__type > output) {
00306 log << "push_operands - start\n" << eolog;
00307
00308 ptr<pi_operand_list__type> args = pi->args_get();
00309
00310 for(pi_operand_list__type::reverse_iterator it = args->rbegin(); it!=args->rend(); ++it) {
00311 ptr<pi_operand> op = *it;
00312 push_operand(pi,*it,stack_pointer,output);
00313 }
00314
00315 log << "push_operands - end\n" << eolog;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void pi_pi2ge_pi::push_operand(ptr<pi_abstract_function_call > pi, ptr<pi_operand> op, ptr<ge_operand>& stack_pointer, ptr< ge_pi_vector__type > output) {
00327 log << "push_operand - start\n" << eolog;
00328
00329 ptr<ge_operand> ge_op1 = pi_op2ge_op_convertor_get()->convert(op);
00330
00331 ulint type = ge_op1->type_get()->id_get();
00332
00333 ptr<ge_pi> prev = output->size()>0 ? (*output)[output->size() - 1] : NULL;
00334
00335 ptr<ge_pi> ge_push;
00336 ptr<ge_operand> new_stack_pointer = ge_operand_reg::create(tm_dt_simple::instance(DT_INT_32U),NULL,NULL);
00337
00338 switch (ge_op1->kind_get()) {
00339 case ge_operand::MEMORY: {
00340
00341 if ( type!=DT_INT_32U && type!=DT_INT_32S ) {
00342
00343
00344
00345
00346 ptr<ge_pi> ge_prep = ge_pi::create(tm_instr::instance(INSTRUCTION_MOVZX__5),pi);
00347 ge_prep->operands_input_get()->push_back(ge_op1);
00348 ptr<ge_operand> ge_op_to_push = ge_operand_reg::create(tm_dt_simple::instance(DT_INT_32U),ge_prep,NULL);
00349 ge_prep->operands_output_get()->push_back(ge_op_to_push);
00350 output->push_back(ge_prep);
00351
00352 ge_push = ge_pi::create(tm_instr::instance(INSTRUCTION_PUSH__2),pi);
00353 ge_push->operands_input_get()->push_back(stack_pointer);
00354 ge_push->operands_input_get()->push_back(ge_op_to_push);
00355 ge_push->dependencies_get()->insert(ge_prep);
00356 } else {
00357 ge_push = ge_pi::create(tm_instr::instance(INSTRUCTION_PUSH__1),pi);
00358 ge_push->operands_input_get()->push_back(stack_pointer);
00359 ge_push->operands_input_get()->push_back(ge_op1);
00360 }
00361 } break;
00362
00363 case ge_operand::REGISTER: {
00364
00365 if ( type!=DT_INT_32U && type!=DT_INT_32S ) {
00366
00367
00368
00369
00370 ptr<ge_pi> ge_prep = ge_pi::create(tm_instr::instance(INSTRUCTION_MOVZX__4),pi);
00371 ge_prep->operands_input_get()->push_back(ge_op1);
00372 ptr<ge_operand> ge_op_to_push = ge_operand_reg::create(tm_dt_simple::instance(DT_INT_32U),ge_prep,NULL);
00373 ge_prep->operands_output_get()->push_back(ge_op_to_push);
00374 output->push_back(ge_prep);
00375
00376 ge_push = ge_pi::create(tm_instr::instance(INSTRUCTION_PUSH__2),pi);
00377 ge_push->operands_input_get()->push_back(stack_pointer);
00378 ge_push->operands_input_get()->push_back(ge_op_to_push);
00379 ge_push->dependencies_get()->insert(ge_prep);
00380 } else {
00381 ge_push = ge_pi::create(tm_instr::instance(INSTRUCTION_PUSH__2),pi);
00382 ge_push->operands_input_get()->push_back(stack_pointer);
00383 ge_push->operands_input_get()->push_back(ge_op1);
00384 }
00385 } break;
00386
00387 default: lassert(false);
00388 }
00389
00390
00391 if ( prev ) {
00392 ge_push->dependencies_get()->insert(prev);
00393 }
00394
00395 ge_push->operands_output_get()->push_back(new_stack_pointer);
00396 new_stack_pointer->origin_set(ge_push);
00397
00398 stack_pointer = new_stack_pointer;
00399
00400 output->push_back(ge_push);
00401
00402 log << "push_operand - end\n" << eolog;
00403 }
00404
00405 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_callv(ptr< ::lestes::backend_v2::intercode::pi_callv > pi) {
00406 log << "visit_pi_callv - start\n" << eolog;
00407
00408 ptr< ge_pi_vector__type > output = ge_pi_vector__type::create();
00409
00410 ptr<ge_operand> stack_pointer = get_stack_pointer(pi);
00411
00412 ptr<ge_call> ge = ge_call::create(tm_instr::instance(INSTRUCTION_CALL__1),pi,pi->f_get());
00413
00414
00415 ptr<tm_data_type_base> type_32u = tm_dt_simple::instance(DT_INT_32U);
00416 ptr<ge_operand> reg_eax = ge_operand_reg::create(type_32u,ge,NULL);
00417 reg_eax->origin_set(ge);
00418 ge->operands_output_get()->push_back(reg_eax);
00419
00420 ptr<ge_operand> reg_ecx = ge_operand_reg::create(type_32u,ge,NULL);
00421 reg_ecx->origin_set(ge);
00422 ge->operands_output_get()->push_back(reg_ecx);
00423
00424 ptr<ge_operand> reg_edx = ge_operand_reg::create(type_32u,ge,NULL);
00425 reg_edx->origin_set(ge);
00426 ge->operands_output_get()->push_back(reg_edx);
00427
00428
00429 push_operands(pi,stack_pointer,output);
00430
00431
00432 if ( output->size()>0 ) {
00433 ptr<ge_pi> last = (*output)[output->size() - 1];
00434 ge->dependencies_get()->insert(last);
00435 }
00436 output->push_back(ge);
00437
00438 if ( pi->args_get()->size()>0 ) {
00439
00440 restore_stack(pi,ge,stack_pointer,pi->args_get()->size(),output);
00441 }
00442
00443 log << "visit_pi_callv - end\n" << eolog;
00444
00445 return output;
00446 }
00447
00448 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_icall(ptr< ::lestes::backend_v2::intercode::pi_icall > ) {
00449 lassert2(false,msg_not_implemented_yet);
00450 }
00451
00452 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_icallv(ptr< ::lestes::backend_v2::intercode::pi_icallv > ){
00453 lassert2(false,msg_not_implemented_yet);
00454 }
00455
00456 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_iba(ptr< ::lestes::backend_v2::intercode::pi_iba > ){
00457 lassert2(false,msg_not_implemented_yet);
00458 }
00459
00460 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibn(ptr< ::lestes::backend_v2::intercode::pi_ibn > ){
00461 lassert2(false,msg_not_implemented_yet);
00462 }
00463
00464 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibm(ptr< ::lestes::backend_v2::intercode::pi_ibm > ){
00465 lassert2(false,msg_not_implemented_yet);
00466 }
00467
00468 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibg(ptr< ::lestes::backend_v2::intercode::pi_ibg > ){
00469 lassert2(false,msg_not_implemented_yet);
00470 }
00471
00472 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibl(ptr< ::lestes::backend_v2::intercode::pi_ibl > ){
00473 lassert2(false,msg_not_implemented_yet);
00474 }
00475
00476 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibe(ptr< ::lestes::backend_v2::intercode::pi_ibe > ){
00477 lassert2(false,msg_not_implemented_yet);
00478 }
00479
00480 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibng(ptr< ::lestes::backend_v2::intercode::pi_ibng > ){
00481 lassert2(false,msg_not_implemented_yet);
00482 }
00483
00484 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibnl(ptr< ::lestes::backend_v2::intercode::pi_ibnl > ){
00485 lassert2(false,msg_not_implemented_yet);
00486 }
00487
00488 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_ibne(ptr< ::lestes::backend_v2::intercode::pi_ibne > ){
00489 lassert2(false,msg_not_implemented_yet);
00490 }
00491
00492 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_bm(ptr< ::lestes::backend_v2::intercode::pi_bm > ){
00493 lassert2(false,msg_not_implemented_yet);
00494 }
00495
00496 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_divrni(ptr< ::lestes::backend_v2::intercode::pi_divrni > ){
00497 lassert2(false,msg_not_implemented_yet);
00498 }
00499
00500 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_divrpi(ptr< ::lestes::backend_v2::intercode::pi_divrpi > ){
00501 lassert2(false,msg_not_implemented_yet);
00502 }
00503
00504 ptr< ge_pi_vector__type > pi_pi2ge_pi::visit_pi_divrz(ptr< ::lestes::backend_v2::intercode::pi_divrz > ){
00505 lassert2(false,msg_not_implemented_yet);
00506 }
00507
00508
00509
00510 end_package(instructions);
00511 end_package(md);
00512 end_package(lestes);
00513