Mercurial > hg > graal-compiler
comparison src/share/vm/adlc/adlparse.cpp @ 2008:2f644f85485d
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: never, kvn
author | twisti |
---|---|
date | Fri, 03 Dec 2010 01:34:31 -0800 |
parents | f95d63e2154a |
children | fe240d87c6ec |
comparison
equal
deleted
inserted
replaced
2007:5ddfcf4b079e | 2008:2f644f85485d |
---|---|
93 skipws(); // Skip any leading whitespace | 93 skipws(); // Skip any leading whitespace |
94 ident = get_ident(); // Get first token | 94 ident = get_ident(); // Get first token |
95 if (ident == NULL) { // Empty line | 95 if (ident == NULL) { // Empty line |
96 continue; // Get the next line | 96 continue; // Get the next line |
97 } | 97 } |
98 if (!strcmp(ident, "instruct")) instr_parse(); | 98 if (!strcmp(ident, "instruct")) instr_parse(); |
99 else if (!strcmp(ident, "operand")) oper_parse(); | 99 else if (!strcmp(ident, "operand")) oper_parse(); |
100 else if (!strcmp(ident, "opclass")) opclass_parse(); | 100 else if (!strcmp(ident, "opclass")) opclass_parse(); |
101 else if (!strcmp(ident, "ins_attrib")) ins_attr_parse(); | 101 else if (!strcmp(ident, "ins_attrib")) ins_attr_parse(); |
102 else if (!strcmp(ident, "op_attrib")) op_attr_parse(); | 102 else if (!strcmp(ident, "op_attrib")) op_attr_parse(); |
103 else if (!strcmp(ident, "source")) source_parse(); | 103 else if (!strcmp(ident, "source")) source_parse(); |
214 } | 214 } |
215 } | 215 } |
216 else if (!strcmp(ident, "encode")) { | 216 else if (!strcmp(ident, "encode")) { |
217 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); | 217 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); |
218 } | 218 } |
219 else if (!strcmp(ident, "ins_encode")) | 219 else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); |
220 instr->_insencode = ins_encode_parse(*instr); | 220 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); |
221 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); | 221 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); |
222 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); | 222 else if (!strcmp(ident, "effect")) effect_parse(instr); |
223 else if (!strcmp(ident, "effect")) effect_parse(instr); | 223 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); |
224 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); | 224 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); |
225 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); | |
226 else if (!strcmp(ident, "constraint")) { | 225 else if (!strcmp(ident, "constraint")) { |
227 parse_err(SYNERR, "Instructions do not specify a constraint\n"); | 226 parse_err(SYNERR, "Instructions do not specify a constraint\n"); |
228 } | 227 } |
229 else if (!strcmp(ident, "construct")) { | 228 else if (!strcmp(ident, "construct")) { |
230 parse_err(SYNERR, "Instructions do not specify a construct\n"); | 229 parse_err(SYNERR, "Instructions do not specify a construct\n"); |
231 } | 230 } |
232 else if (!strcmp(ident, "format")) instr->_format = format_parse(); | 231 else if (!strcmp(ident, "format")) instr->_format = format_parse(); |
233 else if (!strcmp(ident, "interface")) { | 232 else if (!strcmp(ident, "interface")) { |
234 parse_err(SYNERR, "Instructions do not specify an interface\n"); | 233 parse_err(SYNERR, "Instructions do not specify an interface\n"); |
235 } | 234 } |
236 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr); | 235 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr); |
237 else { // Done with staticly defined parts of instruction definition | 236 else { // Done with staticly defined parts of instruction definition |
238 // Check identifier to see if it is the name of an attribute | 237 // Check identifier to see if it is the name of an attribute |
239 const Form *form = _globalNames[ident]; | 238 const Form *form = _globalNames[ident]; |
240 AttributeForm *attr = form ? form->is_attribute() : NULL; | 239 AttributeForm *attr = form ? form->is_attribute() : NULL; |
241 if( attr && (attr->_atype == INS_ATTR) ) { | 240 if( attr && (attr->_atype == INS_ATTR) ) { |
321 const char *result2 = NULL; | 320 const char *result2 = NULL; |
322 const char *name2 = NULL; | 321 const char *name2 = NULL; |
323 const char *optype2 = NULL; | 322 const char *optype2 = NULL; |
324 // Can not have additional base operands in right side of match! | 323 // Can not have additional base operands in right side of match! |
325 if ( ! right->base_operand( position, _globalNames, result2, name2, optype2) ) { | 324 if ( ! right->base_operand( position, _globalNames, result2, name2, optype2) ) { |
326 assert( instr->_predicate == NULL, "ADLC does not support instruction chain rules with predicates"); | 325 if (instr->_predicate != NULL) |
326 parse_err(SYNERR, "ADLC does not support instruction chain rules with predicates"); | |
327 // Chain from input _ideal_operand_type_, | 327 // Chain from input _ideal_operand_type_, |
328 // Needed for shared roots of match-trees | 328 // Needed for shared roots of match-trees |
329 ChainList *lst = (ChainList *)_AD._chainRules[optype]; | 329 ChainList *lst = (ChainList *)_AD._chainRules[optype]; |
330 if (lst == NULL) { | 330 if (lst == NULL) { |
331 lst = new ChainList(); | 331 lst = new ChainList(); |
933 } | 933 } |
934 | 934 |
935 // (2) | 935 // (2) |
936 // If we are at a replacement variable, | 936 // If we are at a replacement variable, |
937 // copy it and record in EncClass | 937 // copy it and record in EncClass |
938 if ( _curchar == '$' ) { | 938 if (_curchar == '$') { |
939 // Found replacement Variable | 939 // Found replacement Variable |
940 char *rep_var = get_rep_var_ident_dup(); | 940 char* rep_var = get_rep_var_ident_dup(); |
941 // Add flag to _strings list indicating we should check _rep_vars | 941 // Add flag to _strings list indicating we should check _rep_vars |
942 encoding->add_rep_var(rep_var); | 942 encoding->add_rep_var(rep_var); |
943 } | 943 } |
944 } // end while part of format description | 944 } // end while part of format description |
945 next_char(); // Skip '%' | 945 next_char(); // Skip '%' |
2772 } | 2772 } |
2773 | 2773 |
2774 | 2774 |
2775 //------------------------------ins_encode_parse_block------------------------- | 2775 //------------------------------ins_encode_parse_block------------------------- |
2776 // Parse the block form of ins_encode. See ins_encode_parse for more details | 2776 // Parse the block form of ins_encode. See ins_encode_parse for more details |
2777 InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) { | 2777 void ADLParser::ins_encode_parse_block(InstructForm& inst) { |
2778 // Create a new encoding name based on the name of the instruction | 2778 // Create a new encoding name based on the name of the instruction |
2779 // definition, which should be unique. | 2779 // definition, which should be unique. |
2780 const char * prefix = "__enc_"; | 2780 const char* prefix = "__ins_encode_"; |
2781 char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1); | 2781 char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); |
2782 sprintf(ec_name, "%s%s", prefix, inst._ident); | 2782 sprintf(ec_name, "%s%s", prefix, inst._ident); |
2783 | 2783 |
2784 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); | 2784 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); |
2785 EncClass *encoding = _AD._encode->add_EncClass(ec_name); | 2785 EncClass* encoding = _AD._encode->add_EncClass(ec_name); |
2786 encoding->_linenum = linenum(); | 2786 encoding->_linenum = linenum(); |
2787 | 2787 |
2788 // synthesize the arguments list for the enc_class from the | 2788 // synthesize the arguments list for the enc_class from the |
2789 // arguments to the instruct definition. | 2789 // arguments to the instruct definition. |
2790 const char * param = NULL; | 2790 const char* param = NULL; |
2791 inst._parameters.reset(); | 2791 inst._parameters.reset(); |
2792 while ((param = inst._parameters.iter()) != NULL) { | 2792 while ((param = inst._parameters.iter()) != NULL) { |
2793 OperandForm *opForm = (OperandForm*)inst._localNames[param]; | 2793 OperandForm* opForm = (OperandForm*) inst._localNames[param]; |
2794 encoding->add_parameter(opForm->_ident, param); | 2794 encoding->add_parameter(opForm->_ident, param); |
2795 } | 2795 } |
2796 | 2796 |
2797 // Add the prologue to create the MacroAssembler | 2797 // Define a MacroAssembler instance for use by the encoding. The |
2798 encoding->add_code("\n" | 2798 // name is chosen to match the __ idiom used for assembly in other |
2799 " // Define a MacroAssembler instance for use by the encoding. The\n" | 2799 // parts of hotspot and assumes the existence of the standard |
2800 " // name is chosen to match the __ idiom used for assembly in other\n" | 2800 // #define __ _masm. |
2801 " // parts of hotspot and assumes the existence of the standard\n" | 2801 encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); |
2802 " // #define __ _masm.\n" | |
2803 " MacroAssembler _masm(&cbuf);\n"); | |
2804 | 2802 |
2805 // Parse the following %{ }% block | 2803 // Parse the following %{ }% block |
2806 enc_class_parse_block(encoding, ec_name); | 2804 ins_encode_parse_block_impl(inst, encoding, ec_name); |
2807 | 2805 |
2808 // Build an encoding rule which invokes the encoding rule we just | 2806 // Build an encoding rule which invokes the encoding rule we just |
2809 // created, passing all arguments that we received. | 2807 // created, passing all arguments that we received. |
2810 InsEncode *encrule = new InsEncode(); // Encode class for instruction | 2808 InsEncode* encrule = new InsEncode(); // Encode class for instruction |
2811 NameAndList *params = encrule->add_encode(ec_name); | 2809 NameAndList* params = encrule->add_encode(ec_name); |
2812 inst._parameters.reset(); | 2810 inst._parameters.reset(); |
2813 while ((param = inst._parameters.iter()) != NULL) { | 2811 while ((param = inst._parameters.iter()) != NULL) { |
2814 params->add_entry(param); | 2812 params->add_entry(param); |
2815 } | 2813 } |
2816 | 2814 |
2817 return encrule; | 2815 // Set encode class of this instruction. |
2816 inst._insencode = encrule; | |
2817 } | |
2818 | |
2819 | |
2820 void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) { | |
2821 skipws_no_preproc(); // Skip leading whitespace | |
2822 // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block | |
2823 if (_AD._adlocation_debug) { | |
2824 encoding->add_code(get_line_string()); | |
2825 } | |
2826 | |
2827 // Collect the parts of the encode description | |
2828 // (1) strings that are passed through to output | |
2829 // (2) replacement/substitution variable, preceeded by a '$' | |
2830 while ((_curchar != '%') && (*(_ptr+1) != '}')) { | |
2831 | |
2832 // (1) | |
2833 // Check if there is a string to pass through to output | |
2834 char *start = _ptr; // Record start of the next string | |
2835 while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) { | |
2836 // If at the start of a comment, skip past it | |
2837 if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) { | |
2838 skipws_no_preproc(); | |
2839 } else { | |
2840 // ELSE advance to the next character, or start of the next line | |
2841 next_char_or_line(); | |
2842 } | |
2843 } | |
2844 // If a string was found, terminate it and record in EncClass | |
2845 if (start != _ptr) { | |
2846 *_ptr = '\0'; // Terminate the string | |
2847 encoding->add_code(start); | |
2848 } | |
2849 | |
2850 // (2) | |
2851 // If we are at a replacement variable, | |
2852 // copy it and record in EncClass | |
2853 if (_curchar == '$') { | |
2854 // Found replacement Variable | |
2855 char* rep_var = get_rep_var_ident_dup(); | |
2856 | |
2857 // Add flag to _strings list indicating we should check _rep_vars | |
2858 encoding->add_rep_var(rep_var); | |
2859 | |
2860 skipws(); | |
2861 | |
2862 // Check if this instruct is a MachConstantNode. | |
2863 if (strcmp(rep_var, "constanttablebase") == 0) { | |
2864 // This instruct is a MachConstantNode. | |
2865 inst.set_is_mach_constant(true); | |
2866 | |
2867 if (_curchar == '(') { | |
2868 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name); | |
2869 return; | |
2870 } | |
2871 } | |
2872 else if ((strcmp(rep_var, "constantaddress") == 0) || | |
2873 (strcmp(rep_var, "constantoffset") == 0)) { | |
2874 // This instruct is a MachConstantNode. | |
2875 inst.set_is_mach_constant(true); | |
2876 | |
2877 // If the constant keyword has an argument, parse it. | |
2878 if (_curchar == '(') constant_parse(inst); | |
2879 } | |
2880 } | |
2881 } // end while part of format description | |
2882 next_char(); // Skip '%' | |
2883 next_char(); // Skip '}' | |
2884 | |
2885 skipws(); | |
2886 | |
2887 if (_AD._adlocation_debug) { | |
2888 encoding->add_code(end_line_marker()); | |
2889 } | |
2890 | |
2891 // Debug Stuff | |
2892 if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name); | |
2818 } | 2893 } |
2819 | 2894 |
2820 | 2895 |
2821 //------------------------------ins_encode_parse------------------------------- | 2896 //------------------------------ins_encode_parse------------------------------- |
2822 // Encode rules have the form | 2897 // Encode rules have the form |
2836 // | 2911 // |
2837 // MacroAssembler masm(&cbuf);\n"); | 2912 // MacroAssembler masm(&cbuf);\n"); |
2838 // | 2913 // |
2839 // making it more compact to take advantage of the MacroAssembler and | 2914 // making it more compact to take advantage of the MacroAssembler and |
2840 // placing the assembly closer to it's use by instructions. | 2915 // placing the assembly closer to it's use by instructions. |
2841 InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) { | 2916 void ADLParser::ins_encode_parse(InstructForm& inst) { |
2842 | 2917 |
2843 // Parse encode class name | 2918 // Parse encode class name |
2844 skipws(); // Skip whitespace | 2919 skipws(); // Skip whitespace |
2845 if (_curchar != '(') { | 2920 if (_curchar != '(') { |
2846 // Check for ins_encode %{ form | 2921 // Check for ins_encode %{ form |
2847 if ((_curchar == '%') && (*(_ptr+1) == '{')) { | 2922 if ((_curchar == '%') && (*(_ptr+1) == '{')) { |
2848 next_char(); // Skip '%' | 2923 next_char(); // Skip '%' |
2849 next_char(); // Skip '{' | 2924 next_char(); // Skip '{' |
2850 | 2925 |
2851 // Parse the block form of ins_encode | 2926 // Parse the block form of ins_encode |
2852 return ins_encode_parse_block(inst); | 2927 ins_encode_parse_block(inst); |
2928 return; | |
2853 } | 2929 } |
2854 | 2930 |
2855 parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n"); | 2931 parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n"); |
2856 return NULL; | 2932 return; |
2857 } | 2933 } |
2858 next_char(); // move past '(' | 2934 next_char(); // move past '(' |
2859 skipws(); | 2935 skipws(); |
2860 | 2936 |
2861 InsEncode *encrule = new InsEncode(); // Encode class for instruction | 2937 InsEncode *encrule = new InsEncode(); // Encode class for instruction |
2864 // identifier is optional. | 2940 // identifier is optional. |
2865 while (_curchar != ')') { | 2941 while (_curchar != ')') { |
2866 ec_name = get_ident(); | 2942 ec_name = get_ident(); |
2867 if (ec_name == NULL) { | 2943 if (ec_name == NULL) { |
2868 parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n"); | 2944 parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n"); |
2869 return NULL; | 2945 return; |
2870 } | 2946 } |
2871 // Check that encoding is defined in the encode section | 2947 // Check that encoding is defined in the encode section |
2872 EncClass *encode_class = _AD._encode->encClass(ec_name); | 2948 EncClass *encode_class = _AD._encode->encClass(ec_name); |
2873 if (encode_class == NULL) { | 2949 if (encode_class == NULL) { |
2874 // Like to defer checking these till later... | 2950 // Like to defer checking these till later... |
2896 if ( (inst._localNames[param] == NULL) && | 2972 if ( (inst._localNames[param] == NULL) && |
2897 !ADLParser::is_literal_constant(param) && | 2973 !ADLParser::is_literal_constant(param) && |
2898 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && | 2974 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && |
2899 ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { | 2975 ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { |
2900 parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); | 2976 parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); |
2901 return NULL; | 2977 return; |
2902 } | 2978 } |
2903 params->add_entry(param); | 2979 params->add_entry(param); |
2904 | 2980 |
2905 skipws(); | 2981 skipws(); |
2906 if (_curchar == ',' ) { | 2982 if (_curchar == ',' ) { |
2913 } | 2989 } |
2914 else { | 2990 else { |
2915 // Only ',' or ')' are valid after a parameter name | 2991 // Only ',' or ')' are valid after a parameter name |
2916 parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", | 2992 parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", |
2917 ec_name); | 2993 ec_name); |
2918 return NULL; | 2994 return; |
2919 } | 2995 } |
2920 | 2996 |
2921 } else { | 2997 } else { |
2922 skipws(); | 2998 skipws(); |
2923 // Did not find a parameter | 2999 // Did not find a parameter |
2924 if (_curchar == ',') { | 3000 if (_curchar == ',') { |
2925 parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name); | 3001 parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name); |
2926 return NULL; | 3002 return; |
2927 } | 3003 } |
2928 if (_curchar != ')') { | 3004 if (_curchar != ')') { |
2929 parse_err(SYNERR, "Expected ')' after encode parameters.\n"); | 3005 parse_err(SYNERR, "Expected ')' after encode parameters.\n"); |
2930 return NULL; | 3006 return; |
2931 } | 3007 } |
2932 } | 3008 } |
2933 } // WHILE loop collecting parameters | 3009 } // WHILE loop collecting parameters |
2934 next_char(); // move past ')' at end of parameters | 3010 next_char(); // move past ')' at end of parameters |
2935 } // done with parameter list for encoding | 3011 } // done with parameter list for encoding |
2942 skipws(); | 3018 skipws(); |
2943 } | 3019 } |
2944 else if ( _curchar != ')' ) { | 3020 else if ( _curchar != ')' ) { |
2945 // If not a ',' then only a ')' is allowed | 3021 // If not a ',' then only a ')' is allowed |
2946 parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name); | 3022 parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name); |
2947 return NULL; | 3023 return; |
2948 } | 3024 } |
2949 | 3025 |
2950 // Check for ',' separating parameters | 3026 // Check for ',' separating parameters |
2951 // if ( _curchar != ',' && _curchar != ')' ) { | 3027 // if ( _curchar != ',' && _curchar != ')' ) { |
2952 // parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n"); | 3028 // parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n"); |
2954 // } | 3030 // } |
2955 | 3031 |
2956 } // done parsing ins_encode methods and their parameters | 3032 } // done parsing ins_encode methods and their parameters |
2957 if (_curchar != ')') { | 3033 if (_curchar != ')') { |
2958 parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n"); | 3034 parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n"); |
2959 return NULL; | 3035 return; |
2960 } | 3036 } |
2961 next_char(); // move past ')' | 3037 next_char(); // move past ')' |
2962 skipws(); // Skip leading whitespace | 3038 skipws(); // Skip leading whitespace |
2963 | 3039 |
2964 if ( _curchar != ';' ) { | 3040 if ( _curchar != ';' ) { |
2965 parse_err(SYNERR, "Missing ';' at end of ins_encode.\n"); | 3041 parse_err(SYNERR, "Missing ';' at end of ins_encode.\n"); |
2966 return NULL; | 3042 return; |
2967 } | 3043 } |
2968 next_char(); // move past ';' | 3044 next_char(); // move past ';' |
2969 skipws(); // be friendly to oper_parse() | 3045 skipws(); // be friendly to oper_parse() |
2970 | 3046 |
2971 // Debug Stuff | 3047 // Debug Stuff |
2972 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); | 3048 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); |
2973 | 3049 |
2974 return encrule; | 3050 // Set encode class of this instruction. |
3051 inst._insencode = encrule; | |
3052 } | |
3053 | |
3054 | |
3055 //------------------------------constant_parse--------------------------------- | |
3056 // Parse a constant expression. | |
3057 void ADLParser::constant_parse(InstructForm& inst) { | |
3058 // Create a new encoding name based on the name of the instruction | |
3059 // definition, which should be unique. | |
3060 const char* prefix = "__constant_"; | |
3061 char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1); | |
3062 sprintf(ec_name, "%s%s", prefix, inst._ident); | |
3063 | |
3064 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); | |
3065 EncClass* encoding = _AD._encode->add_EncClass(ec_name); | |
3066 encoding->_linenum = linenum(); | |
3067 | |
3068 // synthesize the arguments list for the enc_class from the | |
3069 // arguments to the instruct definition. | |
3070 const char* param = NULL; | |
3071 inst._parameters.reset(); | |
3072 while ((param = inst._parameters.iter()) != NULL) { | |
3073 OperandForm* opForm = (OperandForm*) inst._localNames[param]; | |
3074 encoding->add_parameter(opForm->_ident, param); | |
3075 } | |
3076 | |
3077 // Parse the following ( ) expression. | |
3078 constant_parse_expression(encoding, ec_name); | |
3079 | |
3080 // Build an encoding rule which invokes the encoding rule we just | |
3081 // created, passing all arguments that we received. | |
3082 InsEncode* encrule = new InsEncode(); // Encode class for instruction | |
3083 NameAndList* params = encrule->add_encode(ec_name); | |
3084 inst._parameters.reset(); | |
3085 while ((param = inst._parameters.iter()) != NULL) { | |
3086 params->add_entry(param); | |
3087 } | |
3088 | |
3089 // Set encode class of this instruction. | |
3090 inst._constant = encrule; | |
3091 } | |
3092 | |
3093 | |
3094 //------------------------------constant_parse_expression---------------------- | |
3095 void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) { | |
3096 skipws(); | |
3097 | |
3098 // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block | |
3099 if (_AD._adlocation_debug) { | |
3100 encoding->add_code(get_line_string()); | |
3101 } | |
3102 | |
3103 // Start code line. | |
3104 encoding->add_code(" _constant = C->constant_table().add"); | |
3105 | |
3106 // Parse everything in ( ) expression. | |
3107 encoding->add_code("("); | |
3108 next_char(); // Skip '(' | |
3109 int parens_depth = 1; | |
3110 | |
3111 // Collect the parts of the constant expression. | |
3112 // (1) strings that are passed through to output | |
3113 // (2) replacement/substitution variable, preceeded by a '$' | |
3114 while (parens_depth > 0) { | |
3115 if (_curchar == '(') { | |
3116 parens_depth++; | |
3117 encoding->add_code("("); | |
3118 next_char(); | |
3119 } | |
3120 else if (_curchar == ')') { | |
3121 parens_depth--; | |
3122 encoding->add_code(")"); | |
3123 next_char(); | |
3124 } | |
3125 else { | |
3126 // (1) | |
3127 // Check if there is a string to pass through to output | |
3128 char *start = _ptr; // Record start of the next string | |
3129 while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) { | |
3130 next_char(); | |
3131 } | |
3132 // If a string was found, terminate it and record in EncClass | |
3133 if (start != _ptr) { | |
3134 *_ptr = '\0'; // Terminate the string | |
3135 encoding->add_code(start); | |
3136 } | |
3137 | |
3138 // (2) | |
3139 // If we are at a replacement variable, copy it and record in EncClass. | |
3140 if (_curchar == '$') { | |
3141 // Found replacement Variable | |
3142 char* rep_var = get_rep_var_ident_dup(); | |
3143 encoding->add_rep_var(rep_var); | |
3144 } | |
3145 } | |
3146 } | |
3147 | |
3148 // Finish code line. | |
3149 encoding->add_code(";"); | |
3150 | |
3151 if (_AD._adlocation_debug) { | |
3152 encoding->add_code(end_line_marker()); | |
3153 } | |
3154 | |
3155 // Debug Stuff | |
3156 if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name); | |
2975 } | 3157 } |
2976 | 3158 |
2977 | 3159 |
2978 //------------------------------size_parse----------------------------------- | 3160 //------------------------------size_parse----------------------------------- |
2979 char* ADLParser::size_parse(InstructForm *instr) { | 3161 char* ADLParser::size_parse(InstructForm *instr) { |