X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Farch%2Fmicro_asm.py;h=4e5400ceffe8d075ecf935cc64f6b9968aef7184;hb=08754488a30da178effd0414f198462bf268d715;hp=307c9118b0794ff8db1ae82d69af767915ba6bc3;hpb=66ee27078eed95843c5994f0457d199c2317d752;p=gem5.git diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 307c9118b..4e5400cef 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -34,10 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc @@ -55,7 +51,7 @@ class Micro_Container(object): self.micro_classes = {} self.labels = {} - def add_microop(self, microop): + def add_microop(self, mnemonic, microop): self.microops.append(microop) def __str__(self): @@ -127,24 +123,34 @@ def print_error(message): def handle_statement(parser, container, statement): if statement.is_microop: + if statement.mnemonic not in parser.microops.keys(): + raise Exception, "Unrecognized mnemonic: %s" % statement.mnemonic + parser.symbols["__microopClassFromInsideTheAssembler"] = \ + parser.microops[statement.mnemonic] try: - microop = eval('parser.microops[statement.mnemonic](%s)' % - statement.params) + microop = eval('__microopClassFromInsideTheAssembler(%s)' % + statement.params, {}, parser.symbols) except: - print_error("Error creating microop object.") + print_error("Error creating microop object with mnemonic %s." % \ + statement.mnemonic) raise try: for label in statement.labels: - container.labels[label.name] = microop - if label.extern: - container.externs[label.name] = microop - container.add_microop(microop) + container.labels[label.text] = microop + if label.is_extern: + container.externs[label.text] = microop + container.add_microop(statement.mnemonic, microop) except: print_error("Error adding microop.") raise elif statement.is_directive: + if statement.name not in container.directives.keys(): + raise Exception, "Unrecognized directive: %s" % statement.name + parser.symbols["__directiveFunctionFromInsideTheAssembler"] = \ + container.directives[statement.name] try: - eval('container.directives[statement.name](%s)' % statement.params) + eval('__directiveFunctionFromInsideTheAssembler(%s)' % + statement.params, {}, parser.symbols) except: print_error("Error executing directive.") print container.directives @@ -212,6 +218,19 @@ def t_params_COLON(t): t.lexer.begin('asm') return t +# Parameters are a string of text which don't contain an unescaped statement +# statement terminator, ie a newline or semi colon. +def t_params_PARAMS(t): + r'([^\n;\\]|(\\[\n;\\]))+' + t.lineno += t.value.count('\n') + unescapeParamsRE = re.compile(r'(\\[\n;\\])') + def unescapeParams(mo): + val = mo.group(0) + return val[1] + t.value = unescapeParamsRE.sub(unescapeParams, t.value) + t.lexer.begin('asm') + return t + # An "ID" in the micro assembler is either a label, directive, or mnemonic # If it's either a directive or a mnemonic, it will be optionally followed by # parameters. If it's a label, the following colon will make the lexer stop @@ -219,24 +238,19 @@ def t_params_COLON(t): def t_asm_ID(t): r'[A-Za-z_]\w*' t.type = reserved_map.get(t.value, 'ID') - t.lexer.begin('params') + # If the ID is really "extern", we shouldn't start looking for parameters + # yet. The real ID, the label itself, is coming up. + if t.type != 'EXTERN': + t.lexer.begin('params') return t -# If there is a label and you're -not- in the assember (which would be caught +# If there is a label and you're -not- in the assembler (which would be caught # above), don't start looking for parameters. def t_ANY_ID(t): r'[A-Za-z_]\w*' t.type = reserved_map.get(t.value, 'ID') return t -# Parameters are a string of text which don't contain an unescaped statement -# statement terminator, ie a newline or semi colon. -def t_params_PARAMS(t): - r'([^\n;]|((?<=\\)[\n;]))+' - t.lineno += t.value.count('\n') - t.lexer.begin('asm') - return t - # Braces enter and exit micro assembly def t_INITIAL_LBRACE(t): r'\{' @@ -424,6 +438,11 @@ def p_labels_1(t): t[1].append(t[2]) t[0] = t[1] +# labels on lines by themselves are attached to the following instruction. +def p_labels_2(t): + 'labels : labels NEWLINE' + t[0] = t[1] + def p_label_0(t): 'label : ID COLON' label = Label() @@ -471,14 +490,11 @@ class MicroAssembler(object): self.parser.microops = microops self.parser.rom = rom self.parser.rom_macroop_type = rom_macroop_type + self.parser.symbols = {} + self.symbols = self.parser.symbols def assemble(self, asm): self.parser.parse(asm, lexer=self.lexer) - # Begin debug printing - for macroop in self.parser.macroops.values(): - print macroop - print self.parser.rom - # End debug printing macroops = self.parser.macroops self.parser.macroops = {} return macroops