00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <functional>
00040 #include <algorithm>
00041 #include "c_breeze.h"
00042 #include "ref_clone_changer.h"
00043 #include "lir_gen_walker.h"
00044 #include "lirutil.h"
00045
00046 map<unsigned int, BinaryInstProc> lir_gen_walker::binary_map;
00047 map<unsigned int, UnaryInstProc> lir_gen_walker::unary_map;
00048 map<unsigned int, Compare_type> lir_gen_walker::opid_cmptype_map;
00049
00050 lir_gen_walker::lir_gen_walker() :
00051 Walker(Both, Subtree),
00052 _unit(0),
00053 _proc(0)
00054 {
00055 if ( binary_map.empty()
00056 || unary_map.empty()
00057 || opid_cmptype_map.empty() )
00058 init_maps();
00059 }
00060
00061 void lir_gen_walker::init_maps(void) {
00062 binary_map['+'] = &LIR::Add;
00063 binary_map['*'] = &LIR::Mul;
00064 binary_map['/'] = &LIR::Div;
00065 binary_map['-'] = &LIR::Sub;
00066 binary_map['%'] = &LIR::Mod;
00067 binary_map['&'] = &LIR::BitwiseAND;
00068 binary_map['|'] = &LIR::BitwiseOR;
00069 binary_map['^'] = &LIR::BitwiseXOR;
00070 binary_map[Operator::LS] = &LIR::BitwiseShiftLeft;
00071 binary_map[Operator::RS] = &LIR::BitwiseShiftRight;
00072
00073 unary_map['~'] = &LIR::BitwiseNOT;
00074 unary_map[Operator::UMINUS] = &LIR::Neg;
00075
00076 opid_cmptype_map[Operator::EQ] = cmp_EQ;
00077 opid_cmptype_map[Operator::NE] = cmp_NE;
00078 opid_cmptype_map['<'] = cmp_LT;
00079 opid_cmptype_map[Operator::LE] = cmp_LE;
00080 opid_cmptype_map['>'] = cmp_GT;
00081 opid_cmptype_map[Operator::GE] = cmp_GE;
00082 }
00083
00084 void lir_gen_walker::at_unit(unitNode * the_unit, Order ord) {
00085 if ( ord == Preorder ) {
00086 the_unit->instructions().clear();
00087 _unit = the_unit;
00088
00089 AllocSizeChanger::size(the_unit);
00090
00091 for ( def_list_p p = the_unit->defs().begin();
00092 p != the_unit->defs().end();
00093 p++ )
00094 gen_global_decl(*p);
00095
00096 SizeofChanger soc;
00097 the_unit->change(soc);
00098 } else {
00099 _unit = NULL;
00100
00101 #ifdef DEBUG
00102
00103 cout << "Initial unit LIR instruction listing:" << endl;
00104 instruction_list::const_iterator it = the_unit->instructions().begin();
00105 int num = 0;
00106 while ( it != the_unit->instructions().end() )
00107 cout << num++ << " " << **(it++) << endl;
00108 cout << endl << endl;
00109 #endif
00110 }
00111 }
00112
00113 void lir_gen_walker::at_proc(procNode * the_proc, Order ord) {
00114 if ( ord == Preorder ) {
00115 _alloc.reset();
00116
00117 _proc = the_proc;
00118 the_proc->instructions().clear();
00119 the_proc->lir_blocks().clear();
00120 int stackOffset = -1 * CBZ::ArchInfo.get_stack_extra_top();
00121 the_proc->set_initial_stack_local_offset(stackOffset);
00122
00123
00124 AllocToMemWalker atmw;
00125 the_proc->walk(atmw);
00126
00127 the_proc->instructions().push_back(LIR::BeginProc(the_proc));
00128
00129
00130 for ( decl_list_p p = the_proc->body()->decls().begin();
00131 p != the_proc->body()->decls().end();
00132 p++ )
00133 gen_local_decl(*p, atmw);
00134
00135
00136 if ( funcNode * the_func =
00137 dynamic_cast<funcNode *>(the_proc->decl()->type()) ) {
00138 for ( decl_list_p p = the_func->args().begin();
00139 p != the_func->args().end();
00140 p++ )
00141 gen_arg_decl(*p, atmw);
00142 ;
00143 } else
00144 CBZFAIL(("procNode doesn't contain expected funcNode"));
00145
00146 } else {
00147 the_proc->instructions().push_back(LIR::EndProc(the_proc));
00148 _proc = NULL;
00149
00150 #ifdef DEBUG
00151
00152 cout << "Initial proc LIR instruction listing:" << endl;
00153 instruction_list::const_iterator it = the_proc->instructions().begin();
00154 int num = 0;
00155 while ( it != the_proc->instructions().end() )
00156 cout << num++ << " " << **(it++) << endl;
00157 cout << endl << endl;
00158 #endif
00159 }
00160 }
00161
00162 void lir_gen_walker::at_threeAddr(threeAddrNode * the_3addr, Order ord) {
00163 if ( ord == Preorder ) {
00164 if ( the_3addr->lhs() )
00165 gen_assignment(the_3addr);
00166 else if ( the_3addr->op()
00167 && the_3addr->op()->id() == Operator::FUNC_CALL )
00168 gen_call(the_3addr);
00169 else
00170 CBZFAIL(("Ill-formed threeAddrNode"));
00171 }
00172 }
00173
00174 void lir_gen_walker::at_goto(gotoNode *the_goto, Order ord){
00175 if ( ord == Preorder ) {
00176 assert(the_goto->label());
00177 gen_goto(the_goto);
00178 }
00179 }
00180
00181 void lir_gen_walker::at_label(labelNode *the_label, Order ord){
00182 if (ord == Preorder)
00183 gen_label(the_label);
00184 }
00185
00186 void lir_gen_walker::at_conditiongoto(conditiongotoNode * the_condgoto,
00187 Order ord) {
00188 if ( ord == Preorder ) {
00189 assert(the_condgoto->left() && the_condgoto->right()
00190 && the_condgoto->label() && the_condgoto->op()->is_comparison());
00191 gen_conditional_branch(the_condgoto);
00192 }
00193 }
00194
00195 void lir_gen_walker::at_return(returnNode *the_return, Walker::Order ord) {
00196 if (ord == Preorder ) {
00197 assert(the_return->proc_exit());
00198 gen_return(the_return);
00199 }
00200 }
00201
00202 expr_list * lir_gen_walker::flatten_init(exprNode * expr) {
00203 expr_list * retlist = new expr_list;
00204 if ( initializerNode * init =
00205 dynamic_cast<initializerNode *>(expr) ) {
00206 for ( expr_list_p p = init->exprs().begin();
00207 p != init->exprs().end();
00208 p++) {
00209 expr_list * sublist = flatten_init(*p);
00210 retlist->splice(retlist->end(), *sublist);
00211 delete sublist;
00212 }
00213 } else
00214 retlist->push_back(expr);
00215 return retlist;
00216 }
00217
00218 void lir_gen_walker::gen_global_decl(defNode * the_def) {
00219 if ( declNode * the_decl = dynamic_cast<declNode *>(the_def) ) {
00220 if ( the_decl->decl_location() == declNode::TOP
00221 && the_decl->storage_class() != declNode::TYPEDEF
00222 && the_decl->storage_class() != declNode::EXTERN ) {
00223 declNode::Storage_location & loc = the_decl->storage_location();
00224 loc._type = declNode::Storage_location::storageloc_mem_global;
00225
00226
00227 if ( the_decl->init() ) {
00228 _unit->instructions().push_back(LIR::DeclareGlobal(the_decl));
00229 _unit->instructions().push_back(LIR::Label(the_decl->name()));
00230 expr_list * inits = flatten_init(the_decl->init());
00231
00232 for (expr_list_p p = inits->begin(); p != inits->end(); p++ ) {
00233
00234
00235
00236
00237 (*p)->eval();
00238 assert(!(*p)->value().no_val());
00239
00240 LirInst * newInst = NULL;
00241
00242
00243 typeNode * type = (*p)->no_tdef_type();
00244 if ( type->is_pointer() )
00245 if ( type->is_aggregate() )
00246 newInst = LIR::StaticDataString((*p)->value());
00247 else
00248 newInst = LIR::StaticDataInt((*p)->value());
00249 else if ( primNode * prim = dynamic_cast<primNode *>(type) ) {
00250 basic_type basic = prim->basic();
00251 if ( basic.is_char() )
00252 newInst = LIR::StaticDataChar((*p)->value());
00253 else if ( basic.is_int() )
00254 if ( basic.is_short() )
00255 newInst = LIR::StaticDataShort((*p)->value());
00256 else if ( basic.is_long() )
00257 newInst = LIR::StaticDataLong((*p)->value());
00258 else
00259 newInst = LIR::StaticDataInt((*p)->value());
00260 else if ( basic.is_float() )
00261 if ( basic.is_long() )
00262 newInst = LIR::StaticDataDouble((*p)->value());
00263 else
00264 newInst = LIR::StaticDataSingle((*p)->value());
00265 }
00266 assert(newInst);
00267 _unit->instructions().push_back(newInst);
00268 }
00269
00270 delete inits;
00271 } else {
00272 LirInst * newInst =
00273 LIR::StaticDataUninit(the_decl->name(),
00274 the_decl->type()->alloc_size());
00275 _unit->instructions().push_back(newInst);
00276 }
00277 }
00278 }
00279 }
00280
00281 void lir_gen_walker::gen_arg_decl(declNode * the_decl,
00282 AllocToMemWalker & atmw) {
00283 if ( the_decl->type()->is_void() )
00284 return;
00285
00286 assert(the_decl->decl_location() == declNode::FORMAL);
00287
00288 declNode::Storage_location & loc = the_decl->storage_location();
00289 assert(loc._type == declNode::Storage_location::storageloc_unknown);
00290
00291 Register reg;
00292 typeNode * type = the_decl->no_tdef_type();
00293
00294 assert(!type->is_ellipsis());
00295
00296 if ( _alloc.assign_arg_register(type, reg) ) {
00297
00298 loc._type = declNode::Storage_location::storageloc_register;
00299 loc._register = reg;
00300 } else {
00301
00302 int stackLoc = _alloc.assign_arg_stack(type);
00303 loc._type = declNode::Storage_location::storageloc_stack;
00304 loc._stack_offset = stackLoc;
00305 }
00306
00307 _proc->instructions().push_back(LIR::DeclareLocal(the_decl));
00308
00309 if ( ( CBZ::NoRegAlloc || atmw.needsMem(the_decl) )
00310 && loc._type != declNode::Storage_location::storageloc_stack ) {
00311
00312
00313 assert(loc._type == declNode::Storage_location::storageloc_register);
00314
00315
00316 declNode * tempDecl = LirUtil::new_auto_decl(type);
00317 _proc->alloc_stack_local(tempDecl);
00318
00319
00320 declNode::Storage_location oldLoc = loc;
00321 loc = tempDecl->storage_location();
00322 delete tempDecl;
00323
00324 _proc->instructions().push_back(LIR::Store(type, oldLoc._register,
00325 the_decl, Register::getRegFp(),
00326 DATA_CONTENTS_FRAMEP,
00327 loc._stack_offset,
00328 NULL));
00329 }
00330 }
00331
00332 void lir_gen_walker::gen_local_decl(declNode * the_decl,
00333 AllocToMemWalker & atmw) {
00334 assert(the_decl->storage_class() != declNode::STATIC);
00335 assert(the_decl->decl_location() == declNode::BLOCK);
00336
00337 declNode::Storage_location & loc = the_decl->storage_location();
00338 assert(loc._type == declNode::Storage_location::storageloc_unknown);
00339
00340 if ( the_decl == _proc->return_decl() ) {
00341
00342 Register reg;
00343 if ( Register::getRegRetVal(the_decl->no_tdef_type(), reg) ) {
00344 loc._type = declNode::Storage_location::storageloc_register;
00345 loc._register = reg;
00346 } else {
00347
00348
00349 assert(false);
00350 }
00351 } else if ( atmw.needsMem(the_decl) || CBZ::NoRegAlloc ) {
00352 _proc->alloc_stack_local(the_decl);
00353 } else {
00354 _alloc.assign_register(the_decl);
00355 }
00356 _proc->instructions().push_back(LIR::DeclareLocal(the_decl));
00357 if ( the_decl->init() ) {
00358
00359 assert(false);
00360 }
00361 }
00362
00363
00364 void lir_gen_walker::gen_assignment(threeAddrNode * the_3addr) {
00365 if ( ! the_3addr->op() )
00366 gen_simple_assignment(the_3addr);
00367 else if ( the_3addr->op()->is_binary() )
00368 gen_binary_assignment(the_3addr);
00369 else if ( the_3addr->op()->is_unary() )
00370 gen_unary_assignment(the_3addr);
00371 else if ( the_3addr->op()->id() == Operator::FUNC_CALL )
00372 gen_call_assignment(the_3addr);
00373 else
00374 CBZFAIL(("Unknown assignment"));
00375 }
00376
00377
00378 void lir_gen_walker::gen_simple_assignment(threeAddrNode * the_3addr) {
00379 assert(the_3addr->rhs1());
00380 typeNode * type = the_3addr->lhs()->type();
00381 if ( type->is_scalar() ) {
00382
00383 pair<Register, declNode *> loaded = gen_load(the_3addr->rhs1());
00384 gen_store(the_3addr->lhs(), loaded.first, loaded.second);
00385 } else if ( structNode * the_struct = dynamic_cast<structNode *>(type) ) {
00386
00387
00388 assert(false);
00389 } else
00390 CBZFAIL(("Invalid simple assignment"));
00391 }
00392
00393
00394 void lir_gen_walker::gen_unary_assignment(threeAddrNode * the_3addr) {
00395 pair<Register, declNode *> rhsLoaded = gen_load(the_3addr->rhs1());
00396
00397
00398 Register resultReg;
00399 declNode * resultDecl = NULL;
00400 _alloc.get_temp_var(the_3addr->lhs()->type(), resultReg, resultDecl);
00401 LirInst * new_inst =
00402 unary_map[the_3addr->op()->id()](the_3addr->lhs()->type(),
00403 resultReg, resultDecl,
00404 rhsLoaded.first,
00405 rhsLoaded.second);
00406 _proc->instructions().push_back(new_inst);
00407 gen_store(the_3addr->lhs(), resultReg, resultDecl);
00408 }
00409
00410
00411 void lir_gen_walker::gen_binary_assignment(threeAddrNode * the_3addr) {
00412 pair<Register, declNode *> rhs1Loaded;
00413 pair<Register, declNode *> rhs2Loaded;
00414
00415 bool rhs1Pointer = ( the_3addr->rhs1()->type()->typ() == Ptr );
00416 bool rhs2Pointer = ( the_3addr->rhs2()->type()->typ() == Ptr );
00417
00418 if ( ( rhs1Pointer && ! rhs2Pointer )
00419 || ( rhs2Pointer && !rhs1Pointer ) ) {
00420
00421 assert(the_3addr->op()->id() == '-'
00422 || the_3addr->op()->id() == '+');
00423 operandNode * ptrNode = NULL;
00424 operandNode * intNode = NULL;
00425 if ( rhs1Pointer ) {
00426 ptrNode = the_3addr->rhs1();
00427 intNode = the_3addr->rhs2();
00428 } else {
00429 ptrNode = the_3addr->rhs2();
00430 intNode = the_3addr->rhs1();
00431 }
00432 typeNode * typePointed = ptrNode->noncast_type(false)->type();
00433 int size = typePointed->alloc_size();
00434 if ( size != 1 ) {
00435
00436
00437 pair<Register, declNode *> ptrLoaded = gen_load(ptrNode);
00438 pair<Register, declNode *> intLoaded = gen_load(intNode);
00439
00440 Register prodReg;
00441 declNode * prodDecl;
00442 _alloc.get_temp_var(intNode->type(), prodReg, prodDecl);
00443 reg_or_const sizeConst = constant::constant(size);
00444 _proc->instructions().push_back(LIR::Mul(intNode->type(),
00445 prodReg, prodDecl,
00446 intLoaded.first,
00447 intLoaded.second,
00448 sizeConst, NULL));
00449
00450
00451 rhs1Loaded = ptrLoaded;
00452 rhs2Loaded = pair<Register, declNode *>(prodReg, prodDecl);
00453 } else {
00454 rhs1Loaded = gen_load(the_3addr->rhs1());
00455 rhs2Loaded = gen_load(the_3addr->rhs2());
00456 }
00457 } else {
00458
00459 rhs1Loaded = gen_load(the_3addr->rhs1());
00460
00461 rhs2Loaded = gen_load(the_3addr->rhs2());
00462 }
00463
00464
00465 Register resultReg;
00466 declNode * resultDecl = NULL;
00467 _alloc.get_temp_var(the_3addr->lhs()->type(), resultReg, resultDecl);
00468 LirInst * new_inst =
00469 binary_map[the_3addr->op()->id()](the_3addr->lhs()->type(),
00470 resultReg, resultDecl,
00471 rhs1Loaded.first,
00472 rhs1Loaded.second,
00473 rhs2Loaded.first,
00474 rhs2Loaded.second);
00475 _proc->instructions().push_back(new_inst);
00476 gen_store(the_3addr->lhs(), resultReg, resultDecl);
00477 }
00478
00479
00480 void lir_gen_walker::gen_call_assignment(threeAddrNode * the_3addr) {
00481 gen_call(the_3addr);
00482
00483 typeNode * type = the_3addr->lhs()->type();
00484 if ( type->is_scalar() ) {
00485 Register reg;
00486 if ( Register::getRegRetVal(type, reg) ) {
00487 gen_store(the_3addr->lhs(), reg, DATA_CONTENTS_RETVAL);
00488 } else
00489 CBZFAIL(("No return register for scalar type"));
00490 } else {
00491
00492 assert(false);
00493 }
00494 }
00495
00496 void lir_gen_walker::gen_conditional_branch(conditiongotoNode * the_condgoto) {
00497 pair<Register, declNode *> leftLoaded = gen_load(the_condgoto->left());
00498 pair<Register, declNode *> rightLoaded = gen_load(the_condgoto->right());
00499 _proc->instructions().push_back(LIR::Compare(leftLoaded.first,
00500 leftLoaded.second,
00501 rightLoaded.first,
00502 rightLoaded.second));
00503 LirInst * new_inst =
00504 LIR::Branch(opid_cmptype_map[the_condgoto->op()->id()],
00505 the_condgoto->label()->name());
00506 _proc->instructions().push_back(new_inst);
00507 }
00508
00509 void lir_gen_walker::gen_goto(gotoNode * the_goto) {
00510 _proc->instructions().push_back(LIR::Jmp(the_goto->name()));
00511 }
00512
00513 void lir_gen_walker::gen_label(labelNode * the_label) {
00514 _proc->instructions().push_back(LIR::Label(the_label->name()));
00515 }
00516
00517 void lir_gen_walker::gen_return(returnNode * the_return) {
00518
00519
00520
00521
00522 _proc->instructions().push_back(LIR::Return(_proc));
00523 }
00524
00525 void lir_gen_walker::gen_call(threeAddrNode * the_3addr) {
00526
00527 _proc->instructions().push_back(LIR::CallPre());
00528
00529 operand_list & args = the_3addr->arg_list();
00530 operand_list_p currArg = args.begin();
00531 int nextFixed = 0;
00532 int nextFloat = 0;
00533 Register currReg;
00534 const arch_info::register_info_list & fixedRegs =
00535 CBZ::ArchInfo.get_regs_param_fixed();
00536 const arch_info::register_info_list & floatRegs =
00537 CBZ::ArchInfo.get_regs_param_float();
00538
00539 int stack_arg_bytes = 0;
00540 int nextStackOffset = CBZ::ArchInfo.get_stack_extra_bottom();
00541 while ( currArg != args.end() ) {
00542 bool isFloat = (*currArg)->type()->is_float();
00543 bool isFixed = (*currArg)->type()->is_integer()
00544 || (*currArg)->type()->is_pointer();
00545
00546 if ( isFloat && nextFloat < floatRegs.size() ) {
00547 currReg = *(floatRegs[nextFloat++]);
00548 pair<Register, declNode *> argLoaded = gen_load(*currArg);
00549 gen_move(currReg, DATA_CONTENTS_REG_OUT, argLoaded.first,
00550 argLoaded.second);
00551 } else if ( isFixed && nextFixed < fixedRegs.size() ) {
00552 currReg = *(fixedRegs[nextFixed++]);
00553 pair<Register, declNode *> argLoaded = gen_load(*currArg);
00554 gen_move(currReg, DATA_CONTENTS_REG_OUT, argLoaded.first,
00555 argLoaded.second);
00556 } else {
00557
00558
00559
00560 typeNode * argType = (*currArg)->type();
00561 AllocSizeChanger::size(argType);
00562 int align = argType->alloc_align();
00563 int size = argType->alloc_size();
00564 nextStackOffset = ((nextStackOffset + align - 1) / align ) * align;
00565
00566 if ( (*currArg)->type()->is_scalar() ) {
00567 pair<Register, declNode *> argLoaded = gen_load(*currArg);
00568 _proc->instructions().push_back(LIR::Store((*currArg)->type(),
00569 argLoaded.first,
00570 argLoaded.second,
00571 Register::getRegSp(),
00572 DATA_CONTENTS_STACKP,
00573 nextStackOffset,
00574 NULL));
00575 } else {
00576
00577
00578 assert(false);
00579 }
00580 nextStackOffset += size;
00581 stack_arg_bytes += size;
00582 }
00583 currArg++;
00584 }
00585
00586 _proc->instructions().push_back(LIR::Call(the_3addr, stack_arg_bytes));
00587 }
00588
00589 pair<Register, declNode *> lir_gen_walker::gen_load(indexNode * the_index) {
00590 if ( idNode * the_id = dynamic_cast<idNode *>(the_index) ) {
00591 if ( the_id->decl()->decl_location() == declNode::TOP )
00592 return load_global_var(the_id);
00593 else
00594 return load_stack_var(the_id);
00595 } else if ( constNode * the_const = dynamic_cast<constNode *>(the_index) ) {
00596 return load_const(the_const);
00597 } else
00598 CBZFAIL(("Unknown indexNode"));
00599 }
00600
00601 pair<Register, declNode *> lir_gen_walker::gen_load(operandNode * the_oper) {
00602 if ( idNode * the_id = dynamic_cast<idNode *>(the_oper->var()) ) {
00603 if ( the_id->decl()->decl_location() == declNode::TOP )
00604 return load_global(the_oper);
00605 else
00606 return load_stack(the_oper);
00607 }
00608 else if (constNode * the_const = dynamic_cast<constNode*>(the_oper->var())) {
00609 assert(the_oper->fields().empty() && !the_oper->index());
00610 return load_const(the_const);
00611 } else
00612 CBZFAIL(("Malformed operandNode"));
00613 }
00614
00615 int lir_gen_walker::field_offset(operandNode * the_oper) {
00616 int offset = 0;
00617
00618 typeNode * containingType = the_oper->var()->type()->follow_tdefs();
00619 if ( the_oper->star() )
00620 containingType = containingType->type()->follow_tdefs();
00621
00622 for ( id_list_p operField = the_oper->fields().begin();
00623 operField != the_oper->fields().end();
00624 operField++ ) {
00625 if ( structNode * containingStruct =
00626 dynamic_cast<structNode *>(containingType) ) {
00627 suespecNode * suespec = containingStruct->spec();
00628 assert(suespec);
00629 for ( decl_list_p structField = suespec->fields().begin();
00630 structField != suespec->fields().end()
00631 && (*structField) != (*operField)->decl();
00632 structField++ ) {
00633 int align = (*structField)->type()->alloc_align();
00634 int size = (*structField)->type()->alloc_size();
00635 offset = (( (offset + size) + align - 1) / align) * align;
00636
00637 }
00638 }
00639 containingType = (*operField)->decl()->type()->follow_tdefs();
00640 }
00641 typeNode * type = the_oper->type();
00642 AllocSizeChanger::size(type);
00643 int align = type->alloc_align();
00644 offset = (( offset + align - 1) / align) * align;
00645
00646
00647 return offset;
00648 }
00649
00650 pair<reg_or_const, declNode *> lir_gen_walker::index_offset
00651 (
00652 operandNode * the_oper
00653 )
00654 {
00655 if ( the_oper->index() ) {
00656 typeNode * elmtType = the_oper->noncast_type(false);
00657
00658
00659 int elmtSize = elmtType->alloc_size();
00660 if ( idNode * idIndex = dynamic_cast<idNode *>(the_oper->index()) ) {
00661 pair<Register, declNode *> indexLoaded = gen_load(idIndex);
00662
00663 Register resultReg;
00664 declNode * resultDecl;
00665 primNode * intType = new primNode(basic_type::Int);
00666 _alloc.get_temp_var(intType, resultReg, resultDecl);
00667 _proc->instructions().push_back(LIR::Mul(intType, resultReg, resultDecl,
00668 indexLoaded.first,
00669 indexLoaded.second,
00670 constant::constant(elmtSize),
00671 NULL));
00672 return pair<reg_or_const, declNode *>(resultReg, resultDecl);
00673 } else {
00674 constNode * constIndex = dynamic_cast<constNode *>(the_oper->index());
00675 assert(constIndex);
00676 constant constVal = elmtSize * constIndex->value().Integer();
00677
00678 return pair<reg_or_const, declNode *>(constVal, NULL);
00679 }
00680 }
00681 return pair<reg_or_const, declNode *>(constant::constant(0), NULL);
00682 }
00683
00684 pair<Register, declNode *> lir_gen_walker::load_global(operandNode * the_oper)
00685 {
00686 if ( the_oper->addr() ) {
00687 return load_global_ea(the_oper);
00688 } else if ( arrayNode * arrayType =
00689 dynamic_cast<arrayNode *>(the_oper->noncast_type(false)) ) {
00690
00691 return load_global_ea(the_oper);
00692 } else {
00693 return load_global_value(the_oper);
00694 }
00695 }
00696
00697
00698 pair<Register, declNode *> lir_gen_walker::load_global_ea
00699 (
00700 operandNode * the_oper
00701 )
00702 {
00703 idNode * the_id = dynamic_cast<idNode *>(the_oper->var());
00704 assert(the_id);
00705 int fieldOffset = field_offset(the_oper);
00706 pair<reg_or_const, declNode *> indexOffset = index_offset(the_oper);
00707
00708 pair<Register, declNode *> base;
00709 if ( the_oper->star() )
00710 base = load_global_var(the_id);
00711 else
00712 base = load_global_addr(the_id);
00713
00714 if ( indexOffset.first._is_const ) {
00715 int offset = fieldOffset + indexOffset.first._const.Integer();
00716 if ( offset ) {
00717 Register addrReg;
00718 declNode * addrDecl;
00719 _alloc.get_temp_ptr(addrReg, addrDecl);
00720
00721 constNode * offsetConst = new constNode(constant::constant(offset));
00722 pair<Register, declNode *> offLoaded = load_const(offsetConst);
00723 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00724 addrReg, addrDecl,
00725 base.first, base.second,
00726 offLoaded.first,
00727 offLoaded.second));
00728 return pair<Register, declNode *>(addrReg, addrDecl);
00729 } else {
00730 return base;
00731 }
00732 } else {
00733 if ( fieldOffset ) {
00734 Register tempReg;
00735 declNode * tempDecl;
00736 _alloc.get_temp_ptr(tempReg, tempDecl);
00737
00738 constNode * offsetConst = new constNode(constant::constant(fieldOffset));
00739 pair<Register, declNode *> offLoaded = load_const(offsetConst);
00740 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00741 tempReg, tempDecl,
00742 base.first, base.second,
00743 offLoaded.first,
00744 offLoaded.second));
00745 base = pair<Register, declNode *>(tempReg, tempDecl);
00746 }
00747 Register addrReg;
00748 declNode * addrDecl;
00749 _alloc.get_temp_ptr(addrReg, addrDecl);
00750 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00751 addrReg, addrDecl,
00752 base.first, base.second,
00753 indexOffset.first._reg,
00754 indexOffset.second));
00755 return pair<Register, declNode *>(addrReg, addrDecl);
00756 }
00757 }
00758
00759
00760 pair<Register, declNode *> lir_gen_walker::load_global_value
00761 (
00762 operandNode * the_oper
00763 )
00764 {
00765 idNode * the_id = dynamic_cast<idNode *>(the_oper->var());
00766 assert(the_id);
00767 int fieldOffset = field_offset(the_oper);
00768
00769 Register loadReg;
00770 declNode * loadDecl;
00771 _alloc.get_temp_var(the_oper->noncast_type(), loadReg, loadDecl);
00772 const declNode::Storage_location & loc = the_id->decl()->storage_location();
00773 assert(loc._type == declNode::Storage_location::storageloc_mem_global);
00774
00775 if ( the_oper->index() ) {
00776 pair<reg_or_const, declNode *> indexOffset = index_offset(the_oper);
00777 int offset = fieldOffset;
00778 pair<Register, declNode *> base;
00779
00780 if ( the_id->type()->typ() == Ptr ) {
00781 base = load_global_var(the_id);
00782 if ( the_oper->star() ) {
00783
00784 Register tempReg;
00785 declNode * tempDecl;
00786 _alloc.get_temp_ptr(tempReg, tempDecl);
00787 _proc->instructions().push_back(LIR::Load(LirUtil::newVoidPtr(),
00788 tempReg, tempDecl,
00789 base.first, base.second,
00790 constant::constant(0),
00791 NULL));
00792 base = pair<Register, declNode *>(tempReg, tempDecl);
00793 }
00794 } else {
00795 base = load_global_addr(the_id);
00796 }
00797
00798 if ( indexOffset.first._is_const )
00799 offset += indexOffset.first._const.Integer();
00800 else {
00801
00802 Register tempReg;
00803 declNode * tempDecl;
00804 _alloc.get_temp_ptr(tempReg, tempDecl);
00805 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00806 tempReg, tempDecl,
00807 base.first, base.second,
00808 indexOffset.first._reg,
00809 indexOffset.second));
00810 base = pair<Register, declNode *>(tempReg, tempDecl);
00811 }
00812
00813 _proc->instructions().push_back(LIR::Load(the_oper->noncast_type(),
00814 loadReg, loadDecl,
00815 base.first, base.second,
00816 constant::constant(offset),
00817 NULL));
00818 } else {
00819 if ( the_oper->star() ) {
00820 pair<Register, declNode *> base = load_global_var(the_id);
00821 LirInst * newInst = LIR::Load(the_oper->noncast_type(),
00822 loadReg, loadDecl,
00823 base.first, base.second,
00824 constant::constant(fieldOffset),
00825 NULL);
00826 _proc->instructions().push_back(newInst);
00827 } else {
00828 LirInst * newInst = LIR::LoadStatic(the_oper->noncast_type(),
00829 loadReg, loadDecl,
00830 the_id->name(), the_id->decl(),
00831 constant::constant(fieldOffset),
00832 NULL);
00833 _proc->instructions().push_back(newInst);
00834 }
00835 }
00836
00837 if ( needs_conversion(the_oper->noncast_type(), the_oper->type()) )
00838 return gen_conversion(the_oper->type(), loadReg, loadDecl);
00839 else
00840 return pair<Register, declNode *>(loadReg, loadDecl);
00841 }
00842
00843 pair<Register, declNode *> lir_gen_walker::load_global_var(idNode * the_id) {
00844 const declNode::Storage_location & loc = the_id->decl()->storage_location();
00845 assert(loc._type == declNode::Storage_location::storageloc_mem_global);
00846
00847 Register reg;
00848 declNode * regDecl;
00849 _alloc.get_temp_var(the_id->type(), reg, regDecl);
00850 _proc->instructions().push_back(LIR::LoadStatic(the_id->type(), reg, regDecl,
00851 the_id->name(),
00852 the_id->decl(),
00853 constant::constant(0),
00854 NULL));
00855 return pair<Register, declNode *>(reg, regDecl);
00856 }
00857
00858 pair<Register, declNode *> lir_gen_walker::load_global_addr(idNode * the_id) {
00859 const declNode::Storage_location & loc = the_id->decl()->storage_location();
00860 assert(loc._type == declNode::Storage_location::storageloc_mem_global);
00861
00862 Register reg;
00863 declNode * regDecl;
00864 _alloc.get_temp_ptr(reg, regDecl);
00865 _proc->instructions().push_back(LIR::GetGlobalAddress(reg, regDecl,
00866 the_id->name(),
00867 the_id->decl(),
00868 constant::constant(0),
00869 NULL));
00870 return pair<Register, declNode *>(reg, regDecl);
00871 }
00872
00873 pair<Register, declNode *> lir_gen_walker::load_stack(operandNode * the_oper) {
00874 if ( the_oper->addr() ) {
00875 return load_stack_ea(the_oper);
00876 } else if ( arrayNode * arrayType =
00877 dynamic_cast<arrayNode *>(the_oper->noncast_type(false)) ) {
00878
00879 return load_stack_ea(the_oper);
00880 } else {
00881 return load_stack_value(the_oper);
00882 }
00883 }
00884
00885
00886 pair<Register, declNode *> lir_gen_walker::load_stack_ea
00887 (
00888 operandNode * the_oper
00889 )
00890 {
00891 idNode * the_id = dynamic_cast<idNode *>(the_oper->var());
00892 assert(the_id);
00893 int fieldOffset = field_offset(the_oper);
00894 pair<reg_or_const, declNode *> indexOffset = index_offset(the_oper);
00895
00896 pair<Register, declNode *> base;
00897 if ( the_oper->star() )
00898 base = load_stack_var(the_id);
00899 else
00900 base = load_stack_addr(the_id);
00901 if ( indexOffset.first._is_const ) {
00902 int offset = fieldOffset + indexOffset.first._const.Integer();
00903 if ( offset ) {
00904 Register addrReg;
00905 declNode * addrDecl;
00906 _alloc.get_temp_ptr(addrReg, addrDecl);
00907
00908 constNode * offsetConst = new constNode(constant::constant(offset));
00909 pair<Register, declNode *> offLoaded = load_const(offsetConst);
00910 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00911 addrReg, addrDecl,
00912 base.first, base.second,
00913 offLoaded.first,
00914 offLoaded.second));
00915 return pair<Register, declNode *>(addrReg, addrDecl);
00916 } else {
00917 return base;
00918 }
00919 } else {
00920 if ( fieldOffset ) {
00921 Register tempReg;
00922 declNode * tempDecl;
00923 _alloc.get_temp_ptr(tempReg, tempDecl);
00924
00925 constNode * offsetConst = new constNode(constant::constant(fieldOffset));
00926 pair<Register, declNode *> offLoaded = load_const(offsetConst);
00927 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00928 tempReg, tempDecl,
00929 base.first, base.second,
00930 offLoaded.first,
00931 offLoaded.second));
00932 base = pair<Register, declNode *>(tempReg, tempDecl);
00933 }
00934 Register addrReg;
00935 declNode * addrDecl;
00936 _alloc.get_temp_ptr(addrReg, addrDecl);
00937 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00938 addrReg, addrDecl,
00939 base.first, base.second,
00940 indexOffset.first._reg,
00941 indexOffset.second));
00942 return pair<Register, declNode *>(addrReg, addrDecl);
00943 }
00944 }
00945
00946
00947 pair<Register, declNode *> lir_gen_walker::load_stack_value
00948 (
00949 operandNode * the_oper
00950 )
00951 {
00952 idNode * the_id = dynamic_cast<idNode *>(the_oper->var());
00953 assert(the_id);
00954 int fieldOffset = field_offset(the_oper);
00955
00956 Register loadReg;
00957 declNode * loadDecl;
00958 _alloc.get_temp_var(the_oper->noncast_type(), loadReg, loadDecl);
00959 const declNode::Storage_location & loc = the_id->decl()->storage_location();
00960
00961 pair<Register, declNode *> base;
00962 int offset = fieldOffset;
00963
00964 if ( the_oper->index() ) {
00965 pair<reg_or_const, declNode *> indexOffset = index_offset(the_oper);
00966 if ( the_id->type()->typ() == Ptr ) {
00967 base = load_stack_var(the_id);
00968 if ( the_oper->star() ) {
00969
00970 Register tempReg;
00971 declNode * tempDecl;
00972 _alloc.get_temp_ptr(tempReg, tempDecl);
00973 _proc->instructions().push_back(LIR::Load(LirUtil::newVoidPtr(),
00974 tempReg, tempDecl,
00975 base.first, base.second,
00976 constant::constant(0),
00977 NULL));
00978 base = pair<Register, declNode *>(tempReg, tempDecl);
00979 }
00980 } else {
00981 base = pair<Register, declNode *>(Register::getRegFp(),
00982 DATA_CONTENTS_FRAMEP);
00983 offset += loc._stack_offset;
00984 }
00985
00986 if ( indexOffset.first._is_const )
00987 offset += indexOffset.first._const.Integer();
00988 else {
00989
00990
00991 Register tempReg;
00992 declNode * tempDecl;
00993 _alloc.get_temp_ptr(tempReg, tempDecl);
00994 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
00995 tempReg, tempDecl,
00996 base.first, base.second,
00997 indexOffset.first._reg,
00998 indexOffset.second));
00999 base = pair<Register, declNode *>(tempReg, tempDecl);
01000 }
01001 } else {
01002 if ( the_oper->star() )
01003 base = load_stack_var(the_id);
01004 else if ( loc._type == declNode::Storage_location::storageloc_register ) {
01005
01006
01007 assert(the_oper->fields().empty());
01008 return pair<Register, declNode *>(loc._register, the_id->decl());
01009 } else {
01010 base = pair<Register, declNode *>(Register::getRegFp(),
01011 DATA_CONTENTS_FRAMEP);
01012 offset += loc._stack_offset;
01013 }
01014 }
01015 _proc->instructions().push_back(LIR::Load(the_oper->noncast_type(),
01016 loadReg, loadDecl,
01017 base.first, base.second,
01018 constant::constant(offset),
01019 NULL));
01020
01021 if ( needs_conversion(the_oper->noncast_type(), the_oper->type()) )
01022 return gen_conversion(the_oper->type(), loadReg, loadDecl);
01023 else
01024 return pair<Register, declNode *>(loadReg, loadDecl);
01025 }
01026
01027 pair<Register, declNode *> lir_gen_walker::load_stack_var(idNode * the_id) {
01028 const declNode::Storage_location & loc = the_id->decl()->storage_location();
01029
01030 if ( loc._type == declNode::Storage_location::storageloc_register )
01031
01032 return pair<Register, declNode *>(loc._register, the_id->decl());
01033 else if ( loc._type == declNode::Storage_location::storageloc_stack ) {
01034 Register reg;
01035 declNode * regDecl;
01036 _alloc.get_temp_var(the_id->type(), reg, regDecl);
01037 _proc->instructions().push_back(LIR::Load(the_id->type(), reg, regDecl,
01038 Register::getRegFp(),
01039 DATA_CONTENTS_FRAMEP,
01040 loc._stack_offset, NULL));
01041 return pair<Register, declNode *>(reg, regDecl);
01042 } else
01043 CBZFAIL(("Incorrect Storage_location for a local variable."));
01044 }
01045
01046 pair<Register, declNode *> lir_gen_walker::load_stack_addr(idNode * the_id) {
01047 const declNode::Storage_location & loc = the_id->decl()->storage_location();
01048 assert(loc._type == declNode::Storage_location::storageloc_stack);
01049
01050 Register reg;
01051 declNode * regDecl;
01052 _alloc.get_temp_ptr(reg, regDecl);
01053 LirInst * new_inst = LIR::GetEffectiveAddress(reg, regDecl,
01054 Register::getRegFp(),
01055 DATA_CONTENTS_FRAMEP,
01056 loc._stack_offset, NULL);
01057 _proc->instructions().push_back(new_inst);
01058 return pair<Register, declNode *>(reg, regDecl);
01059 }
01060
01061
01062 pair<Register, declNode *> lir_gen_walker::load_const(constNode * the_const) {
01063 assert(the_const);
01064 Register destReg;
01065 declNode * destDecl;
01066 _alloc.get_temp_var(the_const->type(), destReg, destDecl);
01067
01068 constant & const_val = the_const->value();
01069 assert(!const_val.no_val());
01070
01071 if ( const_val.is_str() ) {
01072
01073
01074 declNode * temp_decl = LirUtil::new_static_global(the_const->type(),
01075 the_const);
01076 gen_global_decl(temp_decl);
01077
01078
01079
01080
01081
01082
01083 _proc->instructions().push_back(LIR::GetGlobalAddress(destReg, destDecl,
01084 temp_decl->name(),
01085 temp_decl,
01086 constant(0),
01087 NULL));
01088 } else if ( CBZ::ArchInfo.instruction_supports_immediate(mn_LoadImmediate,
01089 the_const->type(),
01090 const_val) ) {
01091
01092 _proc->instructions().push_back(LIR::LoadImmediate(the_const->type(),
01093 destReg,
01094 destDecl,
01095 const_val));
01096 } else {
01097
01098 declNode * temp_decl = LirUtil::new_static_global(the_const->type(),
01099 the_const);
01100 gen_global_decl(temp_decl);
01101 _proc->instructions().push_back(LIR::LoadStatic(the_const->type(),
01102 destReg, destDecl,
01103 temp_decl->name(),
01104 temp_decl,
01105 constant::constant(0),
01106 NULL));
01107 }
01108
01109 return pair<Register, declNode *>(destReg, destDecl);
01110 }
01111
01112 void lir_gen_walker::gen_store(operandNode * dest, Register reg,
01113 declNode * regDecl) {
01114 if ( idNode * the_id = dynamic_cast<idNode *>(dest->var()) ) {
01115 if ( the_id->decl()->decl_location() == declNode::TOP )
01116 store_global(dest, reg, regDecl);
01117 else
01118 store_stack(dest, reg, regDecl);
01119 } else
01120 CBZFAIL(("Malformed operandNode for storing"));
01121 }
01122
01123
01124 void lir_gen_walker::store_global(operandNode * dest, Register reg,
01125 declNode * regDecl) {
01126 idNode * the_id = dynamic_cast<idNode *>(dest->var());
01127 assert(the_id);
01128 int fieldOffset = field_offset(dest);
01129
01130 const declNode::Storage_location & loc = the_id->decl()->storage_location();
01131 assert(loc._type == declNode::Storage_location::storageloc_mem_global);
01132
01133 if ( dest->index() ) {
01134 pair<reg_or_const, declNode *> indexOffset = index_offset(dest);
01135 pair<Register, declNode *> base;
01136
01137 if ( the_id->type()->typ() == Ptr ) {
01138 base = load_global_var(the_id);
01139 if ( dest->star() ) {
01140
01141 Register tempReg;
01142 declNode * tempDecl;
01143 _alloc.get_temp_ptr(tempReg, tempDecl);
01144 _proc->instructions().push_back(LIR::Load(LirUtil::newVoidPtr(),
01145 tempReg, tempDecl,
01146 base.first, base.second,
01147 constant::constant(0),
01148 NULL));
01149 base = pair<Register, declNode *>(tempReg, tempDecl);
01150 }
01151 } else {
01152 if ( indexOffset.first._is_const ) {
01153 int offset = fieldOffset + indexOffset.first._const.Integer();
01154 LirInst * newInst = LIR::StoreStatic(dest->type(),
01155 reg, regDecl,
01156 the_id->name(),
01157 the_id->decl(),
01158 constant::constant(offset),
01159 NULL);
01160 _proc->instructions().push_back(newInst);
01161 return;
01162 } else
01163 base = load_global_addr(the_id);
01164 }
01165
01166 if ( indexOffset.first._is_const ) {
01167 int offset = fieldOffset + indexOffset.first._const.Integer();
01168 LirInst * newInst = LIR::Store(dest->type(), reg, regDecl,
01169 base.first, base.second,
01170 constant::constant(offset),
01171 NULL);
01172 _proc->instructions().push_back(newInst);
01173 } else {
01174
01175 Register tempReg;
01176 declNode * tempDecl;
01177 _alloc.get_temp_ptr(tempReg, tempDecl);
01178 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
01179 tempReg, tempDecl,
01180 base.first, base.second,
01181 indexOffset.first._reg,
01182 indexOffset.second));
01183 LirInst * newInst = LIR::Store(dest->type(),
01184 reg, regDecl,
01185 tempReg, tempDecl,
01186 constant::constant(fieldOffset),
01187 NULL);
01188 _proc->instructions().push_back(newInst);
01189 }
01190 } else {
01191 if ( dest->star() ) {
01192 pair<Register, declNode *> base = load_global_var(the_id);
01193 LirInst * newInst = LIR::Store(dest->type(),
01194 reg, regDecl,
01195 base.first, base.second,
01196 constant::constant(fieldOffset),
01197 NULL);
01198 _proc->instructions().push_back(newInst);
01199 } else {
01200 LirInst * newInst = LIR::StoreStatic(dest->type(),
01201 reg, regDecl,
01202 the_id->name(),
01203 the_id->decl(),
01204 constant::constant(fieldOffset),
01205 NULL);
01206 _proc->instructions().push_back(newInst);
01207 }
01208 }
01209 }
01210
01211
01212 void lir_gen_walker::store_stack(operandNode * dest, Register reg,
01213 declNode * regDecl) {
01214 idNode * the_id = dynamic_cast<idNode *>(dest->var());
01215 assert(the_id);
01216 int fieldOffset = field_offset(dest);
01217
01218 const declNode::Storage_location & loc = the_id->decl()->storage_location();
01219
01220 pair<Register, declNode *> base;
01221 int offset = fieldOffset;
01222
01223 if ( dest->index() ) {
01224 pair<reg_or_const, declNode *> indexOffset = index_offset(dest);
01225 if ( the_id->type()->typ() == Ptr ) {
01226 base = load_stack_var(the_id);
01227 if ( dest->star() ) {
01228
01229 Register tempReg;
01230 declNode * tempDecl;
01231 _alloc.get_temp_ptr(tempReg, tempDecl);
01232 _proc->instructions().push_back(LIR::Load(LirUtil::newVoidPtr(),
01233 tempReg, tempDecl,
01234 base.first, base.second,
01235 constant::constant(0),
01236 NULL));
01237 base = pair<Register, declNode *>(tempReg, tempDecl);
01238 }
01239 } else {
01240 base = pair<Register, declNode *>(Register::getRegFp(),
01241 DATA_CONTENTS_FRAMEP);
01242 offset += loc._stack_offset;
01243 }
01244
01245 if ( indexOffset.first._is_const )
01246 offset += indexOffset.first._const.Integer();
01247 else {
01248
01249
01250 Register tempReg;
01251 declNode * tempDecl;
01252 _alloc.get_temp_ptr(tempReg, tempDecl);
01253 _proc->instructions().push_back(LIR::Add(LirUtil::newVoidPtr(),
01254 tempReg, tempDecl,
01255 base.first, base.second,
01256 indexOffset.first._reg,
01257 indexOffset.second));
01258 base = pair<Register, declNode *>(tempReg, tempDecl);
01259 }
01260 } else {
01261 if ( dest->star() )
01262 base = load_stack_var(the_id);
01263 else if ( loc._type == declNode::Storage_location::storageloc_register ) {
01264
01265
01266 assert(dest->fields().empty());
01267 gen_move(loc._register, the_id->decl(), reg, regDecl);
01268 return;
01269 } else {
01270 base = pair<Register, declNode *>(Register::getRegFp(),
01271 DATA_CONTENTS_FRAMEP);
01272 offset += loc._stack_offset;
01273 }
01274 }
01275 _proc->instructions().push_back(LIR::Store(dest->type(), reg, regDecl,
01276 base.first, base.second,
01277 constant::constant(offset),
01278 NULL));
01279 }
01280
01281 void lir_gen_walker::gen_move(Register dest, declNode * destDecl, Register src,
01282 declNode * srcDecl) {
01283 _proc->instructions().push_back(LIR::Move(dest, destDecl, src, srcDecl));
01284 }
01285
01286 bool lir_gen_walker::needs_conversion(typeNode * in_memory, typeNode * in_reg)
01287 {
01288 return ( *in_memory != *in_reg );
01289 }
01290
01291 pair<Register, declNode *> lir_gen_walker::gen_conversion
01292 (
01293 typeNode * targetType,
01294 Register srcReg,
01295 declNode * srcDecl
01296 )
01297 {
01298 Register resultReg;
01299 declNode * resultDecl;
01300 _alloc.get_temp_var(targetType, resultReg, resultDecl);
01301 _proc->instructions().push_back(LIR::ConvertType(srcDecl->type(),
01302 srcReg, srcDecl,
01303 targetType,
01304 resultReg, resultDecl));
01305 return pair<Register, declNode *>(resultReg, resultDecl);
01306 }
01307
01308 AllocSizeChanger::AllocSizeChanger(void) :
01309 Changer(Both, Subtree, false)
01310 {}
01311
01312 Node * AllocSizeChanger::at_prim(primNode * the_prim, Order ord) {
01313 if ( ord == Postorder ) {
01314 the_prim->alloc_size(CBZ::ArchInfo.get_data_size(the_prim));
01315 the_prim->alloc_align(CBZ::ArchInfo.get_data_align(the_prim));
01316 }
01317
01318 return the_prim;
01319 }
01320
01321 Node * AllocSizeChanger::at_decl(declNode * the_decl, Order ord) {
01322 if ( ord == Preorder ) {
01323 _decls.push(the_decl);
01324 } else {
01325 assert(_decls.top() == the_decl);
01326 _decls.pop();
01327 }
01328
01329 return the_decl;
01330 }
01331
01332 Node * AllocSizeChanger::at_array(arrayNode * the_array, Order ord) {
01333 if ( ord == Postorder ) {
01334 if ( _decls.empty()
01335 || ( _decls.top()->decl_location() != declNode::FORMAL
01336 && _decls.top()->storage_class() != declNode::EXTERN ) ) {
01337 assert(the_array->dim());
01338 the_array->dim()->eval();
01339 assert(!the_array->dim()->value().no_val());
01340 the_array->alloc_size(the_array->type()->alloc_size()
01341 * the_array->dim()->value().Integer());
01342 the_array->alloc_align(the_array->type()->alloc_align());
01343 } else {
01344
01345
01346 the_array->alloc_size(CBZ::ArchInfo.get_data_size_ptr());
01347 the_array->alloc_align(CBZ::ArchInfo.get_data_align_ptr());
01348 }
01349 }
01350
01351 return the_array;
01352 }
01353
01354 Node * AllocSizeChanger::at_ptr(ptrNode * the_ptr, Order ord) {
01355 if ( ord == Postorder ) {
01356 the_ptr->alloc_size(CBZ::ArchInfo.get_data_size(the_ptr));
01357 the_ptr->alloc_align(CBZ::ArchInfo.get_data_align(the_ptr));
01358 }
01359
01360 return the_ptr;
01361 }
01362
01363 Node * AllocSizeChanger::at_enum(enumNode * the_enum, Order ord) {
01364 if ( ord == Postorder ) {
01365 primNode unsignedInt(typeNode::NONE, basic_type::UInt);
01366 the_enum->alloc_size(CBZ::ArchInfo.get_data_size(&unsignedInt));
01367 the_enum->alloc_align(CBZ::ArchInfo.get_data_align(&unsignedInt));
01368 }
01369
01370 return the_enum;
01371 }
01372
01373 Node * AllocSizeChanger::at_union(unionNode * the_union, Order ord) {
01374 if ( ord == Postorder ) {
01375 int maxSize = -1;
01376 int maxAlign = -1;
01377 for ( decl_list_p p = the_union->spec()->fields().begin();
01378 p != the_union->spec()->fields().end();
01379 p++ ) {
01380 maxSize = max(maxSize, (*p)->type()->alloc_size());
01381 maxAlign = max(maxAlign, (*p)->type()->alloc_align());
01382 }
01383 the_union->alloc_size(maxSize);
01384 the_union->alloc_align(maxAlign);
01385 }
01386
01387 return the_union;
01388 }
01389
01390 Node * AllocSizeChanger::at_struct(structNode * the_struct, Order ord) {
01391 if ( ord == Postorder ) {
01392 int size = 0;
01393 int align = 0;
01394 for ( decl_list_p p = the_struct->spec()->fields().begin();
01395 p != the_struct->spec()->fields().end();
01396 p++ ) {
01397 size += (*p)->type()->alloc_size();
01398 align = max(align, (*p)->type()->alloc_align());
01399 }
01400 the_struct->alloc_size(size);
01401 the_struct->alloc_align(align);
01402 }
01403
01404 return the_struct;
01405 }
01406
01407 Node * AllocSizeChanger::at_tdef(tdefNode * the_tdef, Order ord) {
01408 if ( ord == Postorder ) {
01409 the_tdef->alloc_size(the_tdef->def()->alloc_size());
01410 the_tdef->alloc_align(the_tdef->def()->alloc_align());
01411 }
01412
01413 return the_tdef;
01414 }
01415
01416 Node * AllocSizeChanger::at_unary(unaryNode * the_unary, Order ord) {
01417 if ( ord == Postorder ) {
01418 if ( the_unary->op()
01419 && the_unary->op()->id() == Operator::SIZEOF ) {
01420 typeNode * sizeof_type = the_unary->sizeof_type();
01421 assert(sizeof_type);
01422 ostringstream ost;
01423 ost << sizeof_type->alloc_size();
01424 return new constNode(constant::constant(sizeof_type->alloc_size()),
01425 ost.str().c_str(), the_unary->coord());
01426 }
01427 }
01428
01429 return the_unary;
01430 }
01431
01432 SizeofChanger::SizeofChanger(void) :
01433 Changer(Preorder, Subtree, false)
01434 {}
01435
01436 Node * SizeofChanger::at_threeAddr(threeAddrNode * the_3addr, Order ord) {
01437 if ( typeNode * size_type = the_3addr->sizeof_type() ) {
01438 ostringstream ost;
01439 ost << size_type->alloc_size();
01440 constNode * sizeConst =
01441 new constNode(constant::constant(size_type->alloc_size()),
01442 ost.str().c_str(),
01443 the_3addr->coord());
01444 the_3addr->rhs1(new operandNode(sizeConst, the_3addr->coord()));
01445 the_3addr->sizeof_type(static_cast<typeNode *>(0));
01446 }
01447 return the_3addr;
01448 }
01449
01450 AllocToMemWalker::AllocToMemWalker(void) :
01451 Walker(Preorder, Subtree)
01452 {}
01453
01454 bool AllocToMemWalker::needsMem(declNode * the_decl) {
01455 return ( find(_decls.begin(), _decls.end(), the_decl) != _decls.end() );
01456 }
01457
01458 void AllocToMemWalker::at_decl(declNode * the_decl, Order ord) {
01459 if ( the_decl->type()->is_aggregate()
01460 || the_decl->type()->typ() == Union ) {
01461 _decls.push_back(the_decl);
01462 cout << "Must alloc to memory " << the_decl->name() << endl;
01463 }
01464 }
01465
01466 void AllocToMemWalker::at_operand(operandNode * the_oper, Order ord) {
01467 if ( the_oper->addr()
01468 && the_oper->fields().empty()
01469 && !the_oper->index() ) {
01470 if ( idNode * the_id = dynamic_cast<idNode *>(the_oper->var()) ) {
01471 typeNode * type = the_oper->type();
01472 if ( ( type->is_float()
01473 || type->is_integer()
01474 || type->is_pointer() )
01475 && the_id->decl()->decl_location() == declNode::BLOCK )
01476
01477
01478 _decls.push_back(the_id->decl());
01479 cout << "Must alloc to memory " << the_id->name() << endl;
01480 }
01481 }
01482 }