203 rule->_next = match_parse(instr->_localNames);
204 if (rule->_next) {
205 rule = rule->_next;
206 if( instr->is_ideal_control() ) {
207 parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
208 return;
209 }
210 assert(match_rules_cnt < 100," too many match rule clones");
211 char* buf = (char*) malloc(strlen(instr->_ident) + 4);
212 sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
213 rule->_result = buf;
214 // Check for commutative operations with tree operands.
215 matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
216 }
217 }
218 }
219 else if (!strcmp(ident, "encode")) {
220 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
221 }
222 else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
223 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
224 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
225 else if (!strcmp(ident, "effect")) effect_parse(instr);
226 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
227 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
228 else if (!strcmp(ident, "constraint")) {
229 parse_err(SYNERR, "Instructions do not specify a constraint\n");
230 }
231 else if (!strcmp(ident, "construct")) {
232 parse_err(SYNERR, "Instructions do not specify a construct\n");
233 }
234 else if (!strcmp(ident, "format")) instr->_format = format_parse();
235 else if (!strcmp(ident, "interface")) {
236 parse_err(SYNERR, "Instructions do not specify an interface\n");
237 }
238 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
239 else { // Done with staticly defined parts of instruction definition
240 // Check identifier to see if it is the name of an attribute
241 const Form *form = _globalNames[ident];
242 AttributeForm *attr = form ? form->is_attribute() : NULL;
243 if( attr && (attr->_atype == INS_ATTR) ) {
244 // Insert the new attribute into the linked list.
245 Attribute *temp = attr_parse(ident);
246 temp->_next = instr->_attribs;
247 instr->_attribs = temp;
248 } else {
249 parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident);
250 }
251 }
252 skipws();
253 } while(_curchar != '%');
254 next_char();
255 if (_curchar != '}') {
256 parse_err(SYNERR, "missing '%%}' in instruction definition\n");
257 return;
258 }
259 // Check for "Set" form of chain rule
260 adjust_set_rule(instr);
261 if (_AD._pipeline ) {
262 if( instr->expands() ) {
263 if( instr->_ins_pipe )
264 parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident);
265 } else {
266 if( !instr->_ins_pipe )
267 parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
268 }
269 }
270 // Add instruction to tail of instruction list
271 _AD.addForm(instr);
272
273 // Create instruction form for each additional match rule
274 rule = instr->_matrule;
275 if (rule != NULL) {
276 rule = rule->_next;
277 while (rule != NULL) {
278 ident = (char*)rule->_result;
279 InstructForm *clone = new InstructForm(ident, instr, rule); // Create new instruction form
280 _globalNames.Insert(ident, clone); // Add name to the name table
281 // Debugging Stuff
282 if (_AD._adl_debug > 1)
283 fprintf(stderr,"Parsing Instruction Form %s\n", ident);
284 // Check for "Set" form of chain rule
285 adjust_set_rule(clone);
286 // Add instruction to tail of instruction list
287 _AD.addForm(clone);
288 rule = rule->_next;
289 clone->_matrule->_next = NULL; // One match rule per clone
2840 }
2841
2842 // (2)
2843 // If we are at a replacement variable,
2844 // copy it and record in EncClass
2845 if (_curchar == '$') {
2846 // Found replacement Variable
2847 char* rep_var = get_rep_var_ident_dup();
2848
2849 // Add flag to _strings list indicating we should check _rep_vars
2850 encoding->add_rep_var(rep_var);
2851
2852 skipws();
2853
2854 // Check if this instruct is a MachConstantNode.
2855 if (strcmp(rep_var, "constanttablebase") == 0) {
2856 // This instruct is a MachConstantNode.
2857 inst.set_is_mach_constant(true);
2858
2859 if (_curchar == '(') {
2860 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
2861 return;
2862 }
2863 }
2864 else if ((strcmp(rep_var, "constantaddress") == 0) ||
2865 (strcmp(rep_var, "constantoffset") == 0)) {
2866 // This instruct is a MachConstantNode.
2867 inst.set_is_mach_constant(true);
2868
2869 // If the constant keyword has an argument, parse it.
2870 if (_curchar == '(') constant_parse(inst);
2871 }
2872 }
2873 } // end while part of format description
2874 next_char(); // Skip '%'
2875 next_char(); // Skip '}'
2876
2877 skipws();
2878
2879 if (_AD._adlocation_debug) {
2880 encoding->add_code(end_line_marker());
3033 parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3034 return;
3035 }
3036 next_char(); // move past ';'
3037 skipws(); // be friendly to oper_parse()
3038
3039 // Check for duplicate ins_encode sections after parsing the block
3040 // so that parsing can continue and find any other errors.
3041 if (inst._insencode != NULL) {
3042 parse_err(SYNERR, "Multiple ins_encode sections defined\n");
3043 return;
3044 }
3045
3046 // Debug Stuff
3047 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3048
3049 // Set encode class of this instruction.
3050 inst._insencode = encrule;
3051 }
3052
3053
3054 //------------------------------constant_parse---------------------------------
3055 // Parse a constant expression.
3056 void ADLParser::constant_parse(InstructForm& inst) {
3057 // Create a new encoding name based on the name of the instruction
3058 // definition, which should be unique.
3059 const char* prefix = "__constant_";
3060 char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
3061 sprintf(ec_name, "%s%s", prefix, inst._ident);
3062
3063 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3064 EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3065 encoding->_linenum = linenum();
3066
3067 // synthesize the arguments list for the enc_class from the
3068 // arguments to the instruct definition.
3069 const char* param = NULL;
3070 inst._parameters.reset();
3071 while ((param = inst._parameters.iter()) != NULL) {
3072 OperandForm* opForm = (OperandForm*) inst._localNames[param];
|
203 rule->_next = match_parse(instr->_localNames);
204 if (rule->_next) {
205 rule = rule->_next;
206 if( instr->is_ideal_control() ) {
207 parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
208 return;
209 }
210 assert(match_rules_cnt < 100," too many match rule clones");
211 char* buf = (char*) malloc(strlen(instr->_ident) + 4);
212 sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
213 rule->_result = buf;
214 // Check for commutative operations with tree operands.
215 matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
216 }
217 }
218 }
219 else if (!strcmp(ident, "encode")) {
220 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
221 }
222 else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
223 // Parse late expand keyword.
224 else if (!strcmp(ident, "lateExpand")) lateExpand_parse(*instr);
225 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
226 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
227 else if (!strcmp(ident, "effect")) effect_parse(instr);
228 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
229 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
230 else if (!strcmp(ident, "constraint")) {
231 parse_err(SYNERR, "Instructions do not specify a constraint\n");
232 }
233 else if (!strcmp(ident, "construct")) {
234 parse_err(SYNERR, "Instructions do not specify a construct\n");
235 }
236 else if (!strcmp(ident, "format")) instr->_format = format_parse();
237 else if (!strcmp(ident, "interface")) {
238 parse_err(SYNERR, "Instructions do not specify an interface\n");
239 }
240 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
241 else { // Done with staticly defined parts of instruction definition
242 // Check identifier to see if it is the name of an attribute
243 const Form *form = _globalNames[ident];
244 AttributeForm *attr = form ? form->is_attribute() : NULL;
245 if (attr && (attr->_atype == INS_ATTR)) {
246 // Insert the new attribute into the linked list.
247 Attribute *temp = attr_parse(ident);
248 temp->_next = instr->_attribs;
249 instr->_attribs = temp;
250 } else {
251 parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident);
252 }
253 }
254 skipws();
255 } while(_curchar != '%');
256 next_char();
257 if (_curchar != '}') {
258 parse_err(SYNERR, "missing '%%}' in instruction definition\n");
259 return;
260 }
261 // Check for "Set" form of chain rule
262 adjust_set_rule(instr);
263 if (_AD._pipeline) {
264 // No pipe required for late expand.
265 if (instr->expands() || instr->lateExpands()) {
266 if (instr->_ins_pipe) {
267 parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident);
268 }
269 } else {
270 if (!instr->_ins_pipe) {
271 parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
272 }
273 }
274 }
275 // Add instruction to tail of instruction list
276 _AD.addForm(instr);
277
278 // Create instruction form for each additional match rule
279 rule = instr->_matrule;
280 if (rule != NULL) {
281 rule = rule->_next;
282 while (rule != NULL) {
283 ident = (char*)rule->_result;
284 InstructForm *clone = new InstructForm(ident, instr, rule); // Create new instruction form
285 _globalNames.Insert(ident, clone); // Add name to the name table
286 // Debugging Stuff
287 if (_AD._adl_debug > 1)
288 fprintf(stderr,"Parsing Instruction Form %s\n", ident);
289 // Check for "Set" form of chain rule
290 adjust_set_rule(clone);
291 // Add instruction to tail of instruction list
292 _AD.addForm(clone);
293 rule = rule->_next;
294 clone->_matrule->_next = NULL; // One match rule per clone
2845 }
2846
2847 // (2)
2848 // If we are at a replacement variable,
2849 // copy it and record in EncClass
2850 if (_curchar == '$') {
2851 // Found replacement Variable
2852 char* rep_var = get_rep_var_ident_dup();
2853
2854 // Add flag to _strings list indicating we should check _rep_vars
2855 encoding->add_rep_var(rep_var);
2856
2857 skipws();
2858
2859 // Check if this instruct is a MachConstantNode.
2860 if (strcmp(rep_var, "constanttablebase") == 0) {
2861 // This instruct is a MachConstantNode.
2862 inst.set_is_mach_constant(true);
2863
2864 if (_curchar == '(') {
2865 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
2866 "(only constantaddress and constantoffset)", ec_name);
2867 return;
2868 }
2869 }
2870 else if ((strcmp(rep_var, "constantaddress") == 0) ||
2871 (strcmp(rep_var, "constantoffset") == 0)) {
2872 // This instruct is a MachConstantNode.
2873 inst.set_is_mach_constant(true);
2874
2875 // If the constant keyword has an argument, parse it.
2876 if (_curchar == '(') constant_parse(inst);
2877 }
2878 }
2879 } // end while part of format description
2880 next_char(); // Skip '%'
2881 next_char(); // Skip '}'
2882
2883 skipws();
2884
2885 if (_AD._adlocation_debug) {
2886 encoding->add_code(end_line_marker());
3039 parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3040 return;
3041 }
3042 next_char(); // move past ';'
3043 skipws(); // be friendly to oper_parse()
3044
3045 // Check for duplicate ins_encode sections after parsing the block
3046 // so that parsing can continue and find any other errors.
3047 if (inst._insencode != NULL) {
3048 parse_err(SYNERR, "Multiple ins_encode sections defined\n");
3049 return;
3050 }
3051
3052 // Debug Stuff
3053 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3054
3055 // Set encode class of this instruction.
3056 inst._insencode = encrule;
3057 }
3058
3059 //------------------------------lateExpand_parse-------------------------------
3060 // Encode rules have the form
3061 // lateExpand( encode_class_name(parameter_list) );
3062 //
3063 // The "encode_class_name" must be defined in the encode section.
3064 // The parameter list contains $names that are locals.
3065 //
3066 // This is just a copy of ins_encode_parse without the loop.
3067 void ADLParser::lateExpand_parse(InstructForm& inst) {
3068 inst._is_lateExpand = true;
3069
3070 // Parse encode class name.
3071 skipws(); // Skip whitespace.
3072 if (_curchar != '(') {
3073
3074 parse_err(SYNERR, "missing '(' in lateExpand definition\n");
3075 return;
3076 }
3077 next_char(); // Move past '('.
3078 skipws();
3079
3080 InsEncode *encrule = new InsEncode(); // Encode class for instruction.
3081 encrule->_linenum = linenum();
3082 char *ec_name = NULL; // String representation of encode rule.
3083 // identifier is optional.
3084 if (_curchar != ')') {
3085 ec_name = get_ident();
3086 if (ec_name == NULL) {
3087 parse_err(SYNERR, "Invalid lateExpand class name after 'lateExpand('.\n");
3088 return;
3089 }
3090 // Check that encoding is defined in the encode section.
3091 EncClass *encode_class = _AD._encode->encClass(ec_name);
3092
3093 // Get list for encode method's parameters
3094 NameAndList *params = encrule->add_encode(ec_name);
3095
3096 // Parse the parameters to this encode method.
3097 skipws();
3098 if (_curchar == '(') {
3099 next_char(); // Move past '(' for parameters.
3100
3101 // Parse the encode method's parameters.
3102 while (_curchar != ')') {
3103 char *param = get_ident_or_literal_constant("encoding operand");
3104 if (param != NULL) {
3105 // Found a parameter:
3106
3107 // First check for constant table support.
3108
3109 // Check if this instruct is a MachConstantNode.
3110 if (strcmp(param, "constanttablebase") == 0) {
3111 // This instruct is a MachConstantNode.
3112 inst.set_is_mach_constant(true);
3113
3114 if (_curchar == '(') {
3115 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
3116 "(only constantaddress and constantoffset)", ec_name);
3117 return;
3118 }
3119 }
3120 else if ((strcmp(param, "constantaddress") == 0) ||
3121 (strcmp(param, "constantoffset") == 0)) {
3122 // This instruct is a MachConstantNode.
3123 inst.set_is_mach_constant(true);
3124
3125 // If the constant keyword has an argument, parse it.
3126 if (_curchar == '(') constant_parse(inst);
3127 }
3128
3129 // Else check it is a local name, add it to the list, then check for more.
3130 // New: allow hex constants as parameters to an encode method.
3131 // New: allow parenthesized expressions as parameters.
3132 // New: allow "primary", "secondary", "tertiary" as parameters.
3133 // New: allow user-defined register name as parameter.
3134 else if ((inst._localNames[param] == NULL) &&
3135 !ADLParser::is_literal_constant(param) &&
3136 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
3137 ((_AD._register == NULL) || (_AD._register->getRegDef(param) == NULL))) {
3138 parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
3139 return;
3140 }
3141 params->add_entry(param);
3142
3143 skipws();
3144 if (_curchar == ',') {
3145 // More parameters to come.
3146 next_char(); // Move past ',' between parameters.
3147 skipws(); // Skip to next parameter.
3148 } else if (_curchar == ')') {
3149 // Done with parameter list
3150 } else {
3151 // Only ',' or ')' are valid after a parameter name.
3152 parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name);
3153 return;
3154 }
3155
3156 } else {
3157 skipws();
3158 // Did not find a parameter.
3159 if (_curchar == ',') {
3160 parse_err(SYNERR, "Expected encode parameter before ',' in lateExpand %s.\n", ec_name);
3161 return;
3162 }
3163 if (_curchar != ')') {
3164 parse_err(SYNERR, "Expected ')' after lateExpand parameters.\n");
3165 return;
3166 }
3167 }
3168 } // WHILE loop collecting parameters.
3169 next_char(); // Move past ')' at end of parameters.
3170 } // Done with parameter list for encoding.
3171
3172 // Check for ',' or ')' after encoding.
3173 skipws(); // Move to character after parameters.
3174 if (_curchar != ')') {
3175 // Only a ')' is allowed.
3176 parse_err(SYNERR, "Expected ')' after lateExpand %s.\n", ec_name);
3177 return;
3178 }
3179 } // Done parsing lateExpand method and their parameters.
3180 if (_curchar != ')') {
3181 parse_err(SYNERR, "Missing ')' at end of lateExpand description.\n");
3182 return;
3183 }
3184 next_char(); // Move past ')'.
3185 skipws(); // Skip leading whitespace.
3186
3187 if (_curchar != ';') {
3188 parse_err(SYNERR, "Missing ';' at end of lateExpand.\n");
3189 return;
3190 }
3191 next_char(); // Move past ';'.
3192 skipws(); // Be friendly to oper_parse().
3193
3194 // Debug Stuff.
3195 if (_AD._adl_debug > 1) fprintf(stderr, "Instruction lateExpand: %s\n", ec_name);
3196
3197 // Set encode class of this instruction.
3198 inst._insencode = encrule;
3199 }
3200
3201
3202 //------------------------------constant_parse---------------------------------
3203 // Parse a constant expression.
3204 void ADLParser::constant_parse(InstructForm& inst) {
3205 // Create a new encoding name based on the name of the instruction
3206 // definition, which should be unique.
3207 const char* prefix = "__constant_";
3208 char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
3209 sprintf(ec_name, "%s%s", prefix, inst._ident);
3210
3211 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3212 EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3213 encoding->_linenum = linenum();
3214
3215 // synthesize the arguments list for the enc_class from the
3216 // arguments to the instruct definition.
3217 const char* param = NULL;
3218 inst._parameters.reset();
3219 while ((param = inst._parameters.iter()) != NULL) {
3220 OperandForm* opForm = (OperandForm*) inst._localNames[param];
|