int main (int argc, char *argv[]) { MINT *a, *b, *c, *d; short h; mp_set_memory_functions (NULL, NULL, NULL); a = itom (123); b = xtom ("DEADBEEF"); c = itom (0); d = itom (0); move (a, b); madd (a, b, c); msub (a, b, c); mult (a, b, c); mdiv (b, a, c, d); sdiv (b, 2, c, &h); msqrt (a, c, d); pow (b, a, a, c); rpow (a, 3, c); gcd (a, b, c); mcmp (a, b); if (argc > 1) { min (c); mout (a); } mtox (b); mfree(a); exit (0); }
void sdivgen(Node *l, Node *r, Node *ax, Node *dx) { int a, s; uint32 m; vlong c; c = r->vconst; if(c < 0) c = -c; a = sdiv(c, &m, &s); //print("a=%d i=%ld s=%d m=%lux\n", a, (int32)r->vconst, s, m); gins(AMOVL, nodconst(m), ax); gins(AIMULL, l, Z); gins(AMOVL, l, ax); if(a) gins(AADDL, ax, dx); gins(ASHRL, nodconst(31), ax); gins(ASARL, nodconst(s), dx); gins(AADDL, ax, dx); if(r->vconst < 0) gins(ANEGL, Z, dx); }
static void yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift, int op) { long x, maxx, y, y2, yerr, yden, onehalf; Seg **ep, **next, **p, **q, *s; int n, i, ix, cnt, iy, iy2, miny, maxy; Point pt; for(i=0, s=segtab, p=seg; i<nseg; i++, s++) { *p = s; if(s->p0.x == s->p1.x) continue; if(s->p0.x > s->p1.x) { pt = s->p0; s->p0 = s->p1; s->p1 = pt; s->d = -s->d; } s->num = s->p1.y - s->p0.y; s->den = s->p1.x - s->p0.x; s->dz = sdiv(s->num, s->den) << fixshift; s->dzrem = mod(s->num, s->den) << fixshift; s->dz += sdiv(s->dzrem, s->den); s->dzrem = mod(s->dzrem, s->den); p++; } n = p-seg; if(n == 0) return; *p = 0; qsort(seg, n , sizeof(Seg*), xcompare); onehalf = 0; if(fixshift) onehalf = 1 << (fixshift-1); miny = dst->clipr.min.y; maxy = dst->clipr.max.y; x = seg[0]->p0.x; if(x < (dst->clipr.min.x << fixshift)) x = dst->clipr.min.x << fixshift; ix = (x + onehalf) >> fixshift; x = (ix << fixshift) + onehalf; maxx = dst->clipr.max.x << fixshift; ep = next = seg; while(x<maxx) { for(q = p = seg; p < ep; p++) { s = *p; if(s->p1.x < x) continue; s->z += s->dz; s->zerr += s->dzrem; if(s->zerr >= s->den) { s->z++; s->zerr -= s->den; if(s->zerr < 0 || s->zerr >= s->den) print("bad ratzerr1: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); } *q++ = s; } for(p = next; *p; p++) { s = *p; if(s->p0.x >= x) break; if(s->p1.x < x) continue; s->z = s->p0.y; s->z += smuldivmod(x - s->p0.x, s->num, s->den, &s->zerr); if(s->zerr < 0 || s->zerr >= s->den) print("bad ratzerr2: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); *q++ = s; } ep = q; next = p; if(ep == seg) { if(*next == 0) break; ix = (next[0]->p0.x + onehalf) >> fixshift; x = (ix << fixshift) + onehalf; continue; } zsort(seg, ep); for(p = seg; p < ep; p++) { cnt = 0; y = p[0]->z; yerr = p[0]->zerr; yden = p[0]->den; iy = (y + onehalf) >> fixshift; if(iy >= maxy) break; if(iy < miny) iy = miny; cnt += p[0]->d; p++; for(;;) { if(p == ep) { print("yscan: fill to infinity"); return; } cnt += p[0]->d; if((cnt&wind) == 0) break; p++; } y2 = p[0]->z; iy2 = (y2 + onehalf) >> fixshift; if(iy2 <= miny) continue; if(iy2 > maxy) iy2 = maxy; if(iy == iy2) { if(yerr*p[0]->den + p[0]->zerr*yden > p[0]->den*yden) y++; iy = (y + y2) >> (fixshift+1); fillpoint(dst, ix, iy, src, sp, op); } } x += (1<<fixshift); ix++; } }
static void xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op) { long y, maxy, x, x2, xerr, xden, onehalf; Seg **ep, **next, **p, **q, *s; long n, i, iy, cnt, ix, ix2, minx, maxx; Point pt; void (*fill)(Memimage*, int, int, int, Memimage*, Point, int); fill = fillline; /* * This can only work on 8-bit destinations, since fillcolor is * just using memset on sp.x. * * I'd rather not even enable it then, since then if the general * code is too slow, someone will come up with a better improvement * than this sleazy hack. -rsc * if(clipped && (src->flags&Frepl) && src->depth==8 && Dx(src->r)==1 && Dy(src->r)==1) { fill = fillcolor; sp.x = membyteval(src); } * */ USED(clipped); for(i=0, s=segtab, p=seg; i<nseg; i++, s++) { *p = s; if(s->p0.y == s->p1.y) continue; if(s->p0.y > s->p1.y) { pt = s->p0; s->p0 = s->p1; s->p1 = pt; s->d = -s->d; } s->num = s->p1.x - s->p0.x; s->den = s->p1.y - s->p0.y; s->dz = sdiv(s->num, s->den) << fixshift; s->dzrem = mod(s->num, s->den) << fixshift; s->dz += sdiv(s->dzrem, s->den); s->dzrem = mod(s->dzrem, s->den); p++; } n = p-seg; if(n == 0) return; *p = 0; qsort(seg, p-seg , sizeof(Seg*), ycompare); onehalf = 0; if(fixshift) onehalf = 1 << (fixshift-1); minx = dst->clipr.min.x; maxx = dst->clipr.max.x; y = seg[0]->p0.y; if(y < (dst->clipr.min.y << fixshift)) y = dst->clipr.min.y << fixshift; iy = (y + onehalf) >> fixshift; y = (iy << fixshift) + onehalf; maxy = dst->clipr.max.y << fixshift; ep = next = seg; while(y<maxy) { for(q = p = seg; p < ep; p++) { s = *p; if(s->p1.y < y) continue; s->z += s->dz; s->zerr += s->dzrem; if(s->zerr >= s->den) { s->z++; s->zerr -= s->den; if(s->zerr < 0 || s->zerr >= s->den) print("bad ratzerr1: %ld den %ld dzrem %ld\n", s->zerr, s->den, s->dzrem); } *q++ = s; } for(p = next; *p; p++) { s = *p; if(s->p0.y >= y) break; if(s->p1.y < y) continue; s->z = s->p0.x; s->z += smuldivmod(y - s->p0.y, s->num, s->den, &s->zerr); if(s->zerr < 0 || s->zerr >= s->den) print("bad ratzerr2: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); *q++ = s; } ep = q; next = p; if(ep == seg) { if(*next == 0) break; iy = (next[0]->p0.y + onehalf) >> fixshift; y = (iy << fixshift) + onehalf; continue; } zsort(seg, ep); for(p = seg; p < ep; p++) { cnt = 0; x = p[0]->z; xerr = p[0]->zerr; xden = p[0]->den; ix = (x + onehalf) >> fixshift; if(ix >= maxx) break; if(ix < minx) ix = minx; cnt += p[0]->d; p++; for(;;) { if(p == ep) { print("xscan: fill to infinity"); return; } cnt += p[0]->d; if((cnt&wind) == 0) break; p++; } x2 = p[0]->z; ix2 = (x2 + onehalf) >> fixshift; if(ix2 <= minx) continue; if(ix2 > maxx) ix2 = maxx; if(ix == ix2 && detail) { if(xerr*p[0]->den + p[0]->zerr*xden > p[0]->den*xden) x++; ix = (x + x2) >> (fixshift+1); ix2 = ix+1; } (*fill)(dst, ix, ix2, iy, src, sp, op); } y += (1<<fixshift); iy++; } }
CompileOutput *Compiler::Compile(AMXRef amx) { Prepare(amx); Disassembler disasm(amx); Instruction instr; bool error = false; while (!error && disasm.Decode(instr, error)) { if (!Process(instr)) { error = true; break; } switch (instr.opcode().GetId()) { case OP_LOAD_PRI: load_pri(instr.operand()); break; case OP_LOAD_ALT: load_alt(instr.operand()); break; case OP_LOAD_S_PRI: load_s_pri(instr.operand()); break; case OP_LOAD_S_ALT: load_s_alt(instr.operand()); break; case OP_LREF_PRI: lref_pri(instr.operand()); break; case OP_LREF_ALT: lref_alt(instr.operand()); break; case OP_LREF_S_PRI: lref_s_pri(instr.operand()); break; case OP_LREF_S_ALT: lref_s_alt(instr.operand()); break; case OP_LOAD_I: load_i(); break; case OP_LODB_I: lodb_i(instr.operand()); break; case OP_CONST_PRI: const_pri(instr.operand()); break; case OP_CONST_ALT: const_alt(instr.operand()); break; case OP_ADDR_PRI: addr_pri(instr.operand()); break; case OP_ADDR_ALT: addr_alt(instr.operand()); break; case OP_STOR_PRI: stor_pri(instr.operand()); break; case OP_STOR_ALT: stor_alt(instr.operand()); break; case OP_STOR_S_PRI: stor_s_pri(instr.operand()); break; case OP_STOR_S_ALT: stor_s_alt(instr.operand()); break; case OP_SREF_PRI: sref_pri(instr.operand()); break; case OP_SREF_ALT: sref_alt(instr.operand()); break; case OP_SREF_S_PRI: sref_s_pri(instr.operand()); break; case OP_SREF_S_ALT: sref_s_alt(instr.operand()); break; case OP_STOR_I: stor_i(); break; case OP_STRB_I: strb_i(instr.operand()); break; case OP_LIDX: lidx(); break; case OP_LIDX_B: lidx_b(instr.operand()); break; case OP_IDXADDR: idxaddr(); break; case OP_IDXADDR_B: idxaddr_b(instr.operand()); break; case OP_ALIGN_PRI: align_pri(instr.operand()); break; case OP_ALIGN_ALT: align_alt(instr.operand()); break; case OP_LCTRL: lctrl(instr.operand(), instr.address() + instr.size()); break; case OP_SCTRL: sctrl(instr.operand()); break; case OP_MOVE_PRI: move_pri(); break; case OP_MOVE_ALT: move_alt(); break; case OP_XCHG: xchg(); break; case OP_PUSH_PRI: push_pri(); break; case OP_PUSH_ALT: push_alt(); break; case OP_PUSH_C: push_c(instr.operand()); break; case OP_PUSH: push(instr.operand()); break; case OP_PUSH_S: push_s(instr.operand()); break; case OP_POP_PRI: pop_pri(); break; case OP_POP_ALT: pop_alt(); break; case OP_STACK: // value stack(instr.operand()); break; case OP_HEAP: heap(instr.operand()); break; case OP_PROC: proc(); break; case OP_RET: ret(); break; case OP_RETN: retn(); break; case OP_JUMP_PRI: jump_pri(); break; case OP_CALL: case OP_JUMP: case OP_JZER: case OP_JNZ: case OP_JEQ: case OP_JNEQ: case OP_JLESS: case OP_JLEQ: case OP_JGRTR: case OP_JGEQ: case OP_JSLESS: case OP_JSLEQ: case OP_JSGRTR: case OP_JSGEQ: { cell dest = instr.operand() - reinterpret_cast<cell>(amx.code()); switch (instr.opcode().GetId()) { case OP_CALL: call(dest); break; case OP_JUMP: jump(dest); break; case OP_JZER: jzer(dest); break; case OP_JNZ: jnz(dest); break; case OP_JEQ: jeq(dest); break; case OP_JNEQ: jneq(dest); break; case OP_JLESS: jless(dest); break; case OP_JLEQ: jleq(dest); break; case OP_JGRTR: jgrtr(dest); break; case OP_JGEQ: jgeq(dest); break; case OP_JSLESS: jsless(dest); break; case OP_JSLEQ: jsleq(dest); break; case OP_JSGRTR: jsgrtr(dest); break; case OP_JSGEQ: jsgeq(dest); break; } break; } case OP_SHL: shl(); break; case OP_SHR: shr(); break; case OP_SSHR: sshr(); break; case OP_SHL_C_PRI: shl_c_pri(instr.operand()); break; case OP_SHL_C_ALT: shl_c_alt(instr.operand()); break; case OP_SHR_C_PRI: shr_c_pri(instr.operand()); break; case OP_SHR_C_ALT: shr_c_alt(instr.operand()); break; case OP_SMUL: smul(); break; case OP_SDIV: sdiv(); break; case OP_SDIV_ALT: sdiv_alt(); break; case OP_UMUL: umul(); break; case OP_UDIV: udiv(); break; case OP_UDIV_ALT: udiv_alt(); break; case OP_ADD: add(); break; case OP_SUB: sub(); break; case OP_SUB_ALT: sub_alt(); break; case OP_AND: and_(); break; case OP_OR: or_(); break; case OP_XOR: xor_(); break; case OP_NOT: not_(); break; case OP_NEG: neg(); break; case OP_INVERT: invert(); break; case OP_ADD_C: add_c(instr.operand()); break; case OP_SMUL_C: smul_c(instr.operand()); break; case OP_ZERO_PRI: zero_pri(); break; case OP_ZERO_ALT: zero_alt(); break; case OP_ZERO: zero(instr.operand()); break; case OP_ZERO_S: zero_s(instr.operand()); break; case OP_SIGN_PRI: sign_pri(); break; case OP_SIGN_ALT: sign_alt(); break; case OP_EQ: eq(); break; case OP_NEQ: neq(); break; case OP_LESS: less(); break; case OP_LEQ: leq(); break; case OP_GRTR: grtr(); break; case OP_GEQ: geq(); break; case OP_SLESS: sless(); break; case OP_SLEQ: sleq(); break; case OP_SGRTR: sgrtr(); break; case OP_SGEQ: sgeq(); break; case OP_EQ_C_PRI: eq_c_pri(instr.operand()); break; case OP_EQ_C_ALT: eq_c_alt(instr.operand()); break; case OP_INC_PRI: inc_pri(); break; case OP_INC_ALT: inc_alt(); break; case OP_INC: inc(instr.operand()); break; case OP_INC_S: inc_s(instr.operand()); break; case OP_INC_I: inc_i(); break; case OP_DEC_PRI: dec_pri(); break; case OP_DEC_ALT: dec_alt(); break; case OP_DEC: dec(instr.operand()); break; case OP_DEC_S: dec_s(instr.operand()); break; case OP_DEC_I: dec_i(); break; case OP_MOVS: movs(instr.operand()); break; case OP_CMPS: cmps(instr.operand()); break; case OP_FILL: fill(instr.operand()); break; case OP_HALT: halt(instr.operand()); break; case OP_BOUNDS: bounds(instr.operand()); break; case OP_SYSREQ_PRI: sysreq_pri(); break; case OP_SYSREQ_C: { const char *name = amx.GetNativeName(instr.operand()); if (name == 0) { error = true; } else { sysreq_c(instr.operand(), name); } break; } case OP_SYSREQ_D: { const char *name = amx.GetNativeName(amx.FindNative(instr.operand())); if (name == 0) { error = true; } else { sysreq_d(instr.operand(), name); } break; } case OP_SWITCH: switch_(CaseTable(amx, instr.operand())); break; case OP_CASETBL: casetbl(); break; case OP_SWAP_PRI: swap_pri(); break; case OP_SWAP_ALT: swap_alt(); break; case OP_PUSH_ADR: push_adr(instr.operand()); break; case OP_NOP: nop(); break; case OP_BREAK: break_(); break; default: error = true; } } if (error && error_handler_ != 0) { error_handler_->Execute(instr); } return Finish(error); }