示例#1
0
void EmitterAARCH64::emitLoadOrigRegRelative(
        Register dest, Address offset, Register base, codeGen &gen, bool deref)
{

    gen.markRegDefined(dest);

    // either load the address or the contents at that address
    if(deref)
    {
        Register scratch = gen.rs()->getScratchRegister(gen);
        assert(scratch);
        gen.markRegDefined(scratch);
        // load the stored register 'base' into scratch
        insnCodeGen::generateMove(gen, scratch, base, true);
        // move offset(%scratch), %dest
        insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, dest,
            scratch, offset, /*size==8?true:false*/4, insnCodeGen::Offset);
    }
    else
    {
        // load the stored register 'base' into dest
        insnCodeGen::generateMove(gen, dest, base, true);
        // add $offset, %dest
        emitImm(plusOp, dest, offset, dest, gen, false);
    }
}
示例#2
0
void Assem_x86::emitImm( const string &s,int size ) {

    Operand op(s);
    op.parse();
    if( !(op.mode&IMM) ) throw Ex( "operand must be immediate" );
    emitImm( op,size );
}
示例#3
0
void Assem_x86::assemDir( const string &name,const string &op ) {

    if( !op.size() ) throw Ex( "operand error" );

    if( name==".db" ) {
        if( op[0]!='\"' ) emitImm( op,1 );
        else {
            if( op.size()<2 || op[op.size()-1]!='\"' ) throw Ex( "operand error" );
            for( int k=1; k<op.size()-1; ++k ) emit( op[k] );
        }
    } else if( name==".dw" ) {
        emitImm( op,2 );
    } else if( name==".dd" ) {
        emitImm( op,4 );
    } else if( name==".align" ) {
        Operand o( op );
        o.parse();
        if( !(o.mode&IMM) ) throw Ex( "operand must be immediate" );
        align( o.imm );
    } else {
        throw Ex( "unrecognized assembler directive" );
    }
}
示例#4
0
void Assem_x86::assemInst( const string &name,const string &lhs,const string &rhs ) {

    //parse operands
    Operand lop( lhs ),rop( rhs );
    lop.parse();
    rop.parse();

    //find instruction
    int cc=-1;
    Inst *inst=0;

    //kludge for condition code instructions...
    if( name[0]=='j' ) {
        if( (cc=findCC(name.substr(1)))>=0 ) {
            static Inst jCC= { "jCC",IMM,NONE,RW_RD|PLUSCC,"\x2\x0F\x80" };
            inst=&jCC;
        }
    } else if( name[0]=='s' && name.substr( 0,3 )=="set" ) {
        if( (cc=findCC(name.substr(3)))>=0 ) {
            static Inst setCC= { "setne",R_M8,NONE,_2|PLUSCC,"\x2\x0F\x90" };
            inst=&setCC;
        }
    }

    if( inst ) {
        if( !(lop.mode&inst->lmode) || !(rop.mode&inst->rmode) ) throw Ex( "illegal addressing mode" );
    } else {
        InstIter it=instMap.find( name );
        if( it==instMap.end() ) throw Ex( "unrecognized instruction" );
        inst=it->second;
        for(;;) {
            if( (lop.mode&inst->lmode) && (rop.mode&inst->rmode) ) break;
            if( (++inst)->name ) throw Ex( "illegal addressing mode" );
        }
    }

    //16/32 bit modifier - NOP for now
    if( inst->flags & (O16|O32) ) {}

    int k,n=inst->bytes[0];
    for( k=1; k<n; ++k ) emit( inst->bytes[k] );
    if( inst->flags&PLUSREG ) emit( inst->bytes[k]+lop.reg );
    else if( inst->flags&PLUSCC ) emit( inst->bytes[k]+cc );
    else emit( inst->bytes[k] );

    if( inst->flags&(_0|_1|_2|_3|_4|_5|_6|_7|_R ) ) {

        //find the memop;
        const Operand &mop=
            (inst->rmode&(MEM|MEM8|MEM16|MEM32|R_M|R_M8|R_M16|R_M32))?rop:lop;

        //find the spare field value.
        int rm=0;
        switch( inst->flags&(_0|_1|_2|_3|_4|_5|_6|_7|_R ) ) {
        case _0:
            rm=0;
            break;
        case _1:
            rm=1;
            break;
        case _2:
            rm=2;
            break;
        case _3:
            rm=3;
            break;
        case _4:
            rm=4;
            break;
        case _5:
            rm=5;
            break;
        case _6:
            rm=6;
            break;
        case _7:
            rm=7;
            break;
        case _R:
            rm=(inst->rmode&(REG8|REG16|REG32))?rop.reg:lop.reg;
            break;
        }
        rm<<=3;
        if( mop.mode & REG ) {			//reg
            emit( 0xc0|rm|mop.reg );
        } else if( mop.baseReg>=0 ) {		//base, index?
            int mod=mop.offset ? 0x40 : 0x00;
            if( mop.baseLabel.size() || mop.offset<-128 || mop.offset>127 ) mod=0x80;
            if( mop.baseReg==5 && !mod ) mod=0x40;
            if( mop.indexReg>=0 ) {		//base, index!
                emit( mod|rm|4 );
                emit( (mop.shift<<6)|(mop.indexReg<<3)|mop.baseReg );
            } else {						//base, no index!
                if( mop.baseReg!=4 ) emit( mod|rm|mop.baseReg);
                else {
                    emit( mod|rm|4 );
                    emit( (4<<3)|mop.baseReg );
                }
            }
            if( (mod&0xc0)==0x40 ) emit( mop.offset );
            else if( (mod&0xc0)==0x80 ) {
                //reloc
                a_reloc( mop.baseLabel );
                emitd( mop.offset );
            }
        } else if( mop.indexReg>=0 ) {	//index, no base!
            emit( rm|4 );
            emit( (mop.shift<<6)|(mop.indexReg<<3)|5 );
            //reloc
            a_reloc( mop.baseLabel );
            emitd( mop.offset );
        } else {							//[disp]
            emit( rm|5 );
            //reloc
            a_reloc( mop.baseLabel );
            emitd( mop.offset );
        }
    }

    if( inst->flags&RW_RD ) {
        r_reloc( lop.immLabel );
        emitd( lop.imm-4 );
    }

    if( inst->flags&IB ) {
        if( lop.mode&IMM ) emitImm( lop,1 );
        else emitImm( rop,1 );
    } else if( inst->flags&IW ) {
        if( lop.mode&IMM ) emitImm( lop,2 );
        else emitImm( rop,2 );
    } else if( inst->flags&ID ) {
        if( lop.mode&IMM ) emitImm( lop,4 );
        else emitImm( rop,4 );
    }
}