コード例 #1
0
ファイル: serialize.py プロジェクト: mbrukman/Cwerg
def ProcessLine(token: List, unit: ir.Unit, fun: Optional[ir.Fun],
                cpu_regs: Dict[str, ir.Reg]):
    opc = o.Opcode.Table.get(token[0])
    if not opc:
        raise ir.ParseError(f"unknown opcode/directive: {token}")
    if opc == o.LEA:
        if token[2] in unit.fun_syms:
            opc = o.LEA_FUN
        elif token[2] in unit.mem_syms:
            opc = o.LEA_MEM
        elif token[2] in fun.stk_syms:
            opc = o.LEA_STK

        if opc != o.LEA_FUN and len(token) < 4:
            token.append("0")
    if len(token) - 1 != len(opc.operand_kinds):
        raise ir.ParseError("operand number %d mismatch: %s" %
                            (len(opc.operand_kinds), token))

    if token[0].startswith("."):
        operands = RetrieveActualOperands(unit, fun, opc, token, {})
        directive = DIR_DISPATCHER[token[0]]
        directive(unit, operands)

    else:
        assert fun is not None
        operands = RetrieveActualOperands(unit, fun, opc, token, cpu_regs)
        assert fun.bbls, f"no bbl specified to contain instruction"
        bbl = fun.bbls[-1]
        ins = ir.Ins(opc, operands)
        bbl.AddIns(ins)
        sanity.InsCheckConstraints(ins)
コード例 #2
0
ファイル: serialize.py プロジェクト: robertmuth/Cwerg
def ProcessLine(token: List, unit: ir.Unit, fun: Optional[ir.Fun],
                cpu_regs: Dict[str, ir.Reg]):
    opc = o.Opcode.Table.get(token[0])
    if not opc:
        raise ir.ParseError(f"unknown opcode/directive: {token}")
    # TODO: get rid of this hack which simplifies FrontEndC/translate.py a bit
    if opc == o.LEA:
        if token[2] in fun.reg_syms:
            pass  # in case the register name is shadows a global
        elif token[2] in unit.fun_syms:
            opc = o.LEA_FUN
        elif token[2] in unit.mem_syms:
            opc = o.LEA_MEM
        elif token[2] in fun.stk_syms:
            opc = o.LEA_STK

        if opc != o.LEA_FUN and len(token) < 4:
            token.append("0")
    if len(token) - 1 != len(opc.operand_kinds):
        raise ir.ParseError(
            f"operand number {len(opc.operand_kinds)} mismatch: {token}")

    if token[0].startswith("."):
        operands = RetrieveActualOperands(unit, fun, opc, token, {})
        directive = DIR_DISPATCHER[token[0]]
        directive(unit, operands)

    else:
        assert fun is not None
        operands = RetrieveActualOperands(unit, fun, opc, token, cpu_regs)
        assert fun.bbls, f"no bbl specified to contain instruction"
        bbl = fun.bbls[-1]
        ins = ir.Ins(opc, operands)
        bbl.AddIns(ins)
        sanity.InsCheckConstraints(ins)
コード例 #3
0
def _CheckIns(ins, fun, unit):
    for n, op in enumerate(ins.operands):
        ot = ins.opcode.operand_kinds[n]
        if isinstance(op, ir.Reg):
            assert ot is o.OP_KIND.REG or ot is o.OP_KIND.REG_OR_CONST
            assert op.name in fun.reg_syms, f"UNKNOWN REG: {ins} {op} {fun.reg_syms}"
        elif isinstance(op, ir.Fun):
            assert ot is o.OP_KIND.FUN
            assert (op.kind in {o.FUN_KIND.BUILTIN, o.FUN_KIND.SIGNATURE, o.FUN_KIND.EXTERN} or
                    op.bbls), f"undefined call to {op.name} in {fun.name} [{fun.kind}]"
            if unit:
                assert op.name in unit.fun_syms
        elif isinstance(op, ir.Bbl):
            assert ot is o.OP_KIND.BBL
            assert op.name in fun.bbl_syms
        elif isinstance(op, ir.Mem):
            assert ot is o.OP_KIND.MEM
        elif isinstance(op, ir.Stk):
            assert ot is o.OP_KIND.STK
            assert op.name in fun.stk_syms
        elif isinstance(op, ir.Jtb):
            assert ot is o.OP_KIND.JTB
            assert op.name in fun.jtb_syms
        elif isinstance(op, ir.Const):
            assert ot is o.OP_KIND.CONST or ot is o.OP_KIND.REG_OR_CONST, f"got const wanted {ot} for {ins}"
        else:
            raise ir.ParseError(f"cannot read op type: {op} {ot}")
コード例 #4
0
ファイル: serialize.py プロジェクト: mbrukman/Cwerg
def _GetOperand(unit: ir.Unit, fun: ir.Fun, ok: o.OP_KIND, v: Any) -> Any:
    if ok in o.OKS_LIST:
        assert isinstance(v,
                          list) or v[0] == v[-1] == '"', f"operand {ok}: [{v}]"
    else:
        assert isinstance(v, str), f"bad operand {v} of type [{ok}]"

    if ok is o.OP_KIND.TYPE_LIST:
        out = []
        for kind_name in v:
            kind = o.SHORT_STR_TO_RK.get(kind_name)
            assert kind is not None, f"bad kind name [{kind_name}]"
            out.append(kind)
        return out
    elif ok is o.OP_KIND.FUN:
        return unit.GetFunOrAddForwardDeclaration(v)
    elif ok is o.OP_KIND.BBL:
        return fun.GetBblOrAddForwardDeclaration(v)
    elif ok is o.OP_KIND.BBL_TAB:
        return ExtractBblTable(fun, v)
    elif ok is o.OP_KIND.MEM:
        return unit.GetMem(v)
    elif ok is o.OP_KIND.STK:
        return fun.GetStk(v)
    elif ok is o.OP_KIND.FUN_KIND:
        return o.SHORT_STR_TO_FK[v]
    elif ok is o.OP_KIND.DATA_KIND:
        rk = o.SHORT_STR_TO_RK.get(v)
        assert rk is not None, f"bad kind name [{v}]"
        return rk
    elif ok is o.OP_KIND.NAME:
        assert parse.RE_IDENTIFIER.match(v), f"bad identifier [{v}]"
        return v
    elif ok is o.OP_KIND.NAME_LIST:
        for x in v:
            assert parse.RE_IDENTIFIER.match(x), f"bad identifier [{x}]"
        return v
    elif ok is o.OP_KIND.MEM_KIND:
        return o.SHORT_STR_TO_MK[v]
    elif ok is o.OP_KIND.VALUE:
        return v
    elif ok is o.OP_KIND.BYTES:
        return ExtractBytes(v)
    elif ok is o.OP_KIND.JTB:
        return fun.GetJbl(v)
    else:
        raise ir.ParseError(f"cannot read op type: {ok}")
コード例 #5
0
ファイル: serialize.py プロジェクト: mbrukman/Cwerg
def RetrieveActualOperands(unit: ir.Unit, fun: ir.Fun, opc: o.Opcode,
                           token: List, regs_cpu: Dict[str, ir.Reg]):
    out = []
    assert len(opc.operand_kinds) == len(token) - 1
    last_type: o.DK = o.DK.INVALID
    for ok, tc, token in zip(opc.operand_kinds, opc.constraints, token[1:]):
        if ok in {o.OP_KIND.REG_OR_CONST, o.OP_KIND.REG, o.OP_KIND.CONST}:
            assert isinstance(token,
                              str), f"bad operand {token} of type [{ok}]"
            x = _GetRegOrConstOperand(fun, last_type, ok, tc, token, regs_cpu)
            last_type = x.kind
        else:
            x = _GetOperand(unit, fun, ok, token)
        if x is None:
            raise ir.ParseError(f"cannot read  [{ok}] in ops: {token}")
        out.append(x)
    return out
コード例 #6
0
ファイル: serialize.py プロジェクト: mbrukman/Cwerg
def RenderOperand(v: Any, tc: o.TC):
    if isinstance(v, ir.Reg):
        if v.HasCpuReg():
            return f"{v.name}@{v.cpu_reg.name}"
        return v.name
    elif isinstance(v, ir.Fun):
        return PREFIX + v.name
    elif isinstance(v, ir.Bbl):
        return v.name
    elif isinstance(v, ir.Mem):
        return PREFIX + v.name
    elif isinstance(v, ir.Stk):
        return v.name
    elif isinstance(v, ir.Const):
        if tc in {o.TC.OFFSET, o.TC.SAME_AS_PREV}:
            return str(v.value)
        return str(v)
    elif isinstance(v, ir.Jtb):
        return v.name
    else:
        raise ir.ParseError(f"cannot read op type: {v}")
コード例 #7
0
ファイル: serialize.py プロジェクト: robertmuth/Cwerg
def RenderOperand(v: Any, tc: o.TC):
    if isinstance(v, ir.Reg):
        return _RenderReg(v)
    elif isinstance(v, ir.Fun):
        return PREFIX + v.name
    elif isinstance(v, ir.Bbl):
        return v.name
    elif isinstance(v, ir.Mem):
        return PREFIX + v.name
    elif isinstance(v, ir.Stk):
        return v.name
    elif isinstance(v, ir.Const):
        if tc in {o.TC.OFFSET, o.TC.SAME_AS_PREV}:
            s = str(v.value)
        else:
            s = str(v)
        if s.startswith("inf") or s.startswith("nan"):
            s = "+" + s
        return s
    elif isinstance(v, ir.Jtb):
        return v.name
    else:
        raise ir.ParseError(f"cannot read op type: {v}")