Ejemplo n.º 1
0
 def parse_label_def(self, tok):
     if tok.endswith(':'):
         label = tok[:len(tok) - 1]
         if label in regset:
             raise ParseException(
                 "register name {} cannot be used as a label".format(label))
         if label in self.p.labels.keys():
             raise ParseException(
                 "label name {} already exists".format(label))
         self.p.labels[label] = len(self.p.instrs)
         return True
     return False
Ejemplo n.º 2
0
def p_unsigned(p):
    """unsigned : NUMBER"""
    if not isinstance(p[1], int):
        raise ParseException(
            "ERROR line {0}: expected int, found float".format(p.lineno(1)))
    if p[1] < 0:
        raise ParseException("ERROR line {0}: unsigned int required".format(
            p.lineno(1)))
    # validate that it will fit in 16 bits
    if (p[1] & ~0xffff) is not 0:
        print "WARNING line {0}: unsigned immediate larger than 16 bits".format(
            p.lineno(1))
    p[0] = p[1]
Ejemplo n.º 3
0
    def parse(self):
        lines = []

        for line in self.src:
            toks = parse_line(line)
            lines.append(toks)
            hasInstr = False

            for tok in toks:
                if tok.startswith('#'):
                    break
                if self.parse_label_def(tok):
                    if hasInstr:
                        raise ParseException(
                            "cannot define label " + tok +
                            " after an instruction in the same line")
                    continue
                if self.parse_instr(tok):
                    hasInstr = True
                    continue

        self.p.args = [Int(0) for i in range(len(self.p.instrs) * 2)]

        instrIndex = -1
        for toks in lines:
            hasInstr = False
            argIndex = 0
            for tok in toks:
                if tok.startswith('#'):
                    break
                if tok.endswith(':'):
                    continue
                if tok in opset:
                    instrIndex += 1
                    hasInstr = True
                    continue
                if not hasInstr:
                    raise ParseException("found argument token " + tok +
                                         " without instruction")
                if self.parse_register(tok, instrIndex, argIndex) or \
                    self.parse_label_value(tok, instrIndex, argIndex) or \
                    self.parse_address(tok, instrIndex, argIndex):
                    argIndex += 1
                    continue
                if self.parse_value(tok, instrIndex, argIndex):
                    argIndex += 1

        self.p.instrs.append(opcode._OP_END)
Ejemplo n.º 4
0
def p_instruction_3reg(p):
    """instruction : i_3GPR GPR ',' GPR ',' GPR
                   | i_3GPR GPR ',' GPR ','
                   | i_3GPR GPR ',' GPR
                   | i_3GPR GPR ','
                   | i_3GPR GPR
                   | i_3GPR
                   | i_3DPR dpr ',' dpr ',' dpr
                   | i_3DPR dpr ',' dpr ','
                   | i_3DPR dpr ',' dpr
                   | i_3DPR dpr ','
                   | i_3DPR dpr
                   | i_3DPR
                   | i_3FPR FPR ',' FPR ',' FPR
                   | i_3FPR FPR ',' FPR ','
                   | i_3FPR FPR ',' FPR
                   | i_3FPR FPR ','
                   | i_3FPR FPR
                   | i_3FPR
    """
    if len(p) is 7:
        p[0] = {i_opcode: p[1], i_rd: p[2], i_rs1: p[4], i_rs2: p[6]}
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 5
0
def p_instruction_2gpr_num(p):
    """instruction : i_2GPR_INT GPR ',' GPR ',' NAME
                   | i_2GPR_INT GPR ',' GPR ',' int
                   | i_2GPR_INT GPR ',' GPR ','
                   | i_2GPR_INT GPR ',' GPR
                   | i_2GPR_INT GPR ','
                   | i_2GPR_INT GPR
                   | i_2GPR_INT
                   | i_2GPR_UINT GPR ',' GPR ',' NAME
                   | i_2GPR_UINT GPR ',' GPR ',' unsigned
                   | i_2GPR_UINT GPR ',' GPR ','
                   | i_2GPR_UINT GPR ',' GPR
                   | i_2GPR_UINT GPR ','
                   | i_2GPR_UINT GPR
                   | i_2GPR_UINT
    """
    if len(p) is 7:
        p[0] = {i_opcode: p[1], i_rd: p[2], i_rs1: p[4]}
        # label
        if p.slice[6].type == "NAME":
            p[0][i_label] = p[6]
        # num
        else:
            p[0][i_immediate] = p[6]
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 6
0
def p_instruction_gpr_arg(p):
    """instruction : i_GPR_NAME GPR ',' NAME
                   | i_GPR_NAME GPR ','
                   | i_GPR_NAME GPR
                   | i_GPR_NAME
                   | i_GPR_UINT GPR ',' NAME
                   | i_GPR_UINT GPR ',' unsigned
                   | i_GPR_UINT GPR ','
                   | i_GPR_UINT GPR
                   | i_GPR_UINT
    """
    if len(p) is 5:
        p[0] = {i_opcode: p[1]}
        # these branch instructions use rs1
        if p.slice[1].type == "i_GPR_NAME":
            p[0][i_rs1] = p[2]
        # but lhi uses rd...
        else:
            p[0][i_rd] = p[2]
        # label
        if p.slice[4].type == "NAME":
            p[0][i_label] = p[4]
        # number
        else:
            p[0][i_immediate] = p[4]
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 7
0
def p_error(p):
    if p is not None:
        # line counter isn't auto incremented due to exception
        p.lexer.lineno += 1
        raise ParseException(
            "ERROR line {0}: unknown token type {1} value \"{2}\"".format(
                p.lineno, p.type, p.value))
Ejemplo n.º 8
0
def p_directive_unknown(p):
    """directive : DIRECTIVE numlist
                 | DIRECTIVE stringlist
                 | DIRECTIVE
    """
    raise ParseException("ERROR line {0}: unknown directive {1}".format(
        p.lineno(1), p[1]))
Ejemplo n.º 9
0
def p_dpr(p):
    """dpr : FPR"""
    if int(p[1][1:]) not in range(0, 31, 2):
        raise ParseException(
            "ERROR line {0}: register {1} invalid, even number register "
            "required".format(p.lineno(1), p[1]))
    else:
        p[0] = p[1]
Ejemplo n.º 10
0
def p_directive_word(p):
    """directive : d_WORD numlist
                 | d_WORD
    """
    if len(p) is 3:
        lst = []
        for word in p[2]:
            if not isinstance(word, int):
                raise ParseException(
                    "ERROR line {0}: .word requires integer parameters".format(
                        p.lineno(1)))
            else:
                lst.append(word)
        p[0] = {d_word: lst}
    else:
        raise ParseException(
            "ERROR line {0}: .word requires integer parameters".format(
                p.lineno(1)))
Ejemplo n.º 11
0
def p_directive_space(p):
    """directive : d_SPACE unsigned
                 | d_SPACE
    """
    if len(p) is 3:
        p[0] = {d_space: p[2]}
    else:
        raise ParseException(
            "ERROR line {0}: .space requires 1 integer parameters".format(
                p.lineno(1)))
Ejemplo n.º 12
0
def p_directive_asciiz(p):
    """directive : d_ASCIIZ stringlist
                 | d_ASCIIZ
    """
    if len(p) is 3:
        p[0] = {d_string: p[2]}
    else:
        raise ParseException(
            "ERROR line {0}: .asciiz requires a list of strings.".format(
                p.lineno(1)))
Ejemplo n.º 13
0
 def __init__(self, data):
     data = str(data)
     res = re.match(Number.pattern, data)
     if res:
         data = res.group()
     elif data.lower().startswith('0x'):
         data = int(data, 16)
     else:
         raise ParseException('%s is not a number' % data)
     super(Number, self).__init__(data)
Ejemplo n.º 14
0
def p_directive_align(p):
    """directive : d_ALIGN unsigned
                 | d_ALIGN
    """
    if len(p) is 3:
        p[0] = {d_align: p[2]}
    else:
        raise ParseException(
            "ERROR line {0}: .align requires 1 integer parameter.".format(
                p.lineno(1)))
Ejemplo n.º 15
0
def p_directive_float(p):
    """directive : d_FLOAT numlist
                 | d_FLOAT
    """
    if len(p) is 3:
        p[2] = [float(x) for x in p[2]]
        p[0] = {d_float: p[2]}
    else:
        raise ParseException(
            "ERROR line {0}: .float requires float parameters".format(
                p.lineno(1)))
Ejemplo n.º 16
0
def p_int(p):
    """int : NUMBER"""
    if not isinstance(p[1], int):
        raise ParseException(
            "ERROR line {0}: expected int, found float".format(p.lineno(1)))
    imm_max = int(2**16) - 1
    imm_min = -int(2**16)
    if p[1] > imm_max or p[1] < imm_min:
        print "WARNING line {0}: signed immediate larger than 16 bits".format(
            p.lineno(1))
    p[0] = p[1]
Ejemplo n.º 17
0
def p_directive_double(p):
    """directive : d_DOUBLE numlist
                 | d_DOUBLE
    """
    if len(p) is 3:
        p[2] = [float(x) for x in p[2]]
        p[0] = {d_double: p[2]}
    else:
        raise ParseException(
            "ERROR line {0}: .double requires double parameters".format(
                p.lineno(1)))
Ejemplo n.º 18
0
def p_stringlist(p):
    """stringlist : stringlist ',' STRING
                  | stringlist ','
                  | STRING
    """
    if len(p) is 4:
        p[1].append(p[3])
        p[0] = p[1]
    elif len(p) is 3:
        raise ParseException("ERROR line {0}: incomplete list".format(
            p.lineno(1)))
    else:
        p[0] = [p[1]]
Ejemplo n.º 19
0
def p_numlist(p):
    """numlist : numlist ',' NUMBER
               | numlist ','
               | NUMBER
    """
    if len(p) is 4:
        p[1].append(p[3])
        p[0] = p[1]
    elif len(p) is 3:
        raise ParseException("ERROR line {0}: incomplete list".format(
            p.lineno(1)))
    else:
        p[0] = [p[1]]
Ejemplo n.º 20
0
def p_instruction_offset_reg(p):
    """instruction : i_OFFSET_GPR offset ',' GPR
                   | i_OFFSET_GPR offset ','
                   | i_OFFSET_GPR offset
                   | i_OFFSET_GPR
                   | i_OFFSET_DPR offset ',' dpr
                   | i_OFFSET_DPR offset ','
                   | i_OFFSET_DPR offset
                   | i_OFFSET_DPR
                   | i_OFFSET_FPR offset ',' FPR
                   | i_OFFSET_FPR offset ','
                   | i_OFFSET_FPR offset
                   | i_OFFSET_FPR
    """
    if len(p) is 5:
        p[0] = p[2]
        p[0][i_opcode] = p[1]
        p[0][i_rd] = p[4]
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 21
0
def p_instruction_reg_offset(p):
    """instruction : i_GPR_OFFSET GPR ',' offset
                   | i_GPR_OFFSET GPR ','
                   | i_GPR_OFFSET GPR
                   | i_GPR_OFFSET
                   | i_DPR_OFFSET dpr ',' offset
                   | i_DPR_OFFSET dpr ','
                   | i_DPR_OFFSET dpr
                   | i_DPR_OFFSET
                   | i_FPR_OFFSET FPR ',' offset
                   | i_FPR_OFFSET FPR ','
                   | i_FPR_OFFSET FPR
                   | i_FPR_OFFSET
    """
    if len(p) is 5:
        p[0] = p[4]
        p[0][i_opcode] = p[1]
        p[0][i_rd] = p[2]
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 22
0
def p_instruction_name(p):
    """instruction : i_NAME unsigned
                   | i_NAME NAME
                   | i_NAME
                   | i_GPR GPR
                   | i_GPR
                   | i_NUM unsigned
                   | i_NUM
    """
    if len(p) is 3:
        p[0] = {i_opcode: p[1]}
        # label
        if p.slice[2].type == "NAME":
            p[0][i_label] = p[2]
        # gpr
        elif p.slice[2].type == "GPR":
            p[0][i_rs1] = p[2]
        # number
        else:
            p[0][i_immediate] = p[2]
    else:
        raise ParseException(
            "ERROR line {0}: missing parameter for {1}".format(
                p.lineno(0), p[1]))
Ejemplo n.º 23
0
 def parse(self, text):
     parser = self.parser
     try:
         return parser.parse(text)
     except Exception, e:
         raise ParseException(e, text, self.type, self.rule)