aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/test_mmx.cpp
blob: 230a3650ac6c9e4a917abc1ee4a29ab55c940e0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
	#pragma warning(disable:4514)
	#pragma warning(disable:4786)
#endif
#include <stdio.h>
#include <stdlib.h>
#include "../../include.mie/mie_thread.h"
#include "xbyak/xbyak.h"

class WriteMMX : public Xbyak::CodeGenerator {
public:
	WriteMMX()
	{
#ifdef XBYAK32
		mov(ecx, ptr [esp + 4]);
#endif
		movd(mm0, ecx);
		ret();
	}
	void (*set() const)(int x) { return (void (*)(int x))getCode(); }
};

class ReadMMX : public Xbyak::CodeGenerator {
public:
	ReadMMX()
	{
		movd(eax, mm0);
		ret();
	}
	int (*get() const)() { return (int (*)())getCode(); }
};

class Test : public MIE::ThreadBase<Test> {
	int n_;
public:
	Test(int n)
		: n_(n)
	{
	}
	void threadEntry()
	{
		printf("n=%d\n", n_);
		WriteMMX w;
		w.set()(n_);
		ReadMMX r;
		for (;;) {
			int b = r.get()();
			printf("b=%d\n", b);
			if (b != n_) {
				printf("mm0 has changed!\n");
			}
			MIE::MIE_Sleep(1000);
		}
	}
	void stopThread() { }
};

int main(int argc, char *argv[])
{
#ifdef XBYAK32
	puts("32bit");
#else
	puts("64bit");
#endif
	try {
		int n = atoi(argc == 1 ? "1223" : argv[1]);
		Test test0(n), test1(n + 1);
		test0.beginThread();
		test1.beginThread();

		test0.joinThread();
		test1.joinThread();
	} catch (std::exception& e) {
		printf("ERR:%s\n", e.what());
	} catch (...) {
		printf("unknown error\n");
	}
}