00001 /* 00002 * Copyright 2002, 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* 00006 00007 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of version 2 of the GNU General Public License as 00011 published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it would be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 Further, this software is distributed without any warranty that it is 00018 free of the rightful claim of any third person regarding infringement 00019 or the like. Any license provided herein, whether implied or 00020 otherwise, applies only to this software file. Patent licenses, if 00021 any, provided herein do not apply to combinations of this program with 00022 other software, or any other product whatsoever. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with this program; if not, write the Free Software Foundation, Inc., 59 00026 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00027 00028 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00029 Mountain View, CA 94043, or: 00030 00031 http://www.sgi.com 00032 00033 For further information regarding this notice, see: 00034 00035 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00036 00037 */ 00038 00039 00040 /* ==================================================================== 00041 * ==================================================================== 00042 * 00043 * Target Specific Miscellany 00044 * 00045 * Here are various miscellaneous functions to provide machine dependent 00046 * information. 00047 * 00048 * Exported functions: 00049 * 00050 * Misc: 00051 * 00052 * void CGTARG_Initialize(void) 00053 * Perform one-time initialization. 00054 * 00055 * Target capabilities and peculiarities: 00056 * 00057 * const INT INST_BYTES 00058 * The number of bytes per instruction word. 00059 * 00060 * const INT DEFAULT_LONG_BRANCH_LIMIT 00061 * The default limit for branch displacements (in bytes) after 00062 * which long-branch fixups occur. 00063 * 00064 * const INT DEFAULT_BRP_BRANCH_LIMIT 00065 * The default limit for branch-predict displacements (in bytes). 00066 * This currently applies only for IA-64, all other targets have 00067 * this set to INT32_MAX. This is the legal displacement limit 00068 * of the branch-predict instructions, beyond which they will be 00069 * converted to NOPs by the cgemit phase. 00070 * 00071 * const INT MIN_BRANCH_DISP 00072 * The displacement (in bytes) for the shortest PC-relative branch. 00073 * 00074 * BOOL CGTARG_Have_Indexed_Mem_Insts(void) 00075 * Returns a boolean that indicates if the target supports 00076 * indexed memory reference instructions. 00077 * 00078 * TOP CGTARG_Inter_RegClass_Copy(ISA_REGISTER_CLASS dst, 00079 * ISA_REGISTER_CLASS src, 00080 * BOOL is_double) 00081 * Returns the copy instruction for moving data from register 00082 * class <src> to <dst> in single or double precision according 00083 * to <is_double>. Returns TOP_UNDEFINED if there is no 00084 * such instruction. 00085 * 00086 * INT CGTARG_Text_Alignment(void) 00087 * Return the best instruction alignment for the processor. 00088 * 00089 * INT32 CGTARG_Branch_Taken_Penalty(void) 00090 * Return the number of extra cycles (often 0) consumed by a 00091 * branch that is taken (even if correctly predicted). 00092 * 00093 * BOOL CGTARG_Use_Brlikely(float branch_taken_probability) 00094 * Given a conditional branch with a <branch_taken_probability> 00095 * return TRUE if it would be beneficial to convert it to a brlikely. 00096 * This handles targets that have a penalty for brlikely 00097 * instructions that are not taken (e.g. T5). 00098 * 00099 * BOOL CGTARG_Can_Change_To_Brlikely(OP *xfer_op, TOP *new_opcode) 00100 * Checks to see if <xfer_op> can be converted to its branch-likely 00101 * form and returns the new_opcode if result TRUE. 00102 * 00103 * BOOL CGTARG_Can_Predicate_Calls() 00104 * Returns true if the target supports a predicated call instruction. 00105 * 00106 * BOOL CGTARG_Can_Predicate_Returns() 00107 * Returns true if the target supports a predicated call instruction. 00108 * 00109 * BOOL CGTARG_Can_Predicate_Branches() 00110 * Returns true if the target supports predicated branch instructions. 00111 * 00112 * BOOL CGTARG_Unconditional_Compare(OP* op, TOP* uncond_ver) 00113 * Returns true if a compare sets predicates unconditionally. It 00114 * returns the unconditional version of the compare if one exists. 00115 * 00116 * TOP CGTARG_Noop_Top(void) 00117 * TOP (opcode) to use for noops on current target. 00118 * 00119 * TOP CGTARG_Simulated_Top(TOP, ISA_EXEC_UNIT_PROPERTY) 00120 * Returns the right opcode for simulated TOP which matches 00121 * ISA_EXEC_UNIT_PROPERTY. 00122 * 00123 * TOP CGTARG_Noop(ISA_EXEC_UNIT_PROPERTY) 00124 * TOP (opcode) to use for noops on current target, with given unit. 00125 * 00126 * BOOL CGTARG_Can_daddu_Be_Folded(OP *op1, OP *op2) 00127 * Returns TRUE if <op1> and <op2> is a daddu/addiu sequence 00128 * that can be folded, i.e. <op1> is a addiu op which is feeding 00129 * into daddu op <op2>. 00130 * 00131 * TOP CGTARG_Copy_Op(UINT8 size, BOOL is_float) 00132 * TOP (opcode) to use for copying a register <size> bytes in 00133 * length (FP if <is_float>). 00134 * 00135 * TOP CGTARG_Parallel_Compare(TOP cmp_top, COMPARE_TYPE ctype) 00136 * Return a parallel version of cmp_top if any such exists. 00137 * 00138 * BOOL CGTARG_Dependence_Required(OP *pred_op, OP *succ_op) 00139 * Check for any target-specific dependences (other than the usual 00140 * repertoire) that may be required between <pred_op> and <succ_op>. 00141 * 00142 * void CGTARG_Adjust_Latency(OP *pred_op, OP *succ_op, 00143 * CG_DEP_KIND kind, UINT8 opnd, INT *latency) 00144 * Makes any target-specific latency adjustments that may be 00145 * required between <pred_op> and <succ_op>. 00146 * 00147 * void CGTARG_Peak_Rate( PEAK_RATE_CLASS prc, INT ratio[2] ) 00148 * What is the peak rate (in ops per cycle) for the given 00149 * class of instruction(s). A rate of 0 means the class of 00150 * instruction isn't supported on the target processor. 00151 * The rate is expressed as a fraction: insts/cycle and stored 00152 * in the <ratio> array (ratio[0]==insts, ratio[1]==cycles). 00153 * 00154 * void CGTARG_Compute_PRC_INFO (BB *bb, PRC_INFO *info) 00155 * For the given basic block <bb> compute some basic information 00156 * about the distribution of the different instruction types. 00157 * Return this information in <info>. 00158 * 00159 * void CGTARG_Print_PRC_INFO (FILE *file, PRC_INFO *info, INT ii, 00160 * const char *prefix, const char *suffix) 00161 * Print the PRC_INFO <info> to <file>. The iteration interval to 00162 * be used for printing the statistics is <ii>. Use the string 00163 * <prefix> before printing each line of output. Use the string 00164 * <suffix> after printing each line of output. 00165 * 00166 * INT CGTARG_ARC_Sched_Latency( ARC *arc ) 00167 * Wrapper function for ARC_latency to let us fix up some cases 00168 * where it returns a result that just doesn't make sence. In 00169 * particular a latency of -1 for the pre-branch latency makes no 00170 * scheduling sense for CPUs which have same-cycle branch shadows. 00171 * Should be 0. 00172 * 00173 * void CGTARG_Handle_Errata_Hazard (OP *op, INT erratnum, 00174 * INT ops_to_check) 00175 * Handle all the Errata hazards. These are typically workarounds 00176 * for bugs in particular versions of various target processors. 00177 * 00178 * void CGTARG_Handle_Bundle_Hazard(OP *op, TI_BUNDLE *bundle, 00179 * VECTOR *bundle_vector, 00180 * BOOL can_fill, INT slot_pos, 00181 * INT max_pos, 00182 * ISA_EXEC_UNIT_PROPERTY prop) 00183 * Handle all bundle hazards in this routine. It inserts any extra 00184 * nops required to form a legal bundle. (1) <op> is the current 00185 * OP being processed. (2) <bundle> is the current bundle. (3) 00186 * <bundle_vector> is an internal vect to determine relations with 00187 * any prior filled OPs in the <bundle>. (4) <can_fill> tells that 00188 * a <slot_pos> has already been chosen for the <op> in <bundle>. 00189 * (5) <max_pos> identifies OPs which occupy more than one slot position. 00190 * (6) <prop> is the ISA_EXEC_UNIT_PROPERTY type that is being used. 00191 * 00192 * BOOL CGTARG_Bundle_Slot_Available(TI_BUNDLE *bundle, OP *op, INT slot, 00193 * ISA_EXEC_UNIT_PROPERTY *prop, 00194 * BOOL stop_bit_reqd, 00195 * const CG_GROUPING *grouping) 00196 * Checks to see if <slot> position is available for <op> using the 00197 * property type <prop> in the <bundle>. The <stop_bit_reqd> flag 00198 * checks if stop bit is also required due to dependencies. The 00199 * grouping parameter, if not NULL, is used to choose between property 00200 * types where there is a choice. 00201 * 00202 * BOOL CGTARG_Bundle_Stop_Bit_Available(TI_BUNDLE *bundle, INT slot); 00203 * Checks to see if <stop> bit is available at <slot> position in the 00204 * bundle. 00205 * 00206 * BOOL CGTARG_Preg_Register_And_Class(WN_OFFSET preg, 00207 * ISA_REGISTER_CLASS *rclass, 00208 * REGISTER *reg) 00209 * Return the register and class (by reference through 'rclass' 00210 * and 'reg') corresponding to 'preg'. The return value indicates 00211 * if there was a preg -> register/class mapping. 00212 * 00213 * 00214 * void CGTARG_Compute_Branch_Parameters(INT32 *mispredict, 00215 * INT32 *fixed, 00216 * INT32 *brtaken, 00217 * double factor) 00218 * Various machine dependent values use for non loop if conversion. 00219 * mispredict: 00220 * Branch misprediction penalty. Given the condition ready, how 00221 * many cycles are wasted in resolving the new branch and 00222 * starting the pipline? 00223 * fixed: 00224 * Number of cycles in executing the branch and it's trailer. 00225 * brtaken: 00226 * For some machines, the taken pc requires ALU resources. 00227 * factor 00228 * The misprediction rate may not correlate to the branch 00229 * probability. 00230 * A factor (0..1.0) will scale the misprediction penalty. 00231 * 00232 * INT32 CGTARG_Special_Min_II(BB* loop_body, BOOL trace) 00233 * Check for target specific (tail stepping, and other?) special 00234 * cases that might force a higher Min II. If a case applies, the 00235 * target specific MII is returned, otherwise 0 is returned. 00236 * 00237 * OP/TOP specific: 00238 * 00239 * BOOL CGTARG_Is_OP_Barrier(OP* op) 00240 * Returns TRUE if <op> is a barrier node. 00241 * 00242 * BOOL CGTARG_Is_OP_Intrinsic(OP *op) 00243 * Returns TRUE if <op> is an intrinsic node. 00244 * 00245 * BOOL CGTARG_Is_OP_Speculative(OP *op) 00246 * Returns TRUE if <op> is a safe speculative OP. 00247 * 00248 * BOOL CGTARG_Is_OP_Addr_Incr(OP* op) 00249 * Returns TRUE if <op> is an address increment op 00250 * (eg. {addiu, daddiu} rd, rd, offset) with the destination and 00251 * source1 being the same registers. 00252 * 00253 * void CGTARG_Perform_THR_Code_Generation(OP *op, THR_TYPE type) 00254 * Perform THR (and target-specific) code generation tasks per 00255 * THR_TYPE and OP. Depending on <type>, <op> can now be 00256 * substituted (or replaced with) new ops. 00257 * 00258 * INT CGTARG_Copy_Operand(OP *op) 00259 * If 'op' performs a copy operation, return the index of 00260 * the source operand; otherwise return -1. 00261 * 00262 * TN *CGTARG_Copy_Operand_TN(OP *op) 00263 * If 'op' performs a copy operation, return the TN of 00264 * the source operand; otherwise return NULL. 00265 * 00266 * BOOL CGTARG_Is_Copy(OP *op) 00267 * Return a boolean indicating if 'op' performs a copy operation. 00268 * 00269 * BOOL CGTARG_Is_Preference_Copy(OP *op) 00270 * Return a boolean indicating if 'op' performs a copy operation 00271 * that is a candidate for preferencing. Does extra consistency 00272 * checks. This is the preferred method for testing for a copy 00273 * before invoking CGTARG_Copy_Operand() and friends. 00274 * 00275 * BOOL CGTARG_Is_OP_daddu(OP *op) 00276 * Return a boolean indicating if 'op' is a mips daddu inst. 00277 * 00278 * void CGTARG_Load_From_Memory(TN *tn, ST *mem_loc, OPS *ops) 00279 * void CGTARG_Store_To_Memory(TN *tn, ST *mem_loc, OPS *ops) 00280 * Load/store any TN from/to memory, even if it takes a sequence 00281 * of instructions to do so. Note that the expander can only 00282 * store TNs in register classes that have load and store 00283 * instructions. 00284 * 00285 * TOP CGTARG_Immed_To_Reg(TOP opr) 00286 * <opr> is an immediate format instruction, return its equivalent 00287 * register form if there is one, return TOP_UNDEFINED if 00288 * there isn't. 00289 * 00290 * void CGTARG_Predicate_OP(BB* bb, OP* op, TN* pred_tn) 00291 * Replace <op> with its predicated form, inserting new ops as needed. 00292 * 00293 * BOOL CGTARG_Branches_On_True(OP* br_op, OP* cmp_op) 00294 * Returns TRUE if branch executed on TRUE test of cmp_op. Note 00295 * that it doesn't really verify that br_op is conditional, so it 00296 * may return odd results if given an unconditional branch. 00297 * 00298 * BOOL CGTARG_Is_Long_Latency(TOP op) 00299 * Return a boolean indicating if <op> is a long latency operation. 00300 * 00301 * BOOL CGTARG_Is_Bad_Shift_Op (OP *op) 00302 * Return TRUE if <op> is a shift instruction that has the 00303 * ERRATA01 or the ERRATA02 hazard. 00304 * 00305 * TOP CGTARG_Invert(TOP opr) 00306 * Return the inverse of <opr>. TOP_UNDEFINED is returned 00307 * if there is no inverse. Note that the inverse of an 00308 * instruction that takes an immediate does not also necessarily 00309 * take an immediate. 00310 * 00311 * void CGTARG_Branch_Info ( const OP* op, INT* tfirst, INT* tcount ) 00312 * Given a branch OP, which operand is the first branch target and how 00313 * many branch targets are there? Returns index of first branch target 00314 * by reference in <tfirst> and count of branch targets in <tcount>. 00315 * 00316 * UINT32 CGTARG_Mem_Ref_Bytes(const OP *memop) 00317 * Requires: OP_load(memop) || OP_store(memop) 00318 * Return the number of bytes in memory referenced by <memop>. 00319 * 00320 * BOOL CGTARG_Can_Be_Speculative( OP* op ) 00321 * Determine whether the given OP may be scheduled eagerly. This 00322 * involves a target-specific mapping of its exception classification 00323 * to an exception level, and determination of whether that level of 00324 * speculation is enabled. 00325 * 00326 * There is a major can of worms lurking under this seemingly innocent 00327 * function. Different targets have vastly different styles of 00328 * speculation. For example, TFP was designed with the expectation 00329 * that software would be responsible for speculation and thus fully 00330 * supports dismissing floating point exceptions in hardware. By 00331 * contrast, T5 does not support this. Triton, which does nothing in 00332 * hardware to speculate also cannot dismiss may floating point traps. 00333 * 00334 * BOOL CGTARG_Is_OP_Speculative_Load( OP* memop ) 00335 * BOOL CGTARG_Is_OP_Advanced_Load( OP* memop ) 00336 * BOOL CGTARG_Is_OP_Check_Load( OP* memop ) 00337 * These routines check to see if <memop> is a speculative, 00338 * advanced or check load. Assumes that <memop> is a load operation. 00339 * 00340 * INT CGTARG_Analyze_Compare(OP *br, 00341 * TN **tn1, 00342 * TN **tn2, 00343 * OP **compare_op) 00344 * Analyze a branch to determine the condition of the branch and 00345 * TNs being compared. Where possible and appropriate if the branch 00346 * is based on the result of an slt instruction, take that in to 00347 * consideration in determining the condition and arguments. 00348 * 00349 * The variant of the branch (see variant.h) is returned through 00350 * the function return value. 00351 * 00352 * <br> is a pointer to a branch instruction to be analyzed. The 00353 * arguments of the comparison are returned through the out parameters 00354 * <tn1> and <tn2>. The comparison OP is returned through out 00355 * parameter <compare_op>. 00356 * 00357 * NOTES: Currently restricted to integer branches; also see 00358 * CGTARG_Analyze_Branch 00359 * 00360 * VARIANT CGTARG_Analyze_Branch(OP *br, TN **tn1, TN **tn2) 00361 * Analyze a branch to determine the condition of the branch and 00362 * the operand TNs. 00363 * 00364 * The variant of the branch (see variant.h) is returned through 00365 * the function return value. 00366 * 00367 * <br> is a pointer to a branch instruction to be analyzed. The 00368 * arguments of the branch are returned through the out parameters 00369 * <tn1> and <tn2>. 00370 * 00371 * NOTES: also see CGTARG_Analyze_Compare 00372 * 00373 * Horrible implicit register definitions and uses: 00374 * 00375 * BOOL CGTARG_OP_Defs_TN( OP* op, TN* tn ) 00376 * BOOL CGTARG_OP_Refs_TN( OP* op, TN* tn ) 00377 * There are (only very few) cases where a TN is implictly defined or 00378 * referenced by certain OPs. These functions allow us to find these 00379 * cases. (Currently used only for the floating status register.) 00380 * 00381 * Associated base operations: 00382 * 00383 * void CGTARG_Init_Assoc_Base(void) 00384 * A number of tables are maintained for performing base 00385 * association related inqueries. The accessors to the 00386 * tables are declared below. See cg_loop_recur:Find_Assoc_Base_Opr 00387 * and cgprep:assoc_base_opr for additional details. 00388 * 00389 * OPCODE CGTARG_Assoc_Base_Opr(TOP topcode) 00390 * Return the correpsonding associated base whirl opcode for <topcode>. 00391 * 00392 * TOP CGTARG_Assoc_Base_Top(TOP topcode) 00393 * Return the correpsonding associated base topcode for <topcode>. 00394 * 00395 * CGTARG_ASSOC_BASE_FNC CGTARG_Assoc_Base_Fnc(TOP topcode) 00396 * When the associated base operation is not a simple mapping 00397 * based soley on <topcode>, this function returns an 00398 * enumeration of the function that needs to be performed to 00399 * determine the corresponding base operation, if any. 00400 * The following are the possible enumerations: 00401 * 00402 * ASSOC_BASE_null 00403 * This is a simple mapping, no additional function need be performed. 00404 * 00405 * ASSOC_BASE_inverse 00406 * Indicates this is an inverse operation. 00407 * 00408 * ASSOC_BASE_minmax 00409 * <topcode> is a min/max operation comprised of multiple operations. 00410 * The additional operations need to be checked. 00411 * 00412 * ASSOC_BASE_imul 00413 * <topcode> is an integer multiply. It is necessary to determine 00414 * if the multiply is within a recurrence. 00415 * 00416 * Target specific live range interference: 00417 * 00418 * For TFP we implement two register allocation restrictions. Violation of 00419 * these rules results in stalls. Essentially this is because the hardware 00420 * does not have register renaming and a specific register can contain at 00421 * most one particular value in any given cycle. 00422 * 00423 * 1. No two operations can target the same register with the 00424 * same register write cycle, and 00425 * 00426 * 2. No operand may be read in the register write cycle of 00427 * another value. This particularly disallows flds to overwrite the 00428 * operand of a previous flop in the same cycle. 00429 * 00430 * A third restriction exists but is not implemented: 00431 * 00432 * 3. V0 may not redifine the register of v1 while v1 is in 00433 * flight. A live range is in flight from its definition point 00434 * through the cycle before it is available for bypassing. This 00435 * final rule is not currently implemented. TODO: implement it if 00436 * it becomes a problem. 00437 * 00438 * Theese restrictions are convied through the following functions. They 00439 * are intended to be called for the operation in a set of contigious 00440 * blocks before register allocation is performend but after secheduling. 00441 * The client supplies live ranges and information about which OP define 00442 * and use them when in the schedules. A client supplied function is 00443 * called when two live ranges may not have the same register (interfere). 00444 * 00445 * It is important to call these functions in a particular order: 00446 * 00447 * 1. CGTARG_Interface_Initialize 00448 * 2. All calls to CGTARG_Result_Live_Range 00449 * 3. All calls to CGTARG_Operand_Live_Range 00450 * 4. CGTARG_Interface_Finalize 00451 * 00452 * Exported Function for target specific live range interference: 00453 * 00454 * BOOL CGTARG_Interference_Required(void) 00455 * Does the current target require target specific live range 00456 * interference at all? 00457 * 00458 * void CGTARG_Interference_Initialize( INT32 cycle_count, 00459 * BOOL is_loop, 00460 * void (*inter_fn)(void*,void*) ) 00461 * Prepare to make the target specific interferences. <cycle_count> is 00462 * the number of total cycles in the contigious set of blocks under 00463 * consideration. <is_loop> is true if the blocks constitute a loop 00464 * body (and thus we need to worry about OPs in the final few cycles 00465 * writing in the first few cycles of the loop.) <inter_fn> ia a 00466 * function pointer to be called when for pairs of live ranges that 00467 * must not be allocated to the same register. It is assumed that 00468 * interference is a reflexive relation and thus that it is not 00469 * necessary to call the function for both x,y and y,x. (So the client 00470 * must make sure that both interference graph edges are drawn.) 00471 * 00472 * void CGTARG_Result_Live_Range( void* lrange, OP* op, INT32 offset ) 00473 * Present the <lrange> written by <op>. <offset> gives a cycle count 00474 * to be added to OP_scycle as the start time of <op> relative to the 00475 * first cycle of the blocks under consideration. 00476 * 00477 * void CGTARG_Operand_Live_Range( void * lrange, INT opnd, OP* op, 00478 * INT32 offset ) 00479 * Present the <lrange> used by <op> and it's <opnd> operand. <offset> 00480 * gives a cycle count to be added to OP_scycle as the start time of 00481 * <op> relative tot he first cycle of the blocks under consideration. 00482 * 00483 * void CGTARG_Interference_Finalize(void) 00484 * All done presenting this set of OPs. 00485 * 00486 * TOP CGTARG_Which_OP_Select (UINT16 bit_size, BOOL is_float, 00487 * BOOL is_fcc) 00488 * Determine which opcode to use to copy TNs based upon whether or 00489 * not the value being copied is floating point, its size in bits, 00490 * and whether the condition to be used is a floating CC or integer 00491 * register. 00492 * 00493 * TOP CGTARG_Equiv_Nonindex_Memory_Op(OP *op) 00494 * Return the nonindexed OP code corresponding to a indexed memory 00495 * OP or TOP_UNDEFINED if code is not an indexed memory OP. 00496 * 00497 * void CGTARG_Generate_Remainder_Branch(TN *trip_count, TN *label_tn 00498 * OPS *prolog_ops, OPS *body_ops) 00499 * Generate the branch instruction and its initialization into the 00500 * body_ops and prolog_ops respectively for the unrolling remainder loop. 00501 * 00502 * void CGTARG_Generate_Branch_Cloop(OP *op, TN *unrolled_trip_count, TN *trip_count, INT32 ntimes, 00503 * TN *label_tn, OPS *prolog_ops. OPS *body_ops); 00504 * If the target architecture supports a counted loop instruction, 00505 * generate the initialization and the cloop instruction and append 00506 * them to the prolog_ops and body_ops respectively. 00507 * 00508 * BOOL CGTARG_OP_is_counted_loop(OP *op) 00509 * Returns TRUE if op is the counted loop branch. 00510 * 00511 * TOP CGTARG_Invert_Branch(BB* bb) 00512 * Invert sense of the branch terminating bb. Returns new branch 00513 * op if successful. 00514 * 00515 * void CGTARG_Init_OP_cond_def_kind(OP *op) 00516 * Initialize target dependent OP_cond_def_kind. 00517 * 00518 * void CGTARG_Use_Load_Latency(OP *, TN *) 00519 * The TN is the load-result of the OP, so use of TN has the 00520 * latency of a load 00521 * 00522 * ==================================================================== 00523 * ==================================================================== 00524 */ 00525 00526 /* 00527 * $Revision: 1.15 $ 00528 * $Date: 05/12/05 08:59:06-08:00 $ 00529 * $Author: bos@eng-24.pathscale.com $ 00530 * $Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/SCCS/s.cgtarget.h $ 00531 */ 00532 00533 #ifndef CGTARGET_INCLUDED 00534 #define CGTARGET_INCLUDED 00535 00536 #include "defs.h" 00537 #include "cgir.h" 00538 #include "variants.h" 00539 #include "cg_flags.h" 00540 #include "cg_dep_graph.h" 00541 #include "cg_vector.h" 00542 #include "config_targ.h" 00543 #include "targ_isa_bundle.h" 00544 #include "ti_bundle.h" 00545 #include "cg_thr.h" 00546 00547 #ifdef TARG_IA64 00548 #include "targ_bypass_mck.h" 00549 #endif 00550 00551 extern UINT32 CGTARG_branch_taken_penalty; 00552 extern BOOL CGTARG_branch_taken_penalty_overridden; 00553 00554 #include "cgtarget_arch.h" 00555 00556 class CG_GROUPING; // Defined only for isa where it is used (e.g. IA-64). 00557 00558 00559 inline TOP 00560 CGTARG_Invert(TOP opr) 00561 { 00562 extern TOP CGTARG_Invert_Table[TOP_count+1]; 00563 00564 return CGTARG_Invert_Table[(INT)opr]; 00565 } 00566 00567 inline TOP 00568 CGTARG_Immed_To_Reg(TOP opr) 00569 { 00570 extern TOP CGTARG_Immed_To_Reg_Table[TOP_count+1]; 00571 00572 return CGTARG_Immed_To_Reg_Table[(INT)opr]; 00573 } 00574 00575 extern void CGTARG_Perform_THR_Code_Generation(OP *load_op, OP *check_load, 00576 THR_TYPE type); 00577 extern INT CGTARG_ARC_Sched_Latency( ARC *arc ); 00578 extern void CGTARG_Handle_Errata_Hazard (OP *op, INT erratnum, 00579 INT ops_to_check); 00580 extern void CGTARG_Handle_Bundle_Hazard(OP *op, 00581 TI_BUNDLE *bundle, 00582 VECTOR *bundle_vector, 00583 BOOL can_fill, 00584 INT slot_pos, 00585 INT max_pos, 00586 BOOL stop_bit_reqd, 00587 ISA_EXEC_UNIT_PROPERTY prop); 00588 00589 extern BOOL CGTARG_Bundle_Slot_Available(TI_BUNDLE *bundle, 00590 OP *op, 00591 INT slot, 00592 ISA_EXEC_UNIT_PROPERTY *prop, 00593 BOOL stop_bit_reqd, 00594 const CG_GROUPING *grouping); 00595 00596 extern BOOL CGTARG_Bundle_Stop_Bit_Available(TI_BUNDLE *bundle, INT slot); 00597 00598 extern void CGTARG_Branch_Info ( const OP* op, INT* tfirst, INT* tcount ); 00599 extern BOOL CGTARG_Can_Be_Speculative( OP* op ); 00600 extern BOOL CGTARG_Is_OP_Speculative(OP *op); 00601 extern BOOL CGTARG_Is_OP_Speculative_Load( OP* memop ); 00602 extern BOOL CGTARG_Is_OP_Advanced_Load( OP* memop ); 00603 #ifdef TARG_IA64 00604 extern BOOL CGTARG_Is_Form_For_Advanced_Load (ISA_ENUM_CLASS_VALUE ldform); 00605 #endif 00606 extern BOOL CGTARG_Is_OP_Check_Load( OP* memop ); 00607 00608 extern BOOL CGTARG_OP_Defs_TN( OP* op, TN* tn ); 00609 extern BOOL CGTARG_OP_Refs_TN( OP* op, TN* tn ); 00610 extern BOOL CGTARG_Interference_Required(void); 00611 extern TOP CGTARG_Which_OP_Select (UINT16 bit_size, BOOL is_float, 00612 BOOL is_fcc); 00613 extern TOP CGTARG_Equiv_Nonindex_Memory_Op ( OP *op ); 00614 extern void CGTARG_Interference_Initialize( INT32 cycle_count, 00615 BOOL is_loop, 00616 void (*inter_fn)(void*,void*) ); 00617 extern void CGTARG_Result_Live_Range( void* lrange, OP* op, INT32 offset ); 00618 extern void CGTARG_Operand_Live_Range( void * lrange, INT opnd, OP* op, 00619 INT32 offset ); 00620 extern void CGTARG_Interference_Finalize(void); 00621 extern TOP CGTARG_Invert_Branch(BB* bb); 00622 00623 typedef enum { 00624 PRC_INST, 00625 PRC_MEMREF, 00626 PRC_FLOP, 00627 PRC_FLOP_S, 00628 PRC_MADD, 00629 PRC_MADD_S, 00630 PRC_FADD, 00631 PRC_FADD_S, 00632 PRC_FMUL, 00633 PRC_FMUL_S, 00634 PRC_IOP, 00635 PRC_LAST 00636 } PEAK_RATE_CLASS; 00637 00638 typedef struct { 00639 #ifdef KEY 00640 mUINT16 refs[PRC_LAST]; 00641 #else 00642 mINT16 refs[PRC_LAST]; 00643 #endif 00644 } PRC_INFO; 00645 00646 extern void CGTARG_Peak_Rate( PEAK_RATE_CLASS prc, PRC_INFO *info, INT ratio[2] ); 00647 extern void CGTARG_Print_PRC_INFO (FILE *file, PRC_INFO *info, INT ii, 00648 const char *prefix, const char *suffix); 00649 extern void CGTARG_Compute_PRC_INFO (BB *bb, PRC_INFO *info); 00650 extern UINT32 CGTARG_Mem_Ref_Bytes(const OP *memop); 00651 extern BOOL CGTARG_Preg_Register_And_Class(WN_OFFSET preg, 00652 ISA_REGISTER_CLASS *rclass, 00653 REGISTER *reg); 00654 00655 extern void CGTARG_Compute_Branch_Parameters(INT32 *mispredict, 00656 INT32 *fixed, 00657 INT32 *brtaken, 00658 double *factor); 00659 00660 extern BOOL CGTARG_Can_Change_To_Brlikely(OP *xfer_op, TOP *new_opcode); 00661 extern TOP CGTARG_Negate_Branch(TOP op); 00662 extern BOOL CGTARG_Is_Long_Latency(TOP op); 00663 extern INT32 CGTARG_Latency(TOP op); 00664 00665 extern VARIANT CGTARG_Analyze_Branch(OP *br, TN **tn1, TN **tn2); 00666 extern VARIANT CGTARG_Analyze_Compare(OP *br, TN **tn1, TN **tn2, 00667 OP **compare_op); 00668 00669 extern INT32 CGTARG_Special_Min_II(BB* loop_body, BOOL trace); 00670 00671 /* placeholder for all hardware workarounds */ 00672 extern void Hardware_Workarounds (void); 00673 extern void Insert_Stop_Bits(BB *bb); 00674 00675 extern void CGTARG_Initialize(void); 00676 00677 extern void CGTARG_Load_From_Memory(TN *tn, ST *mem_loc, OPS *ops); 00678 extern void CGTARG_Store_To_Memory(TN *tn, ST *mem_loc, OPS *ops); 00679 00680 typedef enum { 00681 ASSOC_BASE_null, 00682 ASSOC_BASE_inverse, 00683 ASSOC_BASE_minmax, 00684 ASSOC_BASE_imul, 00685 ASSOC_BASE_COUNT 00686 } CGTARG_ASSOC_BASE_FNC; 00687 00688 extern void CGTARG_Init_Assoc_Base(void); 00689 00690 inline OPCODE CGTARG_Assoc_Base_Opr(TOP topcode) 00691 { 00692 extern OPCODE CGTARG_Assoc_Base_Opr_Table[TOP_count]; 00693 00694 return CGTARG_Assoc_Base_Opr_Table[(INT)topcode]; 00695 } 00696 00697 inline TOP CGTARG_Assoc_Base_Top(TOP topcode) 00698 { 00699 extern mTOP CGTARG_Assoc_Base_Top_Table[TOP_count]; 00700 00701 return (TOP)CGTARG_Assoc_Base_Top_Table[(INT)topcode]; 00702 } 00703 00704 inline CGTARG_ASSOC_BASE_FNC CGTARG_Assoc_Base_Fnc(TOP topcode) 00705 { 00706 extern mTOP CGTARG_Assoc_Base_Fnc_Table[TOP_count]; 00707 00708 return (CGTARG_ASSOC_BASE_FNC)CGTARG_Assoc_Base_Fnc_Table[(INT)topcode]; 00709 } 00710 00711 extern INT CGTARG_Copy_Operand(OP *op); 00712 00713 inline BOOL CGTARG_Is_Copy(OP *op) 00714 { 00715 return CGTARG_Copy_Operand(op) >= 0; 00716 } 00717 00718 inline BOOL CGTARG_Is_Preference_Copy(OP* op) 00719 { 00720 if (OP_copy(op)) { 00721 if (CGTARG_Is_Copy(op)) { 00722 return TRUE; 00723 } else { 00724 // 00725 // Ops that are to be deleted sometimes have their opcode temporarily 00726 // set to nop prior to deletion (principally in lra). 00727 // 00728 Is_True(OP_code(op) == CGTARG_Noop_Top(), 00729 ("Op_copy set on non-copy op")); 00730 return FALSE; 00731 } 00732 } 00733 return FALSE; 00734 } 00735 00736 inline TN *CGTARG_Copy_Operand_TN(OP *op) 00737 { 00738 INT iopnd = CGTARG_Copy_Operand(op); 00739 return (iopnd < 0) ? NULL : OP_opnd(op,iopnd); 00740 } 00741 00742 inline TOP CGTARG_Inter_RegClass_Copy(ISA_REGISTER_CLASS dst, 00743 ISA_REGISTER_CLASS src, 00744 BOOL is_double) 00745 { 00746 extern mTOP CGTARG_Inter_RegClass_Copy_Table 00747 [ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_CLASS_MAX+1][2]; 00748 00749 return (TOP)CGTARG_Inter_RegClass_Copy_Table[src][dst][is_double]; 00750 } 00751 00752 00753 extern BOOL CGTARG_Can_Fit_Immediate_In_Add_Instruction (INT64 immed); 00754 extern BOOL CGTARG_Can_Load_Immediate_In_Single_Instruction (INT64 immed); 00755 #ifdef TARG_MIPS 00756 extern BOOL CGTARG_Can_Fit_Displacement_In_Branch_Instruction (INT64 disp); 00757 #endif 00758 00759 extern void CGTARG_Save_Pfs (TN *saved_pfs, OPS *ops); 00760 extern void CGTARG_Restore_Pfs (TN *saved_pfs, OPS *ops); 00761 00762 /* target-specific adjustments to entry ops */ 00763 extern void CGTARG_Fixup_Entry_Code (BB *bb); 00764 00765 typedef enum { 00766 COMPARE_TYPE_unc, 00767 COMPARE_TYPE_or, 00768 COMPARE_TYPE_orcm, 00769 COMPARE_TYPE_and, 00770 COMPARE_TYPE_andcm, 00771 COMPARE_TYPE_or_andcm, 00772 COMPARE_TYPE_and_orcm, 00773 COMPARE_TYPE_normal 00774 } COMPARE_TYPE; 00775 00776 extern TOP CGTARG_Parallel_Compare(OP* cmp_op, COMPARE_TYPE ctype); 00777 00778 extern BOOL CGTARG_Dependence_Required(OP *pred_op, OP *succ_op); 00779 00780 extern void CGTARG_Adjust_Latency(OP *pred_op, OP *succ_op, CG_DEP_KIND kind, UINT8 opnd, INT *latency); 00781 00782 extern BOOL CGTARG_Unconditional_Compare(OP* op, TOP* uncond_ver); 00783 00784 extern BOOL CGTARG_Branches_On_True(OP* br_op, OP* cmp_op); 00785 00786 extern void CGTARG_Predicate_OP(BB* bb, OP* op, TN* pred_tn); 00787 00788 extern void CGTARG_Generate_Remainder_Branch(TN *trip_count, TN *label_tn, 00789 OPS *prolog_ops, OPS *body_ops); 00790 00791 extern BOOL CGTARG_OP_is_counted_loop(OP *op); 00792 00793 extern void CGTARG_Generate_Branch_Cloop(OP *op, TN *unrolled_trip_count, TN *trip_count, 00794 INT32 ntimes, TN *label_tn, OPS *prolog_ops, OPS *body_ops); 00795 #ifdef TARG_X8664 00796 extern void CGTARG_Generate_Countdown_Loop(TN *trip_count_tn, BB *tail, 00797 OPS *prolog_ops, OPS *body_ops, 00798 BOOL single_bb, LOOP_DESCR *loop); 00799 extern void CGTARG_LOOP_Optimize( LOOP_DESCR* loop ); 00800 extern TN* CGTARG_Process_Asm_m_constraint( WN*, void**, OPS* ); 00801 #endif 00802 00803 /* call init routine once per asm stmt */ 00804 extern void CGTARG_Init_Asm_Constraints (void); 00805 00806 /* Given a constraint for an ASM parameter, and the load of the matching 00807 * argument passed to ASM (possibly NULL), choose an appropriate TN for it 00808 */ 00809 #if defined(TARG_IA64) 00810 extern TN* CGTARG_TN_For_Asm_Operand(const char* constraint, 00811 const WN* load, 00812 TN* pref_tn, 00813 ISA_REGISTER_SUBCLASS* subclass); 00814 #else 00815 extern TN* CGTARG_TN_For_Asm_Operand(const char* constraint, 00816 const WN* load, 00817 TN* pref_tn, 00818 ISA_REGISTER_SUBCLASS* subclass, 00819 TYPE_ID type); 00820 #endif 00821 00822 /* given asm constraint and mtype, 00823 * pick appropriate dedicated tn and string name */ 00824 extern void CGTARG_TN_And_Name_For_Asm_Constraint (char *constraint, 00825 TYPE_ID rtype, 00826 TYPE_ID desc, 00827 TN **tn, 00828 const char **name); 00829 00830 /* may have to clean up the asm string */ 00831 extern void CGTARG_Postprocess_Asm_String (char* asm_string); 00832 00833 /* target specific modifiers for printing different versions 00834 * of register names when they appear as AM operands 00835 */ 00836 extern char CGTARG_Asm_Opnd_Modifiers[]; 00837 extern INT CGTARG_Num_Asm_Opnd_Modifiers; 00838 00839 extern const char* CGTARG_Modified_Asm_Opnd_Name(char modifier, TN* tn, char *tn_name); 00840 00841 00842 extern void CGTARG_Init_OP_cond_def_kind(OP *); 00843 00844 00845 // Returns TRUE if the dependence between the latency 00846 // between pred_op and succ_op is the load_latency 00847 // 00848 inline BOOL CGTARG_Use_Load_Latency(OP *pred_op, TN *tn) 00849 { 00850 #ifdef TARG_IA64 00851 return OP_load(pred_op) && OP_result(pred_op,0) == tn; 00852 #else 00853 return TRUE; 00854 #endif 00855 } 00856 00857 #if defined(TARG_IA64) || defined(TARG_X8664) 00858 /* return TRUE iff op is load with UNAT bit (IA64)*/ 00859 extern BOOL CGTARG_Load_with_UNAT (OP* op); 00860 00861 /* return TRUE iff op is store with UNAT bit (IA64) */ 00862 extern BOOL CGTARG_Store_With_UNAT (OP* op); 00863 00864 #endif 00865 00866 /* Returns TRUE if OP is a suitable candidate for HBF. */ 00867 extern BOOL CGTARG_Check_OP_For_HB_Suitability(OP *op); 00868 00869 #ifdef TARG_IA64 00870 /* Return TRUE if OP is def use stack register; */ 00871 extern BOOL OP_def_use_stack_regs(OP* op); 00872 00873 /* return the max number of hidden operands given <op> may have */ 00874 extern INT32 CGTARG_Max_Number_of_Hidden_Opnd (mTOP top); 00875 00876 /* Go through all OP in the current PU and and hidden their hidden operands */ 00877 extern void CGTARG_Add_Implict_Operands (void); 00878 #endif 00879 extern TN* CGTARG_Gen_Dedicated_Subclass_TN( OP* op, int idx, BOOL is_result ); 00880 00881 #ifdef TARG_IA64 00882 typedef mempool_allocator<SCHED_INFO_CLASS> SIC_MEM_ALLOC; 00883 typedef std::vector<SCHED_INFO_CLASS, SIC_MEM_ALLOC> TOP_SET; 00884 void Fix_MM_Latency ( BB *bb, TOP_SET *src_op_class, TOP_SET *tgt_op_class, UINT8 cycles_apart); 00885 void Fix_Cache_Conflict_latency( BB *bb); 00886 #endif 00887 00888 #ifdef KEY 00889 // Return TRUE if OP accesses thread-local memory. 00890 extern BOOL CGTARG_Is_Thread_Local_Memory_OP(OP *op); 00891 #endif 00892 00893 #endif /* CGTARGET_INCLUDED */
1.5.6