/*Orion Lawlor's Simple x86 assembly Examples, olawlor@acm.org, 2004/7/29
Shows how to use MMX instructions via mmintrin.h.
*/
#include <stdio.h>
#include <mmintrin.h>

typedef unsigned long long uint64_t;
void tryMMX(uint64_t a,uint64_t b) {
	// load into MMX
	__m64 ma=*(__m64 *)&a;
	__m64 mb=*(__m64 *)&b;
	// do MMX operations
	__m64 mprod=_mm_mullo_pi16(ma,mb);
	// extract back out
	uint64_t prod=*(uint64_t *)&mprod;
	printf("Product is 0x%016llx\n",prod);
}

volatile float val=1.0;
int main() {
	// Make some values
	//  (gcc 3.2 series gives ICE if you try to load MMX constants directly!)
	uint64_t a=0x0001000200030004llu;
	uint64_t b=0x0003000300030003llu;
	tryMMX(a,b);
	
	/* floating point calculations done after any MMX instruction,
	   but before mm_empty, come out as NaNs: 
	*/
	float pre_val=val*2.0;
	_mm_empty();
	float post_val=val*2.0;
	printf("Floating-point: before MMX flush: %.2f\n",pre_val);
	printf("Floating-point:  after MMX flush: %.2f\n",post_val);
}
/*<@>
<@> ******** Program output: ********
<@> Product is 0x000300060009000c
<@> Floating-point: before MMX flush: nan
<@> Floating-point:  after MMX flush: 2.00
<@> */
