Skip to content

Gem5指令集框架解析

Gem5实现了一套指令集描述语言,或者称为指令集描述框架。主要是借助ply(python版本的lex,yacc)来实现的语法定义和分析

  • lex(Lexical Analyzar), 词法分析生成器
  • yacc(Yet Another Compiler Compiler), 编译器代码生成器

实际上看起来,.isa的语法有点儿像python,甚至可以理解为python

文件结构

src/arch/isa_parser 目录下存放了与架构相关的编译器文件 build_tools 目录下有一些编译器基础文件 src/arch/arm 下面放了指令集描述源文件,不同的架构目录不同

编译原理

Lex

能根据定义的正则表达,将文本中的词进行匹配,生成一个个Token实例。以isa_parser.py中举例,具体使用时需要有如下定义

首先要定义token的关键词,这相当于token类型的声明

   # List of tokens.  The lex module requires this.
    tokens = reserved + (
        # identifier
        'ID',

        # integer literal
        'INTLIT',

        # string literal
        'STRLIT',

        # code literal
        'CODELIT',

        # ( ) [ ] { } < > , ; . : :: *
        'LPAREN', 'RPAREN',
        'LBRACKET', 'RBRACKET',
        'LBRACE', 'RBRACE',
        'LESS', 'GREATER', 'EQUALS',
        'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON',
        'ASTERISK',

        # C preprocessor directives
        'CPPDIRECTIVE'
    )

除此之外,还有定义匹配规则。匹配规则有两种定义方法,字符串和函数。 函数优先级高于字符串,而且按照函数编写的优先级来定义匹配的优先级,字符串则按照匹配长度来定义优先级,长的优先 总结起来,有如下优先级规则:

  • 如果用字符串方式定义,那么用于匹配的正则表达式越长则匹配优先级越高;
  • 如果用函数方式定义,函数在代码中出现的位置越靠前则匹配优先级越高;
  • 用函数方式定义的匹配规则优先级永远高于用字符串定义的

LPAREN是通过字符串的方式定义的,INTLIT是通过函数定义的,无论是字符串还是函数,都应该加上前缀 t_ 函数还应该显式的return t

# Regular expressions for token matching
t_LPAREN           = r'\('
t_RPAREN           = r'\)'
t_LBRACKET         = r'\['

def t_ID(self, t):
    r'[A-Za-z_]\w*'
    t.type = self.reserved_map.get(t.value, 'ID')
    return t

# Integer literal
def t_INTLIT(self, t):
    r'-?(0x[\da-fA-F]+)|\d+'
    try:
        t.value = int(t.value,0)
    except ValueError:
        error(t.lexer.lineno, 'Integer value "%s" too large' % t.value)
        t.value = 0
    return t

yacc