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  

instruction.h

Go to the documentation of this file.
00001 // $Id: instruction.h,v 1.12 2003/08/11 17:38:51 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 // 
00014 //  Permission is hereby granted, free of charge, to any person
00015 //  obtaining a copy of this software and associated documentation
00016 //  files (the "Software"), to deal in the Software without
00017 //  restriction, including without limitation the rights to use, copy,
00018 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00019 //  of the Software, and to permit persons to whom the Software is
00020 //  furnished to do so, subject to the following conditions:
00021 //  
00022 //  The above copyright notice and this permission notice shall be
00023 //  included in all copies or substantial portions of the Software.
00024 //  
00025 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00026 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00027 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00028 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00029 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00030 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00031 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00032 //  THE SOFTWARE.
00033 //
00034 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00035 //  Computer Science for inspiring parts of the C-Breeze design.
00036 //
00037 // ----------------------------------------------------------------------
00038 
00039 #ifndef __INSTRUCTION_H__
00040 #define __INSTRUCTION_H__
00041 
00042 #include <c_breeze.h>
00043 #include "register.h"
00044 
00045 // pseudo-RISC instruction mnemonics
00046 enum mnemonic
00047 {
00048   mn_undefined = 0,
00049 
00050   /* data manipulation instructions */
00051 
00052   mn_ConvertType,               // convert the contents of $opnd1 from $ptype 
00053                                 // to $ctype and place result in $dest
00054   mn_Load,                      // read a value from memory ($base+$offset)
00055                                 // into $dest register
00056   mn_LoadImmediate,             // read immediate value $opnd2 into $dest
00057                                 // register
00058   mn_LoadStatic,                // loads the compile-time static data with
00059                                 // label $target into register $dest
00060   mn_Store,                     // store the value from $opnd1 to memory
00061                                 // ($base+$offset)
00062   mn_StoreStatic,               // store the value from $opnd1 to memory
00063                                 // ($target + $offset)
00064   mn_GetEffectiveAddr,          // compute effective address of
00065                                 // ($base+$offset) and store in $dest
00066   mn_GetGlobalAddr,             // compute effective address of global @
00067                                 // ($target + $offset) and store in $dest
00068   mn_Move,                      // move register $opnd1 into register $dest
00069   // (used for loading things like string constants or floating-point values)
00070 
00071   /* arithmetic instructions */
00072 
00073   mn_Add,                       // store ($opnd1 + $opnd2) in $dest
00074   mn_Sub,                       // store ($opnd1 - $opnd2) in $dest
00075   mn_Mul,                       // store ($opnd1 * $opnd2) in $dest
00076   mn_Div,                       // store ($opnd1 / $opnd2) in $dest
00077   mn_Mod,                       // store ($opnd1 % $opnd2) in $dest
00078   mn_Neg,                       // store (-1 * $opnd1) in $dest
00079 
00080   /* bitwise manipulation instructions */
00081 
00082   mn_BitwiseOR,                 // store ($opnd1 | $opnd2) in $dest
00083   mn_BitwiseAND,                // store ($opnd1 & $opnd2) in $dest
00084   mn_BitwiseXOR,                // store ($opnd1 ^ $opnd2) in $dest
00085   mn_BitwiseNOT,                // store (! $opnd1) in $dest
00086   mn_BitwiseShiftLeft,          // store ($opnd1 << $opnd2) in $dest
00087   mn_BitwiseShiftRight,         // store ($opnd1 >> $opnd2) in $dest
00088   mn_BitwiseRotateRight,        // store ($opnd1 rotated left by $opnd2 bits) 
00089                                 // in $dest
00090   mn_BitwiseRotateLeft,         // store ($opnd1 rotated right by $opnd2
00091                                 // bits) in $dest
00092 
00093   /* flow control instructions */
00094   // 
00095   // NOTE: It is guaranteed that all conditional branch instructions will be 
00096   // immediately preceded by a compare instruction.
00097   // 
00098 
00099   mn_Compare,                   // compare $opnd1, $opnd2, store result in
00100                                 // arch-specific manner
00101   mn_BranchEQ,                  // branch to $target if previous comparison
00102                                 // yielded ==
00103   mn_BranchNE,                  // branch to $target if previous comparison
00104                                 // yielded !=
00105   mn_BranchLT,                  // branch to $target if previous comparison
00106                                 // yielded <
00107   mn_BranchLE,                  // branch to $target if previous comparison
00108                                 // yielded <=
00109   mn_BranchGT,                  // branch to $target if previous comparison
00110                                 // yielded >
00111   mn_BranchGE,                  // branch to $target if previous comparison
00112                                 // yielded >=
00113   mn_Jmp,                       // branch to $target
00114   mn_Label,                     // declare label $target
00115 
00116   /* procedure call stuff */
00117 
00118   mn_Call,                      // call function $target
00119   mn_IndirectCall,              // call function $opnd1
00120                                 // (used for function ptrs)
00121   mn_Return,                    // return from procedure $target with stack
00122                                 // size $stacksize
00123   mn_CallPre,                   // for handling caller-save registers -
00124                                 // instruction inserted before call arguments 
00125                                 // are setup
00126 
00127   /* procedure control instructions */
00128   // NOTE: architecture code template is responsible for setting up and
00129   // tearing down 
00130   // the stack frame, including saving/restoring old stack and frame
00131   // pointers.  stack
00132   // frame is usually setup by BeginProc and torn down by Return.
00133 
00134   mn_BeginProc,                 // start of procedure named $target, with
00135                                 // stack size $stacksize.
00136   mn_EndProc,                   // end of procedure named $target
00137 
00138   /* translation-unit control instructions */
00139 
00140   mn_BeginUnit,                 // beginning of translation unit
00141   mn_EndUnit,                   // end of translation unit
00142 
00143   /* static data stuff */
00144   // 
00145   // for each of these things the template should emit the proper
00146   // macros for encoding the data, such as '.string' for strings and
00147   // '.long' for a 32-bit value.
00148   // 
00149   // the template should not emit a label for the static data - this
00150   // will be handled automatically.
00151   // 
00152 
00153   mn_StaticDataString,          // declaration of static string data $value
00154                                 // (formatted with no quotes)
00155   mn_StaticDataLong,            // declaration of static long $value
00156   mn_StaticDataInt,             // declaration of static int $value
00157   mn_StaticDataShort,           // declaration of static short $value
00158   mn_StaticDataChar,            // declaration of static char $value
00159   mn_StaticDataSingle,          // declaration of static single precision
00160                                 // float $value
00161   mn_StaticDataDouble,          // declaration of static double precision
00162                                 // float $value
00163   mn_StaticDataZero,            // declaration of $size static bytes of zeroes
00164   mn_StaticDataUninit,          // declaration of $size static bytes
00165                                 // uninitialized, at name $target
00166 
00167   /* miscellaneous instructions */
00168 
00169   mn_DeclLocal,                 // declaration of block-local variable
00170                                 // $target (virtual instruction, not emitted)
00171   mn_DeclGlobal,                // declaration of global variable
00172                                 // $target (virtual instruction, not emitted)
00173   mn_NOP,                       // empty operation
00174 
00175   // placeholder - must always be last in enumeration
00176   mn__count
00177 };
00178 
00179 // information about instructions
00180 struct InstructionInfo
00181 {
00182 
00183   InstructionInfo ()
00184   {
00185   }
00186   InstructionInfo (const char *name, const char *opndFormat, bool hasDest,
00187                    bool hasOp1, bool hasOp2, bool hasBase, bool hasOffset,
00188                    bool hasTarget, bool shouldEmit):_name (name),
00189     _opndFormat (opndFormat), _hasDest (hasDest), _hasOpnd1 (hasOp1),
00190     _hasOpnd2 (hasOp2), _hasBase (hasBase), _hasOffset (hasOffset),
00191     _hasTarget (hasTarget), _shouldEmit (shouldEmit)
00192   {
00193   }
00194 
00195   // friendly name
00196   const char *_name;
00197 
00198   // operand format for pretty-printing an instruction
00199   // 
00200   // format fields
00201   // 
00202   // %dest - destination
00203   // %opnd1 - operand1
00204   // %opnd2 - operand2
00205   // %base - load-store base register
00206   // %offset - load-store offset register/constant
00207   // %target - branch target or label name (for Decl instruction, variable
00208   // name)
00209   // %ptype - primary data type (for type conversions, the source type)
00210   // %ctype - data type to convert to (used for type conversions)
00211   // 
00212   const char *_opndFormat;
00213 
00214   // whether or not the instruction has various things
00215   bool _hasDest;
00216   bool _hasOpnd1;
00217   bool _hasOpnd2;
00218   bool _hasBase;
00219   bool _hasOffset;
00220   bool _hasTarget;
00221 
00222   // whether or not the instruction should be emitted
00223   bool _shouldEmit;
00224 };
00225 
00226 // information about all instructions - keyed by instruction mnemonic
00227 extern InstructionInfo instruction_info[mn__count];
00228 
00229 // types of comparisons this ennumeration will be set at binary nodes
00230 // if it is a conditional statement and it will be used when emitting
00231 // conditional and branch instructions
00232 enum Compare_type
00233 {
00234   cmp_unknown,
00235   cmp_GT,                       // cmp_greater cmp_than
00236   cmp_GE,                       // cmp_greater cmp_or cmp_equal
00237   cmp_LE,                       // cmp_less cmp_or cmp_equal
00238   cmp_LT,                       // cmp_less cmp_than
00239   cmp_EQ,                       // cmp_equal cmp_to
00240   cmp_NE                        // cmp_not cmp_equal cmp_to 
00241 };
00242 
00243 
00244 // Class LirInst contains all the useful information about an
00245 // instruction Here we specify the source registers, the destination
00246 // register, immediate values, mnuemonic for the instruction, symbolic
00247 // addresses (var_name), comparison type (for conditionals), and the
00248 // kind of instruction operands (Opnd_type) Most of these values are
00249 // set in LIR.cc If we find that the code generator contains
00250 // insufficient information about instructions or the machine-specific
00251 // instruction set, then we can eliminate ambiguity by adding fields
00252 // in this class.
00253 
00254 class LirInst
00255 {
00256   // for base+offset instructions, if the base register is the stack or frame 
00257   // pointer
00258 #define DATA_CONTENTS_STACKP            ((declNode*)4)
00259 #define DATA_CONTENTS_FRAMEP            ((declNode*)5)
00260 
00261   // for operations involving arch-defined input/output regs
00262 #define DATA_CONTENTS_REG_IN            ((declNode*)6)
00263 #define DATA_CONTENTS_REG_OUT           ((declNode*)7)
00264 
00265   // for function calls, the return value of the function
00266 #define DATA_CONTENTS_RETVAL            ((declNode*)8)
00267 
00268   // flag value
00269 #define DATA_CONTENTS__SPECIAL          ((declNode*)10)
00270 
00271 public:
00272 // instruction components
00273 
00274   // operands (register or constant)
00275   Register opnd1;
00276   declNode *opnd1_contents;
00277   reg_or_const opnd2;
00278   declNode *opnd2_contents;
00279 
00280   // destination register
00281   Register dest;
00282   declNode *dest_contents;
00283 
00284   // base+offset registers for loads/stores
00285   Register memBase;
00286   declNode *memBase_contents;
00287   reg_or_const memOffset;
00288   declNode *memOffset_contents;
00289 
00290   // instruction mnemonic
00291   mnemonic instruction;
00292 
00293   // branch target, procedure name, variable name, or label name
00294   string target;
00295 
00296   // contents for static variables
00297   // for strings, the string is formatted with no quotes
00298   // for binary, this is up to MAX_LIR_DATA_BYTES bytes, most significant
00299   // byte first
00300 /*   string dataString; */
00301   int dataSize;
00302   int dataAlign;
00303   constant dataValue;
00304 
00305   // operand types
00306   typeNode * primaryType;       // primary instruction datatype
00307   typeNode * convertType;       // for conversions, destination datatype
00308 
00309 public:
00310   // other handy stuff
00311 
00312   // the basic block to which we belong
00313   LirBlock * block;
00314 
00315   // for BeginProc, EndProc, and Return, the procNode of the current
00316   // procedure
00317   // for Call, the threeAddrNode of the function call
00318   // for DeclXxx, the declNode of the declaration
00319   // for LoadStatic, the declNode of the static variable
00320   Node *nodeExtra;
00321 
00322   // for Call, indicates the number of bytes of stackspace used by arguments
00323   int _stack_arg_bytes;
00324 
00325   // for jumps/branches, the target instruction (if branch taken)
00326   LirInst *targetInst;
00327 
00328   // for dataflow problems that need to process all instructions, a visited
00329   // flag
00330   bool visited;
00331 
00332   // for dataflow problems on per-instruction level, successors/predecessors
00333   // of each
00334   // instruction
00335   instruction_set succs;
00336   instruction_set preds;
00337 
00338 public:
00339 // primary interface
00340 
00341   // constructor/destructor
00342     LirInst ();
00343     LirInst (mnemonic instruction);
00344 
00345   // for easier printing
00346   friend ostream & operator << (ostream & os, const LirInst & inst);
00347 
00348   // stringize this thing
00349   string to_string () const;
00350 
00351   // find out if this instruction should actually be included in assembly
00352   // generation
00353   bool should_emit () const;
00354 
00355   // find out if this instruction type has various things
00356   //
00357   // declDefines - if true, declaration instructions for register
00358   // variables are considered to define that register.
00359   //
00360   // regOnly - if true, for components that can be a register or a
00361   // constant, return true only if the component is actually a
00362   // register.
00363   bool has_dest (bool declDefines = false) const;
00364   bool has_opnd1 () const;
00365   bool has_opnd2 (bool regOnly = true) const;
00366   bool has_base () const;
00367   bool has_offset (bool regOnly = true) const;
00368   bool has_target () const;
00369 
00370   int stack_arg_bytes(void) { return _stack_arg_bytes; }
00371   void stack_arg_bytes(int bytes) { _stack_arg_bytes = bytes; }
00372 
00373   // get our destination register - this is here so that if we are a
00374   // decl of a variable that is allocated to a register, we can
00375   // pretend to define that register
00376   Register get_dest ();
00377 
00378   // stringize the contents of some part of an instruction
00379   static string contents_str (declNode * pDecl);
00380   static int contents_compiler_temp_index;
00381 
00382 };
00383 
00384 
00385 // represents a basic block at LIR level
00386 class LirBlock
00387 {
00388 public:
00389 // primary interface
00390 
00391   // ctor
00392   LirBlock (int number)
00393   {
00394     // save number
00395     _number = number;
00396 
00397     // init other values
00398     _next = NULL;
00399     _depth = 0;
00400     _visited = false;
00401   }
00402 
00403   // access instruction list instructions
00404   const instruction_list & insts () const;
00405   void add_inst_before (LirInst * newInst, LirInst * otherInst);
00406   void add_inst_after (LirInst * newInst, LirInst * otherInst);
00407   void add_inst (LirInst * inst);
00408   void remove_inst (LirInst * inst);
00409 
00410   // reset visitation flag on this and all successors
00411   void reset_visited ();
00412 
00413   // successors/predecessors
00414   LirBlockSet _preds;
00415   LirBlockSet _succs;
00416 
00417   // next block in linear block order
00418   LirBlock *_next;
00419 
00420   // dominators of this block
00421   LirBlockSet _doms;            // dominators
00422 
00423   // block number
00424   unsigned int _number;
00425 
00426   // loop depth
00427   unsigned int _depth;
00428 
00429   // visitation flag
00430   // NOTE: this is just for the convenience of people that need to traverse 
00431   // the CFG and not worry about getting into an infinite loop.
00432   bool _visited;
00433 
00434 protected:
00435 
00436   // instructions in this block
00437   instruction_list _instructions;
00438 };
00439 
00440 
00441 #endif // __INSTRUCTION_H

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