#include <stdint.h>

#define mul(a,b) \
({ \
	register int32_t res; \
	__asm__ __volatile__("mult %0, %1" : : "r" (a), "r" (b)); \
	__asm__ __volatile__("mfhi %0" : "=r" (res)); \
	res; \
})

#define mul0(hi,lo,a,b) \
	__asm__ __volatile__("mult %0, %1" : : "r" (a), "r" (b))

#define muladd(hi,lo,a,b) \
	__asm__ __volatile__("madd %0, %1" : : "r" (a), "r" (b))

#define mulsub(hi,lo,a,b) \
	__asm__ __volatile__("msub %0, %1" : : "r" (a), "r" (b))

#define mulz(hi,lo) \
do { \
	register int32_t t; \
	__asm__ __volatile__("mfhi %0" : "=r" (t)); \
	(hi) = t; \
} while (0)

#define cmuls(dre, dim, are, aim, bre, bim) \
do { \
	register int32_t t1, t2, tre; \
	__asm__ __volatile__("mult %0, %1" : : "r" (are), "r" (bre)); \
	__asm__ __volatile__("msub %0, %1" : : "r" (aim), "r" (bim)); \
	__asm__ __volatile__("mfhi %0; mflo %1" : "=r" (t1), "=r" (t2)); \
	tre = (t1 << 1) | ((uint32_t)t2 >> 31); \
	__asm__ __volatile__("mult %0, %1" : : "r" (are), "r" (bim)); \
	__asm__ __volatile__("madd %0, %1" : : "r" (bre), "r" (aim)); \
	dre = tre; \
	__asm__ __volatile__("mfhi %0; mflo %1" : "=r" (t1), "=r" (t2)); \
	dim = (t1 << 1) | ((uint32_t)t2 >> 31); \
} while (0)

#if __mips_isa_rev >= 2
static inline uint32_t SWAB32(uint32_t x) __attribute__((nomips16));
static inline uint32_t SWAB32(uint32_t x)
{
	__asm__(
	"	wsbh	%0, %1			\n"
	"	rotr	%0, %0, 16		\n"
	: "=r" (x) : "r" (x));
	return x;
}
#define SWAB32 SWAB32
#endif
