src/share/vm/adlc/output_c.cpp

Print this page
rev 2699 : 7090968: Allow adlc register class to depend on runtime conditions
Summary: allow reg_class definition as a function.
Reviewed-by:


 145 
 146 // Declare an enumeration of user-defined register classes
 147 // and a list of register masks, one for each class.
 148 void ArchDesc::declare_register_masks(FILE *fp_hpp) {
 149   const char  *rc_name;
 150 
 151   if( _register ) {
 152     // Build enumeration of user-defined register classes.
 153     defineRegClassEnum(fp_hpp, _register);
 154 
 155     // Generate a list of register masks, one for each class.
 156     fprintf(fp_hpp,"\n");
 157     fprintf(fp_hpp,"// Register masks, one for each register class.\n");
 158     _register->_rclasses.reset();
 159     for( rc_name = NULL;
 160          (rc_name = _register->_rclasses.iter()) != NULL; ) {
 161       const char *prefix    = "";
 162       RegClass   *reg_class = _register->getRegClass(rc_name);
 163       assert( reg_class, "Using an undefined register class");
 164 
 165       int len = RegisterForm::RegMask_Size();
 166       fprintf(fp_hpp, "extern const RegMask %s%s_mask;\n", prefix, toUpper( rc_name ) );




 167 
 168       if( reg_class->_stack_or_reg ) {
 169         fprintf(fp_hpp, "extern const RegMask %sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );


 170       }
 171     }
 172   }
 173 }
 174 
 175 // Generate an enumeration of user-defined register classes
 176 // and a list of register masks, one for each class.
 177 void ArchDesc::build_register_masks(FILE *fp_cpp) {
 178   const char  *rc_name;
 179 
 180   if( _register ) {
 181     // Generate a list of register masks, one for each class.
 182     fprintf(fp_cpp,"\n");
 183     fprintf(fp_cpp,"// Register masks, one for each register class.\n");
 184     _register->_rclasses.reset();
 185     for( rc_name = NULL;
 186          (rc_name = _register->_rclasses.iter()) != NULL; ) {
 187       const char *prefix    = "";
 188       RegClass   *reg_class = _register->getRegClass(rc_name);
 189       assert( reg_class, "Using an undefined register class");
 190 


 191       int len = RegisterForm::RegMask_Size();
 192       fprintf(fp_cpp, "const RegMask %s%s_mask(", prefix, toUpper( rc_name ) );
 193       { int i;
 194         for( i = 0; i < len-1; i++ )
 195           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,false));
 196         fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,false));
 197       }
 198 
 199       if( reg_class->_stack_or_reg ) {
 200         int i;
 201         fprintf(fp_cpp, "const RegMask %sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
 202         for( i = 0; i < len-1; i++ )
 203           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,true));
 204         fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,true));
 205       }
 206     }
 207   }
 208 }
 209 
 210 // Compute an index for an array in the pipeline_reads_NNN arrays
 211 static int pipeline_reads_initializer(FILE *fp_cpp, NameList &pipeline_reads, PipeClassForm *pipeclass)
 212 {
 213   int templen = 1;
 214   int paramcount = 0;
 215   const char *paramname;
 216 
 217   if (pipeclass->_parameters.count() == 0)
 218     return -1;
 219 
 220   pipeclass->_parameters.reset();
 221   paramname = pipeclass->_parameters.iter();


2673             num_edges);
2674 
2675     // Figure out if all RegMasks are the same.
2676     const char* first_reg_class = oper.in_reg_class(0, globals);
2677     bool all_same = true;
2678     assert(first_reg_class != NULL, "did not find register mask");
2679 
2680     for (uint index = 1; all_same && index < num_edges; index++) {
2681       const char* some_reg_class = oper.in_reg_class(index, globals);
2682       assert(some_reg_class != NULL, "did not find register mask");
2683       if (strcmp(first_reg_class, some_reg_class) != 0) {
2684         all_same = false;
2685       }
2686     }
2687 
2688     if (all_same) {
2689       // Return the sole RegMask.
2690       if (strcmp(first_reg_class, "stack_slots") == 0) {
2691         fprintf(fp,"  return &(Compile::current()->FIRST_STACK_mask());\n");
2692       } else {
2693         fprintf(fp,"  return &%s_mask;\n", toUpper(first_reg_class));
2694       }
2695     } else {
2696       // Build a switch statement to return the desired mask.
2697       fprintf(fp,"  switch (index) {\n");
2698 
2699       for (uint index = 0; index < num_edges; index++) {
2700         const char *reg_class = oper.in_reg_class(index, globals);
2701         assert(reg_class != NULL, "did not find register mask");
2702         if( !strcmp(reg_class, "stack_slots") ) {
2703           fprintf(fp, "  case %d: return &(Compile::current()->FIRST_STACK_mask());\n", index);
2704         } else {
2705           fprintf(fp, "  case %d: return &%s_mask;\n", index, toUpper(reg_class));
2706         }
2707       }
2708       fprintf(fp,"  }\n");
2709       fprintf(fp,"  ShouldNotReachHere();\n");
2710       fprintf(fp,"  return NULL;\n");
2711     }
2712 
2713     // Method close
2714     fprintf(fp, "}\n\n");
2715   }
2716 }
2717 
2718 // generate code to create a clone for a class derived from MachOper
2719 //
2720 // (0)  MachOper  *MachOperXOper::clone(Compile* C) const {
2721 // (1)    return new (C) MachXOper( _ccode, _c0, _c1, ..., _cn);
2722 // (2)  }
2723 //
2724 static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
2725   fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper._ident);


4063   fprintf(fp_cpp,"void Matcher::calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length, bool is_outgoing) {\n");
4064   fprintf(fp_cpp,"%s\n", _frame->_calling_convention);
4065   fprintf(fp_cpp,"}\n\n");
4066   // Native Argument Position
4067   fprintf(fp_cpp,"void Matcher::c_calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length) {\n");
4068   fprintf(fp_cpp,"%s\n", _frame->_c_calling_convention);
4069   fprintf(fp_cpp,"}\n\n");
4070   // Java Return Value Location
4071   fprintf(fp_cpp,"OptoRegPair Matcher::return_value(int ideal_reg, bool is_outgoing) {\n");
4072   fprintf(fp_cpp,"%s\n", _frame->_return_value);
4073   fprintf(fp_cpp,"}\n\n");
4074   // Native Return Value Location
4075   fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(int ideal_reg, bool is_outgoing) {\n");
4076   fprintf(fp_cpp,"%s\n", _frame->_c_return_value);
4077   fprintf(fp_cpp,"}\n\n");
4078 
4079   // Inline Cache Register, mask definition, and encoding
4080   fprintf(fp_cpp,"OptoReg::Name Matcher::inline_cache_reg() {");
4081   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4082           _frame->_inline_cache_reg);
4083   fprintf(fp_cpp,"const RegMask &Matcher::inline_cache_reg_mask() {");
4084   fprintf(fp_cpp," return INLINE_CACHE_REG_mask; }\n\n");
4085   fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
4086   fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
4087 
4088   // Interpreter's Method Oop Register, mask definition, and encoding
4089   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
4090   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4091           _frame->_interpreter_method_oop_reg);
4092   fprintf(fp_cpp,"const RegMask &Matcher::interpreter_method_oop_reg_mask() {");
4093   fprintf(fp_cpp," return INTERPRETER_METHOD_OOP_REG_mask; }\n\n");
4094   fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
4095   fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
4096 
4097   // Interpreter's Frame Pointer Register, mask definition, and encoding
4098   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {");
4099   if (_frame->_interpreter_frame_pointer_reg == NULL)
4100     fprintf(fp_cpp," return OptoReg::Bad; }\n\n");
4101   else
4102     fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4103             _frame->_interpreter_frame_pointer_reg);
4104   fprintf(fp_cpp,"const RegMask &Matcher::interpreter_frame_pointer_reg_mask() {");
4105   if (_frame->_interpreter_frame_pointer_reg == NULL)
4106     fprintf(fp_cpp," static RegMask dummy; return dummy; }\n\n");
4107   else
4108     fprintf(fp_cpp," return INTERPRETER_FRAME_POINTER_REG_mask; }\n\n");
4109 
4110   // Frame Pointer definition
4111   /* CNC - I can not contemplate having a different frame pointer between
4112      Java and native code; makes my head hurt to think about it.
4113   fprintf(fp_cpp,"OptoReg::Name Matcher::frame_pointer() const {");
4114   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4115           _frame->_frame_pointer);
4116   */
4117   // (Native) Frame Pointer definition
4118   fprintf(fp_cpp,"OptoReg::Name Matcher::c_frame_pointer() const {");
4119   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4120           _frame->_frame_pointer);
4121 
4122   // Number of callee-save + always-save registers for calling convention
4123   fprintf(fp_cpp, "// Number of callee-save + always-save registers\n");
4124   fprintf(fp_cpp, "int  Matcher::number_of_saved_registers() {\n");
4125   RegDef *rdef;
4126   int nof_saved_registers = 0;
4127   _register->reset_RegDefs();
4128   while( (rdef = _register->iter_RegDefs()) != NULL ) {




 145 
 146 // Declare an enumeration of user-defined register classes
 147 // and a list of register masks, one for each class.
 148 void ArchDesc::declare_register_masks(FILE *fp_hpp) {
 149   const char  *rc_name;
 150 
 151   if( _register ) {
 152     // Build enumeration of user-defined register classes.
 153     defineRegClassEnum(fp_hpp, _register);
 154 
 155     // Generate a list of register masks, one for each class.
 156     fprintf(fp_hpp,"\n");
 157     fprintf(fp_hpp,"// Register masks, one for each register class.\n");
 158     _register->_rclasses.reset();
 159     for( rc_name = NULL;
 160          (rc_name = _register->_rclasses.iter()) != NULL; ) {
 161       const char *prefix    = "";
 162       RegClass   *reg_class = _register->getRegClass(rc_name);
 163       assert( reg_class, "Using an undefined register class");
 164 
 165       if (reg_class->_user_defined == NULL) {
 166         fprintf(fp_hpp, "extern const RegMask _%s%s_mask;\n", prefix, toUpper( rc_name ) );
 167         fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ));
 168       } else {
 169         fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, toUpper( rc_name ), reg_class->_user_defined);
 170       }
 171 
 172       if( reg_class->_stack_or_reg ) {
 173         assert(reg_class->_user_defined == NULL, "no user defined reg class here");
 174         fprintf(fp_hpp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );
 175         fprintf(fp_hpp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ) );
 176       }
 177     }
 178   }
 179 }
 180 
 181 // Generate an enumeration of user-defined register classes
 182 // and a list of register masks, one for each class.
 183 void ArchDesc::build_register_masks(FILE *fp_cpp) {
 184   const char  *rc_name;
 185 
 186   if( _register ) {
 187     // Generate a list of register masks, one for each class.
 188     fprintf(fp_cpp,"\n");
 189     fprintf(fp_cpp,"// Register masks, one for each register class.\n");
 190     _register->_rclasses.reset();
 191     for( rc_name = NULL;
 192          (rc_name = _register->_rclasses.iter()) != NULL; ) {
 193       const char *prefix    = "";
 194       RegClass   *reg_class = _register->getRegClass(rc_name);
 195       assert( reg_class, "Using an undefined register class");
 196 
 197       if (reg_class->_user_defined != NULL) continue;
 198 
 199       int len = RegisterForm::RegMask_Size();
 200       fprintf(fp_cpp, "const RegMask _%s%s_mask(", prefix, toUpper( rc_name ) );
 201       { int i;
 202         for( i = 0; i < len-1; i++ )
 203           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,false));
 204         fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,false));
 205       }
 206 
 207       if( reg_class->_stack_or_reg ) {
 208         int i;
 209         fprintf(fp_cpp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
 210         for( i = 0; i < len-1; i++ )
 211           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,true));
 212         fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,true));
 213       }
 214     }
 215   }
 216 }
 217 
 218 // Compute an index for an array in the pipeline_reads_NNN arrays
 219 static int pipeline_reads_initializer(FILE *fp_cpp, NameList &pipeline_reads, PipeClassForm *pipeclass)
 220 {
 221   int templen = 1;
 222   int paramcount = 0;
 223   const char *paramname;
 224 
 225   if (pipeclass->_parameters.count() == 0)
 226     return -1;
 227 
 228   pipeclass->_parameters.reset();
 229   paramname = pipeclass->_parameters.iter();


2681             num_edges);
2682 
2683     // Figure out if all RegMasks are the same.
2684     const char* first_reg_class = oper.in_reg_class(0, globals);
2685     bool all_same = true;
2686     assert(first_reg_class != NULL, "did not find register mask");
2687 
2688     for (uint index = 1; all_same && index < num_edges; index++) {
2689       const char* some_reg_class = oper.in_reg_class(index, globals);
2690       assert(some_reg_class != NULL, "did not find register mask");
2691       if (strcmp(first_reg_class, some_reg_class) != 0) {
2692         all_same = false;
2693       }
2694     }
2695 
2696     if (all_same) {
2697       // Return the sole RegMask.
2698       if (strcmp(first_reg_class, "stack_slots") == 0) {
2699         fprintf(fp,"  return &(Compile::current()->FIRST_STACK_mask());\n");
2700       } else {
2701         fprintf(fp,"  return &%s_mask();\n", toUpper(first_reg_class));
2702       }
2703     } else {
2704       // Build a switch statement to return the desired mask.
2705       fprintf(fp,"  switch (index) {\n");
2706 
2707       for (uint index = 0; index < num_edges; index++) {
2708         const char *reg_class = oper.in_reg_class(index, globals);
2709         assert(reg_class != NULL, "did not find register mask");
2710         if( !strcmp(reg_class, "stack_slots") ) {
2711           fprintf(fp, "  case %d: return &(Compile::current()->FIRST_STACK_mask());\n", index);
2712         } else {
2713           fprintf(fp, "  case %d: return &%s_mask();\n", index, toUpper(reg_class));
2714         }
2715       }
2716       fprintf(fp,"  }\n");
2717       fprintf(fp,"  ShouldNotReachHere();\n");
2718       fprintf(fp,"  return NULL;\n");
2719     }
2720 
2721     // Method close
2722     fprintf(fp, "}\n\n");
2723   }
2724 }
2725 
2726 // generate code to create a clone for a class derived from MachOper
2727 //
2728 // (0)  MachOper  *MachOperXOper::clone(Compile* C) const {
2729 // (1)    return new (C) MachXOper( _ccode, _c0, _c1, ..., _cn);
2730 // (2)  }
2731 //
2732 static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
2733   fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper._ident);


4071   fprintf(fp_cpp,"void Matcher::calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length, bool is_outgoing) {\n");
4072   fprintf(fp_cpp,"%s\n", _frame->_calling_convention);
4073   fprintf(fp_cpp,"}\n\n");
4074   // Native Argument Position
4075   fprintf(fp_cpp,"void Matcher::c_calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length) {\n");
4076   fprintf(fp_cpp,"%s\n", _frame->_c_calling_convention);
4077   fprintf(fp_cpp,"}\n\n");
4078   // Java Return Value Location
4079   fprintf(fp_cpp,"OptoRegPair Matcher::return_value(int ideal_reg, bool is_outgoing) {\n");
4080   fprintf(fp_cpp,"%s\n", _frame->_return_value);
4081   fprintf(fp_cpp,"}\n\n");
4082   // Native Return Value Location
4083   fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(int ideal_reg, bool is_outgoing) {\n");
4084   fprintf(fp_cpp,"%s\n", _frame->_c_return_value);
4085   fprintf(fp_cpp,"}\n\n");
4086 
4087   // Inline Cache Register, mask definition, and encoding
4088   fprintf(fp_cpp,"OptoReg::Name Matcher::inline_cache_reg() {");
4089   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4090           _frame->_inline_cache_reg);


4091   fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
4092   fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
4093 
4094   // Interpreter's Method Oop Register, mask definition, and encoding
4095   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
4096   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4097           _frame->_interpreter_method_oop_reg);


4098   fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
4099   fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
4100 
4101   // Interpreter's Frame Pointer Register, mask definition, and encoding
4102   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {");
4103   if (_frame->_interpreter_frame_pointer_reg == NULL)
4104     fprintf(fp_cpp," return OptoReg::Bad; }\n\n");
4105   else
4106     fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4107             _frame->_interpreter_frame_pointer_reg);





4108 
4109   // Frame Pointer definition
4110   /* CNC - I can not contemplate having a different frame pointer between
4111      Java and native code; makes my head hurt to think about it.
4112   fprintf(fp_cpp,"OptoReg::Name Matcher::frame_pointer() const {");
4113   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4114           _frame->_frame_pointer);
4115   */
4116   // (Native) Frame Pointer definition
4117   fprintf(fp_cpp,"OptoReg::Name Matcher::c_frame_pointer() const {");
4118   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
4119           _frame->_frame_pointer);
4120 
4121   // Number of callee-save + always-save registers for calling convention
4122   fprintf(fp_cpp, "// Number of callee-save + always-save registers\n");
4123   fprintf(fp_cpp, "int  Matcher::number_of_saved_registers() {\n");
4124   RegDef *rdef;
4125   int nof_saved_registers = 0;
4126   _register->reset_RegDefs();
4127   while( (rdef = _register->iter_RegDefs()) != NULL ) {