예제 #1
0
void Assembler::movsd(XMMRegister src, Indirect dest) {
    int rex = 0;
    int src_idx = src.regnum;
    int dest_idx = dest.base.regnum;

    if (src_idx >= 8) {
        rex |= REX_R;
        src_idx -= 8;
    }
    if (dest_idx >= 8) {
        trap();
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitByte(0xf2);
    if (rex)
        emitRex(rex);
    emitByte(0x0f);
    emitByte(0x11);

    bool needssib = (dest_idx == 0b100);
    int mode = getModeFromOffset(dest.offset, dest_idx);
    emitModRM(mode, src_idx, dest_idx);

    if (needssib)
        emitSIB(0b00, 0b100, dest_idx);

    if (mode == 0b01) {
        emitByte(dest.offset);
    } else if (mode == 0b10) {
        emitInt(dest.offset, 4);
    }
}
예제 #2
0
void Assembler::incl(Indirect mem) {
    int src_idx = mem.base.regnum;

    int rex = 0;
    if (src_idx >= 8) {
        rex |= REX_B;
        src_idx -= 8;
    }

    assert(src_idx >= 0 && src_idx < 8);

    bool needssib = (src_idx == 0b100);

    if (rex)
        emitRex(rex);
    emitByte(0xff);

    assert(-0x80 <= mem.offset && mem.offset < 0x80);
    if (mem.offset == 0) {
        emitModRM(0b00, 0, src_idx);
        if (needssib)
            emitSIB(0b00, 0b100, src_idx);
    } else {
        emitModRM(0b01, 0, src_idx);
        if (needssib)
            emitSIB(0b00, 0b100, src_idx);
        emitByte(mem.offset);
    }
}
예제 #3
0
void Assembler::movq(Immediate src, Indirect dest) {
    int64_t src_val = src.val;
    assert(fitsInto<int32_t>(src_val));

    int rex = REX_W;

    int dest_idx = dest.base.regnum;

    if (dest_idx >= 8) {
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitRex(rex);
    emitByte(0xc7);

    bool needssib = (dest_idx == 0b100);
    int mode = getModeFromOffset(dest.offset, dest_idx);
    emitModRM(mode, 0, dest_idx);

    if (needssib)
        emitSIB(0b00, 0b100, dest_idx);

    if (mode == 0b01) {
        emitByte(dest.offset);
    } else if (mode == 0b10) {
        emitInt(dest.offset, 4);
    }

    emitInt(src_val, 4);
}
예제 #4
0
void Assembler::mov(Register src, Indirect dest) {
    int rex = REX_W;

    int src_idx = src.regnum;
    int dest_idx = dest.base.regnum;

    assert(src_idx != dest_idx && "while valid this is almost certainly a register allocator bug");

    if (src_idx >= 8) {
        rex |= REX_R;
        src_idx -= 8;
    }
    if (dest_idx >= 8) {
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitRex(rex);
    emitByte(0x89);

    bool needssib = (dest_idx == 0b100);
    int mode = getModeFromOffset(dest.offset, dest_idx);
    emitModRM(mode, src_idx, dest_idx);

    if (needssib)
        emitSIB(0b00, 0b100, dest_idx);

    if (mode == 0b01) {
        emitByte(dest.offset);
    } else if (mode == 0b10) {
        emitInt(dest.offset, 4);
    }
}
예제 #5
0
파일: cb.c 프로젝트: jossk/open-watcom-v2
static void emitMOVZX_EAX_WORD( int off )       // movzx eax,off[ecx]
{
    emitByte( 0x0f );
    emitByte( 0xb7 );
    emitByte( 0x41 );
    emitByte( off );
}
예제 #6
0
void Assembler::decq(Immediate imm) {
    emitByte(0x48);
    emitByte(0xff);
    emitByte(0x0c);
    emitByte(0x25);
    emitInt(imm.val, 4);
}
예제 #7
0
void Assembler::cmp(Indirect mem, Register reg) {
    int mem_idx = mem.base.regnum;
    int reg_idx = reg.regnum;

    int rex = REX_W;
    if (mem_idx >= 8) {
        rex |= REX_B;
        mem_idx -= 8;
    }
    if (reg_idx >= 8) {
        rex |= REX_R;
        reg_idx -= 8;
    }

    assert(mem_idx >= 0 && mem_idx < 8);
    assert(reg_idx >= 0 && reg_idx < 8);

    emitRex(rex);
    emitByte(0x3B);

    if (mem.offset == 0) {
        emitModRM(0b00, reg_idx, mem_idx);
    } else if (-0x80 <= mem.offset && mem.offset < 0x80) {
        emitModRM(0b01, reg_idx, mem_idx);
        emitByte(mem.offset);
    } else {
        assert(fitsInto<int32_t>(mem.offset));
        emitModRM(0b10, reg_idx, mem_idx);
        emitInt(mem.offset, 4);
    }
}
예제 #8
0
void Assembler::emitArith(Immediate imm, Register r, int opcode) {
    // assert(r != RSP && "This breaks unwinding, please don't use.");

    int64_t amount = imm.val;
    RELEASE_ASSERT((-1L << 31) <= amount && amount < (1L << 31) - 1, "");
    assert(0 <= opcode && opcode < 8);

    int rex = REX_W;

    int reg_idx = r.regnum;
    if (reg_idx >= 8) {
        rex |= REX_B;
        reg_idx -= 8;
    }

    emitRex(rex);
    if (-0x80 <= amount && amount < 0x80) {
        emitByte(0x83);
        emitModRM(0b11, opcode, reg_idx);
        emitByte(amount);
    } else {
        emitByte(0x81);
        emitModRM(0b11, opcode, reg_idx);
        emitInt(amount, 4);
    }
}
예제 #9
0
void Assembler::cmp(Indirect mem, Immediate imm) {
    int64_t val = imm.val;
    assert((-1L << 31) <= val && val < (1L << 31) - 1);

    int src_idx = mem.base.regnum;

    int rex = REX_W;
    if (src_idx >= 8) {
        rex |= REX_B;
        src_idx -= 8;
    }

    assert(src_idx >= 0 && src_idx < 8);

    emitRex(rex);
    emitByte(0x81);

    assert(-0x80 <= mem.offset && mem.offset < 0x80);
    if (mem.offset == 0) {
        emitModRM(0b00, 7, src_idx);
    } else {
        emitModRM(0b01, 7, src_idx);
        emitByte(mem.offset);
    }

    emitInt(val, 4);
}
예제 #10
0
void Assembler::lea(Indirect mem, Register reg) {
    int mem_idx = mem.base.regnum;
    int reg_idx = reg.regnum;

    int rex = REX_W;
    if (mem_idx >= 8) {
        rex |= REX_B;
        mem_idx -= 8;
    }
    if (reg_idx >= 8) {
        rex |= REX_R;
        reg_idx -= 8;
    }

    assert(mem_idx >= 0 && mem_idx < 8);
    assert(reg_idx >= 0 && reg_idx < 8);

    emitRex(rex);
    emitByte(0x8D);

    bool needssib = (mem_idx == 0b100);
    int mode = getModeFromOffset(mem.offset, mem_idx);
    emitModRM(mode, reg_idx, mem_idx);

    if (needssib)
        emitSIB(0b00, 0b100, mem_idx);

    if (mode == 0b01) {
        emitByte(mem.offset);
    } else if (mode == 0b10) {
        assert(fitsInto<int32_t>(mem.offset));
        emitInt(mem.offset, 4);
    }
}
예제 #11
0
void Assembler::emitArith(Immediate imm, Register r, int opcode, MovType type) {
    // assert(r != RSP && "This breaks unwinding, please don't use.");

    int64_t amount = imm.val;
    RELEASE_ASSERT(fitsInto<int32_t>(amount), "");
    assert(0 <= opcode && opcode < 8);

    assert(type == MovType::Q || type == MovType::L);
    int rex = type == MovType::Q ? REX_W : 0;

    int reg_idx = r.regnum;
    if (reg_idx >= 8) {
        rex |= REX_B;
        reg_idx -= 8;
    }

    if (rex)
        emitRex(rex);
    if (-0x80 <= amount && amount < 0x80) {
        emitByte(0x83);
        emitModRM(0b11, opcode, reg_idx);
        emitByte(amount);
    } else {
        emitByte(0x81);
        emitModRM(0b11, opcode, reg_idx);
        emitInt(amount, 4);
    }
}
예제 #12
0
void Assembler::callq(Register r) {
    assert(r == R11 && "untested");

    emitRex(REX_B);
    emitByte(0xff);
    emitByte(0xd3);
}
예제 #13
0
파일: cb.c 프로젝트: jossk/open-watcom-v2
static void emitWord( unsigned short word )
{
    char        hi,lo;

    hi = word >> 8;
    lo = word & 0xff;

    emitByte( lo );
    emitByte( hi );
}
void
actionsDir1(opcodeTableEntryType *opcode, int numberOfOperands, valueType **evaluatedOperands)
{
#define	ZERO_PAGE_ADDRESS_BIT		0x00
#define NON_ZERO_PAGE_ADDRESS_BIT	0x08

	if(class==EXPRESSION_OPND && isByteAddress(operand) &&
			isDefined(operand)){
		emitByte(binary | ZERO_PAGE_ADDRESS_BIT);
		emitByte(address);
	} else if (wordCheck(address)) {
예제 #15
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::jmp(JumpDestination dest) {
    assert(dest.type == JumpDestination::FROM_START);
    int offset = dest.offset - (addr - start_addr) - 2;

    if (offset >= -0x80 && offset < 0x80) {
        emitByte(0xeb);
        emitByte(offset);
    } else {
        offset -= 3;
        emitByte(0xe9);
        emitInt(offset, 4);
    }
}
예제 #16
0
파일: cb.c 프로젝트: jossk/open-watcom-v2
/*
 * emitCode - generate callback code for a specified argument list
 */
static int emitCode( int argcnt, int bytecnt, char *array,
                     DWORD fn, int is_cdecl )
{
    int         i;
    int         offset;

    emitOffset = 0;
    emitMOV_EBX_const( fn );            // 32-bit callback routine

    /*
     * emit code to push parms from 16-bit stack onto 32-bit stack
     */
    offset = bytecnt + 6;
    if( is_cdecl ) {
        i = argcnt-1;
    } else {
        i = 0;
    }
    while( argcnt > 0 ) {
        if( array[i] == CB_DWORD ) {
            offset -= 4;
            emitMOV_EAX_DWORD( offset );
        } else {
            offset -= 2;
            emitMOVZX_EAX_WORD( offset );
        }
        emitByte( PUSH_EAX );
        if( is_cdecl ) {
            i--;
        } else {
            i++;
        }
        --argcnt;
    }
    emitByte( PUSH_ES );
    emitByte( POP_DS );
    emitByte( PUSH_CS );
    emitCALL_EBX();
    if( is_cdecl ) {
        emitADD_ESP_const( bytecnt );
        emitMOV_DL_const( 0 );
    } else {
        emitMOV_DL_const( bytecnt );
    }
    emitByte( RET );

    return( emitOffset );

} /* emitCode */
예제 #17
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::set_cond(Register reg, ConditionCode condition) {
    int reg_idx = reg.regnum;

    assert(0 <= reg_idx && reg_idx < 8);

    int rex = 0;
    // Have to emit a blank REX when accessing RSP/RBP/RDI/RSI,
    // since without it this instruction will refer to ah/bh/ch/dh.
    if (reg_idx >= 4 || rex)
        emitRex(rex);

    emitByte(0x0f);
    emitByte(0x90 + condition);
    emitModRM(0b11, 0, reg_idx);
}
예제 #18
0
파일: main.c 프로젝트: NoSuchProcess/Cores
void process_org()
{
    int64_t new_address;

    NextToken();
    new_address = expr();
    if (!rel_out) {
        if (segment==bssseg || segment==tlsseg) {
            bss_address = new_address;
            sections[segment].address = new_address;
        }
        else {
            if (first_org && segment==codeseg) {
               code_address = new_address;
               start_address = new_address;
               sections[0].address = new_address;
               first_org = 0;
            }
            else {
                while(sections[0].address < new_address)
                    emitByte(0x00);
            }
        }
    }
    ScanToEOL();
}
예제 #19
0
파일: assembler.cpp 프로젝트: jmgc/pyston
void Assembler::jmp(Indirect dest) {
    int reg_idx = dest.base.regnum;

    assert(reg_idx >= 0 && reg_idx < 8 && "not yet implemented");
    emitByte(0xFF);
    if (dest.offset == 0) {
        emitModRM(0b00, 0b100, reg_idx);
    } else if (-0x80 <= dest.offset && dest.offset < 0x80) {
        emitModRM(0b01, 0b100, reg_idx);
        emitByte(dest.offset);
    } else {
        assert((-1L << 31) <= dest.offset && dest.offset < (1L << 31) - 1);
        emitModRM(0b10, 0b100, reg_idx);
        emitInt(dest.offset, 4);
    }
}
예제 #20
0
파일: main.c 프로젝트: NoSuchProcess/Cores
void process_fill()
{
    char sz = 'b';
    int64_t count;
    int64_t val;
    int64_t nn;

    if (*inptr=='.') {
        inptr++;
        if (strchr("bchwBCHW",*inptr)) {
            sz = tolower(*inptr);
            inptr++;
        }
        else
            printf("Illegal fill size.\r\n");
    }
    SkipSpaces();
    NextToken();
    count = expr();
    prevToken();
    need(',');
    NextToken();
    val = expr();
    prevToken();
    for (nn = 0; nn < count; nn++)
        switch(sz) {
        case 'b': emitByte(val); break;
        case 'c': emitChar(val); break;
        case 'h': emitHalf(val); break;
        case 'w': emitWord(val); break;
        }
}
예제 #21
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::movsd(Indirect src, XMMRegister dest) {
    int rex = 0;
    int src_idx = src.base.regnum;
    int dest_idx = dest.regnum;

    if (src_idx >= 8) {
        trap();
        rex |= REX_R;
        src_idx -= 8;
    }
    if (dest_idx >= 8) {
        trap();
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitByte(0xf2);
    if (rex)
        emitRex(rex);
    emitByte(0x0f);
    emitByte(0x10);

    bool needssib = (src_idx == 0b100);

    int mode;
    if (src.offset == 0)
        mode = 0b00;
    else if (-0x80 <= src.offset && src.offset < 0x80)
        mode = 0b01;
    else
        mode = 0b10;

    emitModRM(mode, dest_idx, src_idx);

    if (needssib)
        emitSIB(0b00, 0b100, src_idx);

    if (mode == 0b01) {
        emitByte(src.offset);
    } else if (mode == 0b10) {
        emitInt(src.offset, 4);
    }
}
예제 #22
0
void Assembler::clear_reg(Register reg) {
    int reg_idx = reg.regnum;
    // we don't need to generate a REX_W because 32bit instructions will clear the upper 32bits.
    if (reg_idx >= 8) {
        emitRex(REX_R | REX_B);
        reg_idx -= 8;
    }
    emitByte(0x31);
    emitModRM(0b11, reg_idx, reg_idx);
}
예제 #23
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::emitInt(int64_t n, int bytes) {
    assert(bytes > 0 && bytes <= 8);
    if (bytes < 8)
        assert((-1L << (8 * bytes - 1)) <= n && n <= ((1L << (8 * bytes - 1)) - 1));

    for (int i = 0; i < bytes; i++) {
        emitByte(n & 0xff);
        n >>= 8;
    }
    ASSERT(n == 0 || n == -1, "%ld", n);
}
예제 #24
0
void
Violet::Generator::assemble()
{
  emitByte(RETURN);
  for(int i = 0; i < this->scopes.size(); i++)
  {
    (this->scopes[i])->locals.reserve(
      (this->scopes[i])->local_bytes.size()
    );
  }
}
예제 #25
0
void Assembler::emitUInt(uint64_t n, int bytes) {
    assert(bytes > 0 && bytes <= 8);
    if (bytes < 8)
        assert(n < ((1UL << (8 * bytes))));

    for (int i = 0; i < bytes; i++) {
        emitByte(n & 0xff);
        n >>= 8;
    }
    ASSERT(n == 0, "%lu", n);
}
예제 #26
0
void ByteData::emitOpcode (opcode _opcode)
{
    int opcodeLength = _opcode.size();
    opcode::iterator opcode_it = _opcode.begin();
    
    for (int i = 0; i < opcodeLength; i++)
    {
        emitByte (*opcode_it);
        ++opcode_it;
    }   
}
예제 #27
0
파일: main.c 프로젝트: NoSuchProcess/Cores
void process_db()
{
    int64_t val;

    SkipSpaces();
    //NextToken();
    while(token!=tk_eol) {
        SkipSpaces();
        if (*inptr=='\n') break;
        if (*inptr=='"') {
            inptr++;
            while (*inptr!='"') {
                if (*inptr=='\\') {
                    inptr++;
                    switch(*inptr) {
                    case '\\': emitByte('\\'); inptr++; break;
                    case 'r': emitByte(0x13); inptr++; break;
                    case 'n': emitByte(0x0A); inptr++; break;
                    case 'b': emitByte('\b'); inptr++; break;
                    case '"': emitByte('"'); inptr++; break;
                    default: inptr++; break;
                    }
                }
                else {
                    emitByte(*inptr);
                    inptr++;
                }
            }
            inptr++;
        }
        else if (*inptr=='\'') {
            inptr++;
            emitByte(*inptr);
            inptr++;
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
            }
        }
        else {
            NextToken();
            val = expr();
            emitByte(val & 255);
            prevToken();
        }
        SkipSpaces();
        if (*inptr!=',')
            break;
        inptr++;
    }
    ScanToEOL();
}
예제 #28
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::jmp_cond(JumpDestination dest, ConditionCode condition) {
    bool unlikely = false;

    assert(dest.type == JumpDestination::FROM_START);
    int offset = dest.offset - (addr - start_addr) - 2;
    if (unlikely)
        offset--;

    if (offset >= -0x80 && offset < 0x80) {
        if (unlikely)
            emitByte(0x2e);

        emitByte(0x70 | condition);
        emitByte(offset);
    } else {
        offset -= 4;

        if (unlikely)
            emitByte(0x2e);

        emitByte(0x0f);
        emitByte(0x80 | condition);
        emitInt(offset, 4);
    }
}
예제 #29
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::movq(Immediate src, Indirect dest) {
    int64_t src_val = src.val;
    assert((-1L << 31) <= src_val && src_val < (1L << 31) - 1);

    int rex = REX_W;

    int dest_idx = dest.base.regnum;

    if (dest_idx >= 8) {
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitRex(rex);
    emitByte(0xc7);

    bool needssib = (dest_idx == 0b100);

    int mode;
    if (dest.offset == 0)
        mode = 0b00;
    else if (-0x80 <= dest.offset && dest.offset < 0x80)
        mode = 0b01;
    else
        mode = 0b10;

    emitModRM(mode, 0, dest_idx);

    if (needssib)
        emitSIB(0b00, 0b100, dest_idx);

    if (mode == 0b01) {
        emitByte(dest.offset);
    } else if (mode == 0b10) {
        emitInt(dest.offset, 4);
    }

    emitInt(src_val, 4);
}
예제 #30
0
파일: assembler.cpp 프로젝트: kod3r/pyston
void Assembler::mov(Immediate val, Register dest) {
    int rex = REX_W;

    int dest_idx = dest.regnum;
    if (dest_idx >= 8) {
        rex |= REX_B;
        dest_idx -= 8;
    }

    emitRex(rex);
    emitByte(0xb8 + dest_idx);
    emitInt(val.val, 8);
}