/* When you assign just one register to dword(), the second one is
 * automatically extended to hold the higher dword bits. */

/* parametry: DWORD (ax,dx), DWORD (bx,cx), si */
/* vraci DWORD (ax,dx) ; zbytek == garbage */
/* si ma po navratu z funkce puvodni hodnotu */
void
0x17e(uint32_t dword1 /* ax,dx */, uint32_t dword2 /* cx,bx */, uint16_t something /* si */)
{
	/* [0] == lower, [1] == higher */
	uint16_t dword1W[2] = &dword1, dword2W[2] = &dword2;

	dword1W[0] = dword1W[0]              *              dword2W[1];
	dword1W[1] = dword1W[0] * dword2W[0] + dword1W[1] * dword2W[1] + something;
}

void
function()
{
	uint32_t tmp_dword1, tmp_dword2, tmp_dword3;

	enter();

	save(si);

	ax = *(bp + 0x6);
	ax &= 0xf;
	(uint16_t) *(bp - 0x6) = ax;

	/* XXX: Mozna jsem v tehle dvou assignmentech popletl poradi
	 * registru v dwordech, potreba zkontrolovat! */

	dword(cx, bx) = (uint32_t) *(bp + 0xc) + ax;
	dword(ax, dx) = (uint32_t) *(bp + 0xe) + (uint16_t) *(bp - 0x6);

	((void *()) 0x17e)();

	/* Tohle vypada tak hashovite ;-)). */
	dword(cx, bx) = (uint32_t ...) *(bp + 0x6) + *(bp + 0xa) + *(bp + 0xe) + *(bp + 0x12) + dword(ax, dx);
	dword(ax, dx) = (uint16_t) *(bp - 0x6);

	tmp_dword1 = dword(cx, bx);

	dword(bx, si) = (uint32_t) *(bp + 0x12) + dword(ax, dx);
	/* nemuzu vyoptimalizovat, protoze odporne SI ovlivnuje 0x17e */
	dword(cx, bx) = dword(bx, si);

	dword(ax, dx) = (uint16_t) *(bp - 0x6) + (uint32_t) *(bp + 0x6);
	
	((void *()) 0x17e)();

	dword(cx, bx) = tmp_dword1 + dword(ax, dx);

	(uint32_t) *(bp - 0x4) = dword(cx, bx);
	dword(ax, dx) = (uint32_t) *(bp - 0x4);

	dword(ax, dx) <<= (uint16_t) *(bp - 0x6);

	dword(cx, bx) = dword(ax, dx) + (uint32_t) *(bp - 0x4);
	dword(ax, dx) = (uint32_t) dword(*(bp - 0xa), *(bp - 0xc));

	tmp_dword1 = dword(cx, bx);

	dword(ax, dx) <<= 0x7;

	dword(cx, bx) = tmp_dword1 + dword(ax, dx);

	dword(ax, dx) = (uint32_t) *(bp + 0x12);

	tmp_dword1 = dword(cx, bx);

	dword(ax, dx) <<= 0xb;

	dword(cx, bx) = tmp_dword1 + dword(ax, dx);
	
	dword(ax, dx) = (uint32_t) *(bp + 0xe);

	tmp_dword1 = dword(cx, bx);

	dword(ax, dx) <<= 0x11;

	dword(cx, bx) = tmp_dword1 + dword(ax, dx);
	
	dword(ax, dx) = (uint32_t) *(bp - 0x4);

	dword(ax, dx) <<= 0xd;

	tmp_dword1 = dword(ax, dx);
	
	dword(ax, dx) = (uint32_t) *(bp - 0x4);

	dword(ax, dx) >>= 0xf;

	dword(cx, bx) = tmp_dword1 + dword(ax, dx);

	dword(*(bp - 0x4), *(bp - 0x2)) = dword(cx, bx);

	/* Drop the sign. */
	*(bp - 0x4) &= 0xffff;
	*(bp - 0x2) &= 0x7fff;
	/* (uint32_t) *(bp - 0x4) &= 0x7fffffff; but we're low-endian */

	/* ? */
	*(bp - 0x4) |= 0x0;
	*(bp - 0x2) |= 0x4000;
	/* (uint32_t) *(bp - 0x4) |= 0x40000000; but we're low-endian */

	dword(ax, dx) = (uint32_t) *(bp - 0x4);

	goto _3528;
_3528:
	load(si);

	leave();
}
