Exemplo n.º 1
0
Arquivo: s2ir.c Projeto: Faianca/dmd
    void visit(AsmStatement *s)
    {
        block *bpre;
        block *basm;
        Declaration *d;
        Symbol *sym;
        Blockx *blx = irs->blx;

        //printf("AsmStatement::toIR(asmcode = %x)\n", asmcode);
        bpre = blx->curblock;
        block_next(blx,BCgoto,NULL);
        basm = blx->curblock;
        bpre->appendSucc(basm);
        basm->Bcode = s->asmcode;
        basm->Balign = s->asmalign;

        // Loop through each instruction, fixing Dsymbols into Symbol's
        for (code *c = s->asmcode; c; c = c->next)
        {   LabelDsymbol *label;
            block *b;

            switch (c->IFL1)
            {
                case FLblockoff:
                case FLblock:
                    // FLblock and FLblockoff have LabelDsymbol's - convert to blocks
                    label = c->IEVlsym1;
                    b = labelToBlock(irs, s->loc, blx, label);
                    basm->appendSucc(b);
                    c->IEV1.Vblock = b;
                    break;

                case FLdsymbol:
                case FLfunc:
                    sym = toSymbol(c->IEVdsym1);
                    if (sym->Sclass == SCauto && sym->Ssymnum == -1)
                        symbol_add(sym);
                    c->IEVsym1 = sym;
                    c->IFL1 = sym->Sfl ? sym->Sfl : FLauto;
                    break;
            }

            // Repeat for second operand
            switch (c->IFL2)
            {
                case FLblockoff:
                case FLblock:
                    label = c->IEVlsym2;
                    b = labelToBlock(irs, s->loc, blx, label);
                    basm->appendSucc(b);
                    c->IEV2.Vblock = b;
                    break;

                case FLdsymbol:
                case FLfunc:
                    d = c->IEVdsym2;
                    sym = toSymbol(d);
                    if (sym->Sclass == SCauto && sym->Ssymnum == -1)
                        symbol_add(sym);
                    c->IEVsym2 = sym;
                    c->IFL2 = sym->Sfl ? sym->Sfl : FLauto;
                    if (d->isDataseg())
                        sym->Sflags |= SFLlivexit;
                    break;
            }
            //c->print();
        }

        basm->bIasmrefparam = s->refparam;             // are parameters reference?
        basm->usIasmregs = s->regs;                    // registers modified

        block_next(blx,BCasm, NULL);
        basm->prependSucc(blx->curblock);

        if (s->naked)
        {
            blx->funcsym->Stype->Tty |= mTYnaked;
        }
    }