# Node ID 6785122e7e3bc73f9293eef296e99fa6478dc961 # Parent 1a9e235cab09e37837819876d28fbd2914a47291 diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1990,51 +1990,57 @@ # Nested decode block: if the value of the current field matches # the specified constant, do a nested decode on some other field. def p_decode_stmt_decode(self, t): - 'decode_stmt : case_label COLON decode_block' + 'decode_stmt : case_list COLON decode_block' label = t[1] codeObj = t[3] # just wrap the decoding code from the block as a case in the # outer switch statement. - codeObj.wrap_decode_block('\n%s:\n' % label) - codeObj.has_decode_default = (label == 'default') + codeObj.wrap_decode_block('\n%s\n' % ''.join(label)) + codeObj.has_decode_default = (label == ['default:']) t[0] = codeObj # Instruction definition (finally!). def p_decode_stmt_inst(self, t): - 'decode_stmt : case_label COLON inst SEMI' + 'decode_stmt : case_list COLON inst SEMI' label = t[1] codeObj = t[3] - codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') - codeObj.has_decode_default = (label == 'default') + codeObj.wrap_decode_block('\n%s' % ''.join(label), 'break;\n') + codeObj.has_decode_default = (label == ['default:']) t[0] = codeObj - # The case label is either a list of one or more constants or - # 'default' - def p_case_label_0(self, t): - 'case_label : intlit_list' - def make_case(intlit): - if intlit >= 2**32: - return 'case ULL(%#x)' % intlit - else: - return 'case %#x' % intlit - t[0] = ': '.join(map(make_case, t[1])) + def p_case_list_0(self, t): + 'case_list : DEFAULT' + t[0] = ['default:'] - def p_case_label_1(self, t): - 'case_label : DEFAULT' - t[0] = 'default' + def prep_int_lit_case_label(self, lit): + if lit >= 2**32: + return 'case ULL(%#x): ' % lit + else: + return 'case %#x: ' % lit - # - # The constant list for a decode case label must be non-empty, but - # may have one or more comma-separated integer literals in it. - # - def p_intlit_list_0(self, t): - 'intlit_list : INTLIT' - t[0] = [t[1]] + def prep_str_lit_case_label(self, lit): + return 'case %s: ' % lit - def p_intlit_list_1(self, t): - 'intlit_list : intlit_list COMMA INTLIT' + # The constant list for a decode case label must be non-empty and + # be made up of one or more comma-separated integer literals or C++ strings + # which evaluate to constants. + def p_case_list_1(self, t): + 'case_list : INTLIT' + t[0] = [self.prep_int_lit_case_label(t[1])] + + def p_case_list_2(self, t): + 'case_list : STRLIT' + t[0] = [self.prep_str_lit_case_label(t[1])] + + def p_case_list_3(self, t): + 'case_list : case_list COMMA INTLIT' t[0] = t[1] - t[0].append(t[3]) + t[0].append(self.prep_int_lit_case_label(t[3])) + + def p_case_list_4(self, t): + 'case_list : case_list COMMA STRLIT' + t[0] = t[1] + t[0].append(self.prep_str_lit_case_label(t[3])) # Define an instruction using the current instruction format # (specified by an enclosing format block).