1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)formssel.cpp 1.185 07/09/28 10:23:26 JVM"
3 #endif
4 /*
5 * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
712 return MANY_MEMORY_OPERANDS;
713 }
714 if( is_ideal_load() != Form::none ) {
715 fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
716 ((InstructForm*)this)->dump();
717 // pretend it has multiple uses and no defs
718 return MANY_MEMORY_OPERANDS;
719 }
720 }
721
722 return NO_MEMORY_OPERAND;
723 }
724
725
726 // This instruction captures the machine-independent bottom_type
727 // Expected use is for pointer vs oop determination for LoadP
728 bool InstructForm::captures_bottom_type() const {
729 if( _matrule && _matrule->_rChild &&
730 (!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
731 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
732 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
733 !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
734 else if ( is_ideal_load() == Form::idealP ) return true;
735 else if ( is_ideal_store() != Form::none ) return true;
736
737 return false;
738 }
739
740
741 // Access instr_cost attribute or return NULL.
742 const char* InstructForm::cost() {
743 for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
744 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
745 return cur->_val;
746 }
747 }
748 return NULL;
749 }
750
751 // Return count of top-level operands.
1084 }
1085 else if (captures_bottom_type()) {
1086 return "MachTypeNode";
1087 } else {
1088 return "MachNode";
1089 }
1090 assert( false, "ShouldNotReachHere()");
1091 return NULL;
1092 }
1093
1094 // Compare the instruction predicates for textual equality
1095 bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
1096 const Predicate *pred1 = instr1->_predicate;
1097 const Predicate *pred2 = instr2->_predicate;
1098 if( pred1 == NULL && pred2 == NULL ) {
1099 // no predicates means they are identical
1100 return true;
1101 }
1102 if( pred1 != NULL && pred2 != NULL ) {
1103 // compare the predicates
1104 const char *str1 = pred1->_pred;
1105 const char *str2 = pred2->_pred;
1106 if( (str1 == NULL && str2 == NULL)
1107 || (str1 != NULL && str2 != NULL && strcmp(str1,str2) == 0) ) {
1108 return true;
1109 }
1110 }
1111
1112 return false;
1113 }
1114
1115 // Check if this instruction can cisc-spill to 'alternate'
1116 bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) {
1117 assert( _matrule != NULL && instr->_matrule != NULL, "must have match rules");
1118 // Do not replace if a cisc-version has been found.
1119 if( cisc_spill_operand() != Not_cisc_spillable ) return false;
1120
1121 int cisc_spill_operand = Maybe_cisc_spillable;
1122 char *result = NULL;
1123 char *result2 = NULL;
1124 const char *op_name = NULL;
1125 const char *reg_type = NULL;
1126 FormDict &globals = AD.globalNames();
1127 cisc_spill_operand = _matrule->cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
1556 Opcode::Opcode(char *primary, char *secondary, char *tertiary)
1557 : _primary(primary), _secondary(secondary), _tertiary(tertiary) {
1558 }
1559
1560 Opcode::~Opcode() {
1561 }
1562
1563 Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
1564 if( strcmp(param,"primary") == 0 ) {
1565 return Opcode::PRIMARY;
1566 }
1567 else if( strcmp(param,"secondary") == 0 ) {
1568 return Opcode::SECONDARY;
1569 }
1570 else if( strcmp(param,"tertiary") == 0 ) {
1571 return Opcode::TERTIARY;
1572 }
1573 return Opcode::NOT_AN_OPCODE;
1574 }
1575
1576 void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
1577 // Default values previously provided by MachNode::primary()...
1578 const char *description = "default_opcode()";
1579 const char *value = "-1";
1580 // Check if user provided any opcode definitions
1581 if( this != NULL ) {
1582 // Update 'value' if user provided a definition in the instruction
1583 switch (desired_opcode) {
1584 case PRIMARY:
1585 description = "primary()";
1586 if( _primary != NULL) { value = _primary; }
1587 break;
1588 case SECONDARY:
1589 description = "secondary()";
1590 if( _secondary != NULL ) { value = _secondary; }
1591 break;
1592 case TERTIARY:
1593 description = "tertiary()";
1594 if( _tertiary != NULL ) { value = _tertiary; }
1595 break;
1596 default:
1597 assert( false, "ShouldNotReachHere();");
1598 break;
1599 }
1600 }
1601 fprintf(fp, "(%s /*%s*/)", value, description);
1602 }
1603
1604 void Opcode::dump() {
1605 output(stderr);
1606 }
1607
1608 // Write info to output files
1609 void Opcode::output(FILE *fp) {
1610 if (_primary != NULL) fprintf(fp,"Primary opcode: %s\n", _primary);
1611 if (_secondary != NULL) fprintf(fp,"Secondary opcode: %s\n", _secondary);
1612 if (_tertiary != NULL) fprintf(fp,"Tertiary opcode: %s\n", _tertiary);
1613 }
1614
1615 //------------------------------InsEncode--------------------------------------
1616 InsEncode::InsEncode() {
1617 }
1618 InsEncode::~InsEncode() {
1619 }
1620
1621 // Add "encode class name" and its parameters
2087
2088 RegClass* OperandForm::get_RegClass() const {
2089 if (_interface && !_interface->is_RegInterface()) return NULL;
2090 return globalAD->get_registers()->getRegClass(constrained_reg_class());
2091 }
2092
2093
2094 bool OperandForm::is_bound_register() const {
2095 RegClass *reg_class = get_RegClass();
2096 if (reg_class == NULL) return false;
2097
2098 const char * name = ideal_type(globalAD->globalNames());
2099 if (name == NULL) return false;
2100
2101 int size = 0;
2102 if (strcmp(name,"RegFlags")==0) size = 1;
2103 if (strcmp(name,"RegI")==0) size = 1;
2104 if (strcmp(name,"RegF")==0) size = 1;
2105 if (strcmp(name,"RegD")==0) size = 2;
2106 if (strcmp(name,"RegL")==0) size = 2;
2107 if (strcmp(name,"RegP")==0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
2108 if (size == 0) return false;
2109 return size == reg_class->size();
2110 }
2111
2112
2113 // Check if this is a valid field for this operand,
2114 // Return 'true' if valid, and set the value to the string the user provided.
2115 bool OperandForm::is_interface_field(const char *field,
2116 const char * &value) const {
2117 return false;
2118 }
2119
2120
2121 // Return register class name if a constraint specifies the register class.
2122 const char *OperandForm::constrained_reg_class() const {
2123 const char *reg_class = NULL;
2124 if ( _constraint ) {
2125 // !!!!!
2126 Constraint *constraint = _constraint;
2353 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
2354 format_constant( fp, index, dtype );
2355 } else if (ideal_to_sReg_type(_ident) != Form::none) {
2356 // Special format for Stack Slot Register
2357 fprintf(fp, "{ char reg_str[128];\n");
2358 fprintf(fp," ra->dump_register(node->in(idx");
2359 if ( index != 0 ) fprintf(fp, "+%d",index);
2360 fprintf(fp, "),reg_str);\n");
2361 fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
2362 fprintf(fp," }\n");
2363 } else {
2364 fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
2365 assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant");
2366 }
2367 }
2368
2369 void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
2370 switch(const_type) {
2371 case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break;
2372 case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break;
2373 case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break;
2374 case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
2375 case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
2376 default:
2377 assert( false, "ShouldNotReachHere()");
2378 }
2379 }
2380
2381 // Return the operand form corresponding to the given index, else NULL.
2382 OperandForm *OperandForm::constant_operand(FormDict &globals,
2383 uint index) {
2384 // !!!!!
2385 // Check behavior on complex operands
2386 uint n_consts = num_consts(globals);
2387 if( n_consts > 0 ) {
2388 uint i = 0;
2389 const char *type;
2390 Component *comp;
2391 _components.reset();
2392 if ((comp = _components.iter()) == NULL) {
2590 }
2591 MemInterface::~MemInterface() {
2592 // not owner of any character arrays
2593 }
2594
2595 void MemInterface::dump() {
2596 output(stderr);
2597 }
2598
2599 // Write info to output files
2600 void MemInterface::output(FILE *fp) {
2601 Interface::output(fp);
2602 if ( _base != NULL ) fprintf(fp," base == %s\n", _base);
2603 if ( _index != NULL ) fprintf(fp," index == %s\n", _index);
2604 if ( _scale != NULL ) fprintf(fp," scale == %s\n", _scale);
2605 if ( _disp != NULL ) fprintf(fp," disp == %s\n", _disp);
2606 // fprintf(fp,"\n");
2607 }
2608
2609 //------------------------------CondInterface----------------------------------
2610 CondInterface::CondInterface(char *equal, char *not_equal,
2611 char *less, char *greater_equal,
2612 char *less_equal, char *greater)
2613 : Interface("COND_INTER"),
2614 _equal(equal), _not_equal(not_equal),
2615 _less(less), _greater_equal(greater_equal),
2616 _less_equal(less_equal), _greater(greater) {
2617 //
2618 }
2619 CondInterface::~CondInterface() {
2620 // not owner of any character arrays
2621 }
2622
2623 void CondInterface::dump() {
2624 output(stderr);
2625 }
2626
2627 // Write info to output files
2628 void CondInterface::output(FILE *fp) {
2629 Interface::output(fp);
2630 if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal);
2631 if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal);
2632 if ( _less != NULL ) fprintf(fp," less == %s\n", _less);
2633 if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);
2634 if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);
2635 if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);
2636 // fprintf(fp,"\n");
2637 }
3286
3287
3288 void MatchNode::dump() {
3289 output(stderr);
3290 }
3291
3292 void MatchNode::output(FILE *fp) {
3293 if (_lChild==0 && _rChild==0) {
3294 fprintf(fp," %s",_name); // operand
3295 }
3296 else {
3297 fprintf(fp," (%s ",_name); // " (opcodeName "
3298 if(_lChild) _lChild->output(fp); // left operand
3299 if(_rChild) _rChild->output(fp); // right operand
3300 fprintf(fp,")"); // ")"
3301 }
3302 }
3303
3304 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3305 static const char *needs_ideal_memory_list[] = {
3306 "StoreI","StoreL","StoreP","StoreD","StoreF" ,
3307 "StoreB","StoreC","Store" ,"StoreFP",
3308 "LoadI" ,"LoadL", "LoadP" ,"LoadD" ,"LoadF" ,
3309 "LoadB" ,"LoadC" ,"LoadS" ,"Load" ,
3310 "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
3311 "Store8B","Store4B","Store8C","Store4C","Store2C",
3312 "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
3313 "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
3314 "LoadRange", "LoadKlass", "LoadL_unaligned", "LoadD_unaligned",
3315 "LoadPLocked", "LoadLLocked",
3316 "StorePConditional", "StoreLConditional",
3317 "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP",
3318 "StoreCM",
3319 "ClearArray"
3320 };
3321 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3322 if( strcmp(_opType,"PrefetchRead")==0 || strcmp(_opType,"PrefetchWrite")==0 )
3323 return 1;
3324 if( _lChild ) {
3325 const char *opType = _lChild->_opType;
3326 for( int i=0; i<cnt; i++ )
3327 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3328 return 1;
3329 if( _lChild->needs_ideal_memory_edge(globals) )
3330 return 1;
3331 }
3332 if( _rChild ) {
3333 const char *opType = _rChild->_opType;
3334 for( int i=0; i<cnt; i++ )
3335 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3336 return 1;
3337 if( _rChild->needs_ideal_memory_edge(globals) )
3698 // The MatchNode that is called first treats its
3699 bool MatchRule::base_operand(uint &position0, FormDict &globals,
3700 const char *&result, const char * &name,
3701 const char * &opType)const{
3702 uint position = position0;
3703
3704 return (MatchNode::base_operand( position, globals, result, name, opType));
3705 }
3706
3707
3708 bool MatchRule::is_base_register(FormDict &globals) const {
3709 uint position = 1;
3710 const char *result = NULL;
3711 const char *name = NULL;
3712 const char *opType = NULL;
3713 if (!base_operand(position, globals, result, name, opType)) {
3714 position = 0;
3715 if( base_operand(position, globals, result, name, opType) &&
3716 (strcmp(opType,"RegI")==0 ||
3717 strcmp(opType,"RegP")==0 ||
3718 strcmp(opType,"RegL")==0 ||
3719 strcmp(opType,"RegF")==0 ||
3720 strcmp(opType,"RegD")==0 ||
3721 strcmp(opType,"Reg" )==0) ) {
3722 return 1;
3723 }
3724 }
3725 return 0;
3726 }
3727
3728 Form::DataType MatchRule::is_base_constant(FormDict &globals) const {
3729 uint position = 1;
3730 const char *result = NULL;
3731 const char *name = NULL;
3732 const char *opType = NULL;
3733 if (!base_operand(position, globals, result, name, opType)) {
3734 position = 0;
3735 if (base_operand(position, globals, result, name, opType)) {
3736 return ideal_to_const_type(opType);
3737 }
3747 // If this is ideal, then it is a base match, not a chain rule.
3748 if ( form && form->is_operand() && (!form->ideal_only())) {
3749 return true;
3750 }
3751 }
3752 // Check for "Set" form of chain rule, and do not generate a match list
3753 if (_rChild) {
3754 const char *rch = _rChild->_opType;
3755 const Form *form = globals[rch];
3756 if ((!strcmp(_opType,"Set") &&
3757 ((form) && form->is_operand()))) {
3758 return true;
3759 }
3760 }
3761 return false;
3762 }
3763
3764 int MatchRule::is_ideal_copy() const {
3765 if( _rChild ) {
3766 const char *opType = _rChild->_opType;
3767 if( strcmp(opType,"CastII")==0 )
3768 return 1;
3769 // Do not treat *CastPP this way, because it
3770 // may transfer a raw pointer to an oop.
3771 // If the register allocator were to coalesce this
3772 // into a single LRG, the GC maps would be incorrect.
3773 //if( strcmp(opType,"CastPP")==0 )
3774 // return 1;
3775 //if( strcmp(opType,"CheckCastPP")==0 )
3776 // return 1;
3777 //
3778 // Do not treat CastX2P or CastP2X this way, because
3779 // raw pointers and int types are treated differently
3780 // when saving local & stack info for safepoints in
3781 // Output().
3782 //if( strcmp(opType,"CastX2P")==0 )
3783 // return 1;
3784 //if( strcmp(opType,"CastP2X")==0 )
3785 // return 1;
3786 }
3787 if( is_chain_rule(_AD.globalNames()) &&
3788 _lChild && strncmp(_lChild->_opType,"stackSlot",9)==0 )
3789 return 1;
3790 return 0;
3791 }
3792
3793
3794 int MatchRule::is_expensive() const {
3795 if( _rChild ) {
3796 const char *opType = _rChild->_opType;
3797 if( strcmp(opType,"AtanD")==0 ||
3798 strcmp(opType,"CosD")==0 ||
3799 strcmp(opType,"DivD")==0 ||
3800 strcmp(opType,"DivF")==0 ||
3801 strcmp(opType,"DivI")==0 ||
3802 strcmp(opType,"ExpD")==0 ||
3803 strcmp(opType,"LogD")==0 ||
3804 strcmp(opType,"Log10D")==0 ||
3805 strcmp(opType,"ModD")==0 ||
3806 strcmp(opType,"ModF")==0 ||
3807 strcmp(opType,"ModI")==0 ||
3808 strcmp(opType,"PowD")==0 ||
3809 strcmp(opType,"SinD")==0 ||
3810 strcmp(opType,"SqrtD")==0 ||
3811 strcmp(opType,"TanD")==0 ||
3812 strcmp(opType,"ConvD2F")==0 ||
3813 strcmp(opType,"ConvD2I")==0 ||
3814 strcmp(opType,"ConvD2L")==0 ||
3815 strcmp(opType,"ConvF2D")==0 ||
3816 strcmp(opType,"ConvF2I")==0 ||
3817 strcmp(opType,"ConvF2L")==0 ||
3818 strcmp(opType,"ConvI2D")==0 ||
3819 strcmp(opType,"ConvI2F")==0 ||
3820 strcmp(opType,"ConvI2L")==0 ||
3821 strcmp(opType,"ConvL2D")==0 ||
3822 strcmp(opType,"ConvL2F")==0 ||
3823 strcmp(opType,"ConvL2I")==0 ||
3824 strcmp(opType,"RoundDouble")==0 ||
3825 strcmp(opType,"RoundFloat")==0 ||
3826 strcmp(opType,"ReverseBytesI")==0 ||
3827 strcmp(opType,"ReverseBytesL")==0 ||
3828 strcmp(opType,"Replicate16B")==0 ||
3829 strcmp(opType,"Replicate8B")==0 ||
3830 strcmp(opType,"Replicate4B")==0 ||
3831 strcmp(opType,"Replicate8C")==0 ||
3832 strcmp(opType,"Replicate4C")==0 ||
3833 strcmp(opType,"Replicate8S")==0 ||
3834 strcmp(opType,"Replicate4S")==0 ||
3835 strcmp(opType,"Replicate4I")==0 ||
3836 strcmp(opType,"Replicate2I")==0 ||
3837 strcmp(opType,"Replicate2L")==0 ||
3838 strcmp(opType,"Replicate4F")==0 ||
3839 strcmp(opType,"Replicate2F")==0 ||
3840 strcmp(opType,"Replicate2D")==0 ||
3841 0 /* 0 to line up columns nicely */ )
3842 return 1;
3843 }
|
1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)formssel.cpp 1.185 07/09/28 10:23:26 JVM"
3 #endif
4 /*
5 * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
712 return MANY_MEMORY_OPERANDS;
713 }
714 if( is_ideal_load() != Form::none ) {
715 fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
716 ((InstructForm*)this)->dump();
717 // pretend it has multiple uses and no defs
718 return MANY_MEMORY_OPERANDS;
719 }
720 }
721
722 return NO_MEMORY_OPERAND;
723 }
724
725
726 // This instruction captures the machine-independent bottom_type
727 // Expected use is for pointer vs oop determination for LoadP
728 bool InstructForm::captures_bottom_type() const {
729 if( _matrule && _matrule->_rChild &&
730 (!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
731 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
732 !strcmp(_matrule->_rChild->_opType,"DecodeN") ||
733 !strcmp(_matrule->_rChild->_opType,"EncodeP") ||
734 !strcmp(_matrule->_rChild->_opType,"LoadN") ||
735 !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
736 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
737 !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
738 else if ( is_ideal_load() == Form::idealP ) return true;
739 else if ( is_ideal_store() != Form::none ) return true;
740
741 return false;
742 }
743
744
745 // Access instr_cost attribute or return NULL.
746 const char* InstructForm::cost() {
747 for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
748 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
749 return cur->_val;
750 }
751 }
752 return NULL;
753 }
754
755 // Return count of top-level operands.
1088 }
1089 else if (captures_bottom_type()) {
1090 return "MachTypeNode";
1091 } else {
1092 return "MachNode";
1093 }
1094 assert( false, "ShouldNotReachHere()");
1095 return NULL;
1096 }
1097
1098 // Compare the instruction predicates for textual equality
1099 bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
1100 const Predicate *pred1 = instr1->_predicate;
1101 const Predicate *pred2 = instr2->_predicate;
1102 if( pred1 == NULL && pred2 == NULL ) {
1103 // no predicates means they are identical
1104 return true;
1105 }
1106 if( pred1 != NULL && pred2 != NULL ) {
1107 // compare the predicates
1108 if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) {
1109 return true;
1110 }
1111 }
1112
1113 return false;
1114 }
1115
1116 // Check if this instruction can cisc-spill to 'alternate'
1117 bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) {
1118 assert( _matrule != NULL && instr->_matrule != NULL, "must have match rules");
1119 // Do not replace if a cisc-version has been found.
1120 if( cisc_spill_operand() != Not_cisc_spillable ) return false;
1121
1122 int cisc_spill_operand = Maybe_cisc_spillable;
1123 char *result = NULL;
1124 char *result2 = NULL;
1125 const char *op_name = NULL;
1126 const char *reg_type = NULL;
1127 FormDict &globals = AD.globalNames();
1128 cisc_spill_operand = _matrule->cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
1557 Opcode::Opcode(char *primary, char *secondary, char *tertiary)
1558 : _primary(primary), _secondary(secondary), _tertiary(tertiary) {
1559 }
1560
1561 Opcode::~Opcode() {
1562 }
1563
1564 Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
1565 if( strcmp(param,"primary") == 0 ) {
1566 return Opcode::PRIMARY;
1567 }
1568 else if( strcmp(param,"secondary") == 0 ) {
1569 return Opcode::SECONDARY;
1570 }
1571 else if( strcmp(param,"tertiary") == 0 ) {
1572 return Opcode::TERTIARY;
1573 }
1574 return Opcode::NOT_AN_OPCODE;
1575 }
1576
1577 bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
1578 // Default values previously provided by MachNode::primary()...
1579 const char *description = NULL;
1580 const char *value = NULL;
1581 // Check if user provided any opcode definitions
1582 if( this != NULL ) {
1583 // Update 'value' if user provided a definition in the instruction
1584 switch (desired_opcode) {
1585 case PRIMARY:
1586 description = "primary()";
1587 if( _primary != NULL) { value = _primary; }
1588 break;
1589 case SECONDARY:
1590 description = "secondary()";
1591 if( _secondary != NULL ) { value = _secondary; }
1592 break;
1593 case TERTIARY:
1594 description = "tertiary()";
1595 if( _tertiary != NULL ) { value = _tertiary; }
1596 break;
1597 default:
1598 assert( false, "ShouldNotReachHere();");
1599 break;
1600 }
1601 }
1602 if (value != NULL) {
1603 fprintf(fp, "(%s /*%s*/)", value, description);
1604 }
1605 return value != NULL;
1606 }
1607
1608 void Opcode::dump() {
1609 output(stderr);
1610 }
1611
1612 // Write info to output files
1613 void Opcode::output(FILE *fp) {
1614 if (_primary != NULL) fprintf(fp,"Primary opcode: %s\n", _primary);
1615 if (_secondary != NULL) fprintf(fp,"Secondary opcode: %s\n", _secondary);
1616 if (_tertiary != NULL) fprintf(fp,"Tertiary opcode: %s\n", _tertiary);
1617 }
1618
1619 //------------------------------InsEncode--------------------------------------
1620 InsEncode::InsEncode() {
1621 }
1622 InsEncode::~InsEncode() {
1623 }
1624
1625 // Add "encode class name" and its parameters
2091
2092 RegClass* OperandForm::get_RegClass() const {
2093 if (_interface && !_interface->is_RegInterface()) return NULL;
2094 return globalAD->get_registers()->getRegClass(constrained_reg_class());
2095 }
2096
2097
2098 bool OperandForm::is_bound_register() const {
2099 RegClass *reg_class = get_RegClass();
2100 if (reg_class == NULL) return false;
2101
2102 const char * name = ideal_type(globalAD->globalNames());
2103 if (name == NULL) return false;
2104
2105 int size = 0;
2106 if (strcmp(name,"RegFlags")==0) size = 1;
2107 if (strcmp(name,"RegI")==0) size = 1;
2108 if (strcmp(name,"RegF")==0) size = 1;
2109 if (strcmp(name,"RegD")==0) size = 2;
2110 if (strcmp(name,"RegL")==0) size = 2;
2111 if (strcmp(name,"RegN")==0) size = 1;
2112 if (strcmp(name,"RegP")==0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
2113 if (size == 0) return false;
2114 return size == reg_class->size();
2115 }
2116
2117
2118 // Check if this is a valid field for this operand,
2119 // Return 'true' if valid, and set the value to the string the user provided.
2120 bool OperandForm::is_interface_field(const char *field,
2121 const char * &value) const {
2122 return false;
2123 }
2124
2125
2126 // Return register class name if a constraint specifies the register class.
2127 const char *OperandForm::constrained_reg_class() const {
2128 const char *reg_class = NULL;
2129 if ( _constraint ) {
2130 // !!!!!
2131 Constraint *constraint = _constraint;
2358 } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
2359 format_constant( fp, index, dtype );
2360 } else if (ideal_to_sReg_type(_ident) != Form::none) {
2361 // Special format for Stack Slot Register
2362 fprintf(fp, "{ char reg_str[128];\n");
2363 fprintf(fp," ra->dump_register(node->in(idx");
2364 if ( index != 0 ) fprintf(fp, "+%d",index);
2365 fprintf(fp, "),reg_str);\n");
2366 fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
2367 fprintf(fp," }\n");
2368 } else {
2369 fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
2370 assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant");
2371 }
2372 }
2373
2374 void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
2375 switch(const_type) {
2376 case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break;
2377 case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break;
2378 case Form::idealN: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break;
2379 case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break;
2380 case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
2381 case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
2382 default:
2383 assert( false, "ShouldNotReachHere()");
2384 }
2385 }
2386
2387 // Return the operand form corresponding to the given index, else NULL.
2388 OperandForm *OperandForm::constant_operand(FormDict &globals,
2389 uint index) {
2390 // !!!!!
2391 // Check behavior on complex operands
2392 uint n_consts = num_consts(globals);
2393 if( n_consts > 0 ) {
2394 uint i = 0;
2395 const char *type;
2396 Component *comp;
2397 _components.reset();
2398 if ((comp = _components.iter()) == NULL) {
2596 }
2597 MemInterface::~MemInterface() {
2598 // not owner of any character arrays
2599 }
2600
2601 void MemInterface::dump() {
2602 output(stderr);
2603 }
2604
2605 // Write info to output files
2606 void MemInterface::output(FILE *fp) {
2607 Interface::output(fp);
2608 if ( _base != NULL ) fprintf(fp," base == %s\n", _base);
2609 if ( _index != NULL ) fprintf(fp," index == %s\n", _index);
2610 if ( _scale != NULL ) fprintf(fp," scale == %s\n", _scale);
2611 if ( _disp != NULL ) fprintf(fp," disp == %s\n", _disp);
2612 // fprintf(fp,"\n");
2613 }
2614
2615 //------------------------------CondInterface----------------------------------
2616 CondInterface::CondInterface(const char* equal, const char* equal_format,
2617 const char* not_equal, const char* not_equal_format,
2618 const char* less, const char* less_format,
2619 const char* greater_equal, const char* greater_equal_format,
2620 const char* less_equal, const char* less_equal_format,
2621 const char* greater, const char* greater_format)
2622 : Interface("COND_INTER"),
2623 _equal(equal), _equal_format(equal_format),
2624 _not_equal(not_equal), _not_equal_format(not_equal_format),
2625 _less(less), _less_format(less_format),
2626 _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
2627 _less_equal(less_equal), _less_equal_format(less_equal_format),
2628 _greater(greater), _greater_format(greater_format) {
2629 }
2630 CondInterface::~CondInterface() {
2631 // not owner of any character arrays
2632 }
2633
2634 void CondInterface::dump() {
2635 output(stderr);
2636 }
2637
2638 // Write info to output files
2639 void CondInterface::output(FILE *fp) {
2640 Interface::output(fp);
2641 if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal);
2642 if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal);
2643 if ( _less != NULL ) fprintf(fp," less == %s\n", _less);
2644 if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);
2645 if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);
2646 if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);
2647 // fprintf(fp,"\n");
2648 }
3297
3298
3299 void MatchNode::dump() {
3300 output(stderr);
3301 }
3302
3303 void MatchNode::output(FILE *fp) {
3304 if (_lChild==0 && _rChild==0) {
3305 fprintf(fp," %s",_name); // operand
3306 }
3307 else {
3308 fprintf(fp," (%s ",_name); // " (opcodeName "
3309 if(_lChild) _lChild->output(fp); // left operand
3310 if(_rChild) _rChild->output(fp); // right operand
3311 fprintf(fp,")"); // ")"
3312 }
3313 }
3314
3315 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3316 static const char *needs_ideal_memory_list[] = {
3317 "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
3318 "StoreB","StoreC","Store" ,"StoreFP",
3319 "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
3320 "LoadB" ,"LoadC" ,"LoadS" ,"Load" ,
3321 "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
3322 "Store8B","Store4B","Store8C","Store4C","Store2C",
3323 "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
3324 "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
3325 "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3326 "LoadPLocked", "LoadLLocked",
3327 "StorePConditional", "StoreIConditional", "StoreLConditional",
3328 "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3329 "StoreCM",
3330 "ClearArray"
3331 };
3332 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3333 if( strcmp(_opType,"PrefetchRead")==0 || strcmp(_opType,"PrefetchWrite")==0 )
3334 return 1;
3335 if( _lChild ) {
3336 const char *opType = _lChild->_opType;
3337 for( int i=0; i<cnt; i++ )
3338 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3339 return 1;
3340 if( _lChild->needs_ideal_memory_edge(globals) )
3341 return 1;
3342 }
3343 if( _rChild ) {
3344 const char *opType = _rChild->_opType;
3345 for( int i=0; i<cnt; i++ )
3346 if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3347 return 1;
3348 if( _rChild->needs_ideal_memory_edge(globals) )
3709 // The MatchNode that is called first treats its
3710 bool MatchRule::base_operand(uint &position0, FormDict &globals,
3711 const char *&result, const char * &name,
3712 const char * &opType)const{
3713 uint position = position0;
3714
3715 return (MatchNode::base_operand( position, globals, result, name, opType));
3716 }
3717
3718
3719 bool MatchRule::is_base_register(FormDict &globals) const {
3720 uint position = 1;
3721 const char *result = NULL;
3722 const char *name = NULL;
3723 const char *opType = NULL;
3724 if (!base_operand(position, globals, result, name, opType)) {
3725 position = 0;
3726 if( base_operand(position, globals, result, name, opType) &&
3727 (strcmp(opType,"RegI")==0 ||
3728 strcmp(opType,"RegP")==0 ||
3729 strcmp(opType,"RegN")==0 ||
3730 strcmp(opType,"RegL")==0 ||
3731 strcmp(opType,"RegF")==0 ||
3732 strcmp(opType,"RegD")==0 ||
3733 strcmp(opType,"Reg" )==0) ) {
3734 return 1;
3735 }
3736 }
3737 return 0;
3738 }
3739
3740 Form::DataType MatchRule::is_base_constant(FormDict &globals) const {
3741 uint position = 1;
3742 const char *result = NULL;
3743 const char *name = NULL;
3744 const char *opType = NULL;
3745 if (!base_operand(position, globals, result, name, opType)) {
3746 position = 0;
3747 if (base_operand(position, globals, result, name, opType)) {
3748 return ideal_to_const_type(opType);
3749 }
3759 // If this is ideal, then it is a base match, not a chain rule.
3760 if ( form && form->is_operand() && (!form->ideal_only())) {
3761 return true;
3762 }
3763 }
3764 // Check for "Set" form of chain rule, and do not generate a match list
3765 if (_rChild) {
3766 const char *rch = _rChild->_opType;
3767 const Form *form = globals[rch];
3768 if ((!strcmp(_opType,"Set") &&
3769 ((form) && form->is_operand()))) {
3770 return true;
3771 }
3772 }
3773 return false;
3774 }
3775
3776 int MatchRule::is_ideal_copy() const {
3777 if( _rChild ) {
3778 const char *opType = _rChild->_opType;
3779 #if 1
3780 if( strcmp(opType,"CastIP")==0 )
3781 return 1;
3782 #else
3783 if( strcmp(opType,"CastII")==0 )
3784 return 1;
3785 // Do not treat *CastPP this way, because it
3786 // may transfer a raw pointer to an oop.
3787 // If the register allocator were to coalesce this
3788 // into a single LRG, the GC maps would be incorrect.
3789 //if( strcmp(opType,"CastPP")==0 )
3790 // return 1;
3791 //if( strcmp(opType,"CheckCastPP")==0 )
3792 // return 1;
3793 //
3794 // Do not treat CastX2P or CastP2X this way, because
3795 // raw pointers and int types are treated differently
3796 // when saving local & stack info for safepoints in
3797 // Output().
3798 //if( strcmp(opType,"CastX2P")==0 )
3799 // return 1;
3800 //if( strcmp(opType,"CastP2X")==0 )
3801 // return 1;
3802 #endif
3803 }
3804 if( is_chain_rule(_AD.globalNames()) &&
3805 _lChild && strncmp(_lChild->_opType,"stackSlot",9)==0 )
3806 return 1;
3807 return 0;
3808 }
3809
3810
3811 int MatchRule::is_expensive() const {
3812 if( _rChild ) {
3813 const char *opType = _rChild->_opType;
3814 if( strcmp(opType,"AtanD")==0 ||
3815 strcmp(opType,"CosD")==0 ||
3816 strcmp(opType,"DivD")==0 ||
3817 strcmp(opType,"DivF")==0 ||
3818 strcmp(opType,"DivI")==0 ||
3819 strcmp(opType,"ExpD")==0 ||
3820 strcmp(opType,"LogD")==0 ||
3821 strcmp(opType,"Log10D")==0 ||
3822 strcmp(opType,"ModD")==0 ||
3823 strcmp(opType,"ModF")==0 ||
3824 strcmp(opType,"ModI")==0 ||
3825 strcmp(opType,"PowD")==0 ||
3826 strcmp(opType,"SinD")==0 ||
3827 strcmp(opType,"SqrtD")==0 ||
3828 strcmp(opType,"TanD")==0 ||
3829 strcmp(opType,"ConvD2F")==0 ||
3830 strcmp(opType,"ConvD2I")==0 ||
3831 strcmp(opType,"ConvD2L")==0 ||
3832 strcmp(opType,"ConvF2D")==0 ||
3833 strcmp(opType,"ConvF2I")==0 ||
3834 strcmp(opType,"ConvF2L")==0 ||
3835 strcmp(opType,"ConvI2D")==0 ||
3836 strcmp(opType,"ConvI2F")==0 ||
3837 strcmp(opType,"ConvI2L")==0 ||
3838 strcmp(opType,"ConvL2D")==0 ||
3839 strcmp(opType,"ConvL2F")==0 ||
3840 strcmp(opType,"ConvL2I")==0 ||
3841 strcmp(opType,"DecodeN")==0 ||
3842 strcmp(opType,"EncodeP")==0 ||
3843 strcmp(opType,"RoundDouble")==0 ||
3844 strcmp(opType,"RoundFloat")==0 ||
3845 strcmp(opType,"ReverseBytesI")==0 ||
3846 strcmp(opType,"ReverseBytesL")==0 ||
3847 strcmp(opType,"Replicate16B")==0 ||
3848 strcmp(opType,"Replicate8B")==0 ||
3849 strcmp(opType,"Replicate4B")==0 ||
3850 strcmp(opType,"Replicate8C")==0 ||
3851 strcmp(opType,"Replicate4C")==0 ||
3852 strcmp(opType,"Replicate8S")==0 ||
3853 strcmp(opType,"Replicate4S")==0 ||
3854 strcmp(opType,"Replicate4I")==0 ||
3855 strcmp(opType,"Replicate2I")==0 ||
3856 strcmp(opType,"Replicate2L")==0 ||
3857 strcmp(opType,"Replicate4F")==0 ||
3858 strcmp(opType,"Replicate2F")==0 ||
3859 strcmp(opType,"Replicate2D")==0 ||
3860 0 /* 0 to line up columns nicely */ )
3861 return 1;
3862 }
|