예제 #1
0
void Assembler::incq(Indirect mem) {
    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);
    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);
    }
}
예제 #2
0
파일: assembler.cpp 프로젝트: jmgc/pyston
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);
    emitModRM(mode, reg_idx, mem_idx);

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

    if (mode == 0b01) {
        emitByte(mem.offset);
    } else if (mode == 0b10) {
        assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1);
        emitInt(mem.offset, 4);
    }
}
예제 #3
0
파일: assembler.cpp 프로젝트: jmgc/pyston
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);
    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);
    }
}
예제 #4
0
파일: assembler.cpp 프로젝트: jmgc/pyston
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);
    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
파일: assembler.cpp 프로젝트: jmgc/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 = getModeFromOffset(dest.offset);
    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);
}
예제 #6
0
void Assembler::cmp(Indirect mem, Immediate imm, MovType type) {
    int64_t val = imm.val;
    assert(fitsInto<int32_t>(val));

    int src_idx = mem.base.regnum;
    assert(type == MovType::Q || type == MovType::L);
    int rex = type == MovType::Q ? REX_W : 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(0x81);

    if (mem.offset == 0) {
        emitModRM(0b00, 7, src_idx);
        if (needssib)
            emitSIB(0b00, 0b100, src_idx);
    } else if (-0x80 <= mem.offset && mem.offset < 0x80) {
        emitModRM(0b01, 7, src_idx);
        if (needssib)
            emitSIB(0b00, 0b100, src_idx);
        emitByte(mem.offset);
    } else {
        assert(fitsInto<int32_t>(mem.offset));
        emitModRM(0b10, 7, src_idx);
        if (needssib)
            emitSIB(0b00, 0b100, src_idx);
        emitInt(mem.offset, 4);
    }

    emitInt(val, 4);
}
예제 #7
0
void Assembler::emitArith(Immediate imm, Indirect mem, int opcode) {
    int64_t amount = imm.val;
    assert(fitsInto<int32_t>(amount));
    assert(0 <= opcode && opcode < 8);

    int rex = REX_W;

    int mem_idx = mem.base.regnum;
    if (mem_idx >= 8) {
        rex |= REX_B;
        mem_idx -= 8;
    }

    emitRex(rex);

    bool needssib = (mem_idx == 0b100);
    assert(!needssib && "untested");
    int mode = getModeFromOffset(mem.offset, mem_idx);
    assert(mode != 0b10 && "not yet supported");

    if (-0x80 <= amount && amount < 0x80) {
        emitByte(0x83);
        if (needssib)
            emitSIB(0b00, 0b100, mem_idx);
        emitModRM(mode, opcode, mem_idx);
        if (mode == 0b01)
            emitByte(mem.offset);
        emitByte(amount);
    } else {
        emitByte(0x81);
        if (needssib)
            emitSIB(0b00, 0b100, mem_idx);
        emitModRM(mode, opcode, mem_idx);
        if (mode == 0b01)
            emitByte(mem.offset);
        emitInt(amount, 4);
    }
}
예제 #8
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);
    }
}
예제 #9
0
파일: assembler.cpp 프로젝트: jmgc/pyston
void Assembler::mov_generic(Indirect src, Register dest, MovType type) {
    int rex;
    switch (type) {
        case MovType::Q:
        case MovType::ZBQ:
        case MovType::SBQ:
        case MovType::ZWQ:
        case MovType::SWQ:
        case MovType::SLQ:
            rex = REX_W;
            break;
        case MovType::L:
        case MovType::B:
        case MovType::ZBL:
        case MovType::SBL:
        case MovType::ZWL:
        case MovType::SWL:
            rex = 0;
            break;
        default:
            RELEASE_ASSERT(false, "unrecognized MovType");
    }

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

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

    if (rex)
        emitRex(rex);

    // opcode
    switch (type) {
        case MovType::Q:
        case MovType::L:
            emitByte(0x8b);
            break;
        case MovType::B:
            emitByte(0x8a);
            break;
        case MovType::ZBQ:
        case MovType::ZBL:
            emitByte(0x0f);
            emitByte(0xb6);
            break;
        case MovType::SBQ:
        case MovType::SBL:
            emitByte(0x0f);
            emitByte(0xbe);
            break;
        case MovType::ZWQ:
        case MovType::ZWL:
            emitByte(0x0f);
            emitByte(0xb7);
            break;
        case MovType::SWQ:
        case MovType::SWL:
            emitByte(0x0f);
            emitByte(0xbf);
            break;
        case MovType::SLQ:
            emitByte(0x63);
            break;
        default:
            RELEASE_ASSERT(false, "unrecognized MovType");
    }

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