// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include //----------------------------------------------------------------------------// #define STR_MOVE(reg, len) \ if ((flg & DF) == 0) \ R(reg) += len; \ else \ R(reg) -= len; //----------------------------------------------------------------------------// static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg, val; if (p2) { DECV(v2, p2); reg = p1->reg; val = v2; } else if (p1) { DECV(v1, p1); reg = RDI; val = v1; } else { reg = RDI; val = rax; } writemem(ctx, val, R(reg), len); STR_MOVE(reg, len); } IMPL_START_0(stosb) { stos_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(stosw) { stos_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(stosl) { stos_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(stosq) { stos_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------// static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg1, reg2; if (p2) { reg1 = p1->reg; reg2 = p2->reg; } else if (p1) { reg1 = p1->reg; reg2 = RSI; } else { reg1 = RAX; reg2 = RSI; } R(reg1) = readmem(ctx, R(reg2), len); flg = (R(reg1) == 0 ? flg|ZF : flg&~ZF); STR_MOVE(reg2, len); } IMPL_START_0(lodsb) { lods_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(lodsw) { lods_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(lodsl) { lods_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(lodsq) { lods_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------// static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg, val; if (p2) { DECV(v2, p2); reg = p1->reg; val = v2; } else if (p1) { DECV(v1, p1); reg = RDI; val = v1; } else { reg = RDI; val = rax; } ulong x = readmem(ctx, R(reg), len); COMPARE(x, val); STR_MOVE(reg, len); } IMPL_START_0(scasb) { scas_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(scasw) { scas_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(scasl) { scas_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(scasq) { scas_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------// static void scazs_impl(ctx_t *ctx, acc_t *p1, uint len) { ulong reg; if (p1) reg = p1->reg; else reg = RDI; ulong x = readmem(ctx, R(reg), len); COMPARE(x, 0); if (!(flg&ZF)) { STR_MOVE(reg, len); } } IMPL_START_0(scazsb) { scazs_impl(ctx, p1, 1); } IMPL_END; IMPL_START_0(scazsw) { scazs_impl(ctx, p1, 2); } IMPL_END; IMPL_START_0(scazsl) { scazs_impl(ctx, p1, 4); } IMPL_END; IMPL_START_0(scazsq) { scazs_impl(ctx, p1, 8); } IMPL_END; //----------------------------------------------------------------------------// static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg1, reg2; if (p2) { reg1 = p1->reg; reg2 = p2->reg; } else if (p1) { reg1 = RDI; reg2 = p1->reg; } else { reg1 = RDI; reg2 = RSI; } ulong x1 = readmem(ctx, R(reg1), len); ulong x2 = readmem(ctx, R(reg2), len); COMPARE(x1, x2); STR_MOVE(reg1, len); STR_MOVE(reg2, len); } IMPL_START_0(cmpsb) { cmps_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(cmpsw) { cmps_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(cmpsl) { cmps_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(cmpsq) { cmps_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------// static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg1, reg2; if (p2) { reg1 = p1->reg; reg2 = p2->reg; } else if (p1) { reg1 = RDI; reg2 = p1->reg; } else { reg1 = RDI; reg2 = RSI; } ulong x1 = readmem(ctx, R(reg1), len); ulong x2 = readmem(ctx, R(reg2), len); COMPARE(x1, x2); if (!x1 && !x2) flg &= ~ZF; STR_MOVE(reg1, len); STR_MOVE(reg2, len); } IMPL_START_0(cmpzsb) { cmpzs_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(cmzpsw) { cmpzs_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(cmpzsl) { cmpzs_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(cmpzsq) { cmpzs_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------// static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) { ulong reg1, reg2; if (p2) { reg1 = p1->reg; reg2 = p2->reg; } else if (p1) { reg1 = RDI; reg2 = p1->reg; } else { reg1 = RDI; reg2 = RSI; } ulong x = readmem(ctx, R(reg2), len); writemem(ctx, x, R(reg1), len); flg = (x == 0 ? flg|ZF : flg&~ZF); STR_MOVE(reg1, len); STR_MOVE(reg2, len); } IMPL_START_0(movsb) { movs_impl(ctx, p1, p2, 1); } IMPL_END; IMPL_START_0(movsw) { movs_impl(ctx, p1, p2, 2); } IMPL_END; IMPL_START_0(movsl) { movs_impl(ctx, p1, p2, 4); } IMPL_END; IMPL_START_0(movsq) { movs_impl(ctx, p1, p2, 8); } IMPL_END; //----------------------------------------------------------------------------//