Ejemplo n.º 1
0
def EmitUnitAsBinary(unit: ir.Unit, add_startup_code) -> elf_unit.Unit:
    elfunit = elf_unit.Unit()
    for mem in unit.mems:
        assert mem.kind is not o.MEM_KIND.EXTERN
        if mem.kind == o.MEM_KIND.BUILTIN:
            continue
        elfunit.MemStart(mem.name, mem.alignment,
                         _MEMKIND_TO_SECTION[mem.kind], False)
        for d in mem.datas:
            if isinstance(d, ir.DataBytes):
                elfunit.AddData(d.count, d.data)
            elif isinstance(d, ir.DataAddrFun):
                elfunit.AddFunAddr(enum_tab.RELOC_TYPE_ARM.ABS32, d.size,
                                   d.fun.name)
            elif isinstance(d, ir.DataAddrMem):
                elfunit.AddMemAddr(enum_tab.RELOC_TYPE_ARM.ABS32, d.size,
                                   d.mem.name, d.offset)
            else:
                assert False
        elfunit.MemEnd()

    sec_text = elfunit.sec_text
    for fun in unit.funs:
        elfunit.FunStart(fun.name, 16, assembler.NOP_BYTES)
        for jtb in fun.jtbs:
            elfunit.MemStart(jtb.name, 4, "rodata", True)
            for i in range(jtb.size):
                bbl = jtb.bbl_tab.get(i, jtb.def_bbl)
                elfunit.AddBblAddr(enum_tab.RELOC_TYPE_ARM.ABS32, 4, bbl.name)
            elfunit.MemEnd()

        ctx = regs.FunComputeEmitContext(fun)

        for tmpl in isel_tab.EmitFunProlog(ctx):
            assembler.AddIns(elfunit, tmpl.MakeInsFromTmpl(None, ctx))

        for bbl in fun.bbls:
            elfunit.AddLabel(bbl.name, 4, assembler.NOP_BYTES)
            for ins in bbl.inss:
                if ins.opcode is o.NOP1:
                    isel_tab.HandlePseudoNop1(ins, ctx)
                elif ins.opcode is o.RET:
                    for tmpl in isel_tab.EmitFunEpilog(ctx):
                        assembler.AddIns(elfunit,
                                         tmpl.MakeInsFromTmpl(None, ctx))

                else:
                    pattern = isel_tab.FindMatchingPattern(ins)
                    assert pattern, f"could not find pattern for\n{ins} {ins.operands}"
                    for tmpl in pattern.emit:
                        assembler.AddIns(elfunit,
                                         tmpl.MakeInsFromTmpl(ins, ctx))
        elfunit.FunEnd()
    elfunit.AddLinkerDefs()
    if add_startup_code:
        assembler.AddStartUpCode(elfunit)
    return elfunit
Ejemplo n.º 2
0
def HandleIns(ins: ir.Ins, ctx: regs.EmitContext):
    print("INS: " + serialize.InsRenderToAsm(ins).strip() +
          f"  [{' '.join(OpTypeStr(o) for o in ins.operands)}]")
    if ins.opcode in isel_tab.OPCODES_REQUIRING_SPECIAL_HANDLING:
        print(f"    SPECIAL")
        return
    mismatches = isel_tab.FindtImmediateMismatchesInBestMatchPattern(ins)
    if mismatches == isel_tab.MATCH_IMPOSSIBLE:
        print(f"    MATCH_IMPOSSIBLE")
    elif mismatches != 0:
        pattern = isel_tab.FindMatchingPattern(ins)
        assert pattern is None
        print(f"    mismatches: {mismatches:x}")
    else:
        pattern = isel_tab.FindMatchingPattern(ins)
        print(
            f"PAT: reg:[{' '.join(a.name for a in pattern.type_constraints)}]  "
            f"imm:[{' '.join(a.name for a in pattern.imm_constraints)}]")
        for tmpl in pattern.emit:
            armins = tmpl.MakeInsFromTmpl(ins, ctx)
            print(f"    {disassembler.RenderInstructionSystematic(armins)}")
Ejemplo n.º 3
0
def _FunCodeGenArm32(fun: ir.Fun, _mod: ir.Unit) -> List[str]:
    assert fun.kind is not o.FUN_KIND.EXTERN
    assert ir.FUN_FLAG.STACK_FINALIZED in fun.flags
    assert fun.stk_size >= 0, f"did you call FinalizeStk?"
    # DumpFun("codegen", fun)
    out: List[str] = [
        f"# sig: {fun.render_signature()}  stk_size:{fun.stk_size}",
        f".fun {fun.name} 16",
    ]

    for jtb in fun.jtbs:
        out += _JtbCodeGen(jtb)

    ctx = regs.FunComputeEmitContext(fun)

    out += [
        _RenderIns(tmpl.MakeInsFromTmpl(None, ctx))
        for tmpl in isel_tab.EmitFunProlog(ctx)
    ]
    for bbl in fun.bbls:
        live_out = sorted([r.name for r in bbl.live_out])
        out.append(f".bbl {bbl.name} 4")
        for ins in bbl.inss:
            if ins.opcode is o.NOP1:
                isel_tab.HandlePseudoNop1(ins, ctx)
            elif ins.opcode is o.RET:
                out += [
                    _RenderIns(tmpl.MakeInsFromTmpl(None, ctx))
                    for tmpl in isel_tab.EmitFunEpilog(ctx)
                ]
            else:
                pattern = isel_tab.FindMatchingPattern(ins)
                assert pattern, (
                    f"could not find pattern for\n{ins} {ins.operands} "
                    f"in {fun.name}:{bbl.name}")

                out += [
                    _RenderIns(tmpl.MakeInsFromTmpl(ins, ctx))
                    for tmpl in pattern.emit
                ]
    out.append(f".endfun")
    return out
Ejemplo n.º 4
0
def EmitUnitAsBinary(unit: ir.Unit, add_startup_code) -> assembler.Unit:
    armunit = assembler.Unit()
    for mem in unit.mems:
        if mem.kind == o.MEM_KIND.EXTERN:
            continue
        armunit.MemStart(mem.name, mem.alignment,
                         _MEMKIND_TO_SECTION[mem.kind], False)
        for d in mem.datas:
            if isinstance(d, ir.DataBytes):
                armunit.AddData(d.count, d.data)
            elif isinstance(d, ir.DataAddrFun):
                armunit.AddFunAddr(d.size, d.fun.name)
            elif isinstance(d, ir.DataAddrMem):
                armunit.AddMemAddr(d.size, d.mem.name, d.offset)
            else:
                assert False
        armunit.MemEnd()

    sec_text = armunit.sec_text
    for fun in unit.funs:
        armunit.FunStart(fun.name, 16)
        for jtb in fun.jtbs:
            armunit.MemStart(jtb.name, 4, "rodata", True)
            for i in range(jtb.size):
                bbl = jtb.bbl_tab.get(i, jtb.def_bbl)
                armunit.AddBblAddr(4, bbl.name)
            armunit.MemEnd()

        ctx = regs.FunComputeEmitContext(fun)

        def AppendArmIns(armins: arm.Ins):
            if armins.reloc_kind != enum_tab.RELOC_TYPE_ARM.NONE:
                sym = armunit.FindOrAddSymbol(armins.reloc_symbol,
                                              armins.is_local_sym)
                armunit.AddReloc(armins.reloc_kind, sec_text, sym,
                                 armins.operands[armins.reloc_pos])
                # clear reloc info before proceeding
                armins.reloc_kind = enum_tab.RELOC_TYPE_ARM.NONE
                armins.operands[armins.reloc_pos] = 0
            sec_text.AddData(
                arm.Assemble(armins).to_bytes(4, byteorder='little'))

        for tmpl in isel_tab.EmitFunProlog(ctx):
            AppendArmIns(tmpl.MakeInsFromTmpl(None, ctx))

        for bbl in fun.bbls:
            armunit.AddLabel(bbl.name, 4)
            for ins in bbl.inss:
                if ins.opcode is o.NOP1:
                    isel_tab.HandlePseudoNop1(ins, ctx)
                elif ins.opcode is o.RET:
                    for tmpl in isel_tab.EmitFunEpilog(ctx):
                        AppendArmIns(tmpl.MakeInsFromTmpl(None, ctx))

                else:
                    pattern = isel_tab.FindMatchingPattern(ins)
                    assert pattern, f"could not find pattern for\n{ins} {ins.operands}"
                    for tmpl in pattern.emit:
                        AppendArmIns(tmpl.MakeInsFromTmpl(ins, ctx))
        armunit.FunEnd()
    armunit.AddLinkerDefs()
    if add_startup_code:
        armunit.AddStartUpCode()
    return armunit
Ejemplo n.º 5
0
 def testMov(self):
     for kind in [o.DK.S32, o.DK.U32, o.DK.A32, o.DK.F32]:
         ins = ir.Ins(o.MOV, [ir.Reg(name="0", kind=kind), ir.Reg(name="1", kind=kind)])
         assert isel_tab.FindMatchingPattern(ins) is not None