src/share/vm/adlc/output_c.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6961690 Sdiff src/share/vm/adlc

src/share/vm/adlc/output_c.cpp

Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:


1479     generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
1480 
1481     // End of scope for this peephole's constraints
1482     fprintf(fp, "    }\n");
1483     // Closing brace '}' to make each peephole rule individually selectable
1484     fprintf(fp, "  } // end of peephole rule #%d\n", peephole_number);
1485     fprintf(fp, "\n");
1486   }
1487 
1488   fprintf(fp, "  return NULL;  // No peephole rules matched\n");
1489   fprintf(fp, "}\n");
1490   fprintf(fp, "\n");
1491 }
1492 
1493 // Define the Expand method for an instruction node
1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495   unsigned      cnt  = 0;          // Count nodes we have expand into
1496   unsigned      i;
1497 
1498   // Generate Expand function header
1499   fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
1500   fprintf(fp,"Compile* C = Compile::current();\n");
1501   // Generate expand code
1502   if( node->expands() ) {
1503     const char   *opid;
1504     int           new_pos, exp_pos;
1505     const char   *new_id   = NULL;
1506     const Form   *frm      = NULL;
1507     InstructForm *new_inst = NULL;
1508     OperandForm  *new_oper = NULL;
1509     unsigned      numo     = node->num_opnds() +
1510                                 node->_exprule->_newopers.count();
1511 
1512     // If necessary, generate any operands created in expand rule
1513     if (node->_exprule->_newopers.count()) {
1514       for(node->_exprule->_newopers.reset();
1515           (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
1516         frm = node->_localNames[new_id];
1517         assert(frm, "Invalid entry in new operands list of expand rule");
1518         new_oper = frm->is_operand();
1519         char *tmp = (char *)node->_exprule->_newopconst[new_id];
1520         if (tmp == NULL) {


1801           declared_kill = true;
1802         }
1803 
1804         assert( op, "Support additional KILLS for base operands");
1805         const char *regmask    = reg_mask(*op);
1806         const char *ideal_type = op->ideal_type(_globalNames, _register);
1807 
1808         if (!op->is_bound_register()) {
1809           syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
1810                      node->_ident, comp->_type, comp->_name);
1811         }
1812 
1813         fprintf(fp,"  kill = ");
1814         fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
1815                 machNode, proj_no++, regmask, ideal_type);
1816         fprintf(fp,"  proj_list.push(kill);\n");
1817       }
1818     }
1819   }
1820 






1821   fprintf(fp,"\n");
1822   if( node->expands() ) {
1823     fprintf(fp,"  return result;\n");
1824   } else {
1825     fprintf(fp,"  return this;\n");
1826   }
1827   fprintf(fp,"}\n");
1828   fprintf(fp,"\n");
1829 }
1830 
1831 
1832 //------------------------------Emit Routines----------------------------------
1833 // Special classes and routines for defining node emit routines which output
1834 // target specific instruction object encodings.
1835 // Define the ___Node::emit() routine
1836 //
1837 // (1) void  ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1838 // (2)   // ...  encoding defined by user
1839 // (3)
1840 // (4) }


1907     _doing_emit_hi = false;
1908     _doing_emit_lo = false;
1909     _may_reloc     = false;
1910     _must_reloc    = false;
1911     _reloc_form    = RELOC_NONE;
1912     _reloc_type    = AdlcVMDeps::none_reloc_type();
1913     _strings_to_emit.clear();
1914   }
1915 
1916   // Track necessary state when identifying a replacement variable
1917   void update_state(const char *rep_var) {
1918     // A replacement variable or one of its subfields
1919     // Obtain replacement variable from list
1920     if ( (*rep_var) != '$' ) {
1921       // A replacement variable, '$' prefix
1922       // check_rep_var( rep_var );
1923       if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1924         // No state needed.
1925         assert( _opclass == NULL,
1926                 "'primary', 'secondary' and 'tertiary' don't follow operand.");
1927       } else {










1928         // Lookup its position in parameter list
1929         int   param_no  = _encoding.rep_var_index(rep_var);
1930         if ( param_no == -1 ) {
1931           _AD.syntax_err( _encoding._linenum,
1932                           "Replacement variable %s not found in enc_class %s.\n",
1933                           rep_var, _encoding._name);
1934         }
1935 
1936         // Lookup the corresponding ins_encode parameter
1937         const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
1938         if (inst_rep_var == NULL) {
1939           _AD.syntax_err( _ins_encode._linenum,
1940                           "Parameter %s not passed to enc_class %s from instruct %s.\n",
1941                           rep_var, _encoding._name, _inst._ident);
1942         }
1943 
1944         // Check if instruction's actual parameter is a local name in the instruction
1945         const Form  *local     = _inst._localNames[inst_rep_var];
1946         OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
1947         // Note: assert removed to allow constant and symbolic parameters


2363       fprintf(_fp,"->method()");
2364     }
2365     else {
2366       printf("emit_field: %s\n",rep_var);
2367       assert( false, "UnImplemented()");
2368     }
2369   }
2370 
2371 
2372   void emit_rep_var(const char *rep_var) {
2373     _processing_noninput = false;
2374     // A replacement variable, originally '$'
2375     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2376       if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2377         // Missing opcode
2378         _AD.syntax_err( _inst._linenum,
2379                         "Missing $%s opcode definition in %s, used by encoding %s\n",
2380                         rep_var, _inst._ident, _encoding._name);
2381       }
2382     }









2383     else {
2384       // Lookup its position in parameter list
2385       int   param_no  = _encoding.rep_var_index(rep_var);
2386       if ( param_no == -1 ) {
2387         _AD.syntax_err( _encoding._linenum,
2388                         "Replacement variable %s not found in enc_class %s.\n",
2389                         rep_var, _encoding._name);
2390       }
2391       // Lookup the corresponding ins_encode parameter
2392       const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2393 
2394       // Check if instruction's actual parameter is a local name in the instruction
2395       const Form  *local     = _inst._localNames[inst_rep_var];
2396       OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
2397       // Note: assert removed to allow constant and symbolic parameters
2398       // assert( opc, "replacement variable was not found in local names");
2399       // Lookup the index position iff the replacement variable is a localName
2400       int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2401       if( idx != -1 ) {
2402         if (_inst.is_noninput_operand(idx)) {


2448 };  // end class DefineEmitState
2449 
2450 
2451 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2452 
2453   //(1)
2454   // Output instruction's emit prototype
2455   fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
2456           inst._ident);
2457 
2458   fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2459 
2460   //(2)
2461   // Print the size
2462   fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2463 
2464   // (3) and (4)
2465   fprintf(fp,"}\n");
2466 }
2467 
2468 void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
2469   InsEncode *ins_encode = inst._insencode;

2470 
2471   // (1)
2472   // Output instruction's emit prototype
2473   fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
2474           inst._ident);
2475 
2476   // If user did not define an encode section,
2477   // provide stub that does not generate any machine code.
2478   if( (_encode == NULL) || (ins_encode == NULL) ) {
2479     fprintf(fp, "  // User did not define an encode section.\n");
2480     fprintf(fp,"}\n");
2481     return;
2482   }
2483 
2484   // Save current instruction's starting address (helps with relocation).
2485   fprintf(fp, "    cbuf.set_insts_mark();\n");
2486 
2487   // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
2488   // fprintf( fp, "    unsigned idx0  = 0;\n");


2489 
2490   // Output each operand's offset into the array of registers.
2491   inst.index_temps( fp, _globalNames );
2492 
2493   // Output this instruction's encodings
2494   const char *ec_name;
2495   bool        user_defined = false;
2496   ins_encode->reset();
2497   while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
2498     fprintf(fp, "  {");
2499     // Output user-defined encoding
2500     user_defined           = true;
2501 
2502     const char *ec_code    = NULL;
2503     const char *ec_rep_var = NULL;
2504     EncClass   *encoding   = _encode->encClass(ec_name);
2505     if (encoding == NULL) {
2506       fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2507       abort();
2508     }
2509 
2510     if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
2511       globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2512                            inst._ident, ins_encode->current_encoding_num_args(),
2513                            ec_name, encoding->num_args());
2514     }
2515 
2516     DefineEmitState  pending(fp, *this, *encoding, *ins_encode, inst );
2517     encoding->_code.reset();
2518     encoding->_rep_vars.reset();
2519     // Process list of user-defined strings,
2520     // and occurrences of replacement variables.
2521     // Replacement Vars are pushed into a list and then output
2522     while ( (ec_code = encoding->_code.iter()) != NULL ) {
2523       if ( ! encoding->_code.is_signal( ec_code ) ) {
2524         // Emit pending code
2525         pending.emit();
2526         pending.clear();
2527         // Emit this code section
2528         fprintf(fp,"%s", ec_code);
2529       } else {
2530         // A replacement variable or one of its subfields
2531         // Obtain replacement variable from list
2532         ec_rep_var  = encoding->_rep_vars.iter();
2533         pending.add_rep_var(ec_rep_var);
2534       }
2535     }
2536     // Emit pending code
2537     pending.emit();
2538     pending.clear();
2539     fprintf(fp, "}\n");
2540   } // end while instruction's encodings
2541 
2542   // Check if user stated which encoding to user
2543   if ( user_defined == false ) {
2544     fprintf(fp, "  // User did not define which encode class to use.\n");
2545   }
2546 
2547   // (3) and (4)
2548   fprintf(fp,"}\n");















































































2549 }
2550 
2551 // ---------------------------------------------------------------------------
2552 //--------Utilities to build MachOper and MachNode derived Classes------------
2553 // ---------------------------------------------------------------------------
2554 
2555 //------------------------------Utilities to build Operand Classes------------
2556 static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
2557   uint num_edges = oper.num_edges(globals);
2558   if( num_edges != 0 ) {
2559     // Method header
2560     fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
2561             oper._ident);
2562 
2563     // Assert that the index is in range.
2564     fprintf(fp, "  assert(0 <= index && index < %d, \"index out of range\");\n",
2565             num_edges);
2566 
2567     // Figure out if all RegMasks are the same.
2568     const char* first_reg_class = oper.in_reg_class(0, globals);


2935   // Output the definitions for out_RegMask() // & kill_RegMask()
2936   _instructions.reset();
2937   InstructForm *instr;
2938   MachNodeForm *machnode;
2939   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
2940     // Ensure this is a machine-world instruction
2941     if ( instr->ideal_only() ) continue;
2942 
2943     defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
2944   }
2945 
2946   bool used = false;
2947   // Output the definitions for expand rules & peephole rules
2948   _instructions.reset();
2949   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
2950     // Ensure this is a machine-world instruction
2951     if ( instr->ideal_only() ) continue;
2952     // If there are multiple defs/kills, or an explicit expand rule, build rule
2953     if( instr->expands() || instr->needs_projections() ||
2954         instr->has_temps() ||

2955         instr->_matrule != NULL &&
2956         instr->num_opnds() != instr->num_unique_opnds() )
2957       defineExpand(_CPP_EXPAND_file._fp, instr);
2958     // If there is an explicit peephole rule, build it
2959     if ( instr->peepholes() )
2960       definePeephole(_CPP_PEEPHOLE_file._fp, instr);
2961 
2962     // Output code to convert to the cisc version, if applicable
2963     used |= instr->define_cisc_version(*this, fp);
2964 
2965     // Output code to convert to the short branch version, if applicable
2966     used |= instr->define_short_branch_methods(*this, fp);
2967   }
2968 
2969   // Construct the method called by cisc_version() to copy inputs and operands.
2970   define_fill_new_machnode(used, fp);
2971 
2972   // Output the definitions for labels
2973   _instructions.reset();
2974   while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {


3015       fprintf(fp,"int  %sNode::reloc()   const {\n", instr->_ident);
3016       fprintf(fp,  "  return  %d;\n", reloc_size );
3017       fprintf(fp,"}\n");
3018       fprintf(fp,"\n");
3019     }
3020   }
3021   fprintf(fp,"\n");
3022 
3023   // Output the definitions for code generation
3024   //
3025   // address  ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
3026   //   // ...  encoding defined by user
3027   //   return ptr;
3028   // }
3029   //
3030   _instructions.reset();
3031   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3032     // Ensure this is a machine-world instruction
3033     if ( instr->ideal_only() ) continue;
3034 
3035     if (instr->_insencode) defineEmit(fp, *instr);
3036     if (instr->_size)      defineSize(fp, *instr);

3037 
3038     // side-call to generate output that used to be in the header file:
3039     extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3040     gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3041   }
3042 
3043   // Output the definitions for alias analysis
3044   _instructions.reset();
3045   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3046     // Ensure this is a machine-world instruction
3047     if ( instr->ideal_only() ) continue;
3048 
3049     // Analyze machine instructions that either USE or DEF memory.
3050     int memory_operand = instr->memory_operand(_globalNames);
3051     // Some guys kill all of memory
3052     if ( instr->is_wide_memory_kill(_globalNames) ) {
3053       memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
3054     }
3055 
3056     if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {




1479     generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
1480 
1481     // End of scope for this peephole's constraints
1482     fprintf(fp, "    }\n");
1483     // Closing brace '}' to make each peephole rule individually selectable
1484     fprintf(fp, "  } // end of peephole rule #%d\n", peephole_number);
1485     fprintf(fp, "\n");
1486   }
1487 
1488   fprintf(fp, "  return NULL;  // No peephole rules matched\n");
1489   fprintf(fp, "}\n");
1490   fprintf(fp, "\n");
1491 }
1492 
1493 // Define the Expand method for an instruction node
1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495   unsigned      cnt  = 0;          // Count nodes we have expand into
1496   unsigned      i;
1497 
1498   // Generate Expand function header
1499   fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
1500   fprintf(fp, "  Compile* C = Compile::current();\n");
1501   // Generate expand code
1502   if( node->expands() ) {
1503     const char   *opid;
1504     int           new_pos, exp_pos;
1505     const char   *new_id   = NULL;
1506     const Form   *frm      = NULL;
1507     InstructForm *new_inst = NULL;
1508     OperandForm  *new_oper = NULL;
1509     unsigned      numo     = node->num_opnds() +
1510                                 node->_exprule->_newopers.count();
1511 
1512     // If necessary, generate any operands created in expand rule
1513     if (node->_exprule->_newopers.count()) {
1514       for(node->_exprule->_newopers.reset();
1515           (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
1516         frm = node->_localNames[new_id];
1517         assert(frm, "Invalid entry in new operands list of expand rule");
1518         new_oper = frm->is_operand();
1519         char *tmp = (char *)node->_exprule->_newopconst[new_id];
1520         if (tmp == NULL) {


1801           declared_kill = true;
1802         }
1803 
1804         assert( op, "Support additional KILLS for base operands");
1805         const char *regmask    = reg_mask(*op);
1806         const char *ideal_type = op->ideal_type(_globalNames, _register);
1807 
1808         if (!op->is_bound_register()) {
1809           syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
1810                      node->_ident, comp->_type, comp->_name);
1811         }
1812 
1813         fprintf(fp,"  kill = ");
1814         fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
1815                 machNode, proj_no++, regmask, ideal_type);
1816         fprintf(fp,"  proj_list.push(kill);\n");
1817       }
1818     }
1819   }
1820 
1821   // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
1822   // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
1823   if (node->is_mach_constant()) {
1824     fprintf(fp,"  add_req(C->mach_constant_base_node());\n");
1825   }
1826 
1827   fprintf(fp,"\n");
1828   if( node->expands() ) {
1829     fprintf(fp,"  return result;\n");
1830   } else {
1831     fprintf(fp,"  return this;\n");
1832   }
1833   fprintf(fp,"}\n");
1834   fprintf(fp,"\n");
1835 }
1836 
1837 
1838 //------------------------------Emit Routines----------------------------------
1839 // Special classes and routines for defining node emit routines which output
1840 // target specific instruction object encodings.
1841 // Define the ___Node::emit() routine
1842 //
1843 // (1) void  ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1844 // (2)   // ...  encoding defined by user
1845 // (3)
1846 // (4) }


1913     _doing_emit_hi = false;
1914     _doing_emit_lo = false;
1915     _may_reloc     = false;
1916     _must_reloc    = false;
1917     _reloc_form    = RELOC_NONE;
1918     _reloc_type    = AdlcVMDeps::none_reloc_type();
1919     _strings_to_emit.clear();
1920   }
1921 
1922   // Track necessary state when identifying a replacement variable
1923   void update_state(const char *rep_var) {
1924     // A replacement variable or one of its subfields
1925     // Obtain replacement variable from list
1926     if ( (*rep_var) != '$' ) {
1927       // A replacement variable, '$' prefix
1928       // check_rep_var( rep_var );
1929       if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1930         // No state needed.
1931         assert( _opclass == NULL,
1932                 "'primary', 'secondary' and 'tertiary' don't follow operand.");
1933       }
1934       else if ((strcmp(rep_var, "constanttablebase") == 0) ||
1935                (strcmp(rep_var, "constantoffset")    == 0) ||
1936                (strcmp(rep_var, "constantaddress")   == 0)) {
1937         if (!_inst.is_mach_constant()) {
1938           _AD.syntax_err(_encoding._linenum,
1939                          "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
1940                          rep_var, _encoding._name);
1941         }
1942       }
1943       else {
1944         // Lookup its position in parameter list
1945         int   param_no  = _encoding.rep_var_index(rep_var);
1946         if ( param_no == -1 ) {
1947           _AD.syntax_err( _encoding._linenum,
1948                           "Replacement variable %s not found in enc_class %s.\n",
1949                           rep_var, _encoding._name);
1950         }
1951 
1952         // Lookup the corresponding ins_encode parameter
1953         const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
1954         if (inst_rep_var == NULL) {
1955           _AD.syntax_err( _ins_encode._linenum,
1956                           "Parameter %s not passed to enc_class %s from instruct %s.\n",
1957                           rep_var, _encoding._name, _inst._ident);
1958         }
1959 
1960         // Check if instruction's actual parameter is a local name in the instruction
1961         const Form  *local     = _inst._localNames[inst_rep_var];
1962         OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
1963         // Note: assert removed to allow constant and symbolic parameters


2379       fprintf(_fp,"->method()");
2380     }
2381     else {
2382       printf("emit_field: %s\n",rep_var);
2383       assert( false, "UnImplemented()");
2384     }
2385   }
2386 
2387 
2388   void emit_rep_var(const char *rep_var) {
2389     _processing_noninput = false;
2390     // A replacement variable, originally '$'
2391     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2392       if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2393         // Missing opcode
2394         _AD.syntax_err( _inst._linenum,
2395                         "Missing $%s opcode definition in %s, used by encoding %s\n",
2396                         rep_var, _inst._ident, _encoding._name);
2397       }
2398     }
2399     else if (strcmp(rep_var, "constanttablebase") == 0) {
2400       fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
2401     }
2402     else if (strcmp(rep_var, "constantoffset") == 0) {
2403       fprintf(_fp, "constant_offset()");
2404     }
2405     else if (strcmp(rep_var, "constantaddress") == 0) {
2406       fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
2407     }
2408     else {
2409       // Lookup its position in parameter list
2410       int   param_no  = _encoding.rep_var_index(rep_var);
2411       if ( param_no == -1 ) {
2412         _AD.syntax_err( _encoding._linenum,
2413                         "Replacement variable %s not found in enc_class %s.\n",
2414                         rep_var, _encoding._name);
2415       }
2416       // Lookup the corresponding ins_encode parameter
2417       const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2418 
2419       // Check if instruction's actual parameter is a local name in the instruction
2420       const Form  *local     = _inst._localNames[inst_rep_var];
2421       OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
2422       // Note: assert removed to allow constant and symbolic parameters
2423       // assert( opc, "replacement variable was not found in local names");
2424       // Lookup the index position iff the replacement variable is a localName
2425       int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2426       if( idx != -1 ) {
2427         if (_inst.is_noninput_operand(idx)) {


2473 };  // end class DefineEmitState
2474 
2475 
2476 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2477 
2478   //(1)
2479   // Output instruction's emit prototype
2480   fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
2481           inst._ident);
2482 
2483   fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2484 
2485   //(2)
2486   // Print the size
2487   fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2488 
2489   // (3) and (4)
2490   fprintf(fp,"}\n");
2491 }
2492 
2493 // defineEmit -----------------------------------------------------------------
2494 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
2495   InsEncode* encode = inst._insencode;
2496 
2497   // (1)
2498   // Output instruction's emit prototype
2499   fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);

2500 
2501   // If user did not define an encode section,
2502   // provide stub that does not generate any machine code.
2503   if( (_encode == NULL) || (encode == NULL) ) {
2504     fprintf(fp, "  // User did not define an encode section.\n");
2505     fprintf(fp, "}\n");
2506     return;
2507   }
2508 
2509   // Save current instruction's starting address (helps with relocation).
2510   fprintf(fp, "  cbuf.set_insts_mark();\n");
2511 
2512   // For MachConstantNodes which are ideal jump nodes, fill the jump table.
2513   if (inst.is_mach_constant() && inst.is_ideal_jump()) {
2514     fprintf(fp, "  fill_jump_table_in_constant_table(cbuf, _index2label);\n");
2515   }
2516 
2517   // Output each operand's offset into the array of registers.
2518   inst.index_temps(fp, _globalNames);
2519 
2520   // Output this instruction's encodings
2521   const char *ec_name;
2522   bool        user_defined = false;
2523   encode->reset();
2524   while ((ec_name = encode->encode_class_iter()) != NULL) {
2525     fprintf(fp, "  {\n");
2526     // Output user-defined encoding
2527     user_defined           = true;
2528 
2529     const char *ec_code    = NULL;
2530     const char *ec_rep_var = NULL;
2531     EncClass   *encoding   = _encode->encClass(ec_name);
2532     if (encoding == NULL) {
2533       fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2534       abort();
2535     }
2536 
2537     if (encode->current_encoding_num_args() != encoding->num_args()) {
2538       globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2539                            inst._ident, encode->current_encoding_num_args(),
2540                            ec_name, encoding->num_args());
2541     }
2542 
2543     DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2544     encoding->_code.reset();
2545     encoding->_rep_vars.reset();
2546     // Process list of user-defined strings,
2547     // and occurrences of replacement variables.
2548     // Replacement Vars are pushed into a list and then output
2549     while ((ec_code = encoding->_code.iter()) != NULL) {
2550       if (!encoding->_code.is_signal(ec_code)) {
2551         // Emit pending code
2552         pending.emit();
2553         pending.clear();
2554         // Emit this code section
2555         fprintf(fp, "%s", ec_code);
2556       } else {
2557         // A replacement variable or one of its subfields
2558         // Obtain replacement variable from list
2559         ec_rep_var  = encoding->_rep_vars.iter();
2560         pending.add_rep_var(ec_rep_var);
2561       }
2562     }
2563     // Emit pending code
2564     pending.emit();
2565     pending.clear();
2566     fprintf(fp, "  }\n");
2567   } // end while instruction's encodings
2568 
2569   // Check if user stated which encoding to user
2570   if ( user_defined == false ) {
2571     fprintf(fp, "  // User did not define which encode class to use.\n");
2572   }
2573 
2574   // (3) and (4)
2575   fprintf(fp, "}\n");
2576 }
2577 
2578 // defineEvalConstant ---------------------------------------------------------
2579 void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
2580   InsEncode* encode = inst._constant;
2581 
2582   // (1)
2583   // Output instruction's emit prototype
2584   fprintf(fp, "void %sNode::eval_constant() {\n", inst._ident);
2585 
2586   // For ideal jump nodes, allocate a jump table.
2587   if (inst.is_ideal_jump()) {
2588     fprintf(fp, "  allocate_jump_table_in_constant_table();\n");
2589   }
2590 
2591   // If user did not define an encode section,
2592   // provide stub that does not generate any machine code.
2593   if ((_encode == NULL) || (encode == NULL)) {
2594     fprintf(fp, "  // User did not define an encode section.\n");
2595     fprintf(fp, "}\n");
2596     return;
2597   }
2598 
2599   // Output this instruction's encodings
2600   const char *ec_name;
2601   bool        user_defined = false;
2602   encode->reset();
2603   while ((ec_name = encode->encode_class_iter()) != NULL) {
2604     fprintf(fp, "  {\n");
2605     // Output user-defined encoding
2606     user_defined           = true;
2607 
2608     const char *ec_code    = NULL;
2609     const char *ec_rep_var = NULL;
2610     EncClass   *encoding   = _encode->encClass(ec_name);
2611     if (encoding == NULL) {
2612       fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2613       abort();
2614     }
2615 
2616     if (encode->current_encoding_num_args() != encoding->num_args()) {
2617       globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2618                            inst._ident, encode->current_encoding_num_args(),
2619                            ec_name, encoding->num_args());
2620     }
2621 
2622     DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2623     encoding->_code.reset();
2624     encoding->_rep_vars.reset();
2625     // Process list of user-defined strings,
2626     // and occurrences of replacement variables.
2627     // Replacement Vars are pushed into a list and then output
2628     while ((ec_code = encoding->_code.iter()) != NULL) {
2629       if (!encoding->_code.is_signal(ec_code)) {
2630         // Emit pending code
2631         pending.emit();
2632         pending.clear();
2633         // Emit this code section
2634         fprintf(fp, "%s", ec_code);
2635       } else {
2636         // A replacement variable or one of its subfields
2637         // Obtain replacement variable from list
2638         ec_rep_var  = encoding->_rep_vars.iter();
2639         pending.add_rep_var(ec_rep_var);
2640       }
2641     }
2642     // Emit pending code
2643     pending.emit();
2644     pending.clear();
2645     fprintf(fp, "  }\n");
2646   } // end while instruction's encodings
2647 
2648   // Check if user stated which encoding to user
2649   if (user_defined == false) {
2650     fprintf(fp, "  // User did not define which encode class to use.\n");
2651   }
2652 
2653   // (3) and (4)
2654   fprintf(fp, "}\n");
2655 }
2656 
2657 // ---------------------------------------------------------------------------
2658 //--------Utilities to build MachOper and MachNode derived Classes------------
2659 // ---------------------------------------------------------------------------
2660 
2661 //------------------------------Utilities to build Operand Classes------------
2662 static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
2663   uint num_edges = oper.num_edges(globals);
2664   if( num_edges != 0 ) {
2665     // Method header
2666     fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
2667             oper._ident);
2668 
2669     // Assert that the index is in range.
2670     fprintf(fp, "  assert(0 <= index && index < %d, \"index out of range\");\n",
2671             num_edges);
2672 
2673     // Figure out if all RegMasks are the same.
2674     const char* first_reg_class = oper.in_reg_class(0, globals);


3041   // Output the definitions for out_RegMask() // & kill_RegMask()
3042   _instructions.reset();
3043   InstructForm *instr;
3044   MachNodeForm *machnode;
3045   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3046     // Ensure this is a machine-world instruction
3047     if ( instr->ideal_only() ) continue;
3048 
3049     defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
3050   }
3051 
3052   bool used = false;
3053   // Output the definitions for expand rules & peephole rules
3054   _instructions.reset();
3055   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3056     // Ensure this is a machine-world instruction
3057     if ( instr->ideal_only() ) continue;
3058     // If there are multiple defs/kills, or an explicit expand rule, build rule
3059     if( instr->expands() || instr->needs_projections() ||
3060         instr->has_temps() ||
3061         instr->is_mach_constant() ||
3062         instr->_matrule != NULL &&
3063         instr->num_opnds() != instr->num_unique_opnds() )
3064       defineExpand(_CPP_EXPAND_file._fp, instr);
3065     // If there is an explicit peephole rule, build it
3066     if ( instr->peepholes() )
3067       definePeephole(_CPP_PEEPHOLE_file._fp, instr);
3068 
3069     // Output code to convert to the cisc version, if applicable
3070     used |= instr->define_cisc_version(*this, fp);
3071 
3072     // Output code to convert to the short branch version, if applicable
3073     used |= instr->define_short_branch_methods(*this, fp);
3074   }
3075 
3076   // Construct the method called by cisc_version() to copy inputs and operands.
3077   define_fill_new_machnode(used, fp);
3078 
3079   // Output the definitions for labels
3080   _instructions.reset();
3081   while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {


3122       fprintf(fp,"int  %sNode::reloc()   const {\n", instr->_ident);
3123       fprintf(fp,  "  return  %d;\n", reloc_size );
3124       fprintf(fp,"}\n");
3125       fprintf(fp,"\n");
3126     }
3127   }
3128   fprintf(fp,"\n");
3129 
3130   // Output the definitions for code generation
3131   //
3132   // address  ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
3133   //   // ...  encoding defined by user
3134   //   return ptr;
3135   // }
3136   //
3137   _instructions.reset();
3138   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3139     // Ensure this is a machine-world instruction
3140     if ( instr->ideal_only() ) continue;
3141 
3142     if (instr->_insencode)         defineEmit        (fp, *instr);
3143     if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
3144     if (instr->_size)              defineSize        (fp, *instr);
3145 
3146     // side-call to generate output that used to be in the header file:
3147     extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3148     gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3149   }
3150 
3151   // Output the definitions for alias analysis
3152   _instructions.reset();
3153   for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3154     // Ensure this is a machine-world instruction
3155     if ( instr->ideal_only() ) continue;
3156 
3157     // Analyze machine instructions that either USE or DEF memory.
3158     int memory_operand = instr->memory_operand(_globalNames);
3159     // Some guys kill all of memory
3160     if ( instr->is_wide_memory_kill(_globalNames) ) {
3161       memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
3162     }
3163 
3164     if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {


src/share/vm/adlc/output_c.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File