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

Split Close
Expand all
Collapse all
          --- old/src/share/vm/adlc/adlparse.cpp
          +++ new/src/share/vm/adlc/adlparse.cpp
   1    1  /*
   2      - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
        2 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3    3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4    4   *
   5    5   * This code is free software; you can redistribute it and/or modify it
   6    6   * under the terms of the GNU General Public License version 2 only, as
   7    7   * published by the Free Software Foundation.
   8    8   *
   9    9   * This code is distributed in the hope that it will be useful, but WITHOUT
  10   10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11   11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12   12   * version 2 for more details (a copy is included in the LICENSE file that
↓ open down ↓ 75 lines elided ↑ open up ↑
  88   88    char *ident;
  89   89  
  90   90    // Iterate over the lines in the file buffer parsing Level 1 objects
  91   91    for( next_line(); _curline != NULL; next_line()) {
  92   92      _ptr = _curline;             // Reset ptr to start of new line
  93   93      skipws();                    // Skip any leading whitespace
  94   94      ident = get_ident();         // Get first token
  95   95      if (ident == NULL) {         // Empty line
  96   96        continue;                  // Get the next line
  97   97      }
  98      -    if (!strcmp(ident, "instruct"))        instr_parse();
       98 +         if (!strcmp(ident, "instruct"))   instr_parse();
  99   99      else if (!strcmp(ident, "operand"))    oper_parse();
 100  100      else if (!strcmp(ident, "opclass"))    opclass_parse();
 101  101      else if (!strcmp(ident, "ins_attrib")) ins_attr_parse();
 102  102      else if (!strcmp(ident, "op_attrib"))  op_attr_parse();
 103  103      else if (!strcmp(ident, "source"))     source_parse();
 104  104      else if (!strcmp(ident, "source_hpp")) source_hpp_parse();
 105  105      else if (!strcmp(ident, "register"))   reg_parse();
 106  106      else if (!strcmp(ident, "frame"))      frame_parse();
 107  107      else if (!strcmp(ident, "encode"))     encode_parse();
 108  108      else if (!strcmp(ident, "pipeline"))   pipe_parse();
↓ open down ↓ 100 lines elided ↑ open up ↑
 209  209            sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 210  210            rule->_result = buf;
 211  211            // Check for commutative operations with tree operands.
 212  212            matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 213  213          }
 214  214        }
 215  215      }
 216  216      else if (!strcmp(ident, "encode"))  {
 217  217        parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 218  218      }
 219      -    else if (!strcmp(ident, "ins_encode"))
 220      -      instr->_insencode = ins_encode_parse(*instr);
 221      -    else if (!strcmp(ident, "opcode"))  instr->_opcode = opcode_parse(instr);
 222      -    else if (!strcmp(ident, "size"))    instr->_size = size_parse(instr);
 223      -    else if (!strcmp(ident, "effect"))  effect_parse(instr);
 224      -    else if (!strcmp(ident, "expand"))  instr->_exprule = expand_parse(instr);
 225      -    else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
      219 +    else if (!strcmp(ident, "ins_encode"))     ins_encode_parse(*instr);
      220 +    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, "effect"))         effect_parse(instr);
      223 +    else if (!strcmp(ident, "expand"))         instr->_exprule   = expand_parse(instr);
      224 +    else if (!strcmp(ident, "rewrite"))        instr->_rewrule   = rewrite_parse();
 226  225      else if (!strcmp(ident, "constraint")) {
 227  226        parse_err(SYNERR, "Instructions do not specify a constraint\n");
 228  227      }
 229  228      else if (!strcmp(ident, "construct")) {
 230  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  232      else if (!strcmp(ident, "interface")) {
 234  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  236      else {  // Done with staticly defined parts of instruction definition
 238  237        // Check identifier to see if it is the name of an attribute
 239  238        const Form    *form = _globalNames[ident];
 240  239        AttributeForm *attr = form ? form->is_attribute() : NULL;
 241  240        if( attr && (attr->_atype == INS_ATTR) ) {
 242  241          // Insert the new attribute into the linked list.
 243  242          Attribute *temp = attr_parse(ident);
 244  243          temp->_next = instr->_attribs;
 245  244          instr->_attribs = temp;
 246  245        } else {
↓ open down ↓ 681 lines elided ↑ open up ↑
 928  927      }
 929  928      // If a string was found, terminate it and record in EncClass
 930  929      if ( start != _ptr ) {
 931  930        *_ptr  = '\0';          // Terminate the string
 932  931        encoding->add_code(start);
 933  932      }
 934  933  
 935  934      // (2)
 936  935      // If we are at a replacement variable,
 937  936      // copy it and record in EncClass
 938      -    if ( _curchar == '$' ) {
      937 +    if (_curchar == '$') {
 939  938        // Found replacement Variable
 940      -      char *rep_var = get_rep_var_ident_dup();
      939 +      char* rep_var = get_rep_var_ident_dup();
 941  940        // Add flag to _strings list indicating we should check _rep_vars
 942  941        encoding->add_rep_var(rep_var);
 943  942      }
 944  943    } // end while part of format description
 945  944    next_char();                      // Skip '%'
 946  945    next_char();                      // Skip '}'
 947  946  
 948  947    skipws();
 949  948  
 950  949    if (_AD._adlocation_debug) {
↓ open down ↓ 1816 lines elided ↑ open up ↑
2767 2766    next_char();                     // Point after the terminator
2768 2767  
2769 2768    predicate = new Predicate(rule); // Build new predicate object
2770 2769    skipws();
2771 2770    return predicate;
2772 2771  }
2773 2772  
2774 2773  
2775 2774  //------------------------------ins_encode_parse_block-------------------------
2776 2775  // Parse the block form of ins_encode.  See ins_encode_parse for more details
2777      -InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
     2776 +void ADLParser::ins_encode_parse_block(InstructForm& inst) {
2778 2777    // Create a new encoding name based on the name of the instruction
2779 2778    // definition, which should be unique.
2780      -  const char * prefix = "__enc_";
2781      -  char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1);
     2779 +  const char* prefix = "__ins_encode_";
     2780 +  char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
2782 2781    sprintf(ec_name, "%s%s", prefix, inst._ident);
2783 2782  
2784 2783    assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2785      -  EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
     2784 +  EncClass* encoding = _AD._encode->add_EncClass(ec_name);
2786 2785    encoding->_linenum = linenum();
2787 2786  
2788 2787    // synthesize the arguments list for the enc_class from the
2789 2788    // arguments to the instruct definition.
2790      -  const char * param = NULL;
     2789 +  const char* param = NULL;
2791 2790    inst._parameters.reset();
2792 2791    while ((param = inst._parameters.iter()) != NULL) {
2793      -    OperandForm *opForm = (OperandForm*)inst._localNames[param];
     2792 +    OperandForm* opForm = (OperandForm*) inst._localNames[param];
2794 2793      encoding->add_parameter(opForm->_ident, param);
2795 2794    }
2796 2795  
2797      -  // Add the prologue to create the MacroAssembler
2798      -  encoding->add_code("\n"
2799      -  "    // Define a MacroAssembler instance for use by the encoding.  The\n"
2800      -  "    // name is chosen to match the __ idiom used for assembly in other\n"
2801      -  "    // parts of hotspot and assumes the existence of the standard\n"
2802      -  "    // #define __ _masm.\n"
2803      -  "    MacroAssembler _masm(&cbuf);\n");
     2796 +  // Define a MacroAssembler instance for use by the encoding.  The
     2797 +  // name is chosen to match the __ idiom used for assembly in other
     2798 +  // parts of hotspot and assumes the existence of the standard
     2799 +  // #define __ _masm.
     2800 +  encoding->add_code("    MacroAssembler _masm(&cbuf);\n");
2804 2801  
2805 2802    // Parse the following %{ }% block
2806      -  enc_class_parse_block(encoding, ec_name);
     2803 +  ins_encode_parse_block_impl(inst, encoding, ec_name);
2807 2804  
2808 2805    // Build an encoding rule which invokes the encoding rule we just
2809 2806    // created, passing all arguments that we received.
2810      -  InsEncode *encrule  = new InsEncode(); // Encode class for instruction
2811      -  NameAndList *params = encrule->add_encode(ec_name);
     2807 +  InsEncode*   encrule = new InsEncode(); // Encode class for instruction
     2808 +  NameAndList* params  = encrule->add_encode(ec_name);
2812 2809    inst._parameters.reset();
2813 2810    while ((param = inst._parameters.iter()) != NULL) {
2814 2811      params->add_entry(param);
2815 2812    }
2816 2813  
2817      -  return encrule;
     2814 +  // Set encode class of this instruction.
     2815 +  inst._insencode = encrule;
     2816 +}
     2817 +
     2818 +
     2819 +void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) {
     2820 +  skipws_no_preproc();              // Skip leading whitespace
     2821 +  // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
     2822 +  if (_AD._adlocation_debug) {
     2823 +    encoding->add_code(get_line_string());
     2824 +  }
     2825 +
     2826 +  // Collect the parts of the encode description
     2827 +  // (1) strings that are passed through to output
     2828 +  // (2) replacement/substitution variable, preceeded by a '$'
     2829 +  while ((_curchar != '%') && (*(_ptr+1) != '}')) {
     2830 +
     2831 +    // (1)
     2832 +    // Check if there is a string to pass through to output
     2833 +    char *start = _ptr;       // Record start of the next string
     2834 +    while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
     2835 +      // If at the start of a comment, skip past it
     2836 +      if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
     2837 +        skipws_no_preproc();
     2838 +      } else {
     2839 +        // ELSE advance to the next character, or start of the next line
     2840 +        next_char_or_line();
     2841 +      }
     2842 +    }
     2843 +    // If a string was found, terminate it and record in EncClass
     2844 +    if (start != _ptr) {
     2845 +      *_ptr = '\0';          // Terminate the string
     2846 +      encoding->add_code(start);
     2847 +    }
     2848 +
     2849 +    // (2)
     2850 +    // If we are at a replacement variable,
     2851 +    // copy it and record in EncClass
     2852 +    if (_curchar == '$') {
     2853 +      // Found replacement Variable
     2854 +      char* rep_var = get_rep_var_ident_dup();
     2855 +
     2856 +      // Add flag to _strings list indicating we should check _rep_vars
     2857 +      encoding->add_rep_var(rep_var);
     2858 +
     2859 +      skipws();
     2860 +
     2861 +      // Check if this instruct is a MachConstantNode.
     2862 +      if (strcmp(rep_var, "constanttablebase") == 0) {
     2863 +        // This instruct is a MachConstantNode.
     2864 +        inst.set_is_mach_constant(true);
     2865 +
     2866 +        if (_curchar == '(')  {
     2867 +          parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
     2868 +          return;
     2869 +        }
     2870 +      }
     2871 +      else if ((strcmp(rep_var, "constantaddress")   == 0) ||
     2872 +               (strcmp(rep_var, "constantoffset")    == 0)) {
     2873 +        // This instruct is a MachConstantNode.
     2874 +        inst.set_is_mach_constant(true);
     2875 +
     2876 +        // If the constant keyword has an argument, parse it.
     2877 +        if (_curchar == '(')  constant_parse(inst);
     2878 +      }
     2879 +    }
     2880 +  } // end while part of format description
     2881 +  next_char();                      // Skip '%'
     2882 +  next_char();                      // Skip '}'
     2883 +
     2884 +  skipws();
     2885 +
     2886 +  if (_AD._adlocation_debug) {
     2887 +    encoding->add_code(end_line_marker());
     2888 +  }
     2889 +
     2890 +  // Debug Stuff
     2891 +  if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
2818 2892  }
2819 2893  
2820 2894  
2821 2895  //------------------------------ins_encode_parse-------------------------------
2822 2896  // Encode rules have the form
2823 2897  //   ins_encode( encode_class_name(parameter_list), ... );
2824 2898  //
2825 2899  // The "encode_class_name" must be defined in the encode section
2826 2900  // The parameter list contains $names that are locals.
2827 2901  //
↓ open down ↓ 3 lines elided ↑ open up ↑
2831 2905  //      ... // body
2832 2906  //   %}
2833 2907  //
2834 2908  // which synthesizes a new encoding class taking the same arguments as
2835 2909  // the InstructForm, and automatically prefixes the definition with:
2836 2910  //
2837 2911  //    MacroAssembler masm(&cbuf);\n");
2838 2912  //
2839 2913  //  making it more compact to take advantage of the MacroAssembler and
2840 2914  //  placing the assembly closer to it's use by instructions.
2841      -InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
     2915 +void ADLParser::ins_encode_parse(InstructForm& inst) {
2842 2916  
2843 2917    // Parse encode class name
2844 2918    skipws();                        // Skip whitespace
2845 2919    if (_curchar != '(') {
2846 2920      // Check for ins_encode %{ form
2847 2921      if ((_curchar == '%') && (*(_ptr+1) == '{')) {
2848 2922        next_char();                      // Skip '%'
2849 2923        next_char();                      // Skip '{'
2850 2924  
2851 2925        // Parse the block form of ins_encode
2852      -      return ins_encode_parse_block(inst);
     2926 +      ins_encode_parse_block(inst);
     2927 +      return;
2853 2928      }
2854 2929  
2855 2930      parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
2856      -    return NULL;
     2931 +    return;
2857 2932    }
2858 2933    next_char();                     // move past '('
2859 2934    skipws();
2860 2935  
2861 2936    InsEncode *encrule  = new InsEncode(); // Encode class for instruction
2862 2937    encrule->_linenum = linenum();
2863 2938    char      *ec_name  = NULL;      // String representation of encode rule
2864 2939    // identifier is optional.
2865 2940    while (_curchar != ')') {
2866 2941      ec_name = get_ident();
2867 2942      if (ec_name == NULL) {
2868 2943        parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
2869      -      return NULL;
     2944 +      return;
2870 2945      }
2871 2946      // Check that encoding is defined in the encode section
2872 2947      EncClass *encode_class = _AD._encode->encClass(ec_name);
2873 2948      if (encode_class == NULL) {
2874 2949        // Like to defer checking these till later...
2875 2950        // parse_err(WARN, "Using an undefined encode class '%s' in 'ins_encode'.\n", ec_name);
2876 2951      }
2877 2952  
2878 2953      // Get list for encode method's parameters
2879 2954      NameAndList *params = encrule->add_encode(ec_name);
↓ open down ↓ 11 lines elided ↑ open up ↑
2891 2966            // Check it is a local name, add it to the list, then check for more
2892 2967            // New: allow hex constants as parameters to an encode method.
2893 2968            // New: allow parenthesized expressions as parameters.
2894 2969            // New: allow "primary", "secondary", "tertiary" as parameters.
2895 2970            // New: allow user-defined register name as parameter
2896 2971            if ( (inst._localNames[param] == NULL) &&
2897 2972                 !ADLParser::is_literal_constant(param) &&
2898 2973                 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
2899 2974                 ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
2900 2975              parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
2901      -            return NULL;
     2976 +            return;
2902 2977            }
2903 2978            params->add_entry(param);
2904 2979  
2905 2980            skipws();
2906 2981            if (_curchar == ',' ) {
2907 2982              // More parameters to come
2908 2983              next_char();           // move past ',' between parameters
2909 2984              skipws();              // Skip to next parameter
2910 2985            }
2911 2986            else if (_curchar == ')') {
2912 2987              // Done with parameter list
2913 2988            }
2914 2989            else {
2915 2990              // Only ',' or ')' are valid after a parameter name
2916 2991              parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
2917 2992                        ec_name);
2918      -            return NULL;
     2993 +            return;
2919 2994            }
2920 2995  
2921 2996          } else {
2922 2997            skipws();
2923 2998            // Did not find a parameter
2924 2999            if (_curchar == ',') {
2925 3000              parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
2926      -            return NULL;
     3001 +            return;
2927 3002            }
2928 3003            if (_curchar != ')') {
2929 3004              parse_err(SYNERR, "Expected ')' after encode parameters.\n");
2930      -            return NULL;
     3005 +            return;
2931 3006            }
2932 3007          }
2933 3008        } // WHILE loop collecting parameters
2934 3009        next_char();                   // move past ')' at end of parameters
2935 3010      } // done with parameter list for encoding
2936 3011  
2937 3012      // Check for ',' or ')' after encoding
2938 3013      skipws();                      // move to character after parameters
2939 3014      if ( _curchar == ',' ) {
2940 3015        // Found a ','
2941 3016        next_char();                 // move past ',' between encode methods
2942 3017        skipws();
2943 3018      }
2944 3019      else if ( _curchar != ')' ) {
2945 3020        // If not a ',' then only a ')' is allowed
2946 3021        parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
2947      -      return NULL;
     3022 +      return;
2948 3023      }
2949 3024  
2950 3025      // Check for ',' separating parameters
2951 3026      // if ( _curchar != ',' && _curchar != ')' ) {
2952 3027      //   parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n");
2953 3028      //   return NULL;
2954 3029      // }
2955 3030  
2956 3031    } // done parsing ins_encode methods and their parameters
2957 3032    if (_curchar != ')') {
2958 3033      parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
2959      -    return NULL;
     3034 +    return;
2960 3035    }
2961 3036    next_char();                     // move past ')'
2962 3037    skipws();                        // Skip leading whitespace
2963 3038  
2964 3039    if ( _curchar != ';' ) {
2965 3040      parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
2966      -    return NULL;
     3041 +    return;
2967 3042    }
2968 3043    next_char();                     // move past ';'
2969 3044    skipws();                        // be friendly to oper_parse()
2970 3045  
2971 3046    // Debug Stuff
2972 3047    if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
2973 3048  
2974      -  return encrule;
     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];
     3073 +    encoding->add_parameter(opForm->_ident, param);
     3074 +  }
     3075 +
     3076 +  // Parse the following ( ) expression.
     3077 +  constant_parse_expression(encoding, ec_name);
     3078 +
     3079 +  // Build an encoding rule which invokes the encoding rule we just
     3080 +  // created, passing all arguments that we received.
     3081 +  InsEncode*   encrule = new InsEncode(); // Encode class for instruction
     3082 +  NameAndList* params  = encrule->add_encode(ec_name);
     3083 +  inst._parameters.reset();
     3084 +  while ((param = inst._parameters.iter()) != NULL) {
     3085 +    params->add_entry(param);
     3086 +  }
     3087 +
     3088 +  // Set encode class of this instruction.
     3089 +  inst._constant = encrule;
     3090 +}
     3091 +
     3092 +
     3093 +//------------------------------constant_parse_expression----------------------
     3094 +void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
     3095 +  skipws();
     3096 +
     3097 +  // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
     3098 +  if (_AD._adlocation_debug) {
     3099 +    encoding->add_code(get_line_string());
     3100 +  }
     3101 +
     3102 +  // Start code line.
     3103 +  encoding->add_code("    add_to_constant_table");
     3104 +
     3105 +  // Parse everything in ( ) expression.
     3106 +  encoding->add_code("(");
     3107 +  next_char();  // Skip '('
     3108 +  int parens_depth = 1;
     3109 +
     3110 +  // Collect the parts of the constant expression.
     3111 +  // (1) strings that are passed through to output
     3112 +  // (2) replacement/substitution variable, preceeded by a '$'
     3113 +  while (parens_depth > 0) {
     3114 +    if (_curchar == '(') {
     3115 +      parens_depth++;
     3116 +      encoding->add_code("(");
     3117 +      next_char();
     3118 +    }
     3119 +    else if (_curchar == ')') {
     3120 +      parens_depth--;
     3121 +      encoding->add_code(")");
     3122 +      next_char();
     3123 +    }
     3124 +    else {
     3125 +      // (1)
     3126 +      // Check if there is a string to pass through to output
     3127 +      char *start = _ptr;  // Record start of the next string
     3128 +      while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) {
     3129 +        next_char();
     3130 +      }
     3131 +      // If a string was found, terminate it and record in EncClass
     3132 +      if (start != _ptr) {
     3133 +        *_ptr = '\0';  // Terminate the string
     3134 +        encoding->add_code(start);
     3135 +      }
     3136 +
     3137 +      // (2)
     3138 +      // If we are at a replacement variable, copy it and record in EncClass.
     3139 +      if (_curchar == '$') {
     3140 +        // Found replacement Variable
     3141 +        char* rep_var = get_rep_var_ident_dup();
     3142 +        encoding->add_rep_var(rep_var);
     3143 +      }
     3144 +    }
     3145 +  }
     3146 +
     3147 +  // Finish code line.
     3148 +  encoding->add_code(";");
     3149 +
     3150 +  if (_AD._adlocation_debug) {
     3151 +    encoding->add_code(end_line_marker());
     3152 +  }
     3153 +
     3154 +  // Debug Stuff
     3155 +  if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
2975 3156  }
2976 3157  
2977 3158  
2978 3159  //------------------------------size_parse-----------------------------------
2979 3160  char* ADLParser::size_parse(InstructForm *instr) {
2980 3161    char* sizeOfInstr = NULL;
2981 3162  
2982 3163    // Get value of the instruction's size
2983 3164    skipws();
2984 3165  
↓ open down ↓ 1884 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX