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
00040 #include "c_breeze.h"
00041 #include "LIR.h"
00042 #include "lirutil.h"
00043
00044 LirInst *
00045 LIR::ConvertType (typeNode * sourceType, Register source,
00046 declNode * pDeclSrc, typeNode * destType,
00047 Register & dest, declNode * pDeclDest)
00048 {
00049 dest.setType(destType);
00050
00051
00052 LirInst *inst = new LirInst (mn_ConvertType);
00053 inst->opnd1 = source;
00054 inst->opnd1_contents = pDeclSrc;
00055 inst->dest = dest;
00056 inst->dest_contents = pDeclDest;
00057 inst->primaryType = sourceType;
00058 inst->convertType = destType;
00059
00060 return inst;
00061 }
00062
00063 LirInst *
00064 LIR::Load (typeNode * typeToLoad, Register & dest,
00065 declNode * pDeclDest, Register base_reg,
00066 declNode * pDeclBase, constant offset,
00067 declNode * pDeclOffset)
00068 {
00069 dest.setType(typeToLoad);
00070
00071
00072 LirInst *inst = new LirInst (mn_Load);
00073 inst->dest = dest;
00074 inst->dest_contents = pDeclDest;
00075 inst->memBase = base_reg;
00076 inst->memBase_contents = pDeclBase;
00077 inst->memOffset = offset;
00078 inst->memOffset_contents = pDeclOffset;
00079 inst->primaryType = typeToLoad;
00080
00081 return inst;
00082 }
00083
00084 LirInst *
00085 LIR::LoadImmediate (typeNode * typeToLoad, Register & dest,
00086 declNode * pDeclDest, constant value)
00087 {
00088 dest.setType(typeToLoad);
00089
00090
00091 LirInst *inst = new LirInst (mn_LoadImmediate);
00092 inst->opnd2 = value;
00093 inst->dest = dest;
00094 inst->dest_contents = pDeclDest;
00095 inst->primaryType = typeToLoad;
00096
00097 return inst;
00098 }
00099
00100 LirInst *
00101 LIR::LoadStatic (typeNode * typeToLoad, Register & dest,
00102 declNode * pDeclDest, string staticLabel,
00103 declNode * declStatic, constant offset,
00104 declNode * pDeclOffset)
00105 {
00106 dest.setType(typeToLoad);
00107
00108
00109 LirInst *inst = new LirInst (mn_LoadStatic);
00110 inst->dest = dest;
00111 inst->dest_contents = pDeclDest;
00112 inst->target = staticLabel;
00113 inst->memOffset = offset;
00114 inst->memOffset_contents = pDeclOffset;
00115 inst->primaryType = declStatic->type();
00116 inst->nodeExtra = declStatic;
00117
00118 return inst;
00119 }
00120
00121 LirInst *
00122 LIR::Store (typeNode * typeToStore, Register source,
00123 declNode * pDeclSrc, Register base_reg,
00124 declNode * pDeclBase, constant offset,
00125 declNode * pDeclOffset)
00126 {
00127
00128 LirInst *inst = new LirInst (mn_Store);
00129 inst->opnd1 = source;
00130 inst->opnd1_contents = pDeclSrc;
00131 inst->memBase = base_reg;
00132 inst->memBase_contents = pDeclBase;
00133 inst->memOffset = offset;
00134 inst->memOffset_contents = pDeclOffset;
00135 inst->primaryType = typeToStore;
00136
00137 return inst;
00138 }
00139
00140 LirInst *
00141 LIR::StoreStatic(typeNode * typeToStore,
00142 Register source_register, declNode * pDeclSrc,
00143 string staticLabel, declNode * staticDecl,
00144 constant offset, declNode * pDeclOffset)
00145 {
00146
00147 LirInst *inst = new LirInst(mn_StoreStatic);
00148 inst->opnd1 = source_register;
00149 inst->opnd1_contents = pDeclSrc;
00150 inst->target = staticLabel;
00151 inst->memOffset = offset;
00152 inst->memOffset_contents = pDeclOffset;
00153 inst->primaryType = typeToStore;
00154
00155 return inst;
00156 }
00157
00158 LirInst *
00159 LIR::GetEffectiveAddress (Register & dest, declNode * pDeclDest,
00160 Register base_reg, declNode * pDeclBase,
00161 constant offset, declNode * pDeclOffset)
00162 {
00163 dest.makeGPR ();
00164
00165
00166 LirInst *inst = new LirInst (mn_GetEffectiveAddr);
00167 inst->dest = dest;
00168 inst->dest_contents = pDeclDest;
00169 inst->memBase = base_reg;
00170 inst->memBase_contents = pDeclBase;
00171 inst->memOffset = offset;
00172 inst->memOffset_contents = pDeclOffset;
00173 inst->primaryType = LirUtil::newVoidPtr();
00174
00175 return inst;
00176 }
00177
00178 LirInst *
00179 LIR::GetGlobalAddress (Register & dest_register, declNode * pDeclDest,
00180 string staticLabel, declNode * staticDecl,
00181 constant offset, declNode * pDeclOffset) {
00182 dest_register.makeGPR();
00183
00184
00185 LirInst *inst = new LirInst(mn_GetGlobalAddr);
00186 inst->dest = dest_register;
00187 inst->dest_contents = pDeclDest;
00188 inst->target = staticLabel;
00189 inst->memOffset = offset;
00190 inst->memOffset_contents = pDeclOffset;
00191 inst->primaryType = LirUtil::newVoidPtr();
00192
00193 return inst;
00194 }
00195
00196 LirInst *
00197 LIR::Move (Register dest, declNode * pDeclDest, Register source,
00198 declNode * pDeclSrc)
00199 {
00200
00201 LirInst *inst = new LirInst (mn_Move);
00202 inst->dest = dest;
00203 inst->dest_contents = pDeclDest;
00204 inst->opnd1 = source;
00205 inst->opnd1_contents = pDeclSrc;
00206
00207 return inst;
00208 }
00209
00210 LirInst *
00211 LIR::Add (typeNode * destType, Register & dest, declNode * pDeclDest,
00212 Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00213 declNode * pDeclOp2)
00214 {
00215 return make_simple (mn_Add, destType, dest, pDeclDest, opnd1, pDeclOp1,
00216 opnd2, pDeclOp2);
00217 }
00218
00219 LirInst *
00220 LIR::Sub (typeNode * destType, Register & dest, declNode * pDeclDest,
00221 Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00222 declNode * pDeclOp2)
00223 {
00224 return make_simple (mn_Sub, destType, dest, pDeclDest, opnd1, pDeclOp1,
00225 opnd2, pDeclOp2);
00226 }
00227
00228 LirInst *
00229 LIR::Mul (typeNode * destType, Register & dest, declNode * pDeclDest,
00230 Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00231 declNode * pDeclOp2)
00232 {
00233 return make_simple (mn_Mul, destType, dest, pDeclDest, opnd1, pDeclOp1,
00234 opnd2, pDeclOp2);
00235 }
00236
00237 LirInst *
00238 LIR::Div (typeNode * destType, Register & dest, declNode * pDeclDest,
00239 Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00240 declNode * pDeclOp2)
00241 {
00242 return make_simple (mn_Div, destType, dest, pDeclDest, opnd1, pDeclOp1,
00243 opnd2, pDeclOp2);
00244 }
00245
00246 LirInst *
00247 LIR::Mod (typeNode * destType, Register & dest, declNode * pDeclDest,
00248 Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00249 declNode * pDeclOp2)
00250 {
00251 assert (! destType->is_float());
00252 return make_simple (mn_Mod, destType, dest, pDeclDest, opnd1, pDeclOp1,
00253 opnd2, pDeclOp2);
00254 }
00255
00256 LirInst *
00257 LIR::Neg (typeNode * destType, Register & dest, declNode * pDeclDest,
00258 Register opnd1, declNode * pDeclOp1)
00259 {
00260
00261 dest.setType(destType);
00262
00263
00264 LirInst *inst = new LirInst (mn_Neg);
00265 inst->opnd1 = opnd1;
00266 inst->opnd1_contents = pDeclOp1;
00267 inst->dest = dest;
00268 inst->dest_contents = pDeclDest;
00269
00270 return inst;
00271 }
00272
00273 LirInst *
00274 LIR::BitwiseOR (typeNode * destType, Register & dest,
00275 declNode * pDeclDest, Register opnd1,
00276 declNode * pDeclOp1, reg_or_const opnd2,
00277 declNode * pDeclOp2)
00278 {
00279 assert (! destType->is_float());
00280 return make_simple (mn_BitwiseOR, destType, dest, pDeclDest, opnd1, pDeclOp1,
00281 opnd2, pDeclOp2);
00282 }
00283
00284 LirInst *
00285 LIR::BitwiseAND (typeNode * destType, Register & dest,
00286 declNode * pDeclDest, Register opnd1,
00287 declNode * pDeclOp1, reg_or_const opnd2,
00288 declNode * pDeclOp2)
00289 {
00290 assert (! destType->is_float());
00291 return make_simple (mn_BitwiseAND, destType, dest, pDeclDest, opnd1,
00292 pDeclOp1, opnd2, pDeclOp2);
00293 }
00294
00295 LirInst *
00296 LIR::BitwiseXOR (typeNode * destType, Register & dest,
00297 declNode * pDeclDest, Register opnd1,
00298 declNode * pDeclOp1, reg_or_const opnd2,
00299 declNode * pDeclOp2)
00300 {
00301 assert (! destType->is_float());
00302 return make_simple (mn_BitwiseXOR, destType, dest, pDeclDest, opnd1,
00303 pDeclOp1, opnd2, pDeclOp2);
00304 }
00305
00306 LirInst *
00307 LIR::BitwiseNOT (typeNode * destType, Register & dest,
00308 declNode * pDeclDest, Register opnd1,
00309 declNode * pDeclOp1)
00310 {
00311 assert (! destType->is_float());
00312
00313
00314 dest.makeGPR ();
00315
00316
00317 LirInst *inst = new LirInst (mn_BitwiseNOT);
00318 inst->opnd1 = opnd1;
00319 inst->opnd1_contents = pDeclOp1;
00320 inst->dest = dest;
00321 inst->dest_contents = pDeclDest;
00322
00323 return inst;
00324 }
00325
00326 LirInst *
00327 LIR::BitwiseShiftLeft (typeNode * destType, Register & dest,
00328 declNode * pDeclDest, Register opnd1,
00329 declNode * pDeclOp1, reg_or_const bitCnt,
00330 declNode * pDeclBitCnt)
00331 {
00332 assert (! destType->is_float());
00333 return make_simple (mn_BitwiseShiftLeft, destType, dest, pDeclDest, opnd1,
00334 pDeclOp1, bitCnt, pDeclBitCnt);
00335 }
00336
00337 LirInst *
00338 LIR::BitwiseShiftRight (typeNode * destType, Register & dest,
00339 declNode * pDeclDest, Register opnd1,
00340 declNode * pDeclOp1, reg_or_const bitCnt,
00341 declNode * pDeclBitCnt)
00342 {
00343 assert (! destType->is_float());
00344 return make_simple (mn_BitwiseShiftRight, destType, dest, pDeclDest, opnd1,
00345 pDeclOp1, bitCnt, pDeclBitCnt);
00346 }
00347
00348 LirInst *
00349 LIR::BitwiseRotateRight (typeNode * destType, Register & dest,
00350 declNode * pDeclDest, Register opnd1,
00351 declNode * pDeclOp1, reg_or_const bitCnt,
00352 declNode * pDeclBitCnt)
00353 {
00354 assert (! destType->is_float());
00355 return make_simple (mn_BitwiseRotateRight, destType, dest, pDeclDest, opnd1,
00356 pDeclOp1, bitCnt, pDeclBitCnt);
00357 }
00358
00359 LirInst *
00360 LIR::BitwiseRotateLeft (typeNode * destType, Register & dest,
00361 declNode * pDeclDest, Register opnd1,
00362 declNode * pDeclOp1, reg_or_const bitCnt,
00363 declNode * pDeclBitCnt)
00364 {
00365 assert (! destType->is_float());
00366 return make_simple (mn_BitwiseRotateLeft, destType, dest, pDeclDest, opnd1,
00367 pDeclOp1, bitCnt, pDeclBitCnt);
00368 }
00369
00370 LirInst *
00371 LIR::Compare (Register opnd1, declNode * pDeclOp1, reg_or_const opnd2,
00372 declNode * pDeclOp2)
00373 {
00374
00375 LirInst *inst = new LirInst (mn_Compare);
00376 inst->opnd1 = opnd1;
00377 inst->opnd1_contents = pDeclOp1;
00378 inst->opnd2 = opnd2;
00379 inst->opnd2_contents = pDeclOp2;
00380
00381 return inst;
00382 }
00383
00384 LirInst *
00385 LIR::Branch (Compare_type cmp_type, string label)
00386 {
00387
00388 LirInst *inst = new LirInst;
00389 inst->target = label;
00390
00391
00392 switch (cmp_type)
00393 {
00394 case cmp_EQ:
00395 inst->instruction = mn_BranchEQ;
00396 break;
00397 case cmp_NE:
00398 inst->instruction = mn_BranchNE;
00399 break;
00400 case cmp_LT:
00401 inst->instruction = mn_BranchLT;
00402 break;
00403 case cmp_LE:
00404 inst->instruction = mn_BranchLE;
00405 break;
00406 case cmp_GT:
00407 inst->instruction = mn_BranchGT;
00408 break;
00409 case cmp_GE:
00410 inst->instruction = mn_BranchGE;
00411 break;
00412 }
00413
00414 return inst;
00415 }
00416
00417 LirInst *
00418 LIR::Jmp (string label)
00419 {
00420
00421 LirInst *inst = new LirInst (mn_Jmp);
00422 inst->target = label;
00423
00424 return inst;
00425 }
00426
00427 LirInst *
00428 LIR::Call (threeAddrNode * the_call, int stack_arg_bytes)
00429 {
00430
00431 LirInst * inst = new LirInst(mn_Call);
00432
00433 idNode * callId = dynamic_cast<idNode *>(the_call->rhs1()->var());
00434
00435 assert(callId);
00436 assert(!the_call->rhs1()->star()
00437 && !the_call->rhs1()->index()
00438 && the_call->rhs1()->fields().empty());
00439
00440 inst->target = callId->name();
00441 inst->nodeExtra = the_call;
00442
00443
00444 typeNode * vt = callId->decl()->type()->type();
00445
00446 const arch_info::register_info * info = NULL;
00447 typeNode * resultType = callId->decl()->type()->type();
00448 if ( resultType->is_int()
00449 || resultType->is_char()
00450 || resultType->is_pointer() ) {
00451 info = CBZ::ArchInfo.get_reg_retval_fixed();
00452 } else if ( resultType->is_float() ) {
00453 info = CBZ::ArchInfo.get_reg_retval_float();
00454 }
00455 if ( !info )
00456 CBZFAIL(("Call to function %s cannot be handled because it requires"
00457 "a return value register type that is not available.",
00458 callId->name().c_str()));
00459
00460
00461 inst->dest = *info;
00462 inst->dest_contents = DATA_CONTENTS_RETVAL;
00463
00464 return inst;
00465 }
00466
00467 LirInst *
00468 LIR::CallPre(void)
00469 {
00470 LirInst * inst = new LirInst(mn_CallPre);
00471
00472 return inst;
00473 }
00474
00475 LirInst *
00476 LIR::Return (procNode * current_proc)
00477 {
00478
00479 LirInst *inst = new LirInst (mn_Return);
00480 inst->nodeExtra = current_proc;
00481
00482 return inst;
00483 }
00484
00485 LirInst *
00486 LIR::Label (string label)
00487 {
00488
00489 LirInst *inst = new LirInst (mn_Label);
00490 inst->target = label;
00491
00492 return inst;
00493 }
00494
00495 LirInst *
00496 LIR::StaticDataString(constant str)
00497 {
00498 return make_data(mn_StaticDataString, str);
00499 }
00500
00501 LirInst *
00502 LIR::StaticDataLong(constant value)
00503 {
00504 return make_data(mn_StaticDataLong, value);
00505 }
00506
00507 LirInst *
00508 LIR::StaticDataInt(constant value)
00509 {
00510 return make_data(mn_StaticDataInt, value);
00511 }
00512
00513 LirInst *
00514 LIR::StaticDataShort(constant value)
00515 {
00516 return make_data(mn_StaticDataShort, value);
00517 }
00518
00519 LirInst *
00520 LIR::StaticDataChar(constant value)
00521 {
00522 return make_data(mn_StaticDataChar, value);
00523 }
00524
00525 LirInst *
00526 LIR::StaticDataSingle(constant value)
00527 {
00528 return make_data(mn_StaticDataSingle, value);
00529 }
00530
00531 LirInst *
00532 LIR::StaticDataDouble(constant value)
00533 {
00534 return make_data(mn_StaticDataDouble, value);
00535 }
00536
00537 LirInst *
00538 LIR::StaticDataZero(int size)
00539 {
00540 LirInst * inst = new LirInst(mn_StaticDataZero);
00541 inst->dataSize = size;
00542
00543 return inst;
00544 }
00545
00546 LirInst *
00547 LIR::StaticDataUninit(string name, int size)
00548 {
00549 LirInst * inst = new LirInst(mn_StaticDataUninit);
00550 inst->target = name;
00551 inst->dataSize = size;
00552
00553 return inst;
00554 }
00555
00556 LirInst *
00557 LIR::DeclareLocal (declNode * the_decl)
00558 {
00559
00560 LirInst *inst = new LirInst (mn_DeclLocal);
00561 ostringstream target;
00562 target << the_decl->name();
00563 declNode::Storage_location & loc = the_decl->storage_location();
00564 if ( loc._type == declNode::Storage_location::storageloc_stack )
00565 target << " @ " << loc._stack_offset;
00566 else
00567 target << " @ " << loc._register.to_string();
00568 inst->target = target.str();
00569 inst->nodeExtra = the_decl;
00570
00571 return inst;
00572 }
00573
00574 LirInst *
00575 LIR::DeclareGlobal (declNode * the_decl)
00576 {
00577 LirInst *inst = new LirInst (mn_DeclGlobal);
00578 inst->dataSize = the_decl->type()->alloc_size();
00579 inst->dataAlign = the_decl->type()->alloc_align();
00580 inst->target = the_decl->name();
00581 inst->nodeExtra = the_decl;
00582
00583 return inst;
00584 }
00585
00586 LirInst *
00587 LIR::BeginProc (procNode * the_proc)
00588 {
00589
00590 LirInst *inst = new LirInst (mn_BeginProc);
00591 inst->target = the_proc->decl ()->name ();
00592 inst->nodeExtra = the_proc;
00593
00594 return inst;
00595 }
00596
00597 LirInst *
00598 LIR::EndProc (procNode * the_proc)
00599 {
00600
00601 LirInst *inst = new LirInst (mn_EndProc);
00602 inst->target = the_proc->decl ()->name ();
00603 inst->nodeExtra = the_proc;
00604
00605 return inst;
00606 }
00607
00608 LirInst *
00609 LIR::BeginUnit (unitNode * the_unit)
00610 {
00611
00612 LirInst *inst = new LirInst (mn_BeginUnit);
00613
00614 return inst;
00615 }
00616
00617 LirInst *
00618 LIR::EndUnit (unitNode * the_unit)
00619 {
00620
00621 LirInst *inst = new LirInst (mn_EndUnit);
00622
00623 return inst;
00624 }
00625
00626 LirInst *
00627 LIR::make_simple (mnemonic instruction, typeNode * destType,
00628 Register & dest, declNode * pDeclDest, Register opnd1,
00629 declNode * pDeclOp1, reg_or_const opnd2,
00630 declNode * pDeclOp2)
00631 {
00632 dest.setType (destType);
00633
00634
00635 LirInst *inst = new LirInst (instruction);
00636 inst->opnd1 = opnd1;
00637 inst->opnd1_contents = pDeclOp1;
00638 inst->opnd2 = opnd2;
00639 inst->opnd2_contents = pDeclOp2;
00640 inst->dest = dest;
00641 inst->dest_contents = pDeclDest;
00642 inst->primaryType = destType;
00643
00644 return inst;
00645 }
00646
00647 LirInst *
00648 LIR::make_data(mnemonic instruction, constant value)
00649 {
00650 LirInst * inst = new LirInst(instruction);
00651 inst->dataValue = value;
00652
00653 return inst;
00654 }