C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

LIR.cc

Go to the documentation of this file.
00001 // $Id: LIR.cc,v 1.12 2003/08/11 17:38:50 abrown Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2002 University of Texas at Austin
00008 // 
00009 //  Chuck Tsen
00010 //  Charles Nevill
00011 //  Paul Arthur Navratil
00012 //  Calvin Lin
00013 //  Adam C. Brown
00014 // 
00015 //  Permission is hereby granted, free of charge, to any person
00016 //  obtaining a copy of this software and associated documentation
00017 //  files (the "Software"), to deal in the Software without
00018 //  restriction, including without limitation the rights to use, copy,
00019 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00020 //  of the Software, and to permit persons to whom the Software is
00021 //  furnished to do so, subject to the following conditions:
00022 //  
00023 //  The above copyright notice and this permission notice shall be
00024 //  included in all copies or substantial portions of the Software.
00025 //  
00026 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00027 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00028 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00029 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00030 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00031 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00032 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00033 //  THE SOFTWARE.
00034 //
00035 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00036 //  Computer Science for inspiring parts of the C-Breeze design.
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // result depends on operand type
00261   dest.setType(destType);
00262 
00263   // new instruction
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   // result has to be integer
00314   dest.makeGPR ();
00315 
00316   // new instruction
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   // new instruction
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   // new instruction
00388   LirInst *inst = new LirInst;
00389   inst->target = label;
00390 
00391   // pick branch type
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   // new instruction
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   // new instruction
00431   LirInst * inst = new LirInst(mn_Call);
00432   
00433   idNode * callId = dynamic_cast<idNode *>(the_call->rhs1()->var());
00434   // only handles direct calls currently
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   // determine result register
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   // save destination type
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
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   // new instruction
00612   LirInst *inst = new LirInst (mn_BeginUnit);
00613 
00614   return inst;
00615 }
00616 
00617 LirInst *
00618 LIR::EndUnit (unitNode * the_unit)
00619 {
00620   // new instruction
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   // new instruction
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 }

Generated on August 27, 2003
Back to the C-Breeze home page