micro_asm.py revision 4502
12817Sksewell@umich.edu# Copyright (c) 2003-2005 The Regents of The University of Michigan
213610Sgiacomo.gabrielli@arm.com# All rights reserved.
39920Syasuko.eckert@amd.com#
48733Sgeoffrey.blake@arm.com# Redistribution and use in source and binary forms, with or without
58733Sgeoffrey.blake@arm.com# modification, are permitted provided that the following conditions are
68733Sgeoffrey.blake@arm.com# met: redistributions of source code must retain the above copyright
78733Sgeoffrey.blake@arm.com# notice, this list of conditions and the following disclaimer;
88733Sgeoffrey.blake@arm.com# redistributions in binary form must reproduce the above copyright
98733Sgeoffrey.blake@arm.com# notice, this list of conditions and the following disclaimer in the
108733Sgeoffrey.blake@arm.com# documentation and/or other materials provided with the distribution;
118733Sgeoffrey.blake@arm.com# neither the name of the copyright holders nor the names of its
128733Sgeoffrey.blake@arm.com# contributors may be used to endorse or promote products derived from
138733Sgeoffrey.blake@arm.com# this software without specific prior written permission.
148733Sgeoffrey.blake@arm.com#
152817Sksewell@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162817Sksewell@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172817Sksewell@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182817Sksewell@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192817Sksewell@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202817Sksewell@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212817Sksewell@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222817Sksewell@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232817Sksewell@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242817Sksewell@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252817Sksewell@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262817Sksewell@umich.edu#
272817Sksewell@umich.edu# Authors: Gabe Black
282817Sksewell@umich.edu
292817Sksewell@umich.eduimport os
302817Sksewell@umich.eduimport sys
312817Sksewell@umich.eduimport re
322817Sksewell@umich.eduimport string
332817Sksewell@umich.eduimport traceback
342817Sksewell@umich.edu# get type names
352817Sksewell@umich.edufrom types import *
362817Sksewell@umich.edu
372817Sksewell@umich.edu# Prepend the directory where the PLY lex & yacc modules are found
382817Sksewell@umich.edu# to the search path.
392817Sksewell@umich.edusys.path[0:0] = [os.environ['M5_PLY']]
402817Sksewell@umich.edu
412817Sksewell@umich.edufrom ply import lex
422817Sksewell@umich.edufrom ply import yacc
432817Sksewell@umich.edu
442817Sksewell@umich.edu##########################################################################
452817Sksewell@umich.edu#
462817Sksewell@umich.edu# Base classes for use outside of the assembler
476658Snate@binkert.org#
488229Snate@binkert.org##########################################################################
492935Sksewell@umich.edu
502817Sksewell@umich.educlass Micro_Container(object):
512834Sksewell@umich.edu    def __init__(self, name):
522834Sksewell@umich.edu        self.microops = []
532834Sksewell@umich.edu        self.name = name
548902Sandreas.hansson@arm.com        self.directives = {}
552834Sksewell@umich.edu        self.micro_classes = {}
562817Sksewell@umich.edu        self.labels = {}
572817Sksewell@umich.edu
582817Sksewell@umich.edu    def add_microop(self, microop):
592817Sksewell@umich.edu        self.microops.append(microop)
602817Sksewell@umich.edu
612817Sksewell@umich.edu    def __str__(self):
622817Sksewell@umich.edu        string = "%s:\n" % self.name
632817Sksewell@umich.edu        for microop in self.microops:
642817Sksewell@umich.edu            string += "  %s\n" % microop
652817Sksewell@umich.edu        return string
662817Sksewell@umich.edu
672817Sksewell@umich.educlass Macroop(Micro_Container):
682817Sksewell@umich.edu    pass
692817Sksewell@umich.edu
702817Sksewell@umich.educlass Rom(Micro_Container):
712817Sksewell@umich.edu    def __init__(self, name):
722817Sksewell@umich.edu        super(Rom, self).__init__(name)
732817Sksewell@umich.edu        self.externs = {}
742817Sksewell@umich.edu
752817Sksewell@umich.edu##########################################################################
762817Sksewell@umich.edu#
772817Sksewell@umich.edu# Support classes
782817Sksewell@umich.edu#
792817Sksewell@umich.edu##########################################################################
802817Sksewell@umich.edu
813784Sgblack@eecs.umich.educlass Label(object):
8212406Sgabeblack@google.com    def __init__(self):
833784Sgblack@eecs.umich.edu        self.extern = False
843784Sgblack@eecs.umich.edu        self.name = ""
8512406Sgabeblack@google.com
863784Sgblack@eecs.umich.educlass Block(object):
878887Sgeoffrey.blake@arm.com    def __init__(self):
888733Sgeoffrey.blake@arm.com        self.statements = []
899023Sgblack@eecs.umich.edu
909023Sgblack@eecs.umich.educlass Statement(object):
919023Sgblack@eecs.umich.edu    def __init__(self):
929023Sgblack@eecs.umich.edu        self.is_microop = False
939023Sgblack@eecs.umich.edu        self.is_directive = False
948541Sgblack@eecs.umich.edu
952817Sksewell@umich.educlass Microop(Statement):
962817Sksewell@umich.edu    def __init__(self):
972817Sksewell@umich.edu        super(Microop, self).__init__()
982817Sksewell@umich.edu        self.mnemonic = ""
9910110Sandreas.hansson@arm.com        self.labels = []
1002817Sksewell@umich.edu        self.is_microop = True
10110190Sakash.bagdia@arm.com        self.params = ""
10210190Sakash.bagdia@arm.com
10310190Sakash.bagdia@arm.comclass Directive(Statement):
10411005Sandreas.sandberg@arm.com    def __init__(self):
1055714Shsul@eecs.umich.edu        super(Directive, self).__init__()
1065714Shsul@eecs.umich.edu        self.name = ""
1075714Shsul@eecs.umich.edu        self.is_directive = True
1085715Shsul@eecs.umich.edu
10910110Sandreas.hansson@arm.com##########################################################################
1105715Shsul@eecs.umich.edu#
1115715Shsul@eecs.umich.edu# Functions that handle common tasks
1122817Sksewell@umich.edu#
1132817Sksewell@umich.edu##########################################################################
1142817Sksewell@umich.edu
1152817Sksewell@umich.edudef print_error(message):
1163548Sgblack@eecs.umich.edu    print
1172817Sksewell@umich.edu    print "*** %s" % message
1182817Sksewell@umich.edu    print
1198541Sgblack@eecs.umich.edu
1208541Sgblack@eecs.umich.edudef handle_statement(parser, container, statement):
1218754Sgblack@eecs.umich.edu    if statement.is_microop:
12211886Sbrandon.potter@amd.com        try:
12311886Sbrandon.potter@amd.com            microop = eval('parser.microops[statement.mnemonic](%s)' %
1248852Sandreas.hansson@arm.com                    statement.params)
1252817Sksewell@umich.edu        except:
1268852Sandreas.hansson@arm.com            print_error("Error creating microop object.")
1273675Sktlim@umich.edu            raise
1288706Sandreas.hansson@arm.com        try:
1298706Sandreas.hansson@arm.com            for label in statement.labels:
1308799Sgblack@eecs.umich.edu                container.labels[label.name] = microop
1318852Sandreas.hansson@arm.com                if label.extern:
1328706Sandreas.hansson@arm.com                    container.externs[label.name] = microop
1332817Sksewell@umich.edu            container.add_microop(microop)
1342817Sksewell@umich.edu        except:
1352817Sksewell@umich.edu            print_error("Error adding microop.")
1362817Sksewell@umich.edu            raise
1372817Sksewell@umich.edu    elif statement.is_directive:
1382817Sksewell@umich.edu        try:
1392817Sksewell@umich.edu            eval('container.%s()' % statement.name)
1402817Sksewell@umich.edu        except:
14110407Smitch.hayenga@arm.com            print_error("Error executing directive.")
14210407Smitch.hayenga@arm.com            print container.directives
1432817Sksewell@umich.edu            raise
1442817Sksewell@umich.edu    else:
14510407Smitch.hayenga@arm.com        raise Exception, "Didn't recognize the type of statement", statement
1462817Sksewell@umich.edu
1472817Sksewell@umich.edu##########################################################################
14810407Smitch.hayenga@arm.com#
1492817Sksewell@umich.edu# Lexer specification
1502817Sksewell@umich.edu#
1512817Sksewell@umich.edu##########################################################################
1522817Sksewell@umich.edu
1532817Sksewell@umich.edu# Error handler.  Just call exit.  Output formatted to work under
1548777Sgblack@eecs.umich.edu# Emacs compile-mode.  Optional 'print_traceback' arg, if set to True,
1552817Sksewell@umich.edu# prints a Python stack backtrace too (can be handy when trying to
1562817Sksewell@umich.edu# debug the parser itself).
1572817Sksewell@umich.edudef error(lineno, string, print_traceback = False):
1582817Sksewell@umich.edu    # Print a Python stack backtrace if requested.
1592817Sksewell@umich.edu    if (print_traceback):
1602817Sksewell@umich.edu        traceback.print_exc()
1612817Sksewell@umich.edu    if lineno != 0:
1622817Sksewell@umich.edu        line_str = "%d:" % lineno
1632817Sksewell@umich.edu    else:
1642817Sksewell@umich.edu        line_str = ""
1652817Sksewell@umich.edu    sys.exit("%s %s" % (line_str, string))
1662817Sksewell@umich.edu
1672817Sksewell@umich.edureserved = ('DEF', 'MACROOP', 'ROM', 'EXTERN')
1682817Sksewell@umich.edu
1692817Sksewell@umich.edutokens = reserved + (
1702817Sksewell@umich.edu        # identifier
1712817Sksewell@umich.edu        'ID',
1722817Sksewell@umich.edu        # arguments for microops and directives
1732817Sksewell@umich.edu        'PARAMS',
1742817Sksewell@umich.edu
1752817Sksewell@umich.edu        'LPAREN', 'RPAREN',
1762817Sksewell@umich.edu        'LBRACE', 'RBRACE',
1772817Sksewell@umich.edu        'COLON', 'SEMI', 'DOT',
17813557Sgabeblack@google.com        'NEWLINE'
17913557Sgabeblack@google.com        )
18013557Sgabeblack@google.com
18112106SRekai.GonzalezAlberquilla@arm.com# New lines are ignored at the top level, but they end statements in the
18212106SRekai.GonzalezAlberquilla@arm.com# assembler
18312106SRekai.GonzalezAlberquilla@arm.comstates = (
18413557Sgabeblack@google.com    ('asm', 'exclusive'),
18513557Sgabeblack@google.com    ('params', 'exclusive'),
18613557Sgabeblack@google.com)
18712106SRekai.GonzalezAlberquilla@arm.com
18812106SRekai.GonzalezAlberquilla@arm.comreserved_map = { }
1899426SAndreas.Sandberg@ARM.comfor r in reserved:
1902817Sksewell@umich.edu    reserved_map[r.lower()] = r
19113557Sgabeblack@google.com
19213557Sgabeblack@google.comdef t_ANY_COMMENT(t):
19313557Sgabeblack@google.com    r'\#[^\n]*(?=\n)'
19412106SRekai.GonzalezAlberquilla@arm.com    #print "t_ANY_COMMENT %s" % t.value
19512106SRekai.GonzalezAlberquilla@arm.com
1969426SAndreas.Sandberg@ARM.comdef t_ANY_MULTILINECOMMENT(t):
1972817Sksewell@umich.edu    r'/\*([^/]|((?<!\*)/))*\*/'
19813557Sgabeblack@google.com    #print "t_ANY_MULTILINECOMMENT %s" % t.value
19913557Sgabeblack@google.com
20013557Sgabeblack@google.comdef t_params_COLON(t):
20112109SRekai.GonzalezAlberquilla@arm.com    r':'
20212109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('asm')
20312109SRekai.GonzalezAlberquilla@arm.com    #print "t_params_COLON %s" % t.value
20412109SRekai.GonzalezAlberquilla@arm.com    return t
20512109SRekai.GonzalezAlberquilla@arm.com
20612109SRekai.GonzalezAlberquilla@arm.comdef t_asm_ID(t):
20713557Sgabeblack@google.com    r'[A-Za-z_]\w*'
20813557Sgabeblack@google.com    t.type = reserved_map.get(t.value, 'ID')
20913557Sgabeblack@google.com    t.lexer.begin('params')
21012109SRekai.GonzalezAlberquilla@arm.com    #print "t_asm_ID %s" % t.value
21112109SRekai.GonzalezAlberquilla@arm.com    return t
21212109SRekai.GonzalezAlberquilla@arm.com
21312109SRekai.GonzalezAlberquilla@arm.comdef t_ANY_ID(t):
21412109SRekai.GonzalezAlberquilla@arm.com    r'[A-Za-z_]\w*'
21512109SRekai.GonzalezAlberquilla@arm.com    t.type = reserved_map.get(t.value, 'ID')
21612109SRekai.GonzalezAlberquilla@arm.com    #print "t_ANY_ID %s" % t.value
21712109SRekai.GonzalezAlberquilla@arm.com    return t
21812109SRekai.GonzalezAlberquilla@arm.com
21912109SRekai.GonzalezAlberquilla@arm.comdef t_params_PARAMS(t):
22012109SRekai.GonzalezAlberquilla@arm.com    r'([^\n;]|((?<=\\)[\n;]))+'
22112109SRekai.GonzalezAlberquilla@arm.com    t.lineno += t.value.count('\n')
22212109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('asm')
22312109SRekai.GonzalezAlberquilla@arm.com    #print "t_params_PARAMS %s" % t.value
22412109SRekai.GonzalezAlberquilla@arm.com    return t
22512109SRekai.GonzalezAlberquilla@arm.com
22612109SRekai.GonzalezAlberquilla@arm.comdef t_INITIAL_LBRACE(t):
22712109SRekai.GonzalezAlberquilla@arm.com    r'\{'
22812109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('asm')
22912109SRekai.GonzalezAlberquilla@arm.com    #print "t_INITIAL_LBRACE %s" % t.value
23012109SRekai.GonzalezAlberquilla@arm.com    return t
23112109SRekai.GonzalezAlberquilla@arm.com
23212109SRekai.GonzalezAlberquilla@arm.comdef t_asm_RBRACE(t):
23312109SRekai.GonzalezAlberquilla@arm.com    r'\}'
23412109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('INITIAL')
23512109SRekai.GonzalezAlberquilla@arm.com    #print "t_asm_RBRACE %s" % t.value
23612109SRekai.GonzalezAlberquilla@arm.com    return t
23712109SRekai.GonzalezAlberquilla@arm.com
23812109SRekai.GonzalezAlberquilla@arm.comdef t_INITIAL_NEWLINE(t):
23912109SRekai.GonzalezAlberquilla@arm.com    r'\n+'
24012109SRekai.GonzalezAlberquilla@arm.com    t.lineno += t.value.count('\n')
24112109SRekai.GonzalezAlberquilla@arm.com    #print "t_INITIAL_NEWLINE %s" % t.value
24212109SRekai.GonzalezAlberquilla@arm.com
24312109SRekai.GonzalezAlberquilla@arm.comdef t_asm_NEWLINE(t):
24412109SRekai.GonzalezAlberquilla@arm.com    r'\n+'
24512109SRekai.GonzalezAlberquilla@arm.com    t.lineno += t.value.count('\n')
24612109SRekai.GonzalezAlberquilla@arm.com    #print "t_asm_NEWLINE %s" % t.value
24712109SRekai.GonzalezAlberquilla@arm.com    return t
24812109SRekai.GonzalezAlberquilla@arm.com
24912109SRekai.GonzalezAlberquilla@arm.comdef t_params_NEWLINE(t):
25012109SRekai.GonzalezAlberquilla@arm.com    r'\n+'
25112109SRekai.GonzalezAlberquilla@arm.com    t.lineno += t.value.count('\n')
25212109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('asm')
25312109SRekai.GonzalezAlberquilla@arm.com    #print "t_params_NEWLINE %s" % t.value
25412109SRekai.GonzalezAlberquilla@arm.com    return t
25512109SRekai.GonzalezAlberquilla@arm.com
25612109SRekai.GonzalezAlberquilla@arm.comdef t_params_SEMI(t):
25712109SRekai.GonzalezAlberquilla@arm.com    r';'
25812109SRekai.GonzalezAlberquilla@arm.com    t.lexer.begin('asm')
25912109SRekai.GonzalezAlberquilla@arm.com    #print "t_params_SEMI %s" % t.value
26012109SRekai.GonzalezAlberquilla@arm.com    return t
26112109SRekai.GonzalezAlberquilla@arm.com
26212109SRekai.GonzalezAlberquilla@arm.com# Basic regular expressions to pick out simple tokens
26312109SRekai.GonzalezAlberquilla@arm.comt_ANY_LPAREN = r'\('
26412109SRekai.GonzalezAlberquilla@arm.comt_ANY_RPAREN = r'\)'
26512109SRekai.GonzalezAlberquilla@arm.comt_ANY_SEMI   = r';'
26613610Sgiacomo.gabrielli@arm.comt_ANY_DOT    = r'\.'
26713610Sgiacomo.gabrielli@arm.com
26813610Sgiacomo.gabrielli@arm.comt_ANY_ignore = ' \t\x0c'
26913610Sgiacomo.gabrielli@arm.com
27013610Sgiacomo.gabrielli@arm.comdef t_ANY_error(t):
27113610Sgiacomo.gabrielli@arm.com    error(t.lineno, "illegal character '%s'" % t.value[0])
27213610Sgiacomo.gabrielli@arm.com    t.skip(1)
27313610Sgiacomo.gabrielli@arm.com
2749920Syasuko.eckert@amd.com##########################################################################
27512106SRekai.GonzalezAlberquilla@arm.com#
27612106SRekai.GonzalezAlberquilla@arm.com# Parser specification
2779920Syasuko.eckert@amd.com#
2789920Syasuko.eckert@amd.com##########################################################################
2792817Sksewell@umich.edu
28013557Sgabeblack@google.com# Start symbol for a file which may have more than one macroop or rom
28113557Sgabeblack@google.com# specification.
28213557Sgabeblack@google.comdef p_file(t):
28312106SRekai.GonzalezAlberquilla@arm.com    'file : opt_rom_or_macros'
2849426SAndreas.Sandberg@ARM.com
2852817Sksewell@umich.edudef p_opt_rom_or_macros_0(t):
28613557Sgabeblack@google.com    'opt_rom_or_macros : '
28713557Sgabeblack@google.com
28813557Sgabeblack@google.comdef p_opt_rom_or_macros_1(t):
28912106SRekai.GonzalezAlberquilla@arm.com    'opt_rom_or_macros : rom_or_macros'
29012106SRekai.GonzalezAlberquilla@arm.com
2919426SAndreas.Sandberg@ARM.comdef p_rom_or_macros_0(t):
2922817Sksewell@umich.edu    'rom_or_macros : rom_or_macro'
29313557Sgabeblack@google.com
29413557Sgabeblack@google.comdef p_rom_or_macros_1(t):
29513557Sgabeblack@google.com    'rom_or_macros : rom_or_macros rom_or_macro'
29612109SRekai.GonzalezAlberquilla@arm.com
29712109SRekai.GonzalezAlberquilla@arm.comdef p_rom_or_macro_0(t):
29812109SRekai.GonzalezAlberquilla@arm.com    '''rom_or_macro : rom_block'''
29913557Sgabeblack@google.com
30013557Sgabeblack@google.comdef p_rom_or_macro_1(t):
30113557Sgabeblack@google.com    '''rom_or_macro : macroop_def'''
30212109SRekai.GonzalezAlberquilla@arm.com
30312109SRekai.GonzalezAlberquilla@arm.com# A block of statements
30412109SRekai.GonzalezAlberquilla@arm.comdef p_block(t):
30513557Sgabeblack@google.com    'block : LBRACE statements RBRACE'
30613610Sgiacomo.gabrielli@arm.com    block = Block()
30713610Sgiacomo.gabrielli@arm.com    block.statements = t[2]
30813610Sgiacomo.gabrielli@arm.com    t[0] = block
30913610Sgiacomo.gabrielli@arm.com
31013610Sgiacomo.gabrielli@arm.com# Defines a section of microcode that should go in the current ROM
31113610Sgiacomo.gabrielli@arm.comdef p_rom_block(t):
31213610Sgiacomo.gabrielli@arm.com    'rom_block : DEF ROM block SEMI'
31313557Sgabeblack@google.com    for statement in t[3].statements:
31413557Sgabeblack@google.com        handle_statement(t.parser, t.parser.rom, statement)
31512106SRekai.GonzalezAlberquilla@arm.com    t[0] = t.parser.rom
3169920Syasuko.eckert@amd.com
3179920Syasuko.eckert@amd.com# Defines a macroop that jumps to an external label in the ROM
3187720Sgblack@eecs.umich.edudef p_macroop_def_0(t):
3197720Sgblack@eecs.umich.edu    'macroop_def : DEF MACROOP ID LPAREN ID RPAREN SEMI'
3207720Sgblack@eecs.umich.edu    t[0] = t[4]
3217720Sgblack@eecs.umich.edu
3227720Sgblack@eecs.umich.edu# Defines a macroop that is combinationally generated
3237720Sgblack@eecs.umich.edudef p_macroop_def_1(t):
3247720Sgblack@eecs.umich.edu    'macroop_def : DEF MACROOP ID block SEMI'
3258733Sgeoffrey.blake@arm.com    try:
3268733Sgeoffrey.blake@arm.com        curop = t.parser.macro_type(t[3])
3272817Sksewell@umich.edu    except TypeError:
3287720Sgblack@eecs.umich.edu        print_error("Error creating macroop object.")
3297720Sgblack@eecs.umich.edu        raise
3302817Sksewell@umich.edu    for statement in t[4].statements:
3312817Sksewell@umich.edu        handle_statement(t.parser, curop, statement)
3327720Sgblack@eecs.umich.edu    t.parser.macroops[t[3]] = curop
3337720Sgblack@eecs.umich.edu
3342817Sksewell@umich.edudef p_statements_0(t):
3357720Sgblack@eecs.umich.edu    'statements : statement'
3367720Sgblack@eecs.umich.edu    if t[1]:
3377720Sgblack@eecs.umich.edu        t[0] = [t[1]]
3385259Sksewell@umich.edu    else:
3392817Sksewell@umich.edu        t[0] = []
34013557Sgabeblack@google.com
3415715Shsul@eecs.umich.edudef p_statements_1(t):
3424172Ssaidi@eecs.umich.edu    'statements : statements statement'
3434172Ssaidi@eecs.umich.edu    if t[2]:
3444172Ssaidi@eecs.umich.edu        t[1].append(t[2])
34513557Sgabeblack@google.com    t[0] = t[1]
3465715Shsul@eecs.umich.edu
3472817Sksewell@umich.edudef p_statement(t):
3482817Sksewell@umich.edu    'statement : content_of_statement end_of_statement'
34913582Sgabeblack@google.com    t[0] = t[1]
3502817Sksewell@umich.edu
3512817Sksewell@umich.edu# A statement can be a microop or an assembler directive
3522817Sksewell@umich.edudef p_content_of_statement_0(t):
35313582Sgabeblack@google.com    '''content_of_statement : microop
3542817Sksewell@umich.edu                            | directive'''
35512106SRekai.GonzalezAlberquilla@arm.com    t[0] = t[1]
3566313Sgblack@eecs.umich.edu
3572817Sksewell@umich.edudef p_content_of_statement_1(t):
3582817Sksewell@umich.edu    'content_of_statement : '
3592817Sksewell@umich.edu    pass
3602817Sksewell@umich.edu
3612817Sksewell@umich.edu# Statements are ended by newlines or a semi colon
3622817Sksewell@umich.edudef p_end_of_statement(t):
3632817Sksewell@umich.edu    '''end_of_statement : NEWLINE
3642817Sksewell@umich.edu                        | SEMI'''
3652817Sksewell@umich.edu    pass
3662817Sksewell@umich.edu
36711877Sbrandon.potter@amd.comdef p_microop_0(t):
36811877Sbrandon.potter@amd.com    'microop : labels ID'
3692817Sksewell@umich.edu    microop = Microop()
3702817Sksewell@umich.edu    microop.labels = t[1]
3712817Sksewell@umich.edu    microop.mnemonic = t[2]
3728777Sgblack@eecs.umich.edu    t[0] = microop
3735595Sgblack@eecs.umich.edu
37413557Sgabeblack@google.comdef p_microop_1(t):
37513557Sgabeblack@google.com    'microop : ID'
3765595Sgblack@eecs.umich.edu    microop = Microop()
3775595Sgblack@eecs.umich.edu    microop.mnemonic = t[1]
3785595Sgblack@eecs.umich.edu    t[0] = microop
3799382SAli.Saidi@ARM.com
3809382SAli.Saidi@ARM.comdef p_microop_2(t):
3819382SAli.Saidi@ARM.com    'microop : labels ID PARAMS'
3829382SAli.Saidi@ARM.com    microop = Microop()
3839382SAli.Saidi@ARM.com    microop.labels = t[1]
38413557Sgabeblack@google.com    microop.mnemonic = t[2]
38513557Sgabeblack@google.com    microop.params = t[3]
3869382SAli.Saidi@ARM.com    t[0] = microop
3879382SAli.Saidi@ARM.com
3889382SAli.Saidi@ARM.comdef p_microop_3(t):
3899382SAli.Saidi@ARM.com    'microop : ID PARAMS'
3905595Sgblack@eecs.umich.edu    microop = Microop()
39113557Sgabeblack@google.com    microop.mnemonic = t[1]
39213557Sgabeblack@google.com    microop.params = t[2]
3939426SAndreas.Sandberg@ARM.com    t[0] = microop
39413557Sgabeblack@google.com
39513557Sgabeblack@google.comdef p_labels_0(t):
3969920Syasuko.eckert@amd.com    'labels : label'
39712109SRekai.GonzalezAlberquilla@arm.com    t[0] = [t[1]]
39812109SRekai.GonzalezAlberquilla@arm.com
39912109SRekai.GonzalezAlberquilla@arm.comdef p_labels_1(t):
40012109SRekai.GonzalezAlberquilla@arm.com    'labels : labels label'
40112109SRekai.GonzalezAlberquilla@arm.com    t[1].append(t[2])
40212109SRekai.GonzalezAlberquilla@arm.com    t[0] = t[1]
40313557Sgabeblack@google.com
40413557Sgabeblack@google.comdef p_label_0(t):
40512109SRekai.GonzalezAlberquilla@arm.com    'label : ID COLON'
40612109SRekai.GonzalezAlberquilla@arm.com    label = Label()
40712109SRekai.GonzalezAlberquilla@arm.com    label.is_extern = False
40812109SRekai.GonzalezAlberquilla@arm.com    label.text = t[1]
40912109SRekai.GonzalezAlberquilla@arm.com    t[0] = label
41012109SRekai.GonzalezAlberquilla@arm.com
41112109SRekai.GonzalezAlberquilla@arm.comdef p_label_1(t):
41212109SRekai.GonzalezAlberquilla@arm.com    'label : EXTERN ID COLON'
41312109SRekai.GonzalezAlberquilla@arm.com    label = Label()
41412109SRekai.GonzalezAlberquilla@arm.com    label.is_extern = True
41512109SRekai.GonzalezAlberquilla@arm.com    label.text = t[2]
41612109SRekai.GonzalezAlberquilla@arm.com    t[0] = label
41712109SRekai.GonzalezAlberquilla@arm.com
41812109SRekai.GonzalezAlberquilla@arm.comdef p_directive(t):
41912109SRekai.GonzalezAlberquilla@arm.com    'directive : DOT ID'
42012109SRekai.GonzalezAlberquilla@arm.com    directive = Directive()
42113610Sgiacomo.gabrielli@arm.com    directive.name = t[2]
42213610Sgiacomo.gabrielli@arm.com    t[0] = directive
42313610Sgiacomo.gabrielli@arm.com
42413610Sgiacomo.gabrielli@arm.com# Parse error handler.  Note that the argument here is the offending
42513610Sgiacomo.gabrielli@arm.com# *token*, not a grammar symbol (hence the need to use t.value)
42613610Sgiacomo.gabrielli@arm.comdef p_error(t):
4279920Syasuko.eckert@amd.com    if t:
4289920Syasuko.eckert@amd.com        error(t.lineno, "syntax error at '%s'" % t.value)
4292817Sksewell@umich.edu    else:
4302817Sksewell@umich.edu        error(0, "unknown syntax error", True)
4312817Sksewell@umich.edu
432class MicroAssembler(object):
433
434    def __init__(self, macro_type, microops, rom):
435        self.lexer = lex.lex()
436        self.parser = yacc.yacc()
437        self.parser.macro_type = macro_type
438        self.parser.macroops = {}
439        self.parser.microops = microops
440        self.parser.rom = rom
441
442    def assemble(self, asm):
443        self.parser.parse(asm, lexer=self.lexer)
444        # Begin debug printing
445        for macroop in self.parser.macroops.values():
446            print macroop
447        print self.parser.rom
448        # End debug printing
449        macroops = self.parser.macroops
450        self.parser.macroops = {}
451        return macroops
452