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); } }
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 ); }
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" ); } }
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 ); } }