mirror of
https://github.com/ptitSeb/box86.git
synced 2026-11-08 10:10:14 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32accd0e77 | ||
|
|
c4b3fc25e0 | ||
|
|
676b02b5aa | ||
|
|
3c8e34f691 | ||
|
|
630f42e9e2 | ||
|
|
58b0338dff | ||
|
|
80c77bad96 | ||
|
|
771ff1b2e2 | ||
|
|
cef87f7f7d | ||
|
|
e8d4ffc782 | ||
|
|
85397e9895 | ||
|
|
8194ad9728 | ||
|
|
b82f203a9d | ||
|
|
151e2ae3a4 | ||
|
|
0072524d5d | ||
|
|
949417f412 | ||
|
|
21fea0f195 | ||
|
|
9c1317f899 | ||
|
|
127a48f199 | ||
|
|
66b8c58cc1 | ||
|
|
39bb606c06 | ||
|
|
626826f33e | ||
|
|
a9082f60b6 | ||
|
|
3b394b8f0d | ||
|
|
a108a23c56 | ||
|
|
51baede9c1 | ||
|
|
d601b42ddc | ||
|
|
d430332c45 | ||
|
|
63fae1b6c8 | ||
|
|
c45d3d80ab | ||
|
|
57e9e95411 | ||
|
|
68fb291c83 | ||
|
|
f3ee727bc4 | ||
|
|
21ed47c4cb | ||
|
|
2147d92d9d | ||
|
|
1465ff8aad | ||
|
|
ac895e3dad | ||
|
|
983a3d9926 | ||
|
|
ecec73547f | ||
|
|
6ed82e7f7d | ||
|
|
83a9b2cab5 | ||
|
|
666e41a0cb | ||
|
|
c78be09d7f | ||
|
|
21023e9802 | ||
|
|
38c07f2a2f | ||
|
|
e6d124aed4 | ||
|
|
8335a8c2d9 | ||
|
|
6f7a513051 | ||
|
|
43189a2914 | ||
|
|
3bf9e4d989 | ||
|
|
fe3419957e | ||
|
|
f8c8a5d596 | ||
|
|
9ee7f84015 | ||
|
|
36b316746b | ||
|
|
0131572edf | ||
|
|
d74e873a85 | ||
|
|
be53b823d3 | ||
|
|
e5b6c8b6e0 | ||
|
|
ecf7bfd848 | ||
|
|
2a7b848d0e | ||
|
|
fa5fa7b5c0 | ||
|
|
b7283b8d9d | ||
|
|
b8d72023c5 | ||
|
|
e10a710591 | ||
|
|
9ee030a566 | ||
|
|
a8e96764b5 | ||
|
|
c43f1d882c | ||
|
|
1e67cefc43 | ||
|
|
5cdc1b9fa2 | ||
|
|
ab75a3e2d3 | ||
|
|
21d097853b | ||
|
|
2e3bdbefc7 | ||
|
|
a19773cfb0 | ||
|
|
1988eb0366 | ||
|
|
54d5aaa11d | ||
|
|
205ec1f4dc | ||
|
|
005367ea3c | ||
|
|
8ac9bc30a2 | ||
|
|
f0691e56fc | ||
|
|
bc06c277ec | ||
|
|
1341a4a55f | ||
|
|
82cf77b9d9 | ||
|
|
10db79df4a | ||
|
|
bce188e217 | ||
|
|
220a64af1f | ||
|
|
e73fa8f3fb | ||
|
|
053a75f5d5 | ||
|
|
bcb19dbe5d | ||
|
|
039c62f740 | ||
|
|
7663aacd1b | ||
|
|
fd5bf804ec | ||
|
|
70d18cfb7c | ||
|
|
1e32ccc9c7 | ||
|
|
23fa99d148 | ||
|
|
0e3ce6d8b1 | ||
|
|
970384559f | ||
|
|
2f8a939485 | ||
|
|
4f13c33628 | ||
|
|
4ef5da404c | ||
|
|
15fa9f687c | ||
|
|
331e5700a2 | ||
|
|
1411d44b51 | ||
|
|
bf53a76223 | ||
|
|
ecbc1e6642 | ||
|
|
7dc5b501f3 | ||
|
|
af67f69ee2 | ||
|
|
8f2a4ea880 | ||
|
|
eb44fd62fb | ||
|
|
46f015da9d | ||
|
|
705414a3d0 | ||
|
|
4591d337cb | ||
|
|
54e13be02a | ||
|
|
1524e883cd | ||
|
|
7a65bd60e9 | ||
|
|
8c1694e530 | ||
|
|
292d1455b6 | ||
|
|
9c69702011 | ||
|
|
3554d6decb | ||
|
|
7fb36acf85 | ||
|
|
ed3296978e | ||
|
|
4b212f91bf | ||
|
|
94f451c4b7 | ||
|
|
13bbf105ad | ||
|
|
3eb16fb7bd | ||
|
|
e85bcb671a | ||
|
|
1a0888ca51 | ||
|
|
3043f5066f | ||
|
|
b3b55d2d74 | ||
|
|
58426cbfb6 | ||
|
|
4a88ff38ea | ||
|
|
8d96ff02e3 | ||
|
|
eaa6ecb9cc | ||
|
|
027909bddc | ||
|
|
0eca6a8b94 | ||
|
|
24494ba143 | ||
|
|
a813321ad4 | ||
|
|
a43884ff66 | ||
|
|
27b269f53a | ||
|
|
d698861478 | ||
|
|
be02c88792 | ||
|
|
99059ffb19 | ||
|
|
a4752afacf | ||
|
|
a320c37681 | ||
|
|
42a9a40ac4 | ||
|
|
6320a07d17 | ||
|
|
5e251cf478 | ||
|
|
355a2fa8e5 | ||
|
|
78ed9d07f2 | ||
|
|
8c38d5dd36 | ||
|
|
f682ca6bf0 | ||
|
|
70a2a2dd1b | ||
|
|
3678f44945 | ||
|
|
5bb473158b | ||
|
|
3f549749c1 | ||
|
|
11535dabe0 | ||
|
|
1c2d36f98a | ||
|
|
8563ba8b70 | ||
|
|
4b43da2081 | ||
|
|
49c650781f | ||
|
|
36e5bf731c | ||
|
|
f4d4116590 | ||
|
|
11281589e0 | ||
|
|
756811a901 | ||
|
|
dd405c7c49 | ||
|
|
20237019e4 | ||
|
|
7682cdce57 | ||
|
|
1dcac1b868 | ||
|
|
5f0add0e82 | ||
|
|
8f2ef48e25 | ||
|
|
4f98f568a7 | ||
|
|
0e0e346e45 | ||
|
|
4388092f11 | ||
|
|
b83c693192 | ||
|
|
9de1bd884f | ||
|
|
1b462b8200 | ||
|
|
d7c75be001 | ||
|
|
957fcc2449 | ||
|
|
328794e4d6 | ||
|
|
af519f6046 | ||
|
|
fa9a059921 | ||
|
|
771d65dc10 | ||
|
|
1dc92c216f | ||
|
|
db4ff551cc | ||
|
|
7abb9a1893 | ||
|
|
60f987ff90 | ||
|
|
f38d122b67 | ||
|
|
a654193f1d | ||
|
|
632a01dbe6 | ||
|
|
ae2e3aed0f | ||
|
|
244b273250 | ||
|
|
27756113ef | ||
|
|
d550293ccc | ||
|
|
74bb2e84f2 | ||
|
|
09d2b067b5 | ||
|
|
6d7f901167 | ||
|
|
bdc839ef87 | ||
|
|
52f7e89fdb | ||
|
|
6a2b45ec5c | ||
|
|
ac0fd0278b | ||
|
|
db06cec325 | ||
|
|
d93e7f92f2 | ||
|
|
d8e94908ff | ||
|
|
8e9d31e670 | ||
|
|
6ed7bbdb21 | ||
|
|
8338ebaa46 | ||
|
|
d4c08eb083 | ||
|
|
c62dc24155 | ||
|
|
f8e2b81160 | ||
|
|
06b38df650 | ||
|
|
00e6ed3feb | ||
|
|
6ffbacd808 | ||
|
|
8e88ca6985 | ||
|
|
ada65fc0da | ||
|
|
52002ebc64 | ||
|
|
a3e25e32a4 | ||
|
|
8aedf8957e | ||
|
|
db7924e26a | ||
|
|
2b2478381a | ||
|
|
59b1e323f7 | ||
|
|
31e7957362 | ||
|
|
917a9ba11f | ||
|
|
71f6654062 | ||
|
|
5b1670390a | ||
|
|
f4999d71f3 | ||
|
|
64f52cb1b9 | ||
|
|
905780e47d | ||
|
|
6f176bceae | ||
|
|
21a8e20b94 | ||
|
|
20b2b083f5 | ||
|
|
bfeedef03b | ||
|
|
d42767414d | ||
|
|
c83f21cc38 | ||
|
|
f1ce0668f8 | ||
|
|
20e6869e53 | ||
|
|
75a3fb0d89 | ||
|
|
0145c5bb34 | ||
|
|
8e3d0835a2 | ||
|
|
9fe432ac60 | ||
|
|
5e46f8825b | ||
|
|
359ba4836d | ||
|
|
fe57003477 | ||
|
|
067eb6d7da | ||
|
|
69ec807d56 | ||
|
|
8462b62c0b | ||
|
|
3313d7a158 | ||
|
|
47581ddb50 | ||
|
|
ccf1249b24 | ||
|
|
ebab21f211 | ||
|
|
0de956191b | ||
|
|
1e648aa3d6 | ||
|
|
89e5517961 | ||
|
|
a4cfa477d6 | ||
|
|
66d5fa5ef8 | ||
|
|
cb09b0978a | ||
|
|
dbd5e1b565 | ||
|
|
66ef165184 | ||
|
|
f92b5851d0 | ||
|
|
36b62b9464 | ||
|
|
d867acd295 | ||
|
|
f0d525ddcc | ||
|
|
f82ea51a2b | ||
|
|
1be3d617c7 | ||
|
|
8bc26298a0 | ||
|
|
e6cf41c381 | ||
|
|
657f19d357 | ||
|
|
e681acaf36 | ||
|
|
5142245b1f | ||
|
|
6a49000bc5 | ||
|
|
8d06a36508 | ||
|
|
f120154675 | ||
|
|
ef84c8a635 | ||
|
|
33a2716c43 | ||
|
|
3fcdee46b9 | ||
|
|
8b28872b0e | ||
|
|
29158238bc | ||
|
|
a0191247b9 | ||
|
|
f07af5825c | ||
|
|
fcc5528d77 | ||
|
|
ab13305bc0 | ||
|
|
61075afbb9 | ||
|
|
b4ee108c9c | ||
|
|
e31348b6d5 | ||
|
|
d76efc849f | ||
|
|
76700c1dab | ||
|
|
3f58046288 | ||
|
|
069f488f7b | ||
|
|
320977d84a | ||
|
|
2e7af32cd9 | ||
|
|
c10c86e1d4 | ||
|
|
a4bf1d2c72 | ||
|
|
b3d45c348d | ||
|
|
a4ce2bd549 | ||
|
|
891593c1c9 | ||
|
|
b43e4acc3e | ||
|
|
9cbc531502 | ||
|
|
41c9d92593 | ||
|
|
c2a782839d | ||
|
|
e7653bdda8 | ||
|
|
00a2b44be3 | ||
|
|
bb2d5d43cd | ||
|
|
97aae9521b | ||
|
|
9f2745ad53 | ||
|
|
ec4783bb6f | ||
|
|
5760c04de4 | ||
|
|
4250c61e0f | ||
|
|
c16317850a | ||
|
|
3d325747a5 | ||
|
|
21abac8b06 | ||
|
|
89f05a35e3 | ||
|
|
116e700248 | ||
|
|
db3a80b089 | ||
|
|
09b234e719 | ||
|
|
5f0ca6f03e | ||
|
|
bf3da2d1b5 | ||
|
|
caf0bb9d4d | ||
|
|
753f738368 | ||
|
|
06a19ba790 | ||
|
|
d63a846748 | ||
|
|
3f46f9fb68 | ||
|
|
521dae4695 | ||
|
|
4b7a3046ce | ||
|
|
b0ac567e7a | ||
|
|
455fce9ff5 | ||
|
|
e0ba315761 | ||
|
|
e41be11e9f | ||
|
|
9f0c33016f | ||
|
|
faa13945eb | ||
|
|
989952a873 | ||
|
|
bc9f8df2c2 | ||
|
|
ddface22a8 | ||
|
|
cf18090431 | ||
|
|
cd27cf03e1 | ||
|
|
c0f643dcbe | ||
|
|
84ffab7354 | ||
|
|
cbfd949756 | ||
|
|
55ce03844f | ||
|
|
1451fa8c65 | ||
|
|
d87f90dca3 | ||
|
|
6f8164da52 | ||
|
|
aace0531ab | ||
|
|
91609788d4 | ||
|
|
b5b7019b79 | ||
|
|
2bcafd6ef7 | ||
|
|
0f1092200c | ||
|
|
ccf612a711 | ||
|
|
d8ec77da69 | ||
|
|
aa3efd01cc | ||
|
|
58ca96e2a5 | ||
|
|
5bf7a15f8e | ||
|
|
7d863efcf8 | ||
|
|
6f43a14ddd | ||
|
|
369aa14bff | ||
|
|
4bd4f320bc | ||
|
|
e0340b2a74 | ||
|
|
508b2aa580 | ||
|
|
b8ec0f910c | ||
|
|
c716b3b481 | ||
|
|
ddecd61771 | ||
|
|
88c490b843 | ||
|
|
5998ae57ea | ||
|
|
94c99353fa | ||
|
|
b993866def | ||
|
|
b292efc741 | ||
|
|
bc78375816 | ||
|
|
82e4997624 | ||
|
|
51c64e7dce | ||
|
|
294adeae11 | ||
|
|
95c4c277a1 | ||
|
|
3d517c0bf5 | ||
|
|
2bd3a670e8 | ||
|
|
a621a2b61f | ||
|
|
bc810d16f1 | ||
|
|
fd3f8f5990 | ||
|
|
c713f64d7e | ||
|
|
ed2a8ff73d | ||
|
|
31524ed90b | ||
|
|
1c5aef19ae | ||
|
|
1932f8320a | ||
|
|
ae590d8378 | ||
|
|
124ca7fdc2 | ||
|
|
21128f51f5 | ||
|
|
1af9666622 | ||
|
|
abf66a9cd7 | ||
|
|
5ba8672ac8 | ||
|
|
4616ed9bc3 | ||
|
|
047b9f2eac | ||
|
|
14113faaba | ||
|
|
03b20c3f52 | ||
|
|
26a6eb1922 | ||
|
|
a2f00c5c91 | ||
|
|
dea480e10f | ||
|
|
b7fc2cd5ba | ||
|
|
2aad95726c | ||
|
|
105c56a817 | ||
|
|
3da1ed0a8e | ||
|
|
f46068314c | ||
|
|
914df83ba5 | ||
|
|
d7f5290f14 | ||
|
|
9d37471e4e | ||
|
|
57e75a2fa3 | ||
|
|
3fab879089 | ||
|
|
16cb3d36ba | ||
|
|
74ef17ee94 | ||
|
|
f1c540d877 | ||
|
|
6018e65ab9 | ||
|
|
43190d413c | ||
|
|
a156166a8e | ||
|
|
c8141c63ad | ||
|
|
8dd940804c | ||
|
|
d16f956068 | ||
|
|
082b25d81f | ||
|
|
a0e29198f6 | ||
|
|
b4c5a4c531 | ||
|
|
3a1e6ae5df | ||
|
|
3f7464bf6c | ||
|
|
6aef4501f8 | ||
|
|
3024f27b7a | ||
|
|
e8e1b52a9b | ||
|
|
1c8c76d389 | ||
|
|
a30eedf1e2 | ||
|
|
0b3314607f | ||
|
|
8e7c203772 | ||
|
|
399854342f | ||
|
|
bb692f26d0 | ||
|
|
da5a4c9fbe | ||
|
|
37fc3d0daf | ||
|
|
76a86e2e45 | ||
|
|
a25c32a60b | ||
|
|
4946642fc4 | ||
|
|
2ac59458f3 | ||
|
|
6d329e885f | ||
|
|
902da5c619 | ||
|
|
e9fcef3de5 | ||
|
|
b43ddd46ea | ||
|
|
9c3002928a | ||
|
|
17ec8d8a75 | ||
|
|
d241c818df | ||
|
|
6ff1375e44 | ||
|
|
bb3a13db3b | ||
|
|
ea439a7183 | ||
|
|
fa8355eccc | ||
|
|
62340ea5d8 | ||
|
|
e6deec89f8 | ||
|
|
65fae25715 | ||
|
|
f735f2cbdd | ||
|
|
f5658a6079 | ||
|
|
2b1580b73f | ||
|
|
3c519517c7 | ||
|
|
7389dc616b | ||
|
|
2ff0562a82 | ||
|
|
2ecdc3bb09 | ||
|
|
c1eb7cbfa8 | ||
|
|
45d2ac757e | ||
|
|
875f1d094d | ||
|
|
dc1c986c2c | ||
|
|
32db820b3d | ||
|
|
7bde8a55b4 | ||
|
|
dd083b1e66 | ||
|
|
6199c17441 | ||
|
|
064eb2112d | ||
|
|
10578fb7ee | ||
|
|
ea57c6a212 | ||
|
|
d38c59d3a0 | ||
|
|
36f82eb364 | ||
|
|
9d01904145 | ||
|
|
bb74a811e8 | ||
|
|
d70961afa3 | ||
|
|
3c8bd9c0fb | ||
|
|
e0f37bdde9 | ||
|
|
b638262e12 | ||
|
|
9cd4e70a42 | ||
|
|
c7a4d7dc6f | ||
|
|
582503697e | ||
|
|
308a546cc7 | ||
|
|
3a8ea7de1e | ||
|
|
e2690480d9 | ||
|
|
a48a0499b7 | ||
|
|
1bc817c48a | ||
|
|
317c2f0bf4 | ||
|
|
c4aacb4348 | ||
|
|
978ed8da50 | ||
|
|
13b7202dbb | ||
|
|
70280b7346 | ||
|
|
f00653f216 | ||
|
|
70982f4807 | ||
|
|
b629bd409b | ||
|
|
68c7902bf3 | ||
|
|
721b4bbaf8 | ||
|
|
67aa570b4d | ||
|
|
4be1b75a89 | ||
|
|
05d499d99b | ||
|
|
432e09c37b | ||
|
|
c33683c9df | ||
|
|
b0ea5de0ae | ||
|
|
3e3744cb94 | ||
|
|
9a7fe334b5 | ||
|
|
11c5982a26 | ||
|
|
d91fdc0dcd | ||
|
|
5f4f7bec6c | ||
|
|
4a2ff61fc8 | ||
|
|
3606ef8814 | ||
|
|
734aa87904 | ||
|
|
367235dbd3 | ||
|
|
8050fbd3ca | ||
|
|
b4c664b979 | ||
|
|
22b66a71f4 | ||
|
|
2ed43c3c16 | ||
|
|
2b3983b2e2 | ||
|
|
b85fd74144 | ||
|
|
58565cb40f | ||
|
|
2e9ce77612 | ||
|
|
6925b89c13 | ||
|
|
7c75cc3af8 | ||
|
|
56c540ae13 | ||
|
|
da19b4461f | ||
|
|
c1c3674519 | ||
|
|
e5297fa81a | ||
|
|
7fcbbbe5b6 | ||
|
|
ea49f740c0 | ||
|
|
d29fcfa667 | ||
|
|
b1c8e3dc93 | ||
|
|
3c8b70f224 | ||
|
|
0600886d22 | ||
|
|
6af8045c46 | ||
|
|
582977f20e | ||
|
|
4c72e3c910 | ||
|
|
a0aa2e2458 | ||
|
|
f6a92d6909 | ||
|
|
11c6afa687 | ||
|
|
062207c1fe | ||
|
|
f49b70750a | ||
|
|
15be8fb329 | ||
|
|
0c96d9ecde | ||
|
|
e01134a9c0 | ||
|
|
770f709a24 | ||
|
|
e2a37141da | ||
|
|
5accd2f847 | ||
|
|
46eaabf722 | ||
|
|
807da66d87 | ||
|
|
06861f8577 | ||
|
|
44ee38a868 | ||
|
|
89652e9ff2 | ||
|
|
6f1f35217f | ||
|
|
22c6e81e68 | ||
|
|
ab57dfc5c7 | ||
|
|
8d609ed881 | ||
|
|
0e9a422335 | ||
|
|
5cdd2d4947 | ||
|
|
f946cddd45 | ||
|
|
d45aa0dae9 | ||
|
|
464c7e6b47 | ||
|
|
9e4468acb6 | ||
|
|
dcb49fe731 | ||
|
|
03259e67d9 | ||
|
|
0ea662f57f | ||
|
|
4b629b9b28 | ||
|
|
a8b5ebba18 | ||
|
|
c904d9f66c | ||
|
|
f52c5bc6da | ||
|
|
a074ea8ba6 | ||
|
|
3a3f55f9a2 | ||
|
|
490cabcbe3 | ||
|
|
367c5bcfb1 | ||
|
|
d10de8d7df | ||
|
|
41749db028 | ||
|
|
e30f302de9 | ||
|
|
d119ed10b9 | ||
|
|
9281289a1b | ||
|
|
1683c0c679 | ||
|
|
88a8b9569d | ||
|
|
18aaa03381 | ||
|
|
aa3474d06e | ||
|
|
0accab638f | ||
|
|
29b52bc12e | ||
|
|
5840cd3402 | ||
|
|
926ff0f4f8 | ||
|
|
13689e7eac | ||
|
|
e4ed4ad3a8 | ||
|
|
25e4072fef | ||
|
|
1e6037019e | ||
|
|
da083aaab4 | ||
|
|
7a7853d434 | ||
|
|
eebe12ca27 | ||
|
|
7aaade8780 | ||
|
|
cb185d4d44 | ||
|
|
3f691dc4f0 | ||
|
|
d4c33f71eb | ||
|
|
ad106a07ea | ||
|
|
2ad3a0a7f5 | ||
|
|
dc461d4de6 | ||
|
|
d1a9b50dfe | ||
|
|
9a0da8d011 | ||
|
|
2d7e3877e7 | ||
|
|
0248ae0a96 | ||
|
|
9fd27f3b2c | ||
|
|
4152fcc934 | ||
|
|
53c887a06a | ||
|
|
316e10baa0 | ||
|
|
8a71c6bc4a | ||
|
|
9b806de7b0 | ||
|
|
a14dadc228 | ||
|
|
ca850b3d30 | ||
|
|
c01dbbea0e | ||
|
|
b883307881 | ||
|
|
ab9bcb1e0b | ||
|
|
3dc22ff0b8 | ||
|
|
5e382e12ad | ||
|
|
103e55ff97 | ||
|
|
6140b3eee8 | ||
|
|
09574a69e9 | ||
|
|
c53f961e12 | ||
|
|
a1d370fc04 | ||
|
|
471b679d3f | ||
|
|
e60caa8648 | ||
|
|
ccfc8a8d30 | ||
|
|
6a7b7bec6a | ||
|
|
0926c48aea | ||
|
|
d10a9e40ed | ||
|
|
4df12ee5ea | ||
|
|
433294fb40 | ||
|
|
298fe50dd1 | ||
|
|
1717fffe8f | ||
|
|
41521913d5 | ||
|
|
e75ca5d2ff | ||
|
|
0d2081ed30 | ||
|
|
d6abdc2a55 | ||
|
|
0a0cf77461 | ||
|
|
a5c438068c | ||
|
|
d2c8839a69 | ||
|
|
21b560a3b9 | ||
|
|
b1d8de62d4 | ||
|
|
1e41857d37 | ||
|
|
63920e95d3 | ||
|
|
7856b2b7ee | ||
|
|
5daf34ba29 | ||
|
|
e513cbeaaa | ||
|
|
c782ba2429 | ||
|
|
50dae3f5d8 | ||
|
|
d3e6551b40 | ||
|
|
0e1d1a788d | ||
|
|
dfafce7f05 | ||
|
|
eb7381457a | ||
|
|
2f8baf9559 | ||
|
|
34cb03c7df | ||
|
|
d76ecb8a38 | ||
|
|
943c2a0bd9 | ||
|
|
a7552c8bb8 | ||
|
|
8cd78041a2 | ||
|
|
3fe3499ec2 | ||
|
|
70c49f67c4 | ||
|
|
308c316dbf | ||
|
|
c660b3a9aa | ||
|
|
642bb357d3 | ||
|
|
4978177584 | ||
|
|
ae8a69a840 | ||
|
|
383c2be9fc | ||
|
|
1cc4653672 | ||
|
|
6b6daba17a | ||
|
|
d8eb090a7a | ||
|
|
eb2e96f13b | ||
|
|
41201cbb96 | ||
|
|
151115ed10 | ||
|
|
7d4154e0d4 | ||
|
|
7a470daa26 | ||
|
|
a4e40d06ac | ||
|
|
875efd2a42 | ||
|
|
9ee0ac92c3 | ||
|
|
c7f554bebb | ||
|
|
6fe8d71e61 | ||
|
|
f6f24bce25 | ||
|
|
8b81151ec1 | ||
|
|
55033ed25e | ||
|
|
a829a60341 | ||
|
|
0a25e78964 | ||
|
|
dec1acdfb1 | ||
|
|
4f0970138b | ||
|
|
4707997aec | ||
|
|
ae5a4b5f4f | ||
|
|
5187b55a2e | ||
|
|
60078852bd | ||
|
|
580bacaf93 | ||
|
|
eb1ab920cf | ||
|
|
6c0aabd36e | ||
|
|
a3d2443b70 | ||
|
|
313ca172a5 | ||
|
|
ceb4e53f15 | ||
|
|
4510b4997a | ||
|
|
12cc43bd7c | ||
|
|
21069c107a | ||
|
|
93032afe0f | ||
|
|
f422fe13f4 | ||
|
|
ed551d1eb3 | ||
|
|
58cd4119a6 | ||
|
|
c8147ce3d4 | ||
|
|
00df171604 | ||
|
|
50ca38d4d0 | ||
|
|
e31e5c1a5b | ||
|
|
c80356a90a | ||
|
|
4909b039c0 | ||
|
|
dc8ee2718b | ||
|
|
8118f4ad18 | ||
|
|
de422a0d93 | ||
|
|
cbffa01014 | ||
|
|
f8688c33a0 | ||
|
|
6e0e56b85e | ||
|
|
7e81522ed4 | ||
|
|
0c8a76fceb | ||
|
|
35273abff7 | ||
|
|
6c1f3ea4bf | ||
|
|
5e261e0d7f | ||
|
|
53553ece6f | ||
|
|
33d47ff1c8 | ||
|
|
16b8657a47 | ||
|
|
264c834c2c | ||
|
|
28b05465ea | ||
|
|
b903e57ef9 | ||
|
|
d5ffba47a2 | ||
|
|
34b99bfede | ||
|
|
4f5aac8f50 | ||
|
|
fe53eeb010 | ||
|
|
67b6f69926 | ||
|
|
6bf62a3d4e | ||
|
|
54b911550f | ||
|
|
31a988877a | ||
|
|
88642d81c0 | ||
|
|
135e8d98e9 | ||
|
|
bd5c8fd403 | ||
|
|
3b112793aa | ||
|
|
2fc8d9ae4f | ||
|
|
afe63f02fa | ||
|
|
6aa744dff9 | ||
|
|
095b04d31c | ||
|
|
6136fe0c8b | ||
|
|
e2f3752018 | ||
|
|
5d0fdf01f3 | ||
|
|
cb4b6bc76d | ||
|
|
bb0f57b5ab | ||
|
|
c23981b97f | ||
|
|
c005fc6754 | ||
|
|
8d24048c26 | ||
|
|
ac1ae9f9db | ||
|
|
53e8a40e1b | ||
|
|
a7d803bc82 | ||
|
|
944ae100fa | ||
|
|
b68fd36476 | ||
|
|
74d530d65e | ||
|
|
b5cf71c7af | ||
|
|
8d663f80bd | ||
|
|
77257e2532 | ||
|
|
44d6719107 | ||
|
|
05ddaa6356 | ||
|
|
d8a6b6528a | ||
|
|
478c781822 | ||
|
|
93039252f2 | ||
|
|
3efc3ebe25 | ||
|
|
1f5824a55b | ||
|
|
d364c2f53e | ||
|
|
7d0bc98e3e | ||
|
|
85e0b26a53 | ||
|
|
c3f21c8af2 | ||
|
|
8bd2148ae4 | ||
|
|
2c74cef483 | ||
|
|
3a1911f5cd | ||
|
|
d871886ec5 | ||
|
|
146a2e8aae | ||
|
|
727784d90a | ||
|
|
67647bc51e | ||
|
|
3ce9d84669 | ||
|
|
af6ed6c296 | ||
|
|
3f65c0593f | ||
|
|
98e7941371 | ||
|
|
3fb5eb3ec9 | ||
|
|
497c748955 | ||
|
|
230247af17 | ||
|
|
bbea40833b | ||
|
|
146ca6a9c9 | ||
|
|
fb7e8c730c | ||
|
|
e5135ae67b | ||
|
|
f1b524460e | ||
|
|
9c9c910fa8 | ||
|
|
63330cbb84 | ||
|
|
5c6816f8ab | ||
|
|
4c0366e340 | ||
|
|
38e2e4e16a | ||
|
|
430b24c0f3 | ||
|
|
b22b187ce0 | ||
|
|
cc32d6cb98 | ||
|
|
66332ae9e2 | ||
|
|
b6dd3acfea | ||
|
|
b655e89af0 | ||
|
|
2879cf51cd | ||
|
|
725dabea88 | ||
|
|
35f133cacd | ||
|
|
b0e4f2c696 | ||
|
|
65c423917e | ||
|
|
f128af26ec | ||
|
|
1bf955baa8 | ||
|
|
cee2ff2641 | ||
|
|
819cd6c3e2 | ||
|
|
67da32857a | ||
|
|
6796145fa9 | ||
|
|
fea1bcc123 | ||
|
|
b6125b8063 | ||
|
|
ad397bb1b6 | ||
|
|
dc333f052d | ||
|
|
a77e120fc2 | ||
|
|
07166e591e | ||
|
|
a1aac43a4e | ||
|
|
cc69471576 | ||
|
|
ed8e01ea0c | ||
|
|
4fb847196c | ||
|
|
40ee2cb868 | ||
|
|
8d0b2edba2 | ||
|
|
3b6e10a1f9 | ||
|
|
4d4a849c9b | ||
|
|
58f94fe9ec | ||
|
|
ebff6f995a | ||
|
|
5a8a4bb25b | ||
|
|
6d8e781c72 | ||
|
|
834374d0f2 | ||
|
|
f0d17b1f86 | ||
|
|
5478879a37 | ||
|
|
4e2f50eee7 | ||
|
|
c47e25bef3 | ||
|
|
b5203b97bb | ||
|
|
a7ac9a0aa8 | ||
|
|
0540efa171 | ||
|
|
b3b274acf7 | ||
|
|
944ffcb788 | ||
|
|
865baf0d5f | ||
|
|
8b555503c1 | ||
|
|
11bb6bb2aa | ||
|
|
63864adbda | ||
|
|
0d89989c20 | ||
|
|
59d4821bdc | ||
|
|
24ecba3e9e | ||
|
|
d9f9b86996 | ||
|
|
c27febf172 | ||
|
|
d18af9daf8 | ||
|
|
4813a35eec | ||
|
|
5bd33084dd | ||
|
|
939c54792f | ||
|
|
28f6f58dd7 | ||
|
|
27fd1d11b8 | ||
|
|
39355d3bd6 | ||
|
|
1582b486db | ||
|
|
e4d58dd9cb | ||
|
|
f417d640e0 | ||
|
|
f79e16f48d | ||
|
|
365daab33c | ||
|
|
62fceaaa3c | ||
|
|
5af78fb18a | ||
|
|
2dae632d24 | ||
|
|
680e460ecd | ||
|
|
07e715bb6d | ||
|
|
e255bc0874 | ||
|
|
0d0129e7c3 | ||
|
|
3ca24bd45c | ||
|
|
a627363afa | ||
|
|
bcf6ca9e52 | ||
|
|
561579a7d6 | ||
|
|
5368285be0 | ||
|
|
096ff18ee8 | ||
|
|
2cde569916 | ||
|
|
f0afcb2e62 | ||
|
|
5b606a785d | ||
|
|
6bfa4a390c | ||
|
|
1b91e9d614 | ||
|
|
bff458d636 | ||
|
|
8814b73eb3 | ||
|
|
d116855eb8 | ||
|
|
5dd4a31f17 | ||
|
|
a32bf25289 | ||
|
|
eac21c4f59 | ||
|
|
f4f5cb2e80 | ||
|
|
f559a75353 | ||
|
|
aff26ce1c0 | ||
|
|
49717bf706 | ||
|
|
283eecadd6 | ||
|
|
9069f56a9d | ||
|
|
422c095ebf | ||
|
|
8373bee595 | ||
|
|
a474c66e26 | ||
|
|
b933efedd1 | ||
|
|
8719e9a857 | ||
|
|
2995c5312e | ||
|
|
0bed0d5b9c | ||
|
|
4e4d4515d0 | ||
|
|
6b46117211 | ||
|
|
679dbafc9e | ||
|
|
f6415a746c | ||
|
|
b5623128b2 | ||
|
|
cdcf85bdfa | ||
|
|
41f301c3c4 | ||
|
|
2641c5b274 | ||
|
|
9f4c37104a | ||
|
|
428d59a1b0 | ||
|
|
f3532ccb99 | ||
|
|
64f7ff5880 | ||
|
|
79fd8562bf | ||
|
|
b2aab80ef0 | ||
|
|
cb9698a5b0 | ||
|
|
3c0ac75fc7 | ||
|
|
00c7e88da0 | ||
|
|
e26d7981b0 | ||
|
|
2d184211bf | ||
|
|
1d7072bf86 | ||
|
|
33401074e7 | ||
|
|
35fcd0b269 | ||
|
|
6ce9ba83df | ||
|
|
0ee881cf0d | ||
|
|
9bf5db778b | ||
|
|
bcdeff5217 | ||
|
|
4a7c16c336 | ||
|
|
fa4b5fe75a | ||
|
|
7cf983f765 | ||
|
|
102e0a8ab3 | ||
|
|
754d7fc8a6 | ||
|
|
79d355668f | ||
|
|
189cd84c41 | ||
|
|
a5b13f592b | ||
|
|
987c87595a | ||
|
|
dc26964fd2 | ||
|
|
5a94979c69 | ||
|
|
028f700093 | ||
|
|
e782ffc98d | ||
|
|
6675da0661 | ||
|
|
ba965fce28 | ||
|
|
aeca17a36f | ||
|
|
0e64848623 | ||
|
|
52bf1907c5 | ||
|
|
40a2e18034 | ||
|
|
535db78525 | ||
|
|
aee4ee9430 | ||
|
|
20fd7e5b23 | ||
|
|
1cf3dd1cb1 | ||
|
|
a9a88c2f6e | ||
|
|
1b8dd6fa19 | ||
|
|
cffafe8b65 | ||
|
|
1d2752a0be | ||
|
|
6151667c84 | ||
|
|
d87c72298f | ||
|
|
2e1b3d23dc | ||
|
|
1955c22501 | ||
|
|
6378359fd8 | ||
|
|
fe83210938 | ||
|
|
aae0a76d2b | ||
|
|
34d7177768 | ||
|
|
28131360b2 | ||
|
|
7e0f3af5a0 | ||
|
|
cb6c9e8ceb | ||
|
|
b30a071783 | ||
|
|
0e8ab73e49 | ||
|
|
7475e7f68d | ||
|
|
25902550fa | ||
|
|
883b7bf054 | ||
|
|
b3077791b2 | ||
|
|
46fbe2a9a8 | ||
|
|
d5fab7c7b1 | ||
|
|
860a404cb1 | ||
|
|
0fa9c01549 | ||
|
|
b34652d862 | ||
|
|
fcd7578b9a | ||
|
|
f5e0c61d12 | ||
|
|
92d2d2c638 | ||
|
|
79a1dc0564 | ||
|
|
a22c0d3343 | ||
|
|
46114235f9 | ||
|
|
2bb62e419d | ||
|
|
ac6f71b188 | ||
|
|
a438985c8c | ||
|
|
9f310e6be2 | ||
|
|
edfb61a452 | ||
|
|
3b30a559b6 | ||
|
|
497d4dc804 | ||
|
|
631856ae54 | ||
|
|
8b887c7714 | ||
|
|
852f6af362 | ||
|
|
cd6cb2352f | ||
|
|
5bc7a1bf4f | ||
|
|
844566a78a | ||
|
|
2320c0de77 | ||
|
|
6afddae6d8 | ||
|
|
5de22d4ce1 | ||
|
|
3162ae83b4 | ||
|
|
e5bcae6e43 | ||
|
|
a110b60a2a | ||
|
|
9190a20ca1 | ||
|
|
7a7f746782 | ||
|
|
6c148b77a1 | ||
|
|
e30eae7652 | ||
|
|
811ffe83f8 | ||
|
|
ae8d61c3a3 | ||
|
|
0e54aaf70f | ||
|
|
4498f216a0 | ||
|
|
3b4a1e6861 | ||
|
|
83a9f96f20 | ||
|
|
dad2601f0d | ||
|
|
fb79a9eb22 | ||
|
|
5fded645fb | ||
|
|
84f16804bb | ||
|
|
e6969267e9 | ||
|
|
1655a98997 | ||
|
|
4444bd2286 | ||
|
|
fe402954f8 | ||
|
|
9ae3543879 | ||
|
|
e88fa9ab45 | ||
|
|
c707150666 | ||
|
|
c2e5f60526 | ||
|
|
395629f678 | ||
|
|
f77b80899d | ||
|
|
5720619bd2 | ||
|
|
e33ac88379 | ||
|
|
96c9bf168e | ||
|
|
3711622f66 | ||
|
|
a3cd9f7de7 | ||
|
|
389927dc1d | ||
|
|
ff63fa7437 | ||
|
|
b480d6856b | ||
|
|
76786e9e43 | ||
|
|
aa9ff80137 | ||
|
|
2e60a6b6e7 | ||
|
|
f24684f478 | ||
|
|
f43a507e91 | ||
|
|
25f7283af9 | ||
|
|
ea29d3f6df | ||
|
|
1592f9246b | ||
|
|
b481c25ee5 | ||
|
|
e6fa77b3c0 | ||
|
|
3da5f56257 | ||
|
|
d97dfa768a | ||
|
|
1d671b104b | ||
|
|
d7cb28a66b | ||
|
|
d153456653 | ||
|
|
ad77202a05 | ||
|
|
20ffd3681e | ||
|
|
d66c1f4510 | ||
|
|
fcdd6f7947 | ||
|
|
1b54190c15 | ||
|
|
7550203dc9 | ||
|
|
380e9fa09e | ||
|
|
c04aeec3e5 | ||
|
|
b758d842c4 | ||
|
|
ff9da0c850 | ||
|
|
87681ffcaa | ||
|
|
47c33cd5a9 | ||
|
|
ea9e9da829 | ||
|
|
0ffcfcb0c0 | ||
|
|
132d2dc3fc | ||
|
|
de61c33093 | ||
|
|
38b12c9773 | ||
|
|
2734536fa7 | ||
|
|
d4e7852598 | ||
|
|
fd3da6af08 | ||
|
|
de3ec8e7af | ||
|
|
2256560985 | ||
|
|
342ee45558 | ||
|
|
c207597409 | ||
|
|
2f5198eb9f | ||
|
|
96fb201246 | ||
|
|
ff36508548 | ||
|
|
02612749c8 | ||
|
|
7648cd9a56 | ||
|
|
95feb02d97 | ||
|
|
36a49e135e | ||
|
|
8fe7b90daa | ||
|
|
238103a5e0 | ||
|
|
72e0d80af9 | ||
|
|
21b61f07da | ||
|
|
1d67fb050c | ||
|
|
40eaacc33b | ||
|
|
4b47e699f5 | ||
|
|
d845f048ea | ||
|
|
e70dc0af56 | ||
|
|
3c3c64f3c7 | ||
|
|
87a9ce334a | ||
|
|
ace58063e4 | ||
|
|
33ef14cd5d | ||
|
|
4f6196b330 | ||
|
|
fbe1ff93e9 | ||
|
|
b2581fccaa | ||
|
|
056e29c9a8 | ||
|
|
0bf409fc10 | ||
|
|
6d2a3883ac | ||
|
|
d7dcb56105 | ||
|
|
a62a9f6c75 | ||
|
|
b4c32dd56b | ||
|
|
3a323abc9a | ||
|
|
1fefd5c82c | ||
|
|
e470a28bda | ||
|
|
435f1c2a16 | ||
|
|
e9f72c1e33 | ||
|
|
f8d8c6c7a4 | ||
|
|
0c7022a756 | ||
|
|
7254e5558b | ||
|
|
17cdb30ab1 | ||
|
|
db743b1226 | ||
|
|
e9cc8d43a9 | ||
|
|
4dd9bf74d9 | ||
|
|
722909a9cf | ||
|
|
13287a114c | ||
|
|
1a6659d577 | ||
|
|
3a7cc57fde | ||
|
|
c093f18d20 | ||
|
|
f2ebd77ace | ||
|
|
ad55a85b89 | ||
|
|
779e0bdc50 | ||
|
|
80c4d80952 | ||
|
|
42e54c0241 | ||
|
|
b393356b4b | ||
|
|
f65555c810 | ||
|
|
174bf29f28 | ||
|
|
1776027e63 | ||
|
|
4018df12cd | ||
|
|
c400cd5f61 | ||
|
|
4710c4777e | ||
|
|
a872136418 | ||
|
|
da15c9619a | ||
|
|
a67b510cae | ||
|
|
c84d1a827e | ||
|
|
0e2cac5505 | ||
|
|
aa4f39a51b | ||
|
|
3c0b7830de | ||
|
|
25f43108fe | ||
|
|
da64e491bb | ||
|
|
23fe11278c | ||
|
|
f27361bf17 | ||
|
|
91e0120780 | ||
|
|
e4f2af21c3 | ||
|
|
2edb0ed1e3 | ||
|
|
e317c61084 | ||
|
|
5506dbbc77 | ||
|
|
2ed175ee3b | ||
|
|
2a2631075e | ||
|
|
406226bd2b | ||
|
|
6f105f0720 | ||
|
|
e30430be48 | ||
|
|
3a52af11bd | ||
|
|
c73b427d42 | ||
|
|
85f5a619ab | ||
|
|
a6d94027db | ||
|
|
45a3044a61 | ||
|
|
d25b3a307e | ||
|
|
d5e3bc9ceb | ||
|
|
cd8f2997ca | ||
|
|
df65e97491 | ||
|
|
abbb60a4fa | ||
|
|
ff05035bc0 | ||
|
|
71d9d78ed5 | ||
|
|
d8b2e96552 | ||
|
|
c974ce057e | ||
|
|
ddbe50c5ef | ||
|
|
2aaf87bbcf | ||
|
|
8c74fde404 | ||
|
|
dbe5afeaba | ||
|
|
9bf035539b | ||
|
|
5cb73d58cd | ||
|
|
1e3eba1b5b | ||
|
|
87af935494 | ||
|
|
86cc204693 | ||
|
|
d1e6d744ae | ||
|
|
cea3dcea67 | ||
|
|
72a896a95a | ||
|
|
9ca0c429bf | ||
|
|
681e06ce73 | ||
|
|
3a3e393d20 | ||
|
|
6b86cb7d1e | ||
|
|
4a772f1bb6 | ||
|
|
d8309595cf | ||
|
|
6000f4f25c | ||
|
|
3cabeb4f27 | ||
|
|
53b525d758 | ||
|
|
06ebc4cb03 | ||
|
|
25245e2a46 | ||
|
|
4d8adae071 | ||
|
|
d65216df76 | ||
|
|
155c4ba1f9 | ||
|
|
f6ff832e51 | ||
|
|
0b4045ffb1 | ||
|
|
677d9feb87 | ||
|
|
043ac1fdab | ||
|
|
dacd75ca7e | ||
|
|
3e5352f79c | ||
|
|
2f56a667f3 | ||
|
|
cefa19ec6a | ||
|
|
ab2ab88581 | ||
|
|
a5c28c6020 | ||
|
|
ac3ddc134e | ||
|
|
86659b40bd | ||
|
|
fd7c7e356c | ||
|
|
10c4e0323a | ||
|
|
53a647af56 | ||
|
|
026185da74 | ||
|
|
951a85d3b7 | ||
|
|
d6db825ec3 | ||
|
|
d9ab158b97 | ||
|
|
f9305d58e8 | ||
|
|
8da827d06f | ||
|
|
4ee29a6d57 | ||
|
|
e060e060af | ||
|
|
81a63edcbc | ||
|
|
8b1ca1330f | ||
|
|
7bc1a6d7c7 | ||
|
|
9e24a71225 | ||
|
|
8d89e7efdb | ||
|
|
4ca4e84878 | ||
|
|
9461f7d24e | ||
|
|
e29ba9e43e | ||
|
|
a875a16c92 | ||
|
|
de92a8a41b | ||
|
|
d719809440 | ||
|
|
656e7552b5 | ||
|
|
9715a2fef6 | ||
|
|
268166b20a | ||
|
|
f03fb651c2 | ||
|
|
6b05e42582 | ||
|
|
0d42b42459 | ||
|
|
2159d407ee | ||
|
|
2b9645e3a6 | ||
|
|
5d0d1e4eb2 | ||
|
|
0d82e52aa6 | ||
|
|
28cfc17bb6 | ||
|
|
5c8d387c27 | ||
|
|
213f51c14b | ||
|
|
d2e5f715a9 | ||
|
|
bedacef673 | ||
|
|
78bafd8b33 | ||
|
|
6ae9b28325 | ||
|
|
68f01f4267 | ||
|
|
d9f953ec82 | ||
|
|
d06795e979 | ||
|
|
979ce28de9 | ||
|
|
4aa2a95b59 | ||
|
|
b588709ad9 | ||
|
|
ca95cdcb91 | ||
|
|
bf046a68c4 | ||
|
|
490a4ab31c | ||
|
|
205133554f | ||
|
|
4df9b9ac6f | ||
|
|
0b5a943799 | ||
|
|
ede0e9d4c3 | ||
|
|
d33d231120 | ||
|
|
0c1ee23f55 | ||
|
|
f5554dec6e | ||
|
|
6239168118 | ||
|
|
fe9fea0807 | ||
|
|
d33917421b | ||
|
|
7c0b11e5e0 | ||
|
|
6a84e2eee9 | ||
|
|
26bad84244 | ||
|
|
eafd7081f3 | ||
|
|
2ad2851b2c | ||
|
|
f4924f6fd3 | ||
|
|
78920a61ad | ||
|
|
160f9f964f | ||
|
|
f81435cc2e | ||
|
|
62df3cbe98 | ||
|
|
b0b000a3f2 | ||
|
|
9e244e068d | ||
|
|
4a8d19da78 | ||
|
|
5a0fbcd7ba | ||
|
|
1ca20269b7 | ||
|
|
5b3eb577fc | ||
|
|
337d08d466 | ||
|
|
e784c34cb4 | ||
|
|
525c54a035 | ||
|
|
65cc054c9c | ||
|
|
64639ae623 | ||
|
|
74fb70a675 | ||
|
|
ca142fbc56 | ||
|
|
af498728b0 | ||
|
|
a68c5dc00e | ||
|
|
7e279e1963 | ||
|
|
01395347ce | ||
|
|
b5493c779f | ||
|
|
919b071990 | ||
|
|
46a9718d29 | ||
|
|
82e3fbfbad | ||
|
|
9004d2b80f | ||
|
|
ddb91106c2 | ||
|
|
9d7505a61c | ||
|
|
e1140c0401 | ||
|
|
76a0d9bfa3 | ||
|
|
a015c7a368 | ||
|
|
329ed0bb5b | ||
|
|
c3bc2808e9 | ||
|
|
584586dea8 | ||
|
|
8f84f73162 | ||
|
|
ce3bf7151a | ||
|
|
5cb5eb296d | ||
|
|
336b0a42e9 | ||
|
|
a32af2cf76 | ||
|
|
307a4f5010 | ||
|
|
5320b4f22f | ||
|
|
70a1d452f3 | ||
|
|
61869a91c7 | ||
|
|
68bc003fd2 | ||
|
|
f29912620d | ||
|
|
4a780af9fe | ||
|
|
6b6e6c874b | ||
|
|
d42d067945 | ||
|
|
17e80a3a09 | ||
|
|
674c5b5819 | ||
|
|
01629e1faf | ||
|
|
38a33ab15b | ||
|
|
2163365115 | ||
|
|
f67902f098 | ||
|
|
bfe47b408d | ||
|
|
aa2bea2d84 | ||
|
|
40c5b1b8d3 | ||
|
|
ee714259df | ||
|
|
aa7b620d8e | ||
|
|
794c16644b | ||
|
|
dda64c5b5e | ||
|
|
6784a79db0 | ||
|
|
564dfea143 | ||
|
|
7e9f514d8b | ||
|
|
68809a753d | ||
|
|
4ba390abd6 | ||
|
|
fe2b4cb8f3 | ||
|
|
dbef73bd75 | ||
|
|
ec19cc1e41 | ||
|
|
63e099a912 | ||
|
|
282309ee9b | ||
|
|
bd48cae19f | ||
|
|
b2d8a5ceb8 | ||
|
|
438677e61a | ||
|
|
44a7535791 | ||
|
|
2117a62dc1 | ||
|
|
99c27bed99 | ||
|
|
161cd9dc3f | ||
|
|
0228fcd7d3 | ||
|
|
3da4e03ddc | ||
|
|
8030af55b8 | ||
|
|
ee757c117c | ||
|
|
a93665abf4 | ||
|
|
e3c39f4f97 | ||
|
|
9bf5c20a9a | ||
|
|
c02a069c5e | ||
|
|
e5bf05c5c2 | ||
|
|
017d82d16e | ||
|
|
5f6d75da12 | ||
|
|
633919dd74 | ||
|
|
e83a119cbb | ||
|
|
00ac8ec1aa | ||
|
|
491f111caf | ||
|
|
8e92453f4c | ||
|
|
bc198c37d7 | ||
|
|
5ab84a6e78 | ||
|
|
334080dfd0 | ||
|
|
46012a6a8c | ||
|
|
3b546a6048 | ||
|
|
522b8d5fc0 | ||
|
|
74d3bb76da | ||
|
|
a28080e065 | ||
|
|
638b341ba5 | ||
|
|
c254dc3121 | ||
|
|
fe0778656b | ||
|
|
e478b99307 | ||
|
|
9d2cd89a7c | ||
|
|
be82ccbfcd | ||
|
|
18dfbb61b4 | ||
|
|
0f8e39d785 | ||
|
|
c4fdf490a2 | ||
|
|
55764011db | ||
|
|
9a483890b6 | ||
|
|
4421377624 | ||
|
|
f817d06e14 | ||
|
|
6b0b389a69 | ||
|
|
496899ffe3 | ||
|
|
7a05331e76 | ||
|
|
e7e725cb5e | ||
|
|
8385f6ad4e | ||
|
|
aeb3f7a438 | ||
|
|
d9fa04d2ed | ||
|
|
d4b5e585d1 | ||
|
|
8579037bb1 | ||
|
|
13cce1a4dd | ||
|
|
5724dfad87 | ||
|
|
f370bf77a8 | ||
|
|
fc3540ac08 | ||
|
|
c16f361c4a | ||
|
|
92a0f507af | ||
|
|
6bb7cdbdd4 | ||
|
|
1809a2bac3 | ||
|
|
430658c1a4 | ||
|
|
746383b72b | ||
|
|
d244151ca2 | ||
|
|
e4c1626638 | ||
|
|
c07cee0d01 | ||
|
|
43132bd9b0 | ||
|
|
ed982e1d2c | ||
|
|
7420ea052d | ||
|
|
044326d337 | ||
|
|
96c126bbcc | ||
|
|
ba0e524805 | ||
|
|
ba19f56338 | ||
|
|
14df602fa4 | ||
|
|
d972e205ac | ||
|
|
114f2b8cd2 | ||
|
|
87f8830d16 | ||
|
|
a0afe05995 | ||
|
|
ddd4d37ad1 | ||
|
|
ede296ef01 | ||
|
|
1307ce364d | ||
|
|
37fa84d762 | ||
|
|
b3e984bd22 | ||
|
|
7da5b9b7eb | ||
|
|
55b979f656 | ||
|
|
815a6c3ade | ||
|
|
33db7a8005 | ||
|
|
963ac3039e | ||
|
|
552db005b1 | ||
|
|
2d1e8cf1f2 | ||
|
|
8e44e8bf13 | ||
|
|
e7cc7b3409 | ||
|
|
4e5473150a | ||
|
|
e8e7597c62 | ||
|
|
f9b03600d1 | ||
|
|
88a8ebb1dc | ||
|
|
4445785ee1 | ||
|
|
3b3460cbba | ||
|
|
7eb6789a25 | ||
|
|
870fed75ad | ||
|
|
833c2809d9 | ||
|
|
24ec881fe5 | ||
|
|
d7d7bc91a2 | ||
|
|
1ea8dc828a | ||
|
|
ade7d82e52 | ||
|
|
fa5c6652b6 | ||
|
|
a5ab6b1520 | ||
|
|
bf74640917 | ||
|
|
420d309db6 | ||
|
|
c4d170ebb8 | ||
|
|
9cc69095d5 | ||
|
|
eb5dd2c005 | ||
|
|
39fbbe61a3 | ||
|
|
ba71080fb2 | ||
|
|
db176ad3e3 | ||
|
|
002638ef96 | ||
|
|
22b74477ac | ||
|
|
9c5a9ebba7 | ||
|
|
fce3f38e3a | ||
|
|
aabb600aed | ||
|
|
a062a8efa6 | ||
|
|
9b690667dc | ||
|
|
de7897c5c2 | ||
|
|
d3d431d5b1 | ||
|
|
6409f5d40a | ||
|
|
aeab3c815e | ||
|
|
4837797fae | ||
|
|
0ffc8682b1 | ||
|
|
cb35a8d85c | ||
|
|
5999255b5d | ||
|
|
a7654c6a80 | ||
|
|
2b3791f701 | ||
|
|
7f52a18fac | ||
|
|
ff8bb3b2e4 | ||
|
|
5b7cc6d4de | ||
|
|
1d9774c913 | ||
|
|
8b13ba26d7 | ||
|
|
8730f4daa6 | ||
|
|
52f4d2a1a6 | ||
|
|
6a498c373c | ||
|
|
007c7a887e | ||
|
|
922a8864e8 | ||
|
|
16383f4577 | ||
|
|
bc66bb5be9 | ||
|
|
84360f24c1 | ||
|
|
cad160205f | ||
|
|
807519e3c4 | ||
|
|
425ffb6e68 | ||
|
|
0ede6b8fa5 | ||
|
|
381d723462 | ||
|
|
cad8de8cd8 | ||
|
|
7d7d275e7e | ||
|
|
80db7d9a21 | ||
|
|
d8943af79a | ||
|
|
bcbf9360af | ||
|
|
6320b0928e | ||
|
|
74afa2551a | ||
|
|
dd733c4128 | ||
|
|
0eaa1b6c5e | ||
|
|
f595859cf0 | ||
|
|
85e0d01451 | ||
|
|
ec57e035d6 | ||
|
|
0d0b4d7364 | ||
|
|
aeb91fce74 | ||
|
|
e163bd842e | ||
|
|
2ff7bd1bc7 | ||
|
|
533c703b0d | ||
|
|
1d1a82f529 | ||
|
|
911b95a505 | ||
|
|
8209cf8398 | ||
|
|
02423d4a2d | ||
|
|
ba5c13fb6c | ||
|
|
ddd13bcab0 | ||
|
|
3b6800e38e | ||
|
|
6c2ebf91c0 | ||
|
|
a64d1de7cd | ||
|
|
d6ce7f5c16 | ||
|
|
1fe29c512f | ||
|
|
e76176b663 | ||
|
|
acbe0527d7 | ||
|
|
81d8f2f5c3 | ||
|
|
8976e77109 | ||
|
|
31bd7ebfbc | ||
|
|
487b979842 | ||
|
|
efd1408809 | ||
|
|
867e8aaa00 | ||
|
|
e3e5fd7568 | ||
|
|
7e6b012a08 | ||
|
|
546fe18836 | ||
|
|
1cb7683636 | ||
|
|
f89c7faf3c | ||
|
|
cf36c668b3 | ||
|
|
dd41352392 | ||
|
|
ec42322f23 | ||
|
|
3b8a9b5cc5 | ||
|
|
6d3b2fe902 | ||
|
|
819ec41320 | ||
|
|
40fd950b40 | ||
|
|
4f64c106a7 | ||
|
|
b2d5587ea1 | ||
|
|
4b020ab4f5 | ||
|
|
088a85c125 | ||
|
|
2bf60dc00d | ||
|
|
b5ffa0e92a | ||
|
|
258f7f9b50 | ||
|
|
07c403243d | ||
|
|
709de6a858 | ||
|
|
dfed557f61 | ||
|
|
f143771be8 | ||
|
|
fc20c410c0 | ||
|
|
677205a288 | ||
|
|
abb9acfd42 | ||
|
|
75dca68db0 | ||
|
|
5c1a8ad128 | ||
|
|
e4cf8f8c94 | ||
|
|
30968917a4 | ||
|
|
84ea9e3301 | ||
|
|
1f9c046919 | ||
|
|
cefe210184 | ||
|
|
02aa791fd9 | ||
|
|
d8c1341068 | ||
|
|
ca648ea128 | ||
|
|
daf5a9d91d | ||
|
|
16b95f2088 | ||
|
|
41dfcb559a | ||
|
|
37c871ec2e | ||
|
|
34bd1ff42f | ||
|
|
e0f1d4fecf | ||
|
|
c94d992ef6 | ||
|
|
bfe83d827d | ||
|
|
1c45795828 | ||
|
|
8dc5c164d8 | ||
|
|
326032aa23 | ||
|
|
b79e234da2 | ||
|
|
5bc6962a9d | ||
|
|
168717a90a | ||
|
|
dd6b0f6c9a | ||
|
|
0a3c678877 | ||
|
|
e2df6f6ce0 | ||
|
|
e58ebdac18 | ||
|
|
537312a91f | ||
|
|
11c08acd6c | ||
|
|
cf9a38fb02 | ||
|
|
83dff2bf25 | ||
|
|
49694f300a | ||
|
|
daddc8246e | ||
|
|
9f92377edc | ||
|
|
1ce392d968 | ||
|
|
bf730b43e2 | ||
|
|
a4adb47caf | ||
|
|
9317572874 | ||
|
|
eca39e6a8f | ||
|
|
4639dc8ffd | ||
|
|
5a9b34f54b | ||
|
|
dc07d477de | ||
|
|
db5efa8908 | ||
|
|
7d462dd837 | ||
|
|
76010f63c0 | ||
|
|
be7f72808b | ||
|
|
25f1e8e6fa | ||
|
|
047df311f0 | ||
|
|
bcdd99328c | ||
|
|
5cc76a0071 | ||
|
|
dee55a9ac2 | ||
|
|
9ff20da9bb | ||
|
|
0520f5abcd | ||
|
|
e1201ff0de | ||
|
|
bc2d7e7396 | ||
|
|
9a058a2416 | ||
|
|
49fea86b28 | ||
|
|
1617439d37 | ||
|
|
540459cb78 | ||
|
|
54b8522df6 | ||
|
|
bf65e606d3 | ||
|
|
5335a641df | ||
|
|
323ece7417 | ||
|
|
ca1fc0ffad | ||
|
|
c0706e227e | ||
|
|
995e4a9b68 | ||
|
|
7f53379552 | ||
|
|
3e17299a34 | ||
|
|
c63cdc9506 | ||
|
|
7965186817 | ||
|
|
f107612753 | ||
|
|
2295f7bb8b | ||
|
|
cc0845a9d3 | ||
|
|
e9019461b7 | ||
|
|
a19e3ed3dd | ||
|
|
10ec424e96 | ||
|
|
b838c8a7d0 | ||
|
|
0331af0643 | ||
|
|
24561fc37c | ||
|
|
d4ad5334b8 | ||
|
|
7fe3299282 | ||
|
|
23fef75ed5 | ||
|
|
62722b0618 | ||
|
|
e810dba2c9 | ||
|
|
7dfe545161 | ||
|
|
a5f3966b44 | ||
|
|
886573ed8b | ||
|
|
2758c1c955 | ||
|
|
591bafe8c3 | ||
|
|
211a8f42db | ||
|
|
fbc9029a8e | ||
|
|
ceb4b8b06d | ||
|
|
b88dda442f | ||
|
|
6e8163bded | ||
|
|
9b253abb53 | ||
|
|
e5e51e3ea3 | ||
|
|
6a2d9d7663 | ||
|
|
0546b1e212 | ||
|
|
320e6dae72 | ||
|
|
96f944c804 | ||
|
|
fd0e2195f7 | ||
|
|
d2f130a834 | ||
|
|
a3459712ce | ||
|
|
8bf2e49164 | ||
|
|
0f5cd39a64 | ||
|
|
e0ed0076f2 | ||
|
|
bfd4ad39af | ||
|
|
a8ff7d8769 | ||
|
|
39c77beb1c | ||
|
|
d576f7af39 | ||
|
|
74c3f43f75 | ||
|
|
ecacace01d | ||
|
|
a3b0149a84 | ||
|
|
63111577ec | ||
|
|
eb68520709 | ||
|
|
a7bf2c6cc3 | ||
|
|
190788efd9 | ||
|
|
2592a6a342 | ||
|
|
16ee4c348d | ||
|
|
8389097cd3 | ||
|
|
79a885c15e | ||
|
|
eb7c683a6d | ||
|
|
95b2b314f6 | ||
|
|
07eb0aa5cd | ||
|
|
fdce28590a | ||
|
|
572613e377 | ||
|
|
29e597b4ed | ||
|
|
981c464c36 | ||
|
|
d406c5717c | ||
|
|
92208efd24 | ||
|
|
3c98cbccbe | ||
|
|
3a5c6751e2 | ||
|
|
002d3d7b9b | ||
|
|
e57a66da04 | ||
|
|
b1ecad2d49 | ||
|
|
658a107f60 | ||
|
|
7b419ce5f1 | ||
|
|
367df08989 | ||
|
|
2004006a9d | ||
|
|
bed0f24f2b | ||
|
|
7995dfc70a | ||
|
|
b29d569f6b | ||
|
|
3c166c438a | ||
|
|
03dac0ef6a | ||
|
|
27cb5219ae | ||
|
|
97a7459f5d | ||
|
|
1eac337e59 | ||
|
|
1613358927 | ||
|
|
2f0da26f14 | ||
|
|
45fa32cb9d | ||
|
|
9e9f2a37be | ||
|
|
7b37bb6825 | ||
|
|
081378a178 | ||
|
|
ff72343429 | ||
|
|
b0b8a2ca1c | ||
|
|
55be6835b8 | ||
|
|
c465e1de21 | ||
|
|
0f255de201 | ||
|
|
deb04610b5 | ||
|
|
a9887fe471 | ||
|
|
4b3c5a7f6f | ||
|
|
0058d3563d | ||
|
|
52a4808f2c | ||
|
|
7a0874165f | ||
|
|
7c7acd134b | ||
|
|
ddd4874baa | ||
|
|
23f91b1a0d | ||
|
|
b8c32d580b | ||
|
|
c0e67004d5 | ||
|
|
38a557b7e9 | ||
|
|
7d6d5d673d | ||
|
|
2cf067f004 | ||
|
|
92d9bc525f | ||
|
|
dca91b1efc | ||
|
|
6bf1ea7539 | ||
|
|
670b13595b | ||
|
|
dcbb8b29de | ||
|
|
7284c817b2 | ||
|
|
b16912132f | ||
|
|
9805ad7f3a | ||
|
|
4e7e0f6aab | ||
|
|
c905ebfdd2 | ||
|
|
b5c787938c | ||
|
|
69ca5351b4 | ||
|
|
3f42372603 | ||
|
|
595028e9ec | ||
|
|
7358a049ef | ||
|
|
792aeda72e | ||
|
|
53bf2d277b | ||
|
|
0cbc55ba24 | ||
|
|
7b0d228972 | ||
|
|
8ac0b66836 | ||
|
|
2756b1b9dd | ||
|
|
e3f44bae26 | ||
|
|
1963589186 | ||
|
|
a5c9675b84 | ||
|
|
76747d5c38 | ||
|
|
59bfeb9fb2 | ||
|
|
c40669b429 | ||
|
|
d83cdbfeeb | ||
|
|
d8773e96d6 | ||
|
|
78571698c2 | ||
|
|
77282f1ff1 | ||
|
|
953fcb7f1b | ||
|
|
edef6d7f99 | ||
|
|
1905e4a7f6 | ||
|
|
31e6ae0705 | ||
|
|
31a108b685 | ||
|
|
b122c68b16 | ||
|
|
0efae1fdf5 | ||
|
|
0850180861 | ||
|
|
528478b379 | ||
|
|
65302010db | ||
|
|
6b32440347 | ||
|
|
5a0b6c419e | ||
|
|
94c5d0205b | ||
|
|
0f2998a672 | ||
|
|
1ba7936ef7 | ||
|
|
5192aacb22 | ||
|
|
ac2adcaf52 | ||
|
|
1b3e707f62 | ||
|
|
925fc67c66 | ||
|
|
54ce6deb1c | ||
|
|
754859d28a | ||
|
|
269bc9e289 | ||
|
|
35c768c040 | ||
|
|
ff45cfed83 | ||
|
|
38c5c1c17a | ||
|
|
423b301596 | ||
|
|
000c11f9ea | ||
|
|
cea4a02ad9 | ||
|
|
4e9bc39381 | ||
|
|
ad084da13d | ||
|
|
27e5262f1d | ||
|
|
363464092e | ||
|
|
b2cab70427 | ||
|
|
44d5301244 | ||
|
|
8e4f4feb3c | ||
|
|
e9f6f8824c | ||
|
|
be6f9870d0 | ||
|
|
bb086223c7 | ||
|
|
be6a3bff3f | ||
|
|
adfc5fda2e | ||
|
|
d833f136a0 | ||
|
|
1703e9d1b7 | ||
|
|
011b9f93e4 | ||
|
|
e449a4e247 | ||
|
|
fe7f0ff842 | ||
|
|
2033e5764d | ||
|
|
55175263ac | ||
|
|
c484221cd6 | ||
|
|
e9862cb30d | ||
|
|
0c7b99cbc6 | ||
|
|
824f39e4db | ||
|
|
66a5ce1e52 | ||
|
|
f39637a652 | ||
|
|
eaf7d0a277 | ||
|
|
b61bb908a2 | ||
|
|
2e891b807c | ||
|
|
f0b236df88 | ||
|
|
08904dbe0d | ||
|
|
c9c4e226af | ||
|
|
ab3dc70145 | ||
|
|
4d8c841f3f | ||
|
|
a8b247cde9 | ||
|
|
416e161285 | ||
|
|
cc8d1f9bf2 | ||
|
|
ae95f1b0e5 | ||
|
|
c10441bec4 | ||
|
|
6ab334fc34 | ||
|
|
10e849ce60 | ||
|
|
c2206f5452 | ||
|
|
3b66cd3cee | ||
|
|
731a083bb7 | ||
|
|
d35c6ab864 | ||
|
|
e9cade872c | ||
|
|
b2a8146851 | ||
|
|
6fd3d6c452 | ||
|
|
bc3e72a87d | ||
|
|
e50e050aa9 | ||
|
|
c1a75607fa | ||
|
|
b203cd2af3 | ||
|
|
84063f026f | ||
|
|
3ec1ce25d7 | ||
|
|
0e70c543ee | ||
|
|
e4d522a8d2 | ||
|
|
272ecbd8ff | ||
|
|
369fa03f9b | ||
|
|
1675ea3ba2 | ||
|
|
5b7a1bb9e6 | ||
|
|
ace3effa2d | ||
|
|
bd0a14b3ce | ||
|
|
29a82f83c5 | ||
|
|
f7232f09de | ||
|
|
f3eeae9edd | ||
|
|
874468ca07 | ||
|
|
7a972af610 | ||
|
|
4ed42c38c9 | ||
|
|
6a73719a6b | ||
|
|
6efcfc6b93 | ||
|
|
25f30c220e | ||
|
|
2e9665f10e | ||
|
|
197881b430 | ||
|
|
96fe98d71f | ||
|
|
d1ecd4c933 | ||
|
|
fad25caa08 | ||
|
|
98c481e045 | ||
|
|
6082e655e6 | ||
|
|
6a97367242 | ||
|
|
bbcfffdab9 | ||
|
|
2dfb6c1012 | ||
|
|
82317343aa | ||
|
|
0ea0d0ec98 | ||
|
|
33aa27c590 | ||
|
|
c31f990183 | ||
|
|
791956bee0 | ||
|
|
6cebf4f6fd | ||
|
|
1782136e02 | ||
|
|
2f381192dd | ||
|
|
dac2009cab | ||
|
|
d592af694f | ||
|
|
e5ea3f9e49 | ||
|
|
f0af865401 | ||
|
|
1e20a9effe | ||
|
|
ce968f7756 | ||
|
|
00aaf316ef | ||
|
|
3ad9a0ca73 | ||
|
|
14a2d24fba | ||
|
|
e374886fcf | ||
|
|
e25b373f00 | ||
|
|
6fbd270d24 | ||
|
|
6adb55a9c4 | ||
|
|
16aa5cac04 | ||
|
|
dca0009df5 | ||
|
|
1cae441cbc | ||
|
|
8b21d8f74a | ||
|
|
ff141e30ee | ||
|
|
2c970a1b8d | ||
|
|
b433f8194e | ||
|
|
7b2f5e5de0 | ||
|
|
3d1400e347 | ||
|
|
8b5d68f79b | ||
|
|
ded4b461b4 | ||
|
|
13a7be57f2 | ||
|
|
e8fdcd5c06 | ||
|
|
b8e263d7e6 | ||
|
|
b76d17e7b9 | ||
|
|
ce3151b256 | ||
|
|
dd0c3ac51e | ||
|
|
f06c5897db | ||
|
|
7dac72f796 | ||
|
|
e5a55114b7 | ||
|
|
a66d0b3d39 | ||
|
|
b01ad69ba1 | ||
|
|
bbe183e8d4 | ||
|
|
f6c9e5079a | ||
|
|
0b8408d50a | ||
|
|
51682eac11 | ||
|
|
aea38c682c | ||
|
|
6edbe97290 | ||
|
|
304eaab4d2 | ||
|
|
f4e5839931 | ||
|
|
4bac9ea9d5 | ||
|
|
64c9b21849 | ||
|
|
34828b66a2 | ||
|
|
957ba00723 | ||
|
|
d548ee48c1 | ||
|
|
d0e93a22a2 | ||
|
|
fe6c1e260b | ||
|
|
1e5add91d3 | ||
|
|
f4c7329c30 | ||
|
|
b1742ccb8e | ||
|
|
870a0d8361 | ||
|
|
1f0adf92d4 | ||
|
|
18ce562698 | ||
|
|
77af926336 | ||
|
|
33f2269896 | ||
|
|
c477e14a04 | ||
|
|
373494094a | ||
|
|
72ca666007 | ||
|
|
5be299b897 | ||
|
|
49afd5077b | ||
|
|
e7336de8a7 | ||
|
|
5b0f4f5b94 | ||
|
|
0edc037441 | ||
|
|
d4a7f7e658 | ||
|
|
fcf9668e8b | ||
|
|
76e53e0869 | ||
|
|
74764253b4 | ||
|
|
c029c6c152 | ||
|
|
bb4b0d5f92 | ||
|
|
a355cf941b | ||
|
|
e7c5ef1cca | ||
|
|
09d0f7a3cb | ||
|
|
3e7dd07b4c | ||
|
|
c536eed349 | ||
|
|
93948021e6 | ||
|
|
77317f87c0 | ||
|
|
b091ea9c6d | ||
|
|
208493da88 | ||
|
|
7015745c4f | ||
|
|
41a5c72d46 | ||
|
|
2b428641fb | ||
|
|
4ebb1e60db | ||
|
|
5e4c1feed1 | ||
|
|
d13e1da1a7 | ||
|
|
9f57cff43b | ||
|
|
b9d9776d5c | ||
|
|
b57ab8470d | ||
|
|
fe402d2faa | ||
|
|
3d38210752 | ||
|
|
6c4b047b58 | ||
|
|
e861d3415a | ||
|
|
cb251fe88b | ||
|
|
b1e594f4d7 | ||
|
|
f9505f3c9f | ||
|
|
52ee2bb769 | ||
|
|
f0471fac14 | ||
|
|
7baac98959 | ||
|
|
9119443c2a | ||
|
|
c9c33929f0 | ||
|
|
60717d38d4 | ||
|
|
858757f8d1 | ||
|
|
f15a22a3cb | ||
|
|
f6022de7d3 | ||
|
|
8214301231 | ||
|
|
a4745098c5 | ||
|
|
647b06a615 | ||
|
|
a7cbafee07 | ||
|
|
ee0eb2345c | ||
|
|
d37c42761d | ||
|
|
d4984fd0ee | ||
|
|
c770ea1859 | ||
|
|
4d1307e223 | ||
|
|
e9308c11ba | ||
|
|
5206ec0fcb | ||
|
|
c65671a6f9 | ||
|
|
ec99203dc6 | ||
|
|
1cdde047ff | ||
|
|
2375d70782 | ||
|
|
5b0c395293 | ||
|
|
ea0c1abb0b | ||
|
|
cc841812ce | ||
|
|
5104bce7bb | ||
|
|
357ce483a8 | ||
|
|
1a40b4b984 | ||
|
|
cdd0e542f1 | ||
|
|
a9d87a938d | ||
|
|
549ff980a3 | ||
|
|
545af93972 | ||
|
|
72b9ed9f54 | ||
|
|
536c7dd04b | ||
|
|
274d5d1e75 | ||
|
|
7b478e42c0 | ||
|
|
d0ac1e61d4 | ||
|
|
31d73927a3 | ||
|
|
7713bd042a | ||
|
|
664dab76e3 | ||
|
|
6e2c33866d | ||
|
|
7b6dd6765e | ||
|
|
d55d2d0303 | ||
|
|
4df7bec913 | ||
|
|
4ddab1b691 | ||
|
|
b0c0e96fca | ||
|
|
aeee2fc391 | ||
|
|
4f28cb5617 | ||
|
|
a442a841f2 | ||
|
|
9201170ab8 | ||
|
|
4f06cfa0da | ||
|
|
fe03daa01f | ||
|
|
b64c4f6043 | ||
|
|
5884c78b56 | ||
|
|
b01b7373ac | ||
|
|
3cc9482a08 | ||
|
|
83c6b01fae | ||
|
|
1f169bc67e | ||
|
|
ea25675264 | ||
|
|
c302cd680c | ||
|
|
ebf46d0cfd | ||
|
|
2c9b504688 | ||
|
|
41d3de565c | ||
|
|
88430d845d | ||
|
|
c6e5e5d27e | ||
|
|
cd673028b7 | ||
|
|
2cafe12e4f | ||
|
|
febbaca66b | ||
|
|
e410ca748a | ||
|
|
524c04296e | ||
|
|
ef360bf93e | ||
|
|
bd4f7a4783 | ||
|
|
3c2c242225 | ||
|
|
a8e657c86e | ||
|
|
70e103af49 | ||
|
|
006f7a79b4 | ||
|
|
c7a4dbe84b | ||
|
|
31c0c52d7f | ||
|
|
a4590d3771 | ||
|
|
02b5e39c39 | ||
|
|
85dd704f86 | ||
|
|
b4d4efd40c | ||
|
|
8745b0f31a | ||
|
|
3787b3bbfc | ||
|
|
765e1b1231 | ||
|
|
2a2e2bf957 | ||
|
|
c93913732b | ||
|
|
f5bbc99d7d | ||
|
|
27ce42b9b0 | ||
|
|
008d51aeec | ||
|
|
8d0d264c0f | ||
|
|
28717352b4 | ||
|
|
f9e492dfdc | ||
|
|
a8e029f0e0 | ||
|
|
f5be4503c5 | ||
|
|
cd1d3f5026 | ||
|
|
4f55733bdd | ||
|
|
81819d04e8 | ||
|
|
4d4adea6eb | ||
|
|
ca981fbc8e | ||
|
|
b4c64abd1e | ||
|
|
a8787330d8 | ||
|
|
7725234b69 | ||
|
|
062d897fb1 | ||
|
|
e1ed95a638 | ||
|
|
7ffa5d076c | ||
|
|
1ae0ae630a | ||
|
|
d3e8daa9b5 | ||
|
|
5f8be26b73 | ||
|
|
0eb575b472 | ||
|
|
1888d905a4 | ||
|
|
3bc4dc8450 | ||
|
|
78719df8d4 | ||
|
|
d3616b335f | ||
|
|
e72cd086b4 | ||
|
|
c82e67c39a | ||
|
|
9885cf6f10 | ||
|
|
d923b5bc0f | ||
|
|
611d2fcaff | ||
|
|
9b2b312719 | ||
|
|
f84161dafc | ||
|
|
8546a0d0bd | ||
|
|
09f5873806 | ||
|
|
18dc905a8c | ||
|
|
30d64a0aa5 | ||
|
|
8359c9e19f | ||
|
|
571f0c0564 | ||
|
|
736a9ef442 | ||
|
|
aee94b0e14 | ||
|
|
4cfed0d394 | ||
|
|
c714d5d881 | ||
|
|
1c2d07ee56 | ||
|
|
96f7f3d88f | ||
|
|
c743577369 | ||
|
|
e5ea60fe88 | ||
|
|
330d93f335 | ||
|
|
f4936144d0 | ||
|
|
bbaa5dde92 | ||
|
|
e6b46151ec | ||
|
|
655a8de652 | ||
|
|
771d69f38b | ||
|
|
2a46dbf149 | ||
|
|
95a0535462 | ||
|
|
041758fead | ||
|
|
d6bb723c6a | ||
|
|
95f97e1c9f | ||
|
|
b029292dd2 | ||
|
|
82ba663c24 | ||
|
|
fabd5b9d32 | ||
|
|
58736b707d | ||
|
|
9219384650 | ||
|
|
14a904cfa9 | ||
|
|
e73f7a9c10 | ||
|
|
09acd36c08 | ||
|
|
69a6f44b8b | ||
|
|
3ee8fd4ec6 | ||
|
|
4f6c0b45f8 | ||
|
|
06a756a5eb | ||
|
|
b312df3b53 | ||
|
|
8e4b2a90a4 | ||
|
|
85b3091b8a | ||
|
|
3838fc3d22 | ||
|
|
0f4722d580 | ||
|
|
4241258158 | ||
|
|
13c446c918 | ||
|
|
9255026b84 | ||
|
|
119eb57a38 | ||
|
|
731f379bed | ||
|
|
bedcf304e1 | ||
|
|
a4655484cb | ||
|
|
babc5aba4f | ||
|
|
763a6f8b02 | ||
|
|
b08960d4b9 | ||
|
|
2c6e91622f | ||
|
|
4679977612 | ||
|
|
0e387904b0 | ||
|
|
f4238621a6 | ||
|
|
2fa19e8cae | ||
|
|
ab644d0638 | ||
|
|
8d1db88e1a | ||
|
|
12215ac5dd | ||
|
|
97d0b386ba | ||
|
|
f8526be667 | ||
|
|
22624f6a29 | ||
|
|
e70584e7fc | ||
|
|
ebd2346f3e | ||
|
|
03ce553620 | ||
|
|
9418a37846 | ||
|
|
4f186dec68 | ||
|
|
5867fd9912 | ||
|
|
cd327cfc5a | ||
|
|
a3f95871b2 | ||
|
|
53021b770b | ||
|
|
7f93731d0c | ||
|
|
570f82d7f8 | ||
|
|
2c8a069f47 | ||
|
|
bbf23be1f3 | ||
|
|
accca4e700 | ||
|
|
ecc8ebef6a | ||
|
|
6c8a807c8c | ||
|
|
dfb2d5eaaa | ||
|
|
71c7ec6fed | ||
|
|
55d216f024 | ||
|
|
5e22febd54 | ||
|
|
436d871ea9 | ||
|
|
02099912c5 | ||
|
|
601aedb25a | ||
|
|
c65aa3d507 | ||
|
|
9b02837d5a | ||
|
|
dbbff7b833 | ||
|
|
e306db4d0c | ||
|
|
985266fc77 | ||
|
|
a3f771cc7c | ||
|
|
71a1bea9c7 | ||
|
|
565543fbba | ||
|
|
9193194596 | ||
|
|
83ea28ded7 | ||
|
|
1a69782f51 | ||
|
|
394ea0f3d3 | ||
|
|
0241bbdbc0 | ||
|
|
5e00739776 | ||
|
|
5d214ac965 | ||
|
|
d35ae51fbb | ||
|
|
717f319dc7 | ||
|
|
fbd2f52da2 | ||
|
|
853d89ca9c | ||
|
|
9c9e3cef29 | ||
|
|
2237afceff | ||
|
|
180d036fd4 | ||
|
|
7248ee7ed2 | ||
|
|
d1e7944ad2 | ||
|
|
2f53752e05 | ||
|
|
3c0de68a00 | ||
|
|
ef22236f35 | ||
|
|
563fc27eae | ||
|
|
d453e120c8 | ||
|
|
57bd72f147 | ||
|
|
298c62e00b | ||
|
|
3d4abfeba2 | ||
|
|
b412118a79 | ||
|
|
c2b5c32a14 | ||
|
|
06cd0a518f | ||
|
|
947dcc3f3d | ||
|
|
fa5eb23cae | ||
|
|
c43895b602 | ||
|
|
18cb2a2047 | ||
|
|
91637c7b11 | ||
|
|
7b70e987ba | ||
|
|
74dfef3424 | ||
|
|
65255edec5 | ||
|
|
5b00412ba0 | ||
|
|
ef43e3f8a0 | ||
|
|
3fa06d865a | ||
|
|
96f2f12dec | ||
|
|
972079532c | ||
|
|
996d4efa32 | ||
|
|
4704bfb7e6 | ||
|
|
5d3b237854 | ||
|
|
dca290b3f0 | ||
|
|
a84473036d | ||
|
|
1b3cb7abb5 | ||
|
|
7dd99ae13e | ||
|
|
7af511b01a | ||
|
|
bb3dc2d889 | ||
|
|
76268c41bc | ||
|
|
b6963ba7c6 | ||
|
|
bd3ff8f828 | ||
|
|
385326f3a8 | ||
|
|
d896fd9106 | ||
|
|
9c18afee35 | ||
|
|
f0b87c8312 | ||
|
|
297b7d548a | ||
|
|
7c406e8f8a | ||
|
|
f458d8dc39 | ||
|
|
66ed78cf4d | ||
|
|
f6205182b9 | ||
|
|
a661016824 | ||
|
|
448afcea7a | ||
|
|
23881ad861 | ||
|
|
9d41f49741 | ||
|
|
b302ebfbb5 | ||
|
|
88d428f03c | ||
|
|
7396b30615 | ||
|
|
6fe1cc9ed7 | ||
|
|
7622959657 | ||
|
|
6f94fdf133 | ||
|
|
b348ce3660 | ||
|
|
f8638fef92 | ||
|
|
9e895da7ed | ||
|
|
cb659fef0d | ||
|
|
1a9042c8d1 | ||
|
|
aac8cb9775 | ||
|
|
99962a68b6 | ||
|
|
8ce6d7f369 | ||
|
|
3bc5a586fa | ||
|
|
f7630dec30 | ||
|
|
031f41a333 | ||
|
|
d18eb1c9c5 | ||
|
|
a666619de7 | ||
|
|
a6d55175ac | ||
|
|
b33d952b47 | ||
|
|
65fc0f36e7 | ||
|
|
4bb743bde0 | ||
|
|
1b8f92249d | ||
|
|
42838834f6 | ||
|
|
83508fa322 | ||
|
|
044d667b9e | ||
|
|
97274871c8 | ||
|
|
e5fabc828c | ||
|
|
e5601cb09c | ||
|
|
6f87bd8570 | ||
|
|
b393923c6e | ||
|
|
37ab148df6 | ||
|
|
2f977f200b | ||
|
|
e674f1a528 | ||
|
|
fc93d47b14 | ||
|
|
3028d096b9 | ||
|
|
e7313a4df4 | ||
|
|
31af5ec181 | ||
|
|
98222c75c2 | ||
|
|
d0380eccf7 | ||
|
|
f570ee0ea2 | ||
|
|
6ac716b8ba | ||
|
|
e8a080f5c0 | ||
|
|
67237e54f9 | ||
|
|
4acf0f080e | ||
|
|
8e576f3f7d | ||
|
|
037859b007 | ||
|
|
e81e7c7ebd | ||
|
|
a50079b920 | ||
|
|
4a38d8199f | ||
|
|
4dd9337528 | ||
|
|
c6db07039f | ||
|
|
9294b59aae | ||
|
|
490f595d6d | ||
|
|
67af7a0baf | ||
|
|
7da89748bb | ||
|
|
72a82ebece | ||
|
|
12e44a3e62 | ||
|
|
5dd94df9dd | ||
|
|
79051e04b4 | ||
|
|
02a0a77bda | ||
|
|
b3c5115707 | ||
|
|
e069681cfd | ||
|
|
c93356fb1a | ||
|
|
c398c938e1 | ||
|
|
f3c6dc31ac | ||
|
|
06403425f9 | ||
|
|
a9fa9095d5 | ||
|
|
617eacfcd3 | ||
|
|
7ba89639da | ||
|
|
2914ed358e | ||
|
|
72041b6873 | ||
|
|
bf8da23a76 | ||
|
|
f3f3d9cdfe | ||
|
|
05c7d8fec9 | ||
|
|
5201aeffa6 | ||
|
|
2fba190d8b | ||
|
|
9e669ad06b | ||
|
|
7f66be599c | ||
|
|
7d1f429ead | ||
|
|
4e602abfcb | ||
|
|
aad016d418 | ||
|
|
3544428e18 | ||
|
|
459c3ef530 | ||
|
|
a01f5b1f3f | ||
|
|
9183391ab0 | ||
|
|
c22ca077ba | ||
|
|
63c224b073 | ||
|
|
f36567593a | ||
|
|
b2efee99fa | ||
|
|
6510dc9e45 | ||
|
|
213beed360 | ||
|
|
801f374a66 | ||
|
|
7f3eecec4c | ||
|
|
bd92f64df9 | ||
|
|
ab2617c20f | ||
|
|
cd958240df | ||
|
|
4254a2a2f7 | ||
|
|
9735f21f65 | ||
|
|
62343cbb77 | ||
|
|
23eca257f4 | ||
|
|
5a3c17e831 | ||
|
|
de1bb7e438 | ||
|
|
6216d06d0e | ||
|
|
cb03a51d40 | ||
|
|
09a65a622a | ||
|
|
95f6ce1f3e | ||
|
|
7ede988cb1 | ||
|
|
a06e05dc9e | ||
|
|
2a3c6dc55c | ||
|
|
814701324c | ||
|
|
01fea9ce3f | ||
|
|
da5e795858 | ||
|
|
b491241307 | ||
|
|
81f6e87416 | ||
|
|
20a680561a | ||
|
|
a4f2a19505 | ||
|
|
a263283c93 | ||
|
|
ac2cdc65a8 | ||
|
|
c1b7740ac4 | ||
|
|
a1c8868159 | ||
|
|
a157acd185 | ||
|
|
12ec1309bb | ||
|
|
042d55f734 | ||
|
|
67f8c6df42 | ||
|
|
c9d6c72fe0 | ||
|
|
e5fcadae30 | ||
|
|
cb0ee7990a | ||
|
|
0eea4c5913 | ||
|
|
5a8466b0d7 | ||
|
|
372d811f66 | ||
|
|
ff2027846b | ||
|
|
8318eb1a0d | ||
|
|
57c0751793 | ||
|
|
86b00ef7fe | ||
|
|
6e12a556ec | ||
|
|
fba165d121 | ||
|
|
68d77636b0 | ||
|
|
394d46f731 | ||
|
|
702a9f6aa5 | ||
|
|
7ae3813ac5 | ||
|
|
34a933af0b | ||
|
|
4ac5d6df7f | ||
|
|
0260548d9c | ||
|
|
5b64623f50 | ||
|
|
233e472503 | ||
|
|
335512e96a | ||
|
|
d451a3fdd7 | ||
|
|
499de4fd60 | ||
|
|
caf9abc16f | ||
|
|
5dfce69c37 | ||
|
|
8f12829e95 | ||
|
|
15a42f5407 | ||
|
|
c8cdd3f432 | ||
|
|
ac7c72396d | ||
|
|
ce3271f095 | ||
|
|
3ff4b04e52 | ||
|
|
ecd90a41d5 | ||
|
|
87695cf84b | ||
|
|
3bb93e1fd9 | ||
|
|
69279b2233 | ||
|
|
7c811666fe | ||
|
|
9a18dd3718 | ||
|
|
3338d26aaa | ||
|
|
167ea1587e | ||
|
|
7ad6399940 | ||
|
|
71db6b3275 | ||
|
|
00626b9f3e | ||
|
|
d0fa79c9ca | ||
|
|
fc1f75c3f6 | ||
|
|
21b9676093 | ||
|
|
ea2a7204df | ||
|
|
bcdd09a2e6 | ||
|
|
7c394ddeee | ||
|
|
50d7e2d1d7 | ||
|
|
395cecb082 | ||
|
|
c8888915d7 | ||
|
|
38740ce1c9 | ||
|
|
73b893215e | ||
|
|
e93c3f0028 | ||
|
|
be2e35381e | ||
|
|
c79f59c86f | ||
|
|
6f02d5f2c4 | ||
|
|
969bd84f1d | ||
|
|
8865b7bfec | ||
|
|
f60ecc3626 | ||
|
|
824b230bd0 | ||
|
|
71a208334d | ||
|
|
1d75d23772 | ||
|
|
6dd848eac5 | ||
|
|
0c0684bfb7 | ||
|
|
b56337df19 | ||
|
|
0f0512c67c | ||
|
|
b677261976 | ||
|
|
0d0a75319c | ||
|
|
0d283757d5 | ||
|
|
c09f477251 | ||
|
|
1d2bf3cb48 | ||
|
|
7057160b3e | ||
|
|
4244f41c41 | ||
|
|
70f587e305 | ||
|
|
97c5119807 | ||
|
|
77a74d64bf | ||
|
|
0547cec24d | ||
|
|
6837f58a0e | ||
|
|
2518377f83 | ||
|
|
d38e67f539 | ||
|
|
a3d16d3c71 | ||
|
|
14e1363930 | ||
|
|
86eba0aaeb | ||
|
|
10d7e28de3 | ||
|
|
082d08755e | ||
|
|
195bbddd6f | ||
|
|
d68cbfd837 | ||
|
|
851d487015 | ||
|
|
0a3ae03043 | ||
|
|
d56fea52f3 | ||
|
|
1de0f14194 | ||
|
|
d3addae744 | ||
|
|
ee0e831efe | ||
|
|
59559efbb5 | ||
|
|
05e2a9c824 | ||
|
|
9038d94184 | ||
|
|
08a93fc5ae | ||
|
|
6b6075ca48 | ||
|
|
51135b9222 | ||
|
|
922c1770a0 | ||
|
|
b9dc8d79e0 | ||
|
|
7b823e4185 | ||
|
|
fbdb4aa619 | ||
|
|
7716936f77 | ||
|
|
9636fec9da | ||
|
|
e15676e946 | ||
|
|
28fb4ed090 | ||
|
|
8b5474d0a8 | ||
|
|
35e5a48e63 | ||
|
|
470446a104 | ||
|
|
c0cc48d129 | ||
|
|
1134294037 | ||
|
|
f0f49d4f8f | ||
|
|
5f361cbd2d | ||
|
|
20d65d3685 | ||
|
|
51f0780c66 | ||
|
|
b3db9aece7 | ||
|
|
4e22fd1a69 | ||
|
|
d290ccee7f | ||
|
|
4d227ef882 | ||
|
|
6f842cea8b | ||
|
|
36da25e08e | ||
|
|
f586bb2617 | ||
|
|
f3a81ac635 | ||
|
|
266fc0961b | ||
|
|
824ae55d77 | ||
|
|
656bfdc569 | ||
|
|
0f45dd5fee | ||
|
|
82e7faf83d | ||
|
|
0c7310b18d | ||
|
|
2cedd0d2c6 | ||
|
|
b63d087d5c | ||
|
|
bccdb36bd3 | ||
|
|
298ef551ce | ||
|
|
9b23a0a7ab | ||
|
|
5e2546dd0c | ||
|
|
4e9bef301d | ||
|
|
be5d718280 | ||
|
|
3bc1d6d0a1 | ||
|
|
2d23169ea5 | ||
|
|
b486c60d5e | ||
|
|
3246d2bbb6 | ||
|
|
7d7765ce14 | ||
|
|
c1f2750b05 | ||
|
|
bb4d44499c | ||
|
|
195ac3e5b6 | ||
|
|
bc9679cad9 | ||
|
|
a603b58970 | ||
|
|
a740dbf871 | ||
|
|
b10e462e03 | ||
|
|
6f28eb16c6 | ||
|
|
140a41141c | ||
|
|
6f00b50c6e | ||
|
|
a9cb19933a | ||
|
|
cbd8ce408e | ||
|
|
9837888e50 | ||
|
|
42176b6593 | ||
|
|
a320528e64 | ||
|
|
69a9175c67 | ||
|
|
9fdc3196d9 | ||
|
|
0b271fc44f | ||
|
|
0fa2f7b8f1 | ||
|
|
41c775fb44 | ||
|
|
28b06f45fe | ||
|
|
083b3d2a1c | ||
|
|
61866f6dae | ||
|
|
39d7274359 | ||
|
|
a9b4d994eb | ||
|
|
3701dcd0b4 | ||
|
|
efe2588fd9 | ||
|
|
3c17d886cc | ||
|
|
83fe3605f6 | ||
|
|
dec474953b | ||
|
|
f80964d8d7 | ||
|
|
a43687ee30 | ||
|
|
e04233a897 | ||
|
|
93cd9b00bd | ||
|
|
3a592ca9c4 | ||
|
|
555d0d51b0 | ||
|
|
a70f29a8c9 | ||
|
|
dad53a84c8 | ||
|
|
d03b21ee19 | ||
|
|
1a1bf5f76a | ||
|
|
0ebc0f19b8 | ||
|
|
d4cfa94aaa | ||
|
|
383d4c8f9a | ||
|
|
48b187edd1 | ||
|
|
316e18f8c5 | ||
|
|
657595d363 | ||
|
|
9cd9ad16b2 | ||
|
|
7d49d0fc8a | ||
|
|
fa9bdbfd64 | ||
|
|
558dc58a52 | ||
|
|
383b1afe0b | ||
|
|
3d757a2af6 | ||
|
|
2cb20b665d | ||
|
|
eadb36bcdd | ||
|
|
a3bbaeb11b | ||
|
|
816ee7e23b | ||
|
|
2a10da129e | ||
|
|
9784c3bf2d | ||
|
|
f64a7e2c5b | ||
|
|
f01359a62e | ||
|
|
729f392148 | ||
|
|
e48802c898 | ||
|
|
34ed9f03e1 | ||
|
|
4990b6db94 | ||
|
|
ecf50c8181 | ||
|
|
927159011c | ||
|
|
640db5e667 | ||
|
|
509f09dfbc | ||
|
|
4f42ae0d81 | ||
|
|
1b4391ac23 | ||
|
|
5cb6894657 | ||
|
|
be66c8bffa | ||
|
|
5f71bcfe9a | ||
|
|
95d786e9a8 | ||
|
|
8b5e977868 | ||
|
|
49a631b475 | ||
|
|
8b98a68d1a | ||
|
|
c03e46814b | ||
|
|
7efac81f8b | ||
|
|
58e98e9580 | ||
|
|
56c211fbeb | ||
|
|
2aa2e53fef | ||
|
|
3993c88fbb | ||
|
|
f706e7eecc | ||
|
|
549de25a49 | ||
|
|
217b05fb80 | ||
|
|
e1b9d40ca6 | ||
|
|
0eeba809f2 | ||
|
|
4a0df1042d | ||
|
|
e7a4274511 | ||
|
|
b3def68a4f | ||
|
|
3c67de08a3 | ||
|
|
cec67ef3e3 | ||
|
|
881501b278 | ||
|
|
d09a949755 | ||
|
|
bf6fa0f335 | ||
|
|
9dcfa322a5 | ||
|
|
a1c21ce05f | ||
|
|
22be56179d | ||
|
|
24da6fcb3b | ||
|
|
8078b27172 | ||
|
|
89d1254106 | ||
|
|
497f66f5dc | ||
|
|
a321d54142 | ||
|
|
8495b461b8 | ||
|
|
35d6354898 | ||
|
|
a2b4af137c | ||
|
|
756d1c12fd | ||
|
|
63f2e52edb | ||
|
|
fd704eca00 | ||
|
|
8c233f1861 | ||
|
|
669bb00590 | ||
|
|
815fd918cb | ||
|
|
4249adbe4e | ||
|
|
1aec17da4d | ||
|
|
3680a3092e | ||
|
|
b11a269867 | ||
|
|
cccbf75878 | ||
|
|
5ce309e64b | ||
|
|
4b48a43413 | ||
|
|
a05df24c8b | ||
|
|
4f599b521a | ||
|
|
44cf2fc4fb | ||
|
|
0ca9f70796 | ||
|
|
83cb2dbc4d | ||
|
|
b09937ad3d | ||
|
|
c88d5d462c | ||
|
|
78c971cb87 | ||
|
|
1bafddcfe2 | ||
|
|
047b2071f5 | ||
|
|
8aca039ca6 | ||
|
|
db8c6b0c9e | ||
|
|
dbc6aa83f3 | ||
|
|
08472aa68b | ||
|
|
3010068660 | ||
|
|
5e2faff01d | ||
|
|
598338809f | ||
|
|
4778760622 | ||
|
|
3a23cc42f6 | ||
|
|
e23283e794 | ||
|
|
4d730a31c4 | ||
|
|
216b6407f3 | ||
|
|
e95988f402 | ||
|
|
1ce3731d7d | ||
|
|
7420d3c8de | ||
|
|
f1edcc06d3 | ||
|
|
ce5c3db346 | ||
|
|
cc0b7b3719 | ||
|
|
7854fa2e18 | ||
|
|
1b7bc825d5 | ||
|
|
e65f58acb2 | ||
|
|
18fe17dc2d | ||
|
|
8098461e0f | ||
|
|
bf8e9f9242 | ||
|
|
4838067440 | ||
|
|
53a080e32e | ||
|
|
3ac41770b8 | ||
|
|
6fe51fd7f4 | ||
|
|
a6cbe15b5e | ||
|
|
3313eba45c | ||
|
|
b01150f707 | ||
|
|
4502948f89 | ||
|
|
8cb2ffbd2e | ||
|
|
be80cb03d6 | ||
|
|
13d6e96cdc | ||
|
|
9f280b1f9c | ||
|
|
786dfa6700 | ||
|
|
e260aee2e6 | ||
|
|
504c27c934 | ||
|
|
c4ba481561 | ||
|
|
841770aed1 | ||
|
|
1a4643f3a2 | ||
|
|
e89702d99d | ||
|
|
250e3820df | ||
|
|
8b2a509a32 | ||
|
|
6db92c56b9 | ||
|
|
e4914a2139 | ||
|
|
704c4b36ab | ||
|
|
b9d61108bf | ||
|
|
e92d2f737b | ||
|
|
6ec36072c4 | ||
|
|
ab18d4d23a | ||
|
|
1e6893a9d9 | ||
|
|
01bcc957e8 | ||
|
|
3c989cfa04 | ||
|
|
bde29ef155 | ||
|
|
cee4cd26e0 | ||
|
|
f774b88211 | ||
|
|
251f9b7338 | ||
|
|
dd5fc10a95 | ||
|
|
5e84efc542 | ||
|
|
b29fd4abbd | ||
|
|
1c6f2254f3 | ||
|
|
73685273f4 | ||
|
|
76d070777f | ||
|
|
42d18f7302 | ||
|
|
963a7a527a | ||
|
|
df61ed3048 | ||
|
|
2a8e6061a2 | ||
|
|
96c4fe7057 | ||
|
|
124df9ae83 | ||
|
|
62b2eecf6e | ||
|
|
9fb6b7bbd9 | ||
|
|
0ac7929230 | ||
|
|
d16e8f1c51 | ||
|
|
4b59f04930 | ||
|
|
7a375136cc | ||
|
|
62a328af45 | ||
|
|
aafe35dca7 | ||
|
|
c73b728255 | ||
|
|
1186072e48 | ||
|
|
141de19804 | ||
|
|
97d71dfe09 | ||
|
|
f05b4fa7ff | ||
|
|
2f36ec82f9 | ||
|
|
c386a0a356 | ||
|
|
4ba1f972b5 | ||
|
|
525eb10854 | ||
|
|
7176b08882 | ||
|
|
a6f4248502 | ||
|
|
f0da6dd64f | ||
|
|
af3c9042c3 | ||
|
|
d8aa65bc17 | ||
|
|
da6ab3f752 | ||
|
|
3cdf7fe742 | ||
|
|
cb54d7e343 | ||
|
|
60611e54f3 | ||
|
|
a4a78681ef | ||
|
|
4d85147077 | ||
|
|
857048f47c | ||
|
|
6084102d20 | ||
|
|
2dc1fcc875 | ||
|
|
584479c10d | ||
|
|
3430550dac | ||
|
|
81f5bc79aa | ||
|
|
e20ccb7991 | ||
|
|
5cf4af83b0 | ||
|
|
e5cb34d1f8 | ||
|
|
91c46f99a0 | ||
|
|
dbdcaf8962 | ||
|
|
230d6246c6 | ||
|
|
066e5f966a | ||
|
|
ff615cba03 | ||
|
|
631fa0f536 | ||
|
|
ce2eb76703 | ||
|
|
9422039e09 | ||
|
|
0f13eb8611 | ||
|
|
196394f666 | ||
|
|
9b2f7029df | ||
|
|
a2e6b57c35 | ||
|
|
e5fdb4ba85 | ||
|
|
0c83522296 | ||
|
|
f59e30442a | ||
|
|
b67b750009 | ||
|
|
61f2a43628 | ||
|
|
769545ccd7 | ||
|
|
c0b9272b82 | ||
|
|
d5e5cbb393 | ||
|
|
d8251ec441 | ||
|
|
0a04ef44d4 | ||
|
|
79ada49fdc | ||
|
|
1bf134c3ef | ||
|
|
38098290b7 | ||
|
|
b66c95d920 | ||
|
|
25ae0f9311 | ||
|
|
f63799ecbb | ||
|
|
f2de080c68 | ||
|
|
4ceaa7bd4b | ||
|
|
5753983f41 | ||
|
|
58768ca886 | ||
|
|
d3d740c38f | ||
|
|
27f99bd3c0 | ||
|
|
230fa96d2b | ||
|
|
1e7f5692ce | ||
|
|
af884e427d | ||
|
|
00b2002855 | ||
|
|
e5d20ea8ae | ||
|
|
3b4ca235d5 | ||
|
|
8633aca6fa | ||
|
|
85dde4b9d0 | ||
|
|
43e981579f | ||
|
|
f12706599e | ||
|
|
650668eaf7 | ||
|
|
6093589e41 | ||
|
|
ce777c9393 | ||
|
|
983523c2f6 | ||
|
|
8f5843e0fe | ||
|
|
98b0602ae5 | ||
|
|
0286e8362e | ||
|
|
bcfc464f24 | ||
|
|
7a9e9df3c0 | ||
|
|
829bf941f4 | ||
|
|
3e42161c35 | ||
|
|
9cdaa5e028 | ||
|
|
34ef7b9b79 | ||
|
|
201677899b | ||
|
|
fd563c5b4b | ||
|
|
d5b5031f5c | ||
|
|
08f2fcd1b9 | ||
|
|
f7da6bc070 | ||
|
|
1414fed3b2 | ||
|
|
13ff5c80be | ||
|
|
782dd645c3 | ||
|
|
020bcd46c2 | ||
|
|
fefb01f930 | ||
|
|
6489a2ca3b | ||
|
|
cbe4ec30d1 | ||
|
|
38a9b04ce0 | ||
|
|
7de59621c4 | ||
|
|
e9560dd916 | ||
|
|
91fec006ae | ||
|
|
82af74c459 | ||
|
|
32dc46efac | ||
|
|
020b94794b | ||
|
|
bb59ef692e | ||
|
|
8280d4628d | ||
|
|
91c6a71353 | ||
|
|
fa9e8223b9 | ||
|
|
7057ce7a2c | ||
|
|
b98febce24 | ||
|
|
11758cfa90 | ||
|
|
a37928110d | ||
|
|
a3c7674676 | ||
|
|
ed68b17bac | ||
|
|
aa86b8ecf4 | ||
|
|
e0c5630ed7 | ||
|
|
c4b4107f57 | ||
|
|
d198f6c64a | ||
|
|
fd3812c27e | ||
|
|
ddbffd874b | ||
|
|
bc1b5bed0b | ||
|
|
f7019e0ff8 | ||
|
|
e47f88f4f3 | ||
|
|
baf750b89a | ||
|
|
bea256ddc6 | ||
|
|
e7f841b71e | ||
|
|
1df10d7a48 | ||
|
|
53c4a0d418 | ||
|
|
883f1990c6 | ||
|
|
c2efed56e0 | ||
|
|
37814194ae | ||
|
|
03cc86c6d1 | ||
|
|
206f5d3aa8 | ||
|
|
d5c71f3dcc | ||
|
|
1ed35d06c7 | ||
|
|
4456ab2ab5 | ||
|
|
645297de61 | ||
|
|
71dbfda219 | ||
|
|
c8977e68d0 | ||
|
|
9b1bfb17b0 | ||
|
|
95858b46b0 | ||
|
|
d7ca13e7f7 | ||
|
|
a17dfe8ed6 | ||
|
|
1d9eb8fa17 | ||
|
|
6d8e64a213 | ||
|
|
c5859a0d92 | ||
|
|
058b199606 | ||
|
|
5b58985fdf | ||
|
|
b9e1192d69 | ||
|
|
1d0a575773 | ||
|
|
72e3e36f1b | ||
|
|
bd2271de86 | ||
|
|
ffa2aa6f1c | ||
|
|
c0d35aa6e7 | ||
|
|
11c1396d83 | ||
|
|
41e6ba1030 | ||
|
|
e92e9043fa | ||
|
|
c53ab30b2e | ||
|
|
c763ca269a | ||
|
|
bf4c05c41c | ||
|
|
9b9130ed57 | ||
|
|
5fde277748 | ||
|
|
7757666a0b | ||
|
|
4bc52873f7 | ||
|
|
a5a38203ae | ||
|
|
1209862996 | ||
|
|
4f0bb1010d | ||
|
|
050b974051 | ||
|
|
88fb7efec3 | ||
|
|
a91c562dcf | ||
|
|
f1a136c9b4 | ||
|
|
57583b39e7 | ||
|
|
3467ea2476 | ||
|
|
0e6daf412d | ||
|
|
8468c5318d | ||
|
|
853f4865ce | ||
|
|
0742c694b0 | ||
|
|
247622a6db | ||
|
|
cbd4b4f73a | ||
|
|
3782d7f4df | ||
|
|
bc13894b31 | ||
|
|
d6ff293d7f | ||
|
|
9e2ba671b8 | ||
|
|
fb56c5f422 | ||
|
|
a45d6bd79b | ||
|
|
28a26db054 | ||
|
|
95782e7311 | ||
|
|
5f6221de7f | ||
|
|
b42ac3eb11 | ||
|
|
2964727959 | ||
|
|
fca7808b55 | ||
|
|
07c98d30ad | ||
|
|
a7c95a783e | ||
|
|
e84ebce421 | ||
|
|
0df765bbbd | ||
|
|
2af2fbfe6d | ||
|
|
96f5f92b09 | ||
|
|
dedd7f4827 | ||
|
|
28a066a7c9 | ||
|
|
6377884c4a | ||
|
|
41cc61e4c7 | ||
|
|
73e13baa84 | ||
|
|
403707bb5b | ||
|
|
873bdd793a | ||
|
|
edbd6cdfa5 | ||
|
|
e7a9679a20 | ||
|
|
b9d09acf92 | ||
|
|
7a02b1720e | ||
|
|
3c88e8aac0 | ||
|
|
df4e93973b | ||
|
|
c3dbe47f3c | ||
|
|
af91d80c94 | ||
|
|
a133621934 | ||
|
|
329bddc4f6 | ||
|
|
31785d6fbe | ||
|
|
c7bf006b49 | ||
|
|
3fc1458cc2 | ||
|
|
53be7dad84 | ||
|
|
7507a0f20f | ||
|
|
32a6711898 | ||
|
|
223c6513ba | ||
|
|
d395df1f37 | ||
|
|
f5a7d96a77 | ||
|
|
81ae020273 | ||
|
|
57024db6e6 | ||
|
|
e507b964a1 | ||
|
|
d2bff48e88 | ||
|
|
ba364f629f | ||
|
|
ae723c42fe | ||
|
|
8cf46bb5a8 | ||
|
|
ffadb9df59 | ||
|
|
87c55d434c | ||
|
|
ae513fd908 | ||
|
|
4683f2194d | ||
|
|
823174af3e | ||
|
|
77c205cd78 | ||
|
|
ea047b1573 | ||
|
|
c4b9c107af | ||
|
|
5bb580a9e0 | ||
|
|
b82e0f124a | ||
|
|
4e5512ecb3 | ||
|
|
48dffd1d6e | ||
|
|
a0820fcd2d | ||
|
|
0819240675 | ||
|
|
1ae7e8f998 | ||
|
|
bfbf7c2d10 | ||
|
|
8fb4d06858 | ||
|
|
0bec217d1e | ||
|
|
a0a7b8b758 | ||
|
|
5e344b7db6 | ||
|
|
a954773ba6 | ||
|
|
ee27dfd927 | ||
|
|
44995a791f | ||
|
|
df69100282 | ||
|
|
c6b6247812 | ||
|
|
466b9e88b0 | ||
|
|
1c51f99ed4 | ||
|
|
2a68db14dc | ||
|
|
b5bbd3e6d9 | ||
|
|
3ccdce5df4 | ||
|
|
6c9195bae8 | ||
|
|
ed324369a0 | ||
|
|
37efbe3f4b | ||
|
|
0e2f4cd25a | ||
|
|
d773410d6b | ||
|
|
1db72cb2fe | ||
|
|
cd952734e5 | ||
|
|
6b134cc102 | ||
|
|
55c399bab6 | ||
|
|
60a3214375 | ||
|
|
f992b50444 | ||
|
|
65a62df0b1 | ||
|
|
a154752c1a | ||
|
|
9ee6dcd27b | ||
|
|
fc5f512d24 | ||
|
|
089ed989f2 | ||
|
|
b26c2253af | ||
|
|
647429d822 | ||
|
|
8c1368a79f | ||
|
|
cf37e29f96 | ||
|
|
ce9a991a28 | ||
|
|
4faf21a899 | ||
|
|
8f2c02ec2a | ||
|
|
872bd0042c | ||
|
|
c8c2d8de61 | ||
|
|
30e8ebccb7 | ||
|
|
7b0efb110f | ||
|
|
e553d93b17 | ||
|
|
41ba98dc84 | ||
|
|
1dd53d4a03 | ||
|
|
00b1132fcf | ||
|
|
4d1fa73ac7 | ||
|
|
5493e5c35c | ||
|
|
e9c5272435 | ||
|
|
807ad56a39 | ||
|
|
472aa40b53 | ||
|
|
64e2b3e6db | ||
|
|
5dc6f268c7 | ||
|
|
931ef0c0c1 | ||
|
|
290adf2434 | ||
|
|
554c1c36bc | ||
|
|
0e5994a0f9 | ||
|
|
e3fb2b63c9 | ||
|
|
82c67783c1 | ||
|
|
9799bbfedb | ||
|
|
e8a1196674 | ||
|
|
48a4e81214 | ||
|
|
bf441d6918 | ||
|
|
aab4089986 | ||
|
|
c7cf40d55e | ||
|
|
b977e3063f | ||
|
|
e5181e75be | ||
|
|
58c903467e | ||
|
|
a615e0b627 | ||
|
|
b6c729f2d3 | ||
|
|
ff437ce8cf | ||
|
|
66a986c76f | ||
|
|
410729e91a | ||
|
|
916f758e8c | ||
|
|
8affc5529e | ||
|
|
efa07f3ad5 | ||
|
|
9a7daf4cd4 | ||
|
|
c5068ea1d1 | ||
|
|
0db1306563 | ||
|
|
6b42fd6a24 | ||
|
|
d418e67c77 | ||
|
|
26bfef4161 | ||
|
|
c64cffa352 | ||
|
|
863019f113 | ||
|
|
c60581d7d3 | ||
|
|
a1abae4717 | ||
|
|
f970138c5f | ||
|
|
560e88f379 | ||
|
|
18ff3c0b2c | ||
|
|
b92f20fa62 | ||
|
|
2d22e18f5a | ||
|
|
82fce8520c | ||
|
|
21ad3afce8 | ||
|
|
5b680d4925 | ||
|
|
cabcf2cc39 | ||
|
|
9cc5f50f95 | ||
|
|
2097af4172 | ||
|
|
141595e2d5 | ||
|
|
461f8d0e84 | ||
|
|
1775f4a47e | ||
|
|
48a271105d | ||
|
|
01bac8e3c4 | ||
|
|
9f6f94d504 | ||
|
|
cd8ceda3ee | ||
|
|
cd6cb90576 | ||
|
|
b69ed41ea6 | ||
|
|
0d66d57806 | ||
|
|
5762d865bb | ||
|
|
bac874ce38 | ||
|
|
fdf0aaacf1 | ||
|
|
f810e7a5f3 | ||
|
|
13fa2c74ef | ||
|
|
f24bbd1e5f | ||
|
|
ab5f21c34d | ||
|
|
ad6ee87e4f | ||
|
|
b9478291bc | ||
|
|
59228657e5 | ||
|
|
3db1ab2b3e | ||
|
|
8d75b56a2c | ||
|
|
1499ef31a9 | ||
|
|
cdc1e4e18e | ||
|
|
6f5102689f | ||
|
|
decc1af534 | ||
|
|
a912c34b9d | ||
|
|
0fc22270b7 | ||
|
|
0ff9da5d4e | ||
|
|
887ef22002 | ||
|
|
c9adb6bf97 | ||
|
|
33f2c63278 | ||
|
|
950e6d99d3 | ||
|
|
d4ab117327 | ||
|
|
419f2a5707 | ||
|
|
0fac701577 | ||
|
|
c3ea1b17ac | ||
|
|
8ad4bd5178 | ||
|
|
c7896186b0 | ||
|
|
43bd57cf4c | ||
|
|
199d9503b3 | ||
|
|
1d2347f742 | ||
|
|
f0c55d2e45 | ||
|
|
60a18f7e2d | ||
|
|
369ffeb64a | ||
|
|
3f624ab813 | ||
|
|
590abc18f9 | ||
|
|
48f4ccce5d | ||
|
|
28787055e0 | ||
|
|
ba42e0e3e4 | ||
|
|
6aabb24b34 | ||
|
|
5ab5e07775 | ||
|
|
f78ea33be6 | ||
|
|
5fbc9b637e | ||
|
|
a0e6a3edb9 | ||
|
|
29c594ad6b | ||
|
|
ed52a461db | ||
|
|
448313858e | ||
|
|
965cc02452 | ||
|
|
2dc3a02623 | ||
|
|
737df4b330 | ||
|
|
c8f66e72b9 | ||
|
|
f9b121034f | ||
|
|
305002c295 | ||
|
|
3ae728ddc2 | ||
|
|
f0b7b36aea | ||
|
|
dbeb70c08f | ||
|
|
7a8e911cf0 | ||
|
|
9a560c2e95 | ||
|
|
befb826287 | ||
|
|
9613686764 | ||
|
|
d4a2c50164 | ||
|
|
e1b83d432a | ||
|
|
fc2ef2b5f1 | ||
|
|
24243ec0e4 | ||
|
|
65ce48c2a1 | ||
|
|
063968bd3a | ||
|
|
0e9fea45fd | ||
|
|
ba10fdc2b7 | ||
|
|
4a9ced0854 | ||
|
|
f1ef36a0e4 | ||
|
|
857b68a22c | ||
|
|
acfd95c0e0 | ||
|
|
a57e4871a3 | ||
|
|
b5754732d9 | ||
|
|
d29f7d6ba8 | ||
|
|
bc928bb412 | ||
|
|
14de9efaff | ||
|
|
2254ba15d3 | ||
|
|
9318f7f596 | ||
|
|
5d1fb26f15 | ||
|
|
e33df891a4 | ||
|
|
243d185a44 | ||
|
|
7729dfa6c0 | ||
|
|
120eb3271d | ||
|
|
7a9f4c2e50 | ||
|
|
eb2f60b8f6 | ||
|
|
e63053ba48 | ||
|
|
bab12a3af3 | ||
|
|
86f36deee7 | ||
|
|
15724a34f6 | ||
|
|
33063f11b3 | ||
|
|
415bcd544f | ||
|
|
5409e8030b | ||
|
|
16aba6c8bb | ||
|
|
026b2593bb | ||
|
|
3e8e0ef0f3 | ||
|
|
a626c79b8b | ||
|
|
dc6dba42c4 | ||
|
|
b98f7a8459 | ||
|
|
4845ab0d40 | ||
|
|
831fead5ed | ||
|
|
658e2c4200 | ||
|
|
83e4df1c79 | ||
|
|
125f204d58 | ||
|
|
94a75a8e71 | ||
|
|
52412e8a23 | ||
|
|
f931db1c8d | ||
|
|
85363c677b | ||
|
|
7634447fda | ||
|
|
660d1e9ccd | ||
|
|
e73d0157df | ||
|
|
92ebb07369 | ||
|
|
ad19ca0f44 | ||
|
|
aacf835609 | ||
|
|
29690127d2 | ||
|
|
5da1de32f0 | ||
|
|
98035453b8 | ||
|
|
2ef3c925db | ||
|
|
e671b8acfa | ||
|
|
58626e9c0b | ||
|
|
650ede22e0 | ||
|
|
a2648ce970 | ||
|
|
fdc587b964 | ||
|
|
537d447a28 | ||
|
|
b8eb8d5b4e | ||
|
|
823dd8f6cc | ||
|
|
80ce6c091c | ||
|
|
ff740f4983 | ||
|
|
5e16c59b72 | ||
|
|
4c0c6a4348 | ||
|
|
587f38be50 | ||
|
|
6e2f5b09f8 | ||
|
|
b238ab7c64 | ||
|
|
6568138155 | ||
|
|
c167acd84c | ||
|
|
cbd0d9b798 | ||
|
|
51902d0ec5 | ||
|
|
1669f5d261 | ||
|
|
1b5500f7dd | ||
|
|
3f273d4362 | ||
|
|
f540c20cde | ||
|
|
042c4f5935 | ||
|
|
134f63ef59 | ||
|
|
731f12e114 | ||
|
|
2eea0b7f7d | ||
|
|
1734916c7a | ||
|
|
c83f1a2f3b | ||
|
|
3497a9e081 | ||
|
|
cb133cef99 | ||
|
|
db2e6a23b8 | ||
|
|
469e8318ac | ||
|
|
91bf052e7c | ||
|
|
f42c6ee7a3 | ||
|
|
395f734c46 | ||
|
|
a990273258 | ||
|
|
d05528ec5c | ||
|
|
3770cc3a5f | ||
|
|
143b5e8ec7 | ||
|
|
dfaa3d6e8a | ||
|
|
9df95f96c2 | ||
|
|
926f2f3dcd | ||
|
|
d275fd3dba | ||
|
|
c986f8749d | ||
|
|
01f055ef31 | ||
|
|
0b2ba32219 | ||
|
|
79f2eb8f1e | ||
|
|
5857eeb532 | ||
|
|
714018b715 | ||
|
|
bf2c2d4f3b | ||
|
|
80a4578bc3 | ||
|
|
1e918f3226 | ||
|
|
51552f232e | ||
|
|
9ebc0463bf | ||
|
|
8b6ce21884 | ||
|
|
3132398bae | ||
|
|
ff8f50cbf8 | ||
|
|
15b0580133 | ||
|
|
eced4f290a | ||
|
|
8b6e6cfbe9 | ||
|
|
3d46df6922 | ||
|
|
71604cf176 | ||
|
|
1ad7a4f6ca | ||
|
|
03be3e23d4 | ||
|
|
3d7ae93e6c | ||
|
|
dc028adc56 | ||
|
|
fc7740a4ce | ||
|
|
2b8b6ee5cc | ||
|
|
081388d4dc | ||
|
|
5259e8f122 | ||
|
|
39284057c8 | ||
|
|
f9a072ada5 | ||
|
|
bff5bdd5dc | ||
|
|
3f9d60238c | ||
|
|
ae457d72c4 | ||
|
|
bd0e7b7f3f | ||
|
|
a955c6ea7e | ||
|
|
ce647c4f90 | ||
|
|
92ea53a218 | ||
|
|
b7a7dce80d | ||
|
|
b6b1667365 | ||
|
|
def9166e43 | ||
|
|
509fc59ede | ||
|
|
c5bfa7db40 | ||
|
|
ca383864bb | ||
|
|
4d6ea9d8f9 | ||
|
|
3859dcea09 | ||
|
|
1c6f7071bf | ||
|
|
bb0714b624 | ||
|
|
992c530ed5 | ||
|
|
9376d776de | ||
|
|
359e5a28c6 | ||
|
|
4262beb545 | ||
|
|
20e3fb7d70 | ||
|
|
cfc08dfea9 | ||
|
|
c288ac6514 | ||
|
|
326c983bf1 | ||
|
|
073ebaadfc | ||
|
|
250145530f | ||
|
|
3eacb55dbc | ||
|
|
b1958a81a3 | ||
|
|
e04324df79 | ||
|
|
d048d4964e | ||
|
|
53b56ba123 | ||
|
|
36dc893334 | ||
|
|
470db114bd | ||
|
|
8e02b0f75a | ||
|
|
2950c0b8dc | ||
|
|
d03f420b92 | ||
|
|
f005e269c9 | ||
|
|
d5cd2b009b | ||
|
|
dd8c5a3b81 | ||
|
|
3f0a82503f | ||
|
|
c82927f841 | ||
|
|
213f5bf616 | ||
|
|
87f5f26ecb | ||
|
|
ec49241cef | ||
|
|
14f1a8f17b | ||
|
|
aee17dc28a | ||
|
|
5828e5a5a7 | ||
|
|
6d13315fdb | ||
|
|
75f224ccf8 | ||
|
|
85646182e0 | ||
|
|
17654cfe24 | ||
|
|
5286f42314 | ||
|
|
ae9bb4e1c5 | ||
|
|
77f041505b | ||
|
|
6d5487da24 | ||
|
|
e4738ab016 | ||
|
|
10d830aba1 | ||
|
|
62e97c8a3e | ||
|
|
83e9d4606a | ||
|
|
d496fd8977 | ||
|
|
f008a397d0 | ||
|
|
d7c636cf23 | ||
|
|
2094122541 | ||
|
|
5b0769fba3 | ||
|
|
5323837c32 | ||
|
|
ade0289e63 | ||
|
|
156e45d5a2 | ||
|
|
2d47c5502d | ||
|
|
2c963e4e63 | ||
|
|
fd890a2eba | ||
|
|
04df667d0c | ||
|
|
1853a0f11c | ||
|
|
f53f22f53b | ||
|
|
08d3239129 | ||
|
|
d4b9134bee | ||
|
|
fce200380c | ||
|
|
a6c82cce5a | ||
|
|
09a1fa0dac | ||
|
|
7b2064fcd8 | ||
|
|
d0f19c9378 | ||
|
|
0c48bc2293 | ||
|
|
e1efc1682b | ||
|
|
fc1dac64d3 | ||
|
|
b1c1558aa3 | ||
|
|
caee60d13b | ||
|
|
26405c2da6 | ||
|
|
78cb58b146 | ||
|
|
3a4c2e5b65 | ||
|
|
0b08c51036 | ||
|
|
2837f63312 | ||
|
|
2119fd8dd3 | ||
|
|
6e2a7cd0ab | ||
|
|
a1b997966e | ||
|
|
11c374a4b3 | ||
|
|
577c5ac45b | ||
|
|
3110ed8df7 | ||
|
|
421d33772b | ||
|
|
c7366c2e5c | ||
|
|
bb59140a06 | ||
|
|
0a89b2777a | ||
|
|
4ae0ef5f0d | ||
|
|
475a3374d9 | ||
|
|
13a0943ce8 | ||
|
|
11de135dbe | ||
|
|
55a4d96814 | ||
|
|
f3fdd52c2a | ||
|
|
04fcdbb989 | ||
|
|
b6882e4c8b | ||
|
|
c18ae816e9 | ||
|
|
fefc0383b8 | ||
|
|
453c26d648 | ||
|
|
eb32c93750 | ||
|
|
d9907f1e88 | ||
|
|
29706f815b | ||
|
|
777d20651e | ||
|
|
c62448e866 | ||
|
|
eabe18ba6f | ||
|
|
2bbc33bf0d | ||
|
|
36f1c54dbf | ||
|
|
0ce8b2321c | ||
|
|
f5668cce2c | ||
|
|
c75d658238 | ||
|
|
718ceacee6 | ||
|
|
1444cf979d | ||
|
|
de4ae72ed7 | ||
|
|
57fa84f9e7 | ||
|
|
7df5001472 | ||
|
|
f1e049e8be | ||
|
|
f664797a36 | ||
|
|
7bb7c5747a | ||
|
|
aad4c91e01 | ||
|
|
9dc1f02d06 | ||
|
|
59be622226 | ||
|
|
30cecc7694 | ||
|
|
18237cbfd9 | ||
|
|
b4a98f67ee | ||
|
|
2fef0f9652 | ||
|
|
48c3f927eb | ||
|
|
b6e9acc3c3 | ||
|
|
0b74e623d9 | ||
|
|
88b2d7933b | ||
|
|
1b97a18d17 | ||
|
|
2279bc7187 | ||
|
|
d1903570de | ||
|
|
92c947e419 | ||
|
|
34061ad32c | ||
|
|
a1e639dce5 | ||
|
|
a29da7ee6a | ||
|
|
1e8291c3ed | ||
|
|
d7d3bcc868 | ||
|
|
a9c45098c7 | ||
|
|
10b1dbefd2 | ||
|
|
0df5881023 | ||
|
|
93c945b2c8 | ||
|
|
8782441b86 | ||
|
|
ab8edf9bec | ||
|
|
2e5b11af1d | ||
|
|
2e6ea6018e | ||
|
|
f84871cf01 | ||
|
|
9648517b15 | ||
|
|
008f612c08 | ||
|
|
9bd2a19901 | ||
|
|
ce8c82042a | ||
|
|
1310eba02c | ||
|
|
2e2b4d4e08 | ||
|
|
41bbdca01d | ||
|
|
0acd350d7f | ||
|
|
e7216d42aa | ||
|
|
3b33059900 | ||
|
|
4c671d9d85 | ||
|
|
5004a5f482 | ||
|
|
daab23978b | ||
|
|
6e0d8e000b | ||
|
|
5dc5aeabb8 | ||
|
|
faf52f39b5 | ||
|
|
5f173bf10a | ||
|
|
14b13b7074 | ||
|
|
a84d4f4fa0 | ||
|
|
f0b49dfce4 | ||
|
|
a199873854 | ||
|
|
0257cbaa14 | ||
|
|
73cb0c9ee5 | ||
|
|
f754b6269e | ||
|
|
22c0ae5a49 | ||
|
|
1b23f36ecd | ||
|
|
35c60d2a11 | ||
|
|
828fb05d52 | ||
|
|
fb983c53bf | ||
|
|
08ef7aa5a0 | ||
|
|
9ac85482ca | ||
|
|
189915f200 | ||
|
|
d68a9cd996 | ||
|
|
1a8fd4a979 | ||
|
|
b45c92cf98 | ||
|
|
11b3d62d16 | ||
|
|
a46ad1e66e | ||
|
|
970135e098 | ||
|
|
ccec11c059 | ||
|
|
40412a5257 | ||
|
|
dc07f8666b | ||
|
|
d622dba733 | ||
|
|
1dd9c2dddf | ||
|
|
979f49a8b9 | ||
|
|
9a11ee556c | ||
|
|
192b9b8f60 | ||
|
|
d6485f88fd | ||
|
|
bbce797c14 | ||
|
|
e978d42834 | ||
|
|
2d9b5d0f20 | ||
|
|
37d2c4ec22 | ||
|
|
4b60120754 | ||
|
|
02ff4614a2 | ||
|
|
a0b15aa6c2 | ||
|
|
ca21c41bfc | ||
|
|
0591033231 | ||
|
|
c984423c4d | ||
|
|
805397b530 | ||
|
|
394c1bd571 | ||
|
|
c1a016baad | ||
|
|
c667bbcaa6 | ||
|
|
38e7165433 | ||
|
|
e02a8a63e4 | ||
|
|
420d6e6648 | ||
|
|
a78380a3b4 | ||
|
|
fe7c2bd388 | ||
|
|
930f7ce973 | ||
|
|
9f0ad317ad | ||
|
|
1a95ca5065 | ||
|
|
5b912fd9b3 | ||
|
|
ec1ddbd646 | ||
|
|
8e4fbe58b5 | ||
|
|
544e8fb582 | ||
|
|
bd7c19520d | ||
|
|
74817f6959 | ||
|
|
6d6d548284 | ||
|
|
4104d6c128 | ||
|
|
312e9c7634 | ||
|
|
a427be2390 | ||
|
|
33215027e6 | ||
|
|
9ed1be3632 | ||
|
|
23d4759e16 | ||
|
|
239acd0733 | ||
|
|
cdd830c256 | ||
|
|
f5f5a7533f | ||
|
|
a87c542d6b | ||
|
|
2470905bf8 | ||
|
|
d1d67b4cf5 | ||
|
|
c010c899b7 | ||
|
|
57f1bb36ea | ||
|
|
8637c3a8cf | ||
|
|
e431c5f4e1 | ||
|
|
84e175b265 | ||
|
|
34facb1bd4 | ||
|
|
710d8b311c | ||
|
|
efa5701654 | ||
|
|
2b3ececc3f | ||
|
|
eec37508f4 | ||
|
|
dd7f508a91 | ||
|
|
d05db1c8d4 | ||
|
|
ef534db878 | ||
|
|
48b4b3d4ae | ||
|
|
a15c4771c8 | ||
|
|
fc929f622b | ||
|
|
707be246e9 | ||
|
|
3eee490042 | ||
|
|
9d3d250545 | ||
|
|
e912e0a98a | ||
|
|
20ca0566be | ||
|
|
d092d2e6e9 | ||
|
|
180e49847b | ||
|
|
62c055f7ac | ||
|
|
3a4753ef70 | ||
|
|
43d02c8f3e | ||
|
|
b7d6955b43 | ||
|
|
2941140df6 | ||
|
|
47bd2db9c3 | ||
|
|
e7460dc878 | ||
|
|
89504ca289 | ||
|
|
652b2d9d86 | ||
|
|
c46dff15dc | ||
|
|
b121064454 | ||
|
|
ce952b9ab9 | ||
|
|
3567d9eccf | ||
|
|
34e24f6fa4 | ||
|
|
4084c5a448 | ||
|
|
e0e426fe53 | ||
|
|
cede4198fa | ||
|
|
249d008272 | ||
|
|
9ba8db83bd | ||
|
|
de3202630d | ||
|
|
db5a19ec82 | ||
|
|
5a140abd05 | ||
|
|
c6b6e9e78f | ||
|
|
f35975e748 | ||
|
|
0056aaf687 | ||
|
|
bf6ccfbf1e | ||
|
|
1467c8f48f | ||
|
|
c334e3b4da | ||
|
|
c7b6dc0762 | ||
|
|
03045e2a78 | ||
|
|
628bbc5810 | ||
|
|
e2ddaa67fa | ||
|
|
dba3675688 | ||
|
|
54073bb12f | ||
|
|
d512a56bb9 | ||
|
|
e2e63d3121 | ||
|
|
e51a5682b5 | ||
|
|
38991a4b2e | ||
|
|
bb368f910c | ||
|
|
a68c9f2f65 | ||
|
|
f3535225ab | ||
|
|
e20f7663f1 | ||
|
|
c222cb4e0d | ||
|
|
bcb03fc62f | ||
|
|
51c0afa1a1 | ||
|
|
6008798b99 | ||
|
|
9e1376657b | ||
|
|
572ebc27fa | ||
|
|
363c851f2b | ||
|
|
516b4bdbbd | ||
|
|
47f4ca2b3a | ||
|
|
4808a19633 | ||
|
|
b2e61ea5f6 | ||
|
|
5f698e971e | ||
|
|
71ed1c374b | ||
|
|
757ee37905 | ||
|
|
eee9899cbe | ||
|
|
ab00993f21 | ||
|
|
29590f0327 | ||
|
|
459f209a20 | ||
|
|
6f2e829e87 | ||
|
|
1d5b98f564 | ||
|
|
f3837e2954 | ||
|
|
99306352a3 | ||
|
|
5e95c04139 | ||
|
|
ae7f6de506 | ||
|
|
650ae663e4 | ||
|
|
88cffdf4ec | ||
|
|
824547a96d | ||
|
|
ad9b6e570b | ||
|
|
9c9e1944f8 | ||
|
|
043db28b00 | ||
|
|
e8c1af8822 | ||
|
|
18316aca9a | ||
|
|
e86df52fbb | ||
|
|
b66d0fe188 | ||
|
|
076fa22486 | ||
|
|
5b433fd6d0 | ||
|
|
1aa37cec89 | ||
|
|
2c8cd5e4fa | ||
|
|
20bd4aed8f | ||
|
|
a01ba37d6c | ||
|
|
79926534cb | ||
|
|
695adb718d | ||
|
|
5284e9270a | ||
|
|
e260019df8 | ||
|
|
6c8c4b3e45 | ||
|
|
295d5db77a | ||
|
|
3e556eae78 | ||
|
|
a97f278bb1 | ||
|
|
6cd864e64e | ||
|
|
1002a23b71 | ||
|
|
694a6052fe | ||
|
|
80bfdf62e9 | ||
|
|
6f58c7200c | ||
|
|
fce629c1f0 | ||
|
|
93dad28d0b | ||
|
|
a7b2a140a9 | ||
|
|
08a4ba0614 | ||
|
|
6275d20fb1 | ||
|
|
1318798124 | ||
|
|
3f86366cfa | ||
|
|
bf5485a268 | ||
|
|
e34934fd92 | ||
|
|
a350f7f955 | ||
|
|
25ddf08f88 | ||
|
|
b131c5ee64 | ||
|
|
6b4b19f9da | ||
|
|
4d7a788598 | ||
|
|
957b85d72e | ||
|
|
beed90e6e9 | ||
|
|
2c561b1e80 | ||
|
|
e9622d7738 | ||
|
|
d285951785 | ||
|
|
b3bf4a161d | ||
|
|
ed187e4513 | ||
|
|
79df27c12b | ||
|
|
1fb9a4297c | ||
|
|
9b914a7791 | ||
|
|
8891cbee05 | ||
|
|
3c36e8bfe6 | ||
|
|
3e55dd04f2 | ||
|
|
96f084d69e | ||
|
|
4c69e02643 | ||
|
|
0b4015fa9f | ||
|
|
3f09f67fca | ||
|
|
b170e39523 | ||
|
|
119a42d696 | ||
|
|
613f46e8a7 | ||
|
|
2f32f36e47 | ||
|
|
754844d4bd | ||
|
|
91dfeba954 | ||
|
|
af24315968 | ||
|
|
af7cb756cd | ||
|
|
de403a57e1 | ||
|
|
386e8e5383 | ||
|
|
19cfbd07b5 | ||
|
|
69e2b511af | ||
|
|
c7b1564a20 | ||
|
|
b313e75ef6 | ||
|
|
d43072e902 | ||
|
|
5d7c1e84bc | ||
|
|
9e57593a79 | ||
|
|
2a8fc16241 | ||
|
|
7c1ca92fcb | ||
|
|
dd81e06d35 | ||
|
|
6f17e1e0e8 | ||
|
|
8c4a4c2999 | ||
|
|
ed92cd0945 | ||
|
|
eeeaa6d339 | ||
|
|
8c8782d1e5 | ||
|
|
6b6b926347 | ||
|
|
2ef3b9689e | ||
|
|
023b0723ea | ||
|
|
97d2e4bc30 | ||
|
|
c2b2a73329 | ||
|
|
4185a6a144 | ||
|
|
3eb2ef6cfd | ||
|
|
0b1fec3927 | ||
|
|
25f8668b88 | ||
|
|
1b47bed603 | ||
|
|
bf418055a3 | ||
|
|
125224f976 | ||
|
|
af34862b9c | ||
|
|
d6121c4d82 | ||
|
|
11f03846ab | ||
|
|
d4ad0bf00a | ||
|
|
ed12f40b32 | ||
|
|
f018edcc5b | ||
|
|
078742c054 | ||
|
|
3e05a60d38 | ||
|
|
6cacba1a67 | ||
|
|
21bb5d5e2a | ||
|
|
57c13b9a73 | ||
|
|
5a41eaaa6f | ||
|
|
71efacc050 | ||
|
|
e64b6cf64a | ||
|
|
bff43a86e8 | ||
|
|
1de4494bc2 | ||
|
|
7edace78f7 | ||
|
|
106ebc1abd | ||
|
|
884aebab48 | ||
|
|
fec4803386 | ||
|
|
c39c8cceef | ||
|
|
34f71cf75a | ||
|
|
c631ee1292 | ||
|
|
df9cbc04a8 | ||
|
|
bd2728399d | ||
|
|
556465529b | ||
|
|
4033c7aef0 | ||
|
|
09609997b3 | ||
|
|
dd510d9086 | ||
|
|
d65e14910b | ||
|
|
fe0809cef8 | ||
|
|
0532f5adc3 | ||
|
|
fadee457ba | ||
|
|
10bda2b797 | ||
|
|
262e93a6b4 | ||
|
|
8c4b2bb777 | ||
|
|
f7fff13094 | ||
|
|
e0b2560ffa | ||
|
|
dc5fc68387 | ||
|
|
b3027741f6 | ||
|
|
ad8c74e0c3 | ||
|
|
7c569f5b80 | ||
|
|
06d07b200e | ||
|
|
19c6e4e79d | ||
|
|
f78ea4d279 | ||
|
|
e95142fffc | ||
|
|
7f181e09da | ||
|
|
5276449269 | ||
|
|
f63cc905d5 | ||
|
|
fa51cb3ea1 | ||
|
|
1fb5dd39ed | ||
|
|
1d85be7bb2 | ||
|
|
e7ffc6d0d3 | ||
|
|
dc9d6ff55a | ||
|
|
335dbf233c | ||
|
|
cb8cb43194 | ||
|
|
c234a4fefc | ||
|
|
682ec6745c | ||
|
|
5de4ec65e2 | ||
|
|
e15e8259a2 | ||
|
|
aac6571998 | ||
|
|
129730e73f | ||
|
|
f9ab62025d | ||
|
|
7a61fff0c8 | ||
|
|
43f407559d | ||
|
|
b2eefc00e8 | ||
|
|
21ca9af789 | ||
|
|
068b259777 | ||
|
|
15225bed69 | ||
|
|
6dd402978f | ||
|
|
717e6ac0f9 | ||
|
|
ed3c1ccf49 | ||
|
|
b8f540474d | ||
|
|
32562b84bf | ||
|
|
488932fa17 | ||
|
|
2e61a2a4db | ||
|
|
fd9f620bab | ||
|
|
ac72791a48 | ||
|
|
171f9b317c | ||
|
|
f311a6f566 | ||
|
|
df0084e037 | ||
|
|
4ec601b537 | ||
|
|
29da3f9408 | ||
|
|
aa014eaf14 | ||
|
|
e2306956a5 | ||
|
|
d604f0f746 | ||
|
|
6fff9c1314 | ||
|
|
faec52284f | ||
|
|
bf1c6ee242 | ||
|
|
330da45dca | ||
|
|
c79bd682e5 | ||
|
|
e9f6992059 | ||
|
|
289d6beb17 | ||
|
|
e11e825c3a | ||
|
|
2916541885 | ||
|
|
3eac50321c | ||
|
|
1f2442f384 | ||
|
|
0ea6c8e1e2 | ||
|
|
0a6d6cee32 | ||
|
|
c8debfd8ed | ||
|
|
c6ef22a226 | ||
|
|
0d8a21e85b | ||
|
|
88f97ebaf3 | ||
|
|
b652e9959c | ||
|
|
cadea596e1 | ||
|
|
f7074bcce9 | ||
|
|
6ab8e78133 | ||
|
|
a8c53255a8 | ||
|
|
aaeb4677e1 | ||
|
|
269535411b | ||
|
|
33f179b78f | ||
|
|
abe6d22870 | ||
|
|
2ac095fd04 | ||
|
|
a319b98daf | ||
|
|
547ed02318 | ||
|
|
15faf7e061 | ||
|
|
afc91dfc4d | ||
|
|
8a6ccf6ddf | ||
|
|
7014b1a1c0 | ||
|
|
6b12ad18ef | ||
|
|
8f6021657f | ||
|
|
185fe1f092 | ||
|
|
ca0d56e33e | ||
|
|
fb1b84c12e | ||
|
|
bfcff3170e | ||
|
|
e864759628 | ||
|
|
14ba777e85 | ||
|
|
268d68927d | ||
|
|
70ac928a78 | ||
|
|
c16987c1b6 | ||
|
|
3f45496b70 | ||
|
|
58ebd0f1a3 | ||
|
|
56ce86b08b | ||
|
|
4d6e6c43fd | ||
|
|
08d8f98742 | ||
|
|
d501c6f321 | ||
|
|
6ff13a1c5d | ||
|
|
35a3cf229a | ||
|
|
9619b023c7 | ||
|
|
c0251d78a2 | ||
|
|
4877ea333d | ||
|
|
e11da4bc5f | ||
|
|
0d0ac4e7f5 | ||
|
|
7b33635997 | ||
|
|
47fd5dc02f | ||
|
|
37568985ac | ||
|
|
0dc1fcebc3 | ||
|
|
ea6d20f154 | ||
|
|
cb430ac2b1 | ||
|
|
fbf7e5b92b | ||
|
|
04bae841bf | ||
|
|
c2ae984b2c | ||
|
|
c78a0c31b5 | ||
|
|
64f519b094 | ||
|
|
4fc50631c1 | ||
|
|
1e0411b303 | ||
|
|
16c77bedde | ||
|
|
5c143cf736 | ||
|
|
ffe8831ff6 | ||
|
|
9395c39d4f | ||
|
|
827c9169f9 | ||
|
|
d3f17d0ced | ||
|
|
a8cfb46964 | ||
|
|
11dbb69635 | ||
|
|
5a8f986748 | ||
|
|
ce766cea74 | ||
|
|
8f2da8fe37 | ||
|
|
360ba93e4c | ||
|
|
f17b1f8e67 | ||
|
|
e52681e3f1 | ||
|
|
6b14acfb93 | ||
|
|
d5c6847d1f | ||
|
|
2fc49d5d68 | ||
|
|
2c68b3933d | ||
|
|
cea91ec477 | ||
|
|
375717346b | ||
|
|
ef856ce1ce | ||
|
|
2da87ea466 | ||
|
|
c1ee773c83 | ||
|
|
ca1f0e11ff | ||
|
|
83cf1a8662 | ||
|
|
a68aef90f5 | ||
|
|
0b432e8139 | ||
|
|
cb795b8089 | ||
|
|
949e781e64 | ||
|
|
8de42fc6d3 | ||
|
|
e9f07fa36a | ||
|
|
5f91619de7 | ||
|
|
df7818bc87 | ||
|
|
e381c79535 | ||
|
|
055dcb8cf5 | ||
|
|
b679fade0b | ||
|
|
b9d35c3327 | ||
|
|
f1a01e7563 | ||
|
|
a2735296b7 | ||
|
|
a4b26be5e7 | ||
|
|
0d4e4081c4 | ||
|
|
2099b0866c | ||
|
|
07cc1a7fc5 | ||
|
|
8ceedc8c9e | ||
|
|
c8735a444e | ||
|
|
352da49fdc | ||
|
|
0285cd1522 | ||
|
|
8d4ff9076d | ||
|
|
5053141678 | ||
|
|
3075400211 | ||
|
|
b301237ac6 | ||
|
|
c6f071d37d | ||
|
|
85011ebd1e | ||
|
|
bb783ca8eb | ||
|
|
61fecbab28 | ||
|
|
fc5562e110 | ||
|
|
82d3bc26ca | ||
|
|
e7d9ec3875 | ||
|
|
6359841f34 | ||
|
|
7d2f002139 | ||
|
|
86fe4487d0 | ||
|
|
b9aebfbe50 | ||
|
|
350f77397d | ||
|
|
5d6a4fc068 | ||
|
|
71ae77070e | ||
|
|
4867096bba | ||
|
|
db495d3331 | ||
|
|
33c34a9f2c | ||
|
|
9024d36bb0 | ||
|
|
083d4d3ebb | ||
|
|
1fc0ac852f | ||
|
|
402f1af78d | ||
|
|
c1b9c43c08 | ||
|
|
08680c30bc | ||
|
|
9db394408c | ||
|
|
1575c15a2b | ||
|
|
a019198997 | ||
|
|
ada81a7129 | ||
|
|
4f833dbf60 | ||
|
|
50fed3ee4b | ||
|
|
429dbd78cc | ||
|
|
3c354dc67b | ||
|
|
79ecafe9a6 | ||
|
|
3a69598d93 | ||
|
|
6f8f539c47 | ||
|
|
ee49cec5ae | ||
|
|
f231f70d7f | ||
|
|
acedd159ad | ||
|
|
8cfdaeeac7 | ||
|
|
059ad7b0c2 | ||
|
|
a05cda5d72 | ||
|
|
82a5870e39 | ||
|
|
77fdb3ad1f | ||
|
|
b1c6cb605e | ||
|
|
13ecf84ae0 | ||
|
|
69e3489ef8 | ||
|
|
f45e64dbb9 | ||
|
|
390b2e0601 | ||
|
|
f7b97e556d | ||
|
|
02dd7f7554 | ||
|
|
eb817d4469 | ||
|
|
55e37b7605 | ||
|
|
7cf51a387c | ||
|
|
a93fb9c690 | ||
|
|
b7e963f005 | ||
|
|
12f2d917d3 | ||
|
|
eb4172c08d | ||
|
|
0bd6a97867 | ||
|
|
52a78b7ac2 | ||
|
|
f8d56351b9 | ||
|
|
5ac9477284 | ||
|
|
73b76d3fd7 | ||
|
|
c835972b8b | ||
|
|
d6341fd2de | ||
|
|
e5140393de | ||
|
|
a24946719c | ||
|
|
c7018d1dac | ||
|
|
015f1551aa | ||
|
|
fe9417f217 | ||
|
|
80d28b50e0 | ||
|
|
9d60c8ef1a | ||
|
|
6aea2acad0 | ||
|
|
31f0efd7cd | ||
|
|
7bb7d8857d | ||
|
|
9f59d66ab7 | ||
|
|
0b16044f1a | ||
|
|
6b45e4886a | ||
|
|
b3472e35f1 | ||
|
|
c42574030d | ||
|
|
6040f1316f | ||
|
|
196a73d416 | ||
|
|
20f3bb2fa0 | ||
|
|
aac73a1476 | ||
|
|
92ec9a8446 | ||
|
|
9c7e5ffc18 | ||
|
|
98eeaebdae | ||
|
|
fafd015424 | ||
|
|
7109034f4b | ||
|
|
df5f152ba8 | ||
|
|
5aa35b98bc | ||
|
|
e362963d2a | ||
|
|
34dc5355bc | ||
|
|
9812c5250d | ||
|
|
0432851f94 | ||
|
|
a8721b637c | ||
|
|
26c2dafaf8 | ||
|
|
e6f85c01bd | ||
|
|
edcc388dd4 | ||
|
|
965bf6af4e | ||
|
|
834b3f7dfb | ||
|
|
141d57f5b0 | ||
|
|
8c285de23c | ||
|
|
034f290d9c | ||
|
|
a38c98dccd | ||
|
|
325582b295 | ||
|
|
f024818d2e | ||
|
|
6699449e9f | ||
|
|
18860e2980 | ||
|
|
7a1cc9925d | ||
|
|
de99a7af47 | ||
|
|
e15647ae1b | ||
|
|
d897087b3d | ||
|
|
b4a788e03a | ||
|
|
fb0928c0f5 | ||
|
|
1e449415b1 | ||
|
|
dc672db867 | ||
|
|
50a300ddd7 | ||
|
|
55224d6f4c | ||
|
|
80d9ce417c | ||
|
|
d28a3b7c30 | ||
|
|
f3b80cbb4b | ||
|
|
5b0d212ba2 | ||
|
|
5741d76b96 | ||
|
|
86d7f65026 | ||
|
|
9f0b1af6b7 | ||
|
|
e9b90ee58e | ||
|
|
8e1ab7d505 | ||
|
|
21a72bd2e5 | ||
|
|
245c4eaacb | ||
|
|
d08a85eeae | ||
|
|
92bb8906ca | ||
|
|
1caf52e02a | ||
|
|
9ac44be751 | ||
|
|
9ace74fee7 | ||
|
|
a8f1d26ea9 | ||
|
|
d8ae82c5f9 | ||
|
|
56552528cb | ||
|
|
0cab13f614 | ||
|
|
020327969f | ||
|
|
e269cdaa6d | ||
|
|
c0f04ccf0e | ||
|
|
d45f94ee2e | ||
|
|
32017cdf6b | ||
|
|
36db516db5 | ||
|
|
1d0bfe643e | ||
|
|
269a96c5eb | ||
|
|
b9a160320b | ||
|
|
bb075ea82e | ||
|
|
fd873f8b8f | ||
|
|
29a33b9836 | ||
|
|
6b01e4226c | ||
|
|
9aa0a6352d | ||
|
|
26f50ca98c | ||
|
|
1e605a9561 | ||
|
|
556ac3db76 | ||
|
|
83d1b68ef5 | ||
|
|
917d6df290 | ||
|
|
65d4af771d | ||
|
|
34ae8d5274 | ||
|
|
f3d20f5605 | ||
|
|
de879d55e0 | ||
|
|
9271efd4ed | ||
|
|
12c2798017 | ||
|
|
e5d0da5042 | ||
|
|
3b29a5d7c6 | ||
|
|
938bdabd26 | ||
|
|
454fd20cf5 | ||
|
|
03277cbf42 | ||
|
|
41433715c1 | ||
|
|
b59e38519b | ||
|
|
7500aa3c6d | ||
|
|
7655700eff | ||
|
|
666cd30c2b | ||
|
|
9a2b00891b | ||
|
|
80c0213543 | ||
|
|
0d9f841123 | ||
|
|
fe0bc588a8 | ||
|
|
9bc2b1fe44 | ||
|
|
912e9388ba | ||
|
|
a4078c5e73 | ||
|
|
b0faec1c87 | ||
|
|
5f2ac78654 | ||
|
|
853552ca3a | ||
|
|
dd00f1b1a1 | ||
|
|
19095d3fd3 | ||
|
|
5cc4da0364 | ||
|
|
565a0fdb1b | ||
|
|
19a4b3188e | ||
|
|
a9f584575a | ||
|
|
3030cb2fdc | ||
|
|
21107c9a42 | ||
|
|
cb19661909 | ||
|
|
70845c2977 | ||
|
|
a2bf66da50 | ||
|
|
2710f621ae | ||
|
|
370fbd6072 | ||
|
|
6ce990ce36 | ||
|
|
235e99de96 | ||
|
|
08a0b537e8 | ||
|
|
285f30c8c0 | ||
|
|
48cea000dc | ||
|
|
b405516719 | ||
|
|
d278f8c77a | ||
|
|
58a731e6fd | ||
|
|
b9f0754140 | ||
|
|
1c0b79d783 | ||
|
|
84ed9f5c50 | ||
|
|
691296bb57 | ||
|
|
6af7acc980 | ||
|
|
b5c0ec57ec | ||
|
|
e3e3aafc29 | ||
|
|
30d585e008 | ||
|
|
fa630b07f8 | ||
|
|
95b32ae801 | ||
|
|
4abc5ca757 | ||
|
|
ddc0523c10 | ||
|
|
af8b188336 | ||
|
|
b6bc5ccef0 | ||
|
|
daca7ac870 | ||
|
|
310c618a48 | ||
|
|
f8ce687308 | ||
|
|
cafc5b07b7 | ||
|
|
18f07083b2 | ||
|
|
d67bba49e4 | ||
|
|
9d4af2ae1f | ||
|
|
76ade17a44 | ||
|
|
238c294a98 | ||
|
|
d0c4223b2d | ||
|
|
c01850ff6a | ||
|
|
bda2fca514 | ||
|
|
8857c4e566 | ||
|
|
26c901a84d | ||
|
|
54382bcb22 | ||
|
|
78a4e7046d | ||
|
|
f8b795b0e6 | ||
|
|
e39bdb0078 | ||
|
|
1656400a08 | ||
|
|
816ee723ad | ||
|
|
b489bc4b54 | ||
|
|
d2ef0f0c6d | ||
|
|
4fe93aef9d | ||
|
|
261e32ab8b | ||
|
|
388eba5d2f | ||
|
|
8196b61a3c | ||
|
|
bfad527fcc | ||
|
|
70c7adb06a | ||
|
|
1aeb73b040 | ||
|
|
ad1a24c541 | ||
|
|
6da33d8192 | ||
|
|
33ad1a998c | ||
|
|
8e96b1e948 | ||
|
|
7eacd670bc | ||
|
|
9a66e188d4 | ||
|
|
469fb711a8 | ||
|
|
b903d208dd | ||
|
|
ca31e209ec | ||
|
|
bff8f2fc19 | ||
|
|
bce1bbd9a2 | ||
|
|
dcccc8bcfd | ||
|
|
fe1bf1b562 | ||
|
|
0c95fc166e | ||
|
|
149d707edb | ||
|
|
37c1fffd97 | ||
|
|
68863455fc | ||
|
|
da8f26e309 | ||
|
|
b49d726835 | ||
|
|
ba4722aeec | ||
|
|
8bbd79a065 | ||
|
|
426fdee8b7 | ||
|
|
0f025df81f | ||
|
|
13c8c97f2a | ||
|
|
5eaccc69c4 | ||
|
|
6c0942d9ca | ||
|
|
c90bfa252f | ||
|
|
d4c5e5e332 | ||
|
|
4cb2ee6803 | ||
|
|
37961f5e4d | ||
|
|
93ec8163f0 | ||
|
|
026520da2f | ||
|
|
09ca4b0398 | ||
|
|
d7e5790cce | ||
|
|
39822d9c20 | ||
|
|
61a4b6bf26 | ||
|
|
fe95e0b4e4 | ||
|
|
f8c53bfd20 | ||
|
|
e5912fda9d | ||
|
|
82f7eb268c | ||
|
|
8abb139f29 | ||
|
|
f48e68402b | ||
|
|
210d571296 | ||
|
|
7b4266f443 | ||
|
|
4db0e4c1ae | ||
|
|
36e8e55522 | ||
|
|
0cb23d957a | ||
|
|
fdea5394df | ||
|
|
8c4bea9e52 | ||
|
|
e4a2fea4df | ||
|
|
cd6b9f69b3 | ||
|
|
54f785888d | ||
|
|
ba44d9c07c | ||
|
|
d84888ec7c | ||
|
|
c760f52e6d | ||
|
|
7e0ce2cbce | ||
|
|
c9868e094b | ||
|
|
76d6dfe2bf | ||
|
|
b0f15ea3ed | ||
|
|
ebb6f3bcdb | ||
|
|
20eb136c76 | ||
|
|
31dea5eccd | ||
|
|
fe2850a50a | ||
|
|
ce16ff49cd | ||
|
|
0af1112020 | ||
|
|
ac441ab136 | ||
|
|
f275040887 | ||
|
|
2f3efa1bec | ||
|
|
d1103f4ac6 | ||
|
|
7a25243cd2 | ||
|
|
5fb5872d0d | ||
|
|
b6ebf9f4ad | ||
|
|
080dc51f4b | ||
|
|
4ff6e20073 | ||
|
|
44c9c28fa3 | ||
|
|
7e8794fcf0 | ||
|
|
76b3afe8f9 | ||
|
|
20db25cf89 | ||
|
|
7abea0870f | ||
|
|
1ab062d899 | ||
|
|
d60f7c319c | ||
|
|
0398803f1b | ||
|
|
2538e7ef8c | ||
|
|
f122665e3c | ||
|
|
3e691791b6 | ||
|
|
430303d9c0 | ||
|
|
ecdb0aab03 | ||
|
|
2522e9bb1d | ||
|
|
822d8f45b6 | ||
|
|
d036cab4c1 | ||
|
|
3ee1c2b282 | ||
|
|
b2b2775504 | ||
|
|
3a5ea0379a | ||
|
|
dc3281203d | ||
|
|
d94a049cfd | ||
|
|
c7b1c337e2 | ||
|
|
116eaefd8f | ||
|
|
8c70a9395d | ||
|
|
29fbe46d41 | ||
|
|
aa4d982d4c | ||
|
|
fa6ab1c8c4 | ||
|
|
a9216705e1 | ||
|
|
20828213b2 | ||
|
|
f4e228730f | ||
|
|
bd9c8f0f12 | ||
|
|
d07db1054a | ||
|
|
18deecddea | ||
|
|
f3991199dd | ||
|
|
007411411b | ||
|
|
75124ba900 | ||
|
|
1d9589c093 | ||
|
|
6974d96f6e |
No files matched your search
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: ptitSeb
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: paypal.me/0ptitSeb
|
||||
@@ -0,0 +1,100 @@
|
||||
### Manual build Box86 with Github Action
|
||||
name: Custom build Box86
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Target platform name'
|
||||
required: true
|
||||
default: 'GENERIC_ARM'
|
||||
type: choice
|
||||
options:
|
||||
- I386
|
||||
- GENERIC_ARM
|
||||
- A64
|
||||
- GAMESHELL
|
||||
- ODROID
|
||||
- PANDORA
|
||||
- PHYTIUM
|
||||
- PYRA
|
||||
- RK3288
|
||||
- RK3399
|
||||
- RPI4
|
||||
- RPI4ARM64
|
||||
- SD845
|
||||
build_type:
|
||||
description: 'Build type'
|
||||
required: true
|
||||
default: 'RelWithDebInfo'
|
||||
type: choice
|
||||
options:
|
||||
- RelWithDebInfo
|
||||
- Release
|
||||
- Debug
|
||||
- MinSizeRel
|
||||
dynarec:
|
||||
description: 'Enable dynarec'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: boolean
|
||||
trace:
|
||||
description: 'Enable trace'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout Box86 Repository"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: "Environment preparation"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
||||
if [[ ${{ github.event.inputs.platform }} != 'I386' && ${{ github.event.inputs.platform }} != 'GENERIC_ARM' ]]; then
|
||||
echo "BOX86_PLATFORM_MARCRO=-D${{ github.event.inputs.platform }}=1" >> $GITHUB_ENV
|
||||
echo "BOX86_COMPILER=arm-linux-gnueabihf-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-arm-linux-gnueabihf cmake make python3
|
||||
else
|
||||
if [[ ${{ github.event.inputs.platform }} == 'I386' ]]; then
|
||||
echo "BOX86_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
|
||||
echo "BOX86_COMPILER=/bin/i686-linux-gnu-gcc-10" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git libc6-dev-i386-amd64-cross gcc-10-i686-linux-gnu cmake make python3
|
||||
else
|
||||
echo "BOX86_PLATFORM_MARCRO=-DCMAKE_C_FLAGS=-marm" >> $GITHUB_ENV
|
||||
echo "BOX86_COMPILER=arm-linux-gnueabihf-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-arm-linux-gnueabihf cmake make python3
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: "Display Build info"
|
||||
run: |
|
||||
echo "CMake Platform Macro: ${{ env.BOX86_PLATFORM_MARCRO }}"
|
||||
echo "CMake C Compiler: ${{ env.BOX86_COMPILER }}"
|
||||
echo "Build type: ${{ github.event.inputs.build_type }}"
|
||||
echo "Dynarec Enabled: ${{ github.event.inputs.dynarec }}"
|
||||
echo "Trace Enabled: ${{ github.event.inputs.trace }}"
|
||||
|
||||
- name: "Build Box86"
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX86_COMPILER }} ${{ env.BOX86_PLATFORM_MARCRO }}\
|
||||
-DCMAKE_BUILD_TYPE=${{ github.event.inputs.build_type }}\
|
||||
-DARM_DYNAREC:BOOL=${{ github.event.inputs.dynarec }}\
|
||||
-DHAVE_TRACE:BOOL=${{ github.event.inputs.trace }}\
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
||||
make -j$(nproc) VERBOSE=1
|
||||
|
||||
- name: "Upload Artifact"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: box86-${{ github.event.inputs.platform }}-${{ github.event.inputs.build_type }}
|
||||
path: build/box86
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
### Auto build Box86 and release its binary with Github Action
|
||||
name: Build and Release Box86
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
push:
|
||||
paths:
|
||||
- "**/*.c"
|
||||
- "**/*.h"
|
||||
- "**/*.S"
|
||||
- "**/*.py"
|
||||
- "CMakeLists.txt"
|
||||
- "**/*.yml"
|
||||
pull_request:
|
||||
types: [assigned, opened, synchronize, reopened]
|
||||
paths:
|
||||
- "**/*.c"
|
||||
- "**/*.h"
|
||||
- "**/*.S"
|
||||
- "**/*.py"
|
||||
- "CMakeLists.txt"
|
||||
- "**/*.yml"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [I386, OTHER_ARM, PANDORA, PYRA, GAMESHELL, RPI4, RPI4ARM64, ODROID, RK3399, RK3288, A64, SD845, PHYTIUM, ANDROID]
|
||||
type: [Release, Trace]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
include:
|
||||
- platform: TEGRAX1
|
||||
type: Release
|
||||
os: ubuntu-20.04
|
||||
- platform: TEGRAX1
|
||||
type: Trace
|
||||
os: ubuntu-20.04
|
||||
- platform: TEGRAX1ARM32
|
||||
type: Release
|
||||
os: ubuntu-20.04
|
||||
- platform: TEGRAX1ARM32
|
||||
type: Trace
|
||||
os: ubuntu-20.04
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: "Checkout Box86 Repository"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Environment preparation"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
||||
if [[ ${{ matrix.platform }} != 'I386' && ${{ matrix.platform }} != 'OTHER_ARM' ]]; then
|
||||
sudo apt-get -y install git cmake make python3
|
||||
if [[ ${{ matrix.platform }} == 'ANDROID' ]]; then
|
||||
wget https://dl.google.com/android/repository/android-ndk-r23b-linux.zip
|
||||
unzip android-ndk-r23b-linux.zip
|
||||
echo "BOX86_COMPILER=$PWD/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi31-clang" >> $GITHUB_ENV
|
||||
echo "BOX86_PLATFORM_MARCRO=-DANDROID=1 -DNOLOADADDR=1" >> $GITHUB_ENV
|
||||
else
|
||||
sudo apt-get -y install gcc-arm-linux-gnueabihf
|
||||
echo "BOX86_COMPILER=arm-linux-gnueabihf-gcc" >> $GITHUB_ENV
|
||||
echo "BOX86_PLATFORM_MARCRO=-D${{ matrix.platform }}=1" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
if [[ ${{ matrix.platform }} == 'I386' ]]; then
|
||||
echo "BOX86_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
|
||||
echo "BOX86_COMPILER=/bin/i686-linux-gnu-gcc-10" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git libc6-dev-i386-amd64-cross gcc-10-i686-linux-gnu cmake make python3
|
||||
else
|
||||
echo BOX86_PLATFORM_MARCRO="-DARM_DYNAREC=ON -DCMAKE_C_FLAGS=-marm" >> $GITHUB_ENV
|
||||
echo "BOX86_COMPILER=arm-linux-gnueabihf-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-arm-linux-gnueabihf cmake make python3
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${{ matrix.type }} == 'Release' ]]; then
|
||||
echo BOX86_BUILD_TYPE=Release >> $GITHUB_ENV
|
||||
echo BOX86_HAVE_TRACE=0 >> $GITHUB_ENV
|
||||
else
|
||||
echo BOX86_BUILD_TYPE=RelWithDebInfo >> $GITHUB_ENV
|
||||
echo BOX86_HAVE_TRACE=1 >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: "Display Build info"
|
||||
run: |
|
||||
echo "CMake Platform Macro: ${{ env.BOX86_PLATFORM_MARCRO }}"
|
||||
echo "CMake C Compiler: ${{ env.BOX86_COMPILER }}"
|
||||
echo "Build type: ${{ env.BOX86_BUILD_TYPE }}"
|
||||
echo "Trace Enabled: ${{ env.BOX86_HAVE_TRACE }}"
|
||||
|
||||
- name: "Build Box86"
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX86_COMPILER }}\
|
||||
${{ env.BOX86_PLATFORM_MARCRO }}\
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BOX86_BUILD_TYPE }}\
|
||||
-DHAVE_TRACE=${{ env.BOX86_HAVE_TRACE }}\
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
||||
make -j$(nproc) VERBOSE=1
|
||||
|
||||
- name: "Test Box86"
|
||||
if: ${{ matrix.platform == 'I386' }}
|
||||
run: |
|
||||
cd build
|
||||
ctest -j$(nproc)
|
||||
|
||||
- name: "Upload Artifact"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: box86-${{ matrix.platform }}-${{ matrix.type }}
|
||||
path: build/box86
|
||||
|
||||
|
||||
|
||||
+8
-2
@@ -1,3 +1,9 @@
|
||||
build
|
||||
build_llvm
|
||||
build/
|
||||
build*/
|
||||
.vscode
|
||||
.gdb_history
|
||||
src/git_head.h
|
||||
backup/
|
||||
box86_update.sh
|
||||
restore_backup.sh
|
||||
.cache
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
language: c
|
||||
arch:
|
||||
- arm64-graviton2
|
||||
- amd64
|
||||
os: linux
|
||||
dist: focal
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- python3
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
#Build steps
|
||||
before_script:
|
||||
- if [ "$TRAVIS_CPU_ARCH" = "arm64" ]; then sudo dpkg --add-architecture armhf ; else sudo dpkg --add-architecture i386 ; fi
|
||||
- if [ "$TRAVIS_CPU_ARCH" = "arm64" ]; then sudo apt-get -y install gcc-arm-linux-gnueabihf ; else sudo apt-get -y install gcc-multilib libc6-dev:i386 libgcc1:i386 ; fi
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [ "$TRAVIS_CPU_ARCH" = "arm64" ]; then cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; else CFLAGS="-m32" cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; fi
|
||||
|
||||
script:
|
||||
- make
|
||||
- if [ "$TRAVIS_CPU_ARCH" != "arm64" ]; then ctest --output-on-failure ; fi
|
||||
@@ -1,27 +0,0 @@
|
||||
Current version
|
||||
=======
|
||||
|
||||
v0.0.4
|
||||
=======
|
||||
* Improved the Init of dependant Libs. More things work now.
|
||||
* Added a lot of wrapped functions.
|
||||
* Added a few wrapped libs (like libz or some other x11 related libs)
|
||||
* For trace enabled build, Trace can be enabled only after a certain amount of opcodes (still, a debugger would be better)
|
||||
* Some fixes in a few opcodes, and implemented x87 rounding (SuperMeatBoy behaves better now)
|
||||
* FTL 1.6.9 stiil sounds bad, but older 1.5.13 seems fine (different set of libs)
|
||||
|
||||
v0.0.2
|
||||
=======
|
||||
* A full commercial games runs fine on the Pandora: Airline Tycoon Deluxe
|
||||
* Implemented all planed subpart of Box86 except JIT
|
||||
* CPU Emulation is at 75%, roughly, including x87 and SSE/SSE2. MMX is barely implemented, but barely used anyway
|
||||
* x87 emulation is simplified, no real x87 State handling (but should not be mandatory, as native libm is used)
|
||||
* No Signal handling yet
|
||||
* ELF Loader is crude and probably full of bug. Also, the Init of libs is defered after all symbols are resolved for now.
|
||||
* Wrapped lib include libc, libm, rt, pthread, libdl, dllinux, libasound, GL, GLU, SDL1/mixer/image, SDL2/mixer/image/smpeg, OpenAL/ALUT, libz, libpng16, vorbisfile, x11/xrandr/xxf86vm.
|
||||
* Most wrapped libs are still partially implemented (SDL1 & GL should be complete)
|
||||
* Implemented specific mecanism for SDL(1/2) RWops, to be able to used them both in Native and x86 world
|
||||
* WorldOfGoo works, but painfully slow on th Pandora (too much double math, and lack of JIT)
|
||||
* FTL works, but sound is broken (issue with thread? asound? or CPU core?)
|
||||
* Limbo launch but crash before main menu
|
||||
|
||||
+821
-108
@@ -1,39 +1,260 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(box86)
|
||||
option(PANDORA "Set to ON if targeting an OpenPandora device" ${PANDORA})
|
||||
option(PYRA "Set to ON if targeting an OpenPandora device" ${PYRA})
|
||||
option(RPI2 "Set to ON if targeting an RaspberryPI2 device" ${RPI2})
|
||||
option(RPI3 "Set to ON if targeting an RaspberryPI3 device" ${RPI3})
|
||||
option(RPI4 "Set to ON if targeting an RaspberryPI4 device" ${RPI4})
|
||||
option(RPI3ARM64 "Set to ON if targeting an RaspberryPI3 device with multiarch arm64 and armhf" ${RPI3ARM64})
|
||||
option(RPI4ARM64 "Set to ON if targeting an RaspberryPI4 device with multiarch arm64 and armhf" ${RPI4ARM64})
|
||||
option(GOA_CLONE "Set to ON if targeting GO Advance clones, like RG351p/v, Gameforce Chi, RGB10..." ${GOA_CLONE})
|
||||
option(RK3288 "Set to ON if targeting an Rockchip RK3288 based device" ${RK3288})
|
||||
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
|
||||
option(RK3588 "Set to ON if targeting an Rockchip RK3588 / RK3588S based device" ${RK3588})
|
||||
option(ODROIDN2 "Set to ON if targeting an Odroid-N2 device" ${ODROIDN2})
|
||||
option(TEGRAX1 "Set to ON if targeting an Tegra X1 (ARM64) based device" ${TEGRAX1})
|
||||
option(TEGRAX1ARM32 "Set to ON if targeting an Tegra X1 (ARM32) based device" ${TEGRAX1ARM32})
|
||||
option(PHYTIUM "Set to ON if targeting an Phytium (D2000 or FT2000/4) based device" ${PHYTIUM})
|
||||
option(GAMESHELL "Set to ON if targeting a GameShell device" ${GAMESHELL})
|
||||
option(ODROID "Set to ON if targeting an ODroid device" ${ODROID})
|
||||
option(POWER9 "Set to ON if targeting a POWER9 processor" ${POWER9})
|
||||
option(SD845 "Set to ON if targeting a Snapragon 845 based device" ${SD845})
|
||||
option(A64 "Set to ON if targeting an Allwinner A64 based device" ${A64})
|
||||
option(ARM64 "Set to ON if targeting a generic ARM64 based device" ${ARM64})
|
||||
option(BAD_SIGNAL "Set to ON to activate the workaround for incoherent si_info on SIGSEGV" ${BAD_SIGNAL})
|
||||
option(LX2160A "Set to ON if targeting an LX2160A based device" ${LX2160A})
|
||||
option(ANDROID "Set to ON if targeting an Android device" ${ANDROID})
|
||||
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
|
||||
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
|
||||
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box86" ${NO_LOADAADR})
|
||||
option(NOGETCLOCK "Set to ON to avoid using clock_gettime with CLOCK_MONOTONIC_COARSE for RDTSC opcode (use gltimeofday instead)" ${NOGETCLOCK})
|
||||
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
|
||||
option(NO_LIB_INSTALL "Set ON to not install a few x86 libs that are used by many program" ${NO_LIB_INSTALL})
|
||||
option(NO_CONF_INSTALL "Set ON to not install config files" ${NO_CONF_INSTALL})
|
||||
|
||||
if(PANDORA OR PYRA OR RPI2 OR RPI3 OR RPI4 OR GAMESHELL OR ODROID OR GOA_CLONE OR RK3288 OR RK3399 OR ODROIDN2 OR TEGRAX1 OR TEGRAX1ARM32 OR RPI3ARM64 OR RPI4ARM64 OR PHYTIUM OR SD845 OR A64 OR LX2160A OR ARM64 OR RK3588)
|
||||
set(LD80BITS OFF CACHE BOOL "")
|
||||
set(NOALIGN OFF CACHE BOOL "")
|
||||
set(ARM_DYNAREC ON CACHE BOOL "")
|
||||
if(RK3588)
|
||||
set(BAD_SIGNAL ON CACHE BOOL "")
|
||||
endif()
|
||||
endif()
|
||||
if(ANDROID)
|
||||
set(NOLOADADDR ON CACHE BOOL "")
|
||||
endif()
|
||||
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
|
||||
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
|
||||
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation" ${ARM_DYNAREC})
|
||||
option(POWERPCLE "Set to ON if targeting a little-endian PowerPC device" ${POWERPCLE})
|
||||
option(SYSV_VARARG "Set to ON if host device uses SysVR4 vararg calling convention" ${SYSV_VARARG})
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.2")
|
||||
find_package(PythonInterp 3)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message( FATAL_ERROR "You need a Python interpretor, CMake will exit." )
|
||||
endif()
|
||||
if(${PYTHON_VERSION_MAJOR} LESS 3)
|
||||
message( FATAL_ERROR "You need a Python 3 interpretor, CMake will exit." )
|
||||
endif()
|
||||
else()
|
||||
find_package(Python3)
|
||||
if(NOT Python3_Interpreter_FOUND)
|
||||
message( FATAL_ERROR "You need a Python interpretor, CMake will exit." )
|
||||
endif()
|
||||
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE} CACHE INTERNAL "The Python3 executable" FORCE)
|
||||
endif()
|
||||
|
||||
cmake_host_system_information(RESULT CMAKE_HOST_SYSTEM_PROCESSOR QUERY OS_PLATFORM)
|
||||
string(COMPARE EQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}" "i686" _x86)
|
||||
string(COMPARE EQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}" "x86_64" _x86_64)
|
||||
string(COMPARE EQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}" "aarch64" _aarch64)
|
||||
string(COMPARE EQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}" "armhf" _armhf)
|
||||
|
||||
if(_aarch64 AND (RK3399 OR ODROIDN2 OR TEGRAX1 OR RPI3ARM64 OR RPI4ARM64 OR PHYTIUM OR SD845 OR A64 OR LX2160A OR RK3588 OR ARM64))
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
#set(CMAKE_ASM_COMPILER arm-linux-gnueabihf-as) #will use gcc in fact
|
||||
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
|
||||
endif()
|
||||
|
||||
project(box86 C ASM)
|
||||
|
||||
enable_testing()
|
||||
|
||||
option(PANDORA "Set to ON if targeting an OpenPandora device" ${PANDORA})
|
||||
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
|
||||
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
|
||||
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
|
||||
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
|
||||
option(USE_FLOAT "Set to ON to use only float, no double, in all x87 Emulation" ${USE_FLOAT})
|
||||
set(default_build_type "RelwithDebInfo")
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
# Pandora
|
||||
if(PANDORA)
|
||||
add_definitions(-DPANDORA)
|
||||
#add_definitions(-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -fsingle-precision-constant -ffast-math)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp")
|
||||
elseif(GAMESHELL)
|
||||
add_definitions(-DGAMESHELL)
|
||||
add_definitions(-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard")
|
||||
elseif(PYRA)
|
||||
add_definitions(-DPYRA)
|
||||
add_definitions(-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard -marm)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard")
|
||||
elseif(RPI2)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI2)
|
||||
add_definitions(-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard")
|
||||
elseif(RPI3)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI3)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(RPI4)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI4)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(RPI3ARM64)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI3ARM64)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(RPI4ARM64)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI4ARM64)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(ODROID)
|
||||
add_definitions(-DODROID)
|
||||
add_definitions(-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard")
|
||||
elseif(RK3288)
|
||||
add_definitions(-DRK3288)
|
||||
add_definitions(-mcpu=cortex-a17 -mfpu=neon -mfloat-abi=hard -marm)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a17 -mfpu=neon -mfloat-abi=hard")
|
||||
elseif(SD845)
|
||||
add_definitions(-DSD845)
|
||||
add_definitions(-marm -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(A64)
|
||||
add_definitions(-DA64)
|
||||
add_definitions(-marm -march=armv8-a+crc+simd+crypto -mcpu=cortex-a53+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc+simd+crypto -mcpu=cortex-a53+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(GOA_CLONE)
|
||||
add_definitions(-DGOA_CLONE)
|
||||
add_definitions(-marm -mcpu=cortex-a35 -mfpu=neon-vfpv3 -march=armv8-a+crc+simd+crypto -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a35 -mfpu=neon-vfpv3 -march=armv8-a+crc+simd+crypto -mfloat-abi=hard")
|
||||
elseif(RK3399)
|
||||
add_definitions(-DRK3399)
|
||||
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(RK3588)
|
||||
add_definitions(-DRK3588)
|
||||
add_definitions(-pipe -mcpu=cortex-a76.cortex-a55+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
add_definitions(-DBAD_SIGNAL)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -mcpu=cortex-a76.cortex-a55+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(ARM64)
|
||||
add_definitions(-DARM64)
|
||||
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(ODROIDN2)
|
||||
add_definitions(-DODROIDN2)
|
||||
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a73.cortex-a53+crypto -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a73.cortex-a53+crypto -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(TEGRAX1)
|
||||
add_definitions(-DTEGRAX1)
|
||||
add_definitions(-marm -pipe -march=armv8-a+crc -mcpu=cortex-a57 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -pipe -march=armv8-a+crc -mcpu=cortex-a57 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(TEGRAX1ARM32)
|
||||
add_definitions(-DTEGRAX1ARM32)
|
||||
add_definitions(-marm -pipe -march=armv8-a+crc -mcpu=cortex-a57 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -pipe -march=armv8-a+crc -mcpu=cortex-a57 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(PHYTIUM)
|
||||
add_definitions(-DPHYTIUM)
|
||||
add_definitions(-pipe -march=armv8.1-a+simd+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.1-a+simd+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(LX2160A)
|
||||
add_definitions(-DLX2160A)
|
||||
add_definitions(-pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
elseif(ANDROID)
|
||||
add_definitions(-DANDROID)
|
||||
elseif(ARM_DYNAREC)
|
||||
#if DYNAREC is selected alone, without any arch
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv7-a+simd -mfpu=neon")
|
||||
endif()
|
||||
|
||||
if(BAD_SIGNAL)
|
||||
add_definitions(-DBAD_SIGNAL)
|
||||
endif()
|
||||
|
||||
if(POWER9)
|
||||
add_definitions(-mcpu=power9 -mtune=power9)
|
||||
endif()
|
||||
|
||||
if(NOGIT)
|
||||
add_definitions(-DNOGIT)
|
||||
endif()
|
||||
|
||||
if(BOX86LIB)
|
||||
set(BOX86 box86)
|
||||
elseif(HAVE_TRACE)
|
||||
set(BOX86 box86)
|
||||
else()
|
||||
set(BOX86 box86)
|
||||
endif()
|
||||
|
||||
|
||||
set(BOX86_ELF_ADDRESS "0x62800000")
|
||||
|
||||
if(LD80BITS)
|
||||
add_definitions(-DHAVE_LD80BITS)
|
||||
endif()
|
||||
|
||||
if(NOALIGN)
|
||||
add_definitions(-DNOALIGN)
|
||||
add_definitions(-pipe -march=core2 -msse2)
|
||||
endif()
|
||||
|
||||
if(HAVE_TRACE)
|
||||
add_definitions(-DHAVE_TRACE)
|
||||
endif()
|
||||
|
||||
if(USE_FLOAT)
|
||||
add_definitions(-DUSE_FLOAT)
|
||||
if(ARM_DYNAREC)
|
||||
add_definitions(-DDYNAREC)
|
||||
add_definitions(-DARM)
|
||||
add_definitions(-marm)
|
||||
enable_language(ASM)
|
||||
endif()
|
||||
|
||||
add_definitions(-g -std=gnu99 -funwind-tables -O3 -fvisibility=hidden)
|
||||
if(POWERPCLE)
|
||||
add_definitions(-DPOWERPCLE)
|
||||
endif()
|
||||
|
||||
if(SYSV_VARARG)
|
||||
add_definitions(-DSYSV_VARARG)
|
||||
endif()
|
||||
|
||||
if(NOGETCLOCK)
|
||||
add_definitions(-DNOGETCLOCK)
|
||||
endif()
|
||||
|
||||
if(BOX86LIB)
|
||||
add_definitions(-DBUILD_LIB)
|
||||
if(BOX86DYNAMIC)
|
||||
add_definitions(-DBUILD_DYNAMIC)
|
||||
endif()
|
||||
add_definitions(-fPIC)
|
||||
if(NOT BOX86_ROOT)
|
||||
message(FATAL_ERROR "BOX86_ROOT not set when build as lib")
|
||||
endif()
|
||||
else()
|
||||
set(BOX86_ROOT ${CMAKE_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
|
||||
add_definitions(-std=gnu11 -funwind-tables -fvisibility=hidden)
|
||||
|
||||
if(USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
@@ -43,136 +264,628 @@ if(USE_CCACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#include_directories(include)
|
||||
include_directories(
|
||||
"${BOX86_ROOT}/src/include"
|
||||
"${BOX86_ROOT}/src"
|
||||
"${BOX86_ROOT}/src/wrapped/generated"
|
||||
)
|
||||
|
||||
# git_head.h is a generated file
|
||||
set_source_files_properties(
|
||||
"${BOX86_ROOT}/src/git_head.h"
|
||||
PROPERTIES GENERATED TRUE
|
||||
HEADER_FILE_ONLY TRUE)
|
||||
|
||||
set(ELFLOADER_SRC
|
||||
"${CMAKE_HOME_DIRECTORY}/src/bridge.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/main.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/pathcoll.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/box86context.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/fileutils.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/elfloader.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/elfparser.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/elfload_dump.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/library.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/librarian.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/stack.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/threads.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrapper.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86emu.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86run.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86run66.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86run_private.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86syscall.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86primop.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86trace.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x86int3.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x87emu_private.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/x87run.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/myalign.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/callback.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/sdl1rwops.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/sdl2rwops.c"
|
||||
"${BOX86_ROOT}/src/main.c"
|
||||
"${BOX86_ROOT}/src/box86context.c"
|
||||
"${BOX86_ROOT}/src/build_info.c"
|
||||
"${BOX86_ROOT}/src/custommem.c"
|
||||
"${BOX86_ROOT}/src/mallochook.c"
|
||||
"${BOX86_ROOT}/src/tools/bridge.c"
|
||||
"${BOX86_ROOT}/src/tools/pathcoll.c"
|
||||
"${BOX86_ROOT}/src/tools/fileutils.c"
|
||||
"${BOX86_ROOT}/src/tools/callback.c"
|
||||
"${BOX86_ROOT}/src/tools/box86stack.c"
|
||||
"${BOX86_ROOT}/src/tools/my_cpuid.c"
|
||||
"${BOX86_ROOT}/src/tools/gtkclass.c"
|
||||
"${BOX86_ROOT}/src/tools/rcfile.c"
|
||||
"${BOX86_ROOT}/src/tools/wine_tools.c"
|
||||
"${BOX86_ROOT}/src/elfs/elfloader.c"
|
||||
"${BOX86_ROOT}/src/elfs/elfparser.c"
|
||||
"${BOX86_ROOT}/src/elfs/elfload_dump.c"
|
||||
"${BOX86_ROOT}/src/librarian/library.c"
|
||||
"${BOX86_ROOT}/src/librarian/librarian.c"
|
||||
"${BOX86_ROOT}/src/librarian/dictionnary.c"
|
||||
"${BOX86_ROOT}/src/librarian/symbols.c"
|
||||
"${BOX86_ROOT}/src/librarian/globalsymbols.c"
|
||||
"${BOX86_ROOT}/src/emu/x86emu.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run_private.c"
|
||||
"${BOX86_ROOT}/src/emu/x86syscall.c"
|
||||
"${BOX86_ROOT}/src/emu/x86primop.c"
|
||||
"${BOX86_ROOT}/src/emu/x86trace.c"
|
||||
"${BOX86_ROOT}/src/emu/x86int3.c"
|
||||
"${BOX86_ROOT}/src/emu/x86tls.c"
|
||||
"${BOX86_ROOT}/src/emu/x87emu_private.c"
|
||||
"${BOX86_ROOT}/src/libtools/auxval.c"
|
||||
"${BOX86_ROOT}/src/libtools/myalign.c"
|
||||
"${BOX86_ROOT}/src/libtools/myalign64.c"
|
||||
"${BOX86_ROOT}/src/libtools/myfts.c"
|
||||
"${BOX86_ROOT}/src/libtools/sdl1rwops.c"
|
||||
"${BOX86_ROOT}/src/libtools/sdl2rwops.c"
|
||||
"${BOX86_ROOT}/src/libtools/signals.c"
|
||||
"${BOX86_ROOT}/src/libtools/threads.c"
|
||||
"${BOX86_ROOT}/src/libtools/vkalign.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec.c"
|
||||
"${BOX86_ROOT}/src/wrapped/generated/wrapper.c"
|
||||
)
|
||||
if(NOT ANDROID)
|
||||
list(APPEND ELFLOADER_SRC "${BOX86_ROOT}/src/libtools/obstack.c")
|
||||
endif()
|
||||
|
||||
set(INTERPRETER
|
||||
"${BOX86_ROOT}/src/emu/x86run.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run0f.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run64.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run640f.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run6466.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run6467.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run66.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run660f.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run66d9.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run66dd.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run67.c"
|
||||
"${BOX86_ROOT}/src/emu/x86run6766.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rund8.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rund9.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runda.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rundb.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rundc.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rundd.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runde.c"
|
||||
"${BOX86_ROOT}/src/emu/x86rundf.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runf0.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runf066.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runf20f.c"
|
||||
"${BOX86_ROOT}/src/emu/x86runf30f.c"
|
||||
)
|
||||
|
||||
set(WRAPPEDS
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibc.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibpthread.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibrt.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibgl.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibglu.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibx11.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibasound.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibdl.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibm.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl1.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl1mixer.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl1image.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl2.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl2mixer.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsdl2image.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedsmpeg2.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedvorbisfile.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibvorbis.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibogg.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedpng16.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxxf86vm.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxrandr.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxext.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedxinerama.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxfixes.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxcursor.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxrender.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxi.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxss.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibx11xcb.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibxcb.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibz.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedopenal.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedalut.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedlibjpeg.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedcurl.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedudev0.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappeddbus.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappediconv.c"
|
||||
"${CMAKE_HOME_DIRECTORY}/src/wrappedldlinux.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibc.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibpthread.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibrt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibgl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibglu.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibx11.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibasound.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibdl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1mixer.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1net.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1image.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1sound.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl1ttf.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl2mixer.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl2net.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl2image.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsdl2ttf.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsmpeg.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsmpeg2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedvorbisfile.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibvorbis.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibogg.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpng12.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpng16.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxxf86vm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxrandr.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxpresent.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxext.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedxinerama.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxfixes.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcursor.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxrender.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxft.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxi.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxss.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxpm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxau.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxdmcp.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibx11xcb.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcb.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbxfixes.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbshape.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbshm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbrandr.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbimage.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbkeysyms.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbxtest.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbdri2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbdri3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcbpresent.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxtst.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxcomposite.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxdamage.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibxmu.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibz.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedopenal.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedalure.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedalut.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcurl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedudev0.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedudev1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappeddbus.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappediconv.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibdrm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcrypto.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibssl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibcrypt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedutil.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibuuid.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibresolv.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpulsesimple.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpulse.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibsndfile.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedfontconfig.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedfreetype.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedbz2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedexpat.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibsm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibice.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibusb1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibncursesw.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibformw.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibncurses.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibtinfo.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibpanel.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibncurses6.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibtinfo6.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgmp.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgcrypt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgtkx112.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgdkx112.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgtk3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgdk3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgdkpixbuf2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgio2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgmodule2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgobject2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedglib2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgconf2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstreamer010.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstinterfaces010.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstreamer.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstaudio.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstvideo.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgsttag.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstbase.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgstapp.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibibus.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappeddbusmenugtk.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappeddbusmenuglib.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedappindicator.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedappindicator3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedatk.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedatkbridge.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpangoft2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpangocairo.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgthread2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcairo.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcairogobject.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpango.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappeddbusglib1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgudev1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibnm.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedtcmallocminimal.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedmpg123.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgnutls.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibcups.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedd3dadapter9.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedvulkan.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedwaylandclient.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedxml2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedxslt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedldapr.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlber.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappednsl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlcms2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedkrb5.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgssapikrb5.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibtiff.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedldlinux.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcrashhandler.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibv4l2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappednspr4.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsmime3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappednssutil3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappednss3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedplds4.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedplc4.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedssl3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsoftokn3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedfreebl3.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedsecret1.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedtbbmalloc.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedmimalloc.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedselinux.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibharfbuzz.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibcairogobject.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibvkd3d.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgomp.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedcap.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedpcap.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedfaudio.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedtbbmallocproxy.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibfuse.c"
|
||||
)
|
||||
set(WRAPPER "${CMAKE_HOME_DIRECTORY}/src/wrapper.c" "${CMAKE_HOME_DIRECTORY}/src/wrapper.h")
|
||||
add_custom_command(OUTPUT ${WRAPPER} COMMAND "${CMAKE_HOME_DIRECTORY}/rebuild_wrappers.py" "${CMAKE_HOME_DIRECTORY}" MAIN_DEPENDENCY "${CMAKE_HOME_DIRECTORY}/rebuild_wrappers.py" DEPENDS ${WRAPPEDS})
|
||||
set_source_files_properties(${WRAPPER} PROPERTIES GENERATED TRUE)
|
||||
|
||||
if(USE_FLOAT)
|
||||
set(BOX86 box86f)
|
||||
if(ANDROID)
|
||||
list(APPEND WRAPPEDS
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedandroidshmem.c"
|
||||
)
|
||||
else()
|
||||
set(BOX86 box86)
|
||||
list(APPEND WRAPPEDS
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibjpeg.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlibjpeg62.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedturbojpeg.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(${BOX86} ${ELFLOADER_SRC} ${WRAPPEDS})
|
||||
target_link_libraries(${BOX86} m dl rt pthread)
|
||||
# If BOX86_ROOT contains a ".c", the build breaks...
|
||||
string(REPLACE ".c" "_private.h" MODROOT ${BOX86_ROOT})
|
||||
set(WRAPPEDS_HEAD "${BOX86_ROOT}/src/wrapped/wrappedd3dadapter9_genvate.h")
|
||||
foreach(A ${WRAPPEDS})
|
||||
string(REPLACE ".c" "_private.h" C ${A})
|
||||
string(REPLACE "${MODROOT}" "${BOX86_ROOT}" B ${C})
|
||||
set(WRAPPEDS_HEAD ${WRAPPEDS_HEAD} ${B})
|
||||
set_source_files_properties(${A} PROPERTIES OBJECT_DEPENDS ${B})
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(${BOX86} -Wl,-Ttext-segment,0xA8000000)
|
||||
set(WRAPPER "${BOX86_ROOT}/src/wrapped/generated/wrapper.c" "${BOX86_ROOT}/src/wrapped/generated/wrapper.h")
|
||||
|
||||
add_test(test01 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test01 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_custom_command(
|
||||
OUTPUT "${BOX86_ROOT}/src/wrapped/generated/functions_list.txt"
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX86_ROOT}/rebuild_wrappers.py"
|
||||
"${BOX86_ROOT}"
|
||||
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "POWERPCLE" "ANDROID" "--"
|
||||
${WRAPPEDS_HEAD}
|
||||
MAIN_DEPENDENCY "${BOX86_ROOT}/rebuild_wrappers.py"
|
||||
DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
|
||||
BYPRODUCTS ${WRAPPER}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${BOX86_ROOT}/src/dynarec/last_run.txt"
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX86_ROOT}/rebuild_printer.py" "${BOX86_ROOT}"
|
||||
MAIN_DEPENDENCY "${BOX86_ROOT}/rebuild_printer.py"
|
||||
DEPENDS "${BOX86_ROOT}/src/dynarec/arm_instructions.txt"
|
||||
BYPRODUCTS "${BOX86_ROOT}/src/dynarec/arm_printer.c"
|
||||
)
|
||||
|
||||
add_custom_target(WRAPPERS DEPENDS "${BOX86_ROOT}/src/wrapped/generated/functions_list.txt")
|
||||
add_custom_target(PRINTER DEPENDS "${BOX86_ROOT}/src/dynarec/last_run.txt")
|
||||
|
||||
if(ARM_DYNAREC)
|
||||
set(DYNAREC_SRC
|
||||
"${BOX86_ROOT}/src/dynarec/dynablock.c"
|
||||
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_functions.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_jmpnext.c"
|
||||
"${BOX86_ROOT}/src/dynarec/arm_printer.c"
|
||||
"${BOX86_ROOT}/src/emu/x86test.c"
|
||||
|
||||
"${BOX86_ROOT}/src/dynarec/arm_prolog.S"
|
||||
"${BOX86_ROOT}/src/dynarec/arm_epilog.S"
|
||||
"${BOX86_ROOT}/src/dynarec/arm_next.S"
|
||||
"${BOX86_ROOT}/src/dynarec/arm_lock_helper.S"
|
||||
)
|
||||
|
||||
set(DYNAREC_PASS
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_helper.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_emit_tests.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_emit_math.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_emit_logic.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_emit_shift.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_pass.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_00.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_0f.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_64.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_65.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_66.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_67.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_d8.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_d9.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_da.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_db.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_dc.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_dd.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_de.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_df.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_f0.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_660f.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_66f0.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_f20f.c"
|
||||
"${BOX86_ROOT}/src/dynarec/dynarec_arm_f30f.c"
|
||||
)
|
||||
|
||||
set(DYNAREC_PASS "${BOX86_ROOT}/src/wrapped/generated/wrapper.h" ${DYNAREC_PASS})
|
||||
|
||||
add_library(dynarec_arm OBJECT ${DYNAREC_SRC})
|
||||
|
||||
add_library(arm_pass0 OBJECT ${DYNAREC_PASS})
|
||||
set_target_properties(arm_pass0 PROPERTIES COMPILE_FLAGS "-DSTEP=0")
|
||||
add_library(arm_pass1 OBJECT ${DYNAREC_PASS})
|
||||
set_target_properties(arm_pass1 PROPERTIES COMPILE_FLAGS "-DSTEP=1")
|
||||
add_library(arm_pass2 OBJECT ${DYNAREC_PASS})
|
||||
set_target_properties(arm_pass2 PROPERTIES COMPILE_FLAGS "-DSTEP=2")
|
||||
add_library(arm_pass3 OBJECT ${DYNAREC_PASS})
|
||||
set_target_properties(arm_pass3 PROPERTIES COMPILE_FLAGS "-DSTEP=3")
|
||||
add_library(test_interpreter OBJECT ${INTERPRETER})
|
||||
set_target_properties(test_interpreter PROPERTIES COMPILE_FLAGS "-DTEST_INTERPRETER")
|
||||
add_dependencies(arm_pass0 WRAPPERS)
|
||||
add_dependencies(arm_pass1 WRAPPERS)
|
||||
add_dependencies(arm_pass2 WRAPPERS)
|
||||
add_dependencies(arm_pass3 WRAPPERS)
|
||||
|
||||
add_library(dynarec STATIC
|
||||
$<TARGET_OBJECTS:dynarec_arm>
|
||||
$<TARGET_OBJECTS:arm_pass0>
|
||||
$<TARGET_OBJECTS:arm_pass1>
|
||||
$<TARGET_OBJECTS:arm_pass2>
|
||||
$<TARGET_OBJECTS:arm_pass3>
|
||||
$<TARGET_OBJECTS:test_interpreter>
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
# creates git_head.h
|
||||
if(ARM_DYNAREC)
|
||||
add_custom_command(
|
||||
OUTPUT "${BOX86_ROOT}/src/git_head.h"
|
||||
COMMAND bash -c "echo \\\#define GITREV \\\"$(git rev-parse --short HEAD)\\\">\"${BOX86_ROOT}/src/git_head.h\""
|
||||
DEPENDS dynarec ${ELFLOADER_SRC} ${INTERPRETER} ${WRAPPEDS}
|
||||
VERBATIM)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT "${BOX86_ROOT}/src/git_head.h"
|
||||
COMMAND bash -c "echo \\\#define GITREV \\\"$(git rev-parse --short HEAD)\\\">\"${BOX86_ROOT}/src/git_head.h\""
|
||||
DEPENDS ${ELFLOADER_SRC} ${INTERPRETER} ${WRAPPEDS}
|
||||
VERBATIM)
|
||||
endif()
|
||||
|
||||
add_library(interpreter OBJECT ${INTERPRETER})
|
||||
|
||||
if(BOX86LIB)
|
||||
#build a static or dynamic lib...
|
||||
if(BOX86DYNAMIC)
|
||||
add_library(box86 SHARED ${ELFLOADER_SRC} ${WRAPPEDS} "${BOX86_ROOT}/src/git_head.h")
|
||||
else()
|
||||
add_library(${BOX86} OBJECT ${ELFLOADER_SRC} ${WRAPPEDS} "${BOX86_ROOT}/src/git_head.h")
|
||||
endif()
|
||||
if(ARM_DYNAREC)
|
||||
if(ANDROID)
|
||||
target_link_libraries(${BOX86} dynarec interpreter m dl)
|
||||
else()
|
||||
target_link_libraries(${BOX86} dynarec interpreter m dl rt pthread resolv)
|
||||
endif()
|
||||
endif()
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.13")
|
||||
set_target_properties(${BOX86} PROPERTIES LINK_FLAGS -rdynamic)
|
||||
else()
|
||||
target_link_options(${BOX86} PUBLIC -rdynamic)
|
||||
endif()
|
||||
add_dependencies(${BOX86} WRAPPERS)
|
||||
add_dependencies(${BOX86} PRINTER)
|
||||
|
||||
add_custom_target(buildinfo ${BOX86}
|
||||
DEPENDS dynarec ${BOX86} )
|
||||
|
||||
else(BOX86LIB)
|
||||
|
||||
add_executable(${BOX86} ${ELFLOADER_SRC} ${WRAPPEDS} "${BOX86_ROOT}/src/git_head.h")
|
||||
add_dependencies(${BOX86} WRAPPERS)
|
||||
add_dependencies(${BOX86} PRINTER)
|
||||
if(ANDROID)
|
||||
target_link_libraries(${BOX86} c m dl)
|
||||
else()
|
||||
#target_link_libraries(${BOX86} c m dl rt pthread resolv)
|
||||
set_target_properties(${BOX86} PROPERTIES LINK_FLAGS "-Wl,--no-as-needed -lc -lm -ldl -lrt -lpthread -lresolv -Wl,--as-needed -pthread")
|
||||
endif()
|
||||
if(ARM_DYNAREC)
|
||||
target_link_libraries(${BOX86} dynarec interpreter)
|
||||
else()
|
||||
target_link_libraries(${BOX86} interpreter)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.13")
|
||||
if(NOT NOLOADADDR)
|
||||
set_target_properties(${BOX86} PROPERTIES LINK_FLAGS "-rdynamic -Wl,-Ttext-segment,${BOX86_ELF_ADDRESS}")
|
||||
else()
|
||||
set_target_properties(${BOX86} PROPERTIES LINK_FLAGS -rdynamic)
|
||||
endif()
|
||||
else()
|
||||
target_link_options(${BOX86} PUBLIC -rdynamic)
|
||||
if(NOT NOLOADADDR)
|
||||
target_link_options(${BOX86} PUBLIC -Wl,-Ttext-segment,${BOX86_ELF_ADDRESS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _x86 AND NOT _x86_64)
|
||||
install(TARGETS ${BOX86}
|
||||
RUNTIME DESTINATION bin)
|
||||
if(NOT NO_CONF_INSTALL)
|
||||
configure_file(system/box86.conf.cmake system/box86.conf)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/system/box86.conf DESTINATION /etc/binfmt.d/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/system/box86.box86rc DESTINATION /etc/)
|
||||
endif()
|
||||
if(NOT NO_LIB_INSTALL)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libstdc++.so.6 DESTINATION /usr/lib/i386-linux-gnu/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libstdc++.so.5 DESTINATION /usr/lib/i386-linux-gnu/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libgcc_s.so.1 DESTINATION /usr/lib/i386-linux-gnu/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libpng12.so.0 DESTINATION /usr/lib/i386-linux-gnu/)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
set(CPACK_GENERATOR "DEB")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ptitSeb")
|
||||
set(CPACK_PACKAGE_CONTACT "[email protected]")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "Box86 - Linux Userspace x86 Emulator with a twist")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL, "https://box86.org")
|
||||
file(STRINGS "${BOX86_ROOT}/src/box86version.h" TEMP_STRING REGEX "BOX86_MAJOR\\s*")
|
||||
string(REGEX REPLACE "BOX86_MAJOR" "" TEMP_STRING ${TEMP_STRING})
|
||||
string(REGEX MATCH "[0-9]" BOX86_MAJOR ${TEMP_STRING})
|
||||
file(STRINGS "${BOX86_ROOT}/src/box86version.h" TEMP_STRING REGEX "BOX86_MINOR\\s*")
|
||||
string(REGEX REPLACE "BOX86_MINOR" "" TEMP_STRING ${TEMP_STRING})
|
||||
string(REGEX MATCH "[0-9]" BOX86_MINOR ${TEMP_STRING})
|
||||
file(STRINGS "${BOX86_ROOT}/src/box86version.h" TEMP_STRING REGEX "BOX86_REVISION\\s*")
|
||||
string(REGEX REPLACE "BOX86_REVISION" "" TEMP_STRING ${TEMP_STRING})
|
||||
string(REGEX MATCH "[0-9]" BOX86_REVISION ${TEMP_STRING})
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${BOX86_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${BOX86_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${BOX86_REVISION})
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst")
|
||||
if(_aarch64 OR _armhf)
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf")
|
||||
elseif(_x86_64 OR _x86)
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386")
|
||||
else()
|
||||
#probably wrong...
|
||||
execute_process(COMMAND "dpkg --print-architecture" OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||
endif()
|
||||
set(CPACK_DEBIAN_FILE_NAME "${BOX86}-${BOX86_MAJOR}.${BOX86_MINOR}.${BOX86_REVISION}_Linux-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
|
||||
INCLUDE(CPack)
|
||||
|
||||
add_test(NAME bootSyscall COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test01 -D TEST_OUTPUT=tmpfile01.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref01.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test02 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test02 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME bootSyscallC COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test02 -D TEST_OUTPUT=tmpfile02.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref02.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test03 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test03 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME printf COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test03 -D TEST_OUTPUT=tmpfile03.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref03.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test04 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test04 -D TEST_ARGS2=yeah -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME args COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test04 -D TEST_ARGS2=yeah -D TEST_OUTPUT=tmpfile04.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref04.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test05 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME maths1 COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile05.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref05.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test06 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test06 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME threadsStart COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test06 -D TEST_OUTPUT=tmpfile06.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref06.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test07 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test07 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME trig COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test07 -D TEST_OUTPUT=tmpfile07.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref07.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test08 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test08 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME pi COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test08 -D TEST_OUTPUT=tmpfile08.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref08.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test09 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test09 -D TEST_OUTPUT=tmpfile.txt
|
||||
add_test(NAME fork COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test09 -D TEST_OUTPUT=tmpfile09.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref09.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME cppThreads COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test10 -D TEST_OUTPUT=tmpfile10.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref10.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME tlsData COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test11 -D TEST_OUTPUT=tmpfile11.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref11.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME fpu COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test12 -D TEST_OUTPUT=tmpfile12.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref12.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME contexts COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test13 -D TEST_OUTPUT=tmpfile13.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref13.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
if(NOT LD80BITS)
|
||||
add_test(NAME conditionalThreads COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test14 -D TEST_OUTPUT=tmpfile14.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref14.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
endif()
|
||||
|
||||
add_test(NAME linkingIndirectNoversion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test15 -D TEST_OUTPUT=tmpfile15.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref15.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME linkingIndirectVersion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test16 -D TEST_OUTPUT=tmpfile16.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref16.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME sse COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test17 -D TEST_OUTPUT=tmpfile17.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref17.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
set_tests_properties(sse PROPERTIES ENVIRONMENT "BOX86_DYNAREC_FASTNAN=0;BOX86_DYNAREC_FASTROUND=0")
|
||||
|
||||
add_test(NAME longjumpInSignals COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test18 -D TEST_OUTPUT=tmpfile18.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref18.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME x87 COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test19 -D TEST_OUTPUT=tmpfile19.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref19.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(NAME idiv COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test20 -D TEST_OUTPUT=tmpfile20.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref20.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
|
||||
foreach(file ${extension_tests})
|
||||
get_filename_component(testname "${file}" NAME_WE)
|
||||
add_test(NAME "${testname}" COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/extensions/${testname} -D TEST_OUTPUT=tmpfile-${testname}.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/extensions/${testname}.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake)
|
||||
endforeach()
|
||||
|
||||
add_test(NAME sse_optimized COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test17_o2 -D TEST_OUTPUT=tmpfile17_o2.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref17_o2.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
set_tests_properties(sse_optimized PROPERTIES ENVIRONMENT "BOX86_DYNAREC_FASTNAN=0;BOX86_DYNAREC_FASTROUND=0")
|
||||
|
||||
endif(BOX86LIB)
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
Compiling
|
||||
----
|
||||
*for Pandora*
|
||||
|
||||
`mkdir build; cd build; cmake .. -DPANDORA=1; make`
|
||||
|
||||
*or for Other ARM Linux*
|
||||
|
||||
`mkdir build; cd build; cmake .. -DLD80BITS=1 -DNOALIGN=1; make`
|
||||
|
||||
*or for x86 Linux*
|
||||
|
||||
`mkdir build; cd build; cmake .. ; make`
|
||||
|
||||
*or use ccmake*
|
||||
|
||||
Alternatively, you can use the curses-bases ccmake (or any other gui frontend for cmake) to select wich platform to use interactively.
|
||||
|
||||
*use ccache if you have it*
|
||||
Add `-DUSE_CCACHE=1` if you have ccache (it's better if you plan to touch the sources)
|
||||
|
||||
*to have a Trace Enabled build*
|
||||
To have a trace enabled build (warning, it will be slower), add `-DHAVE_TRACE=1` but you will need, at runtime, to have the [Zydis library](https://github.com/zyantific/zydis) library in your `LD_LIBRARY_PATH` or in the system lib folders.
|
||||
|
||||
----
|
||||
|
||||
Testing
|
||||
----
|
||||
A few tests are included.
|
||||
They can be launched with `ctest`
|
||||
They are very basic and don't test much for now.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2018-2019 Sebastien Chevalier ("ptitSeb")
|
||||
Copyright (c) 2018-2021 Sebastien Chevalier ("ptitSeb")
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
# box86
|
||||
|
||||
Linux Userspace x86 Emulator with a twist
|
||||
|
||||
Box86 will let run x86 Linux program (games) on non-x86 Linux, like ARM (needs to be 32bits little-endian).
|
||||
|
||||
Also, Box86 use native version for some "system" libraries, like libc, libm, or SDL and OpenGL, leading to more performance and easier integration with host system.
|
||||
|
||||
Most x86 Games needs OpenGL, so on ARM platform, a solution like [gl4es](https://github.com/ptitSeb/gl4es) is probably needed.
|
||||
|
||||
Note that current version of Box86 doesn't feature any form of JIT/Dynarec: expect everything to be slow.
|
||||
|
||||
Current version is higly experimental and early, and most stuff wont run and run correctly. For example, WorldOfGoo does run correctly (at least on the Pandora), Airline Tycoon Deluxe runs too. but if FTL runs, the music is distorted...
|
||||
|
||||
If you are serious about developping Box86, you should install ccache and activate it's support in the cmake project (use ccmake for example)
|
||||
To have the TRACE enabled (i.e. dumping to stdout all individual x86 instruction execute, with dump of registers), you'll also need [Zydis library](https://github.com/zyantific/zydis) accessible on your system.
|
||||
|
||||
Some x86 internal opcode use parts of "Realmode X86 Emulator Library", see [x86primop.c](src/x86primop.c) for copyright details
|
||||
|
||||
Here are 2 videos, one of "Airline Tycoon Deluxe" running on an gigahertz OpenPandora, and the other of "Bit.Trip.Runner" running on an ODroid XU4.
|
||||
|
||||
[](https://www.youtube.com/watch?v=bLt0hMoFDLk) [](https://www.youtube.com/watch?v=8hr71S029Hg)
|
||||
|
||||
----
|
||||
|
||||
Compiling
|
||||
----
|
||||
How to compile can be found [here](COMPILE.md)
|
||||
|
||||
----
|
||||
|
||||
Usage
|
||||
----
|
||||
|
||||
There are a few environnement variable to control Box86 behavour.
|
||||
|
||||
See [here](USAGE.md) for all variables and what they do.
|
||||
----
|
||||
|
||||
Version history
|
||||
----
|
||||
|
||||
The change log is [here](CHANGELOG.md)
|
||||
|
||||
|
||||
(If you use Box86 in your project, please don't forget to mention Box86)
|
||||
@@ -1,46 +0,0 @@
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environnement variable to control Box86 behavour.
|
||||
|
||||
##### BOX86_LOG
|
||||
Controls the Verbose level of the log
|
||||
* 0
|
||||
* NONE : No message (exept some fatal error)
|
||||
* 1
|
||||
* INFO : Current default. Show some log
|
||||
* 2
|
||||
* DEBUG : Verbose a lot of stuffs (like relocations or function called)
|
||||
* 3
|
||||
* DUMP : All DEBUG plus DUMP of all ELF Info
|
||||
|
||||
#### BOX86_LD_LIBRARY_PATH
|
||||
Controls the folder scanned to look for x86 libs. Default is current folder and `lib` in current folder.
|
||||
Also `/usr/lib/i386-linux-gnu` and `/lib/i386-linux-gnu` are added if they exists
|
||||
|
||||
#### BOX86_PATH
|
||||
Controls the folder scanned to look for x86 executable. Default is current folder and `bin` in current folder.
|
||||
|
||||
#### BOX86_DLSYM_ERROR
|
||||
* 0 : default. Don't log `dlsym` error
|
||||
* 1 : Log dlsym error
|
||||
|
||||
#### BOX86_TRACE_FILE
|
||||
Send all log and trace to a file instead of `stdout`
|
||||
|
||||
#### BOX86_TRACE
|
||||
Only on build with trace enabled. Trace allow the logging of all instruction execute, along with register dump
|
||||
* 0 : No trace
|
||||
* 1 : Trace enabled. The trace start after the init off all depending libs is done
|
||||
* symbolname : Trace only `symbolname` (trace is disable if the symbol is not found)
|
||||
* 0xXXXXXXX-0xYYYYYYY : trace only between the 2 addresses
|
||||
|
||||
#### BOX86_TRACE_START
|
||||
Only on build with trace enabled.
|
||||
* NNNNNNN : Start trace anly after NNNNNNNN opcode execute (number is an `uint64_t`)
|
||||
|
||||
#### BOX86_TRACE_XMM
|
||||
Only on build with trace enabled.
|
||||
* 0 : Default, the XMM (i.e. SSE/SSE2) register will not be logged with the general and x87 registers
|
||||
* 1 : Dump the XMM registers
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-hacker
|
||||
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
box86 (0.3.0) unstable; urgency=low
|
||||
|
||||
* Added rcfile handling: box86 now read "/etc/box86.box86rc" and "~/.box86rc" and apply per process parameters
|
||||
* Added BOX86_DYNAREC_FORWARD to allow bigger Dynarec block to be build
|
||||
* Refactored Strong Memory Model emulation (faster and more accurate)
|
||||
* Box86 now return a custom name for the CPU instal of P4, build with Box86 and the cpu name it's running on
|
||||
* Improved memory protection tracking and signal handling, again
|
||||
* More wrapped libs (especially on the gtk familly)
|
||||
* More wrapped functions
|
||||
* Added support for CreateDeviceEx in d3dadapter9, for better gallium nine support
|
||||
* Improved dladdr/dladdr1 wrapped function
|
||||
* Some fixes to flags handling in the Dynarec on some special cases
|
||||
* Added specific suppport for RK3588 board (needed some hack in signal handling, probably due to the use of a non mainlined kernel)
|
||||
* Lots of improvment in the Rounding of float & double (Dynarec and Interpretor), and proper handling of denormals when converting to/from 80 bits long double
|
||||
* Added specific suppport for RK3588 board (needed some hack in signal handling, probably due to the use of a non mainlined kernel)
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 10 Mar 2023 10:20:33 -0500
|
||||
|
||||
box86 (0.2.8) unstable; urgency=low
|
||||
|
||||
* Wrapped more Vulkan functions, dxvk2.0 now works
|
||||
* Added support for overridden malloc/free functions
|
||||
* Improved elf loader
|
||||
* Improved dlsym handling with RTLD_NEXT
|
||||
* Added BOX86_DYNAREC_SAFEFLAGS to allow finetuning Dynarec generated code handling of flags accross function calls and returns.
|
||||
* Added BOX86_BASH to setup x86 bash binary, so shell script can be run in x86 world
|
||||
* Added BOX86_ROLLING_LOG to have details log only on crash
|
||||
* Improved TLS Size handling (Unity3D games now works)
|
||||
* Improved execv family of function to have better box86 integration
|
||||
* Added a few more wrapped libs, like FAudio
|
||||
* Improved gtk, SDL2, GL, vulkan (and more) wrapping
|
||||
* Improved Signal Handling and memory protection traking
|
||||
* Added some basic support for statically linked program. Thread are not working yet, but memory allocation and file access does.
|
||||
* add LX2160A config by @lizthegrey in #612
|
||||
* Grammar and formatting COMPILE.md by @Radiicall in #615
|
||||
* Update README.md by @everypizza1 in #617
|
||||
* docs: add instructions for Debian-based Linux by @ryanfortner in #622
|
||||
* Fix typoes in readme by @ryanfortner in #621
|
||||
* Various improvements to install_steam.sh by @ryanfortner in #620
|
||||
* docs: remove unnecessary newline by @ryanfortner in #624
|
||||
* fix: the first parameter of realpath may be null by @ye-yeshun in #630
|
||||
* Add 6 wrapped function to libdrm, and 2 to libexpat. by @cjy880927 in #632
|
||||
* Fix #610 by @rajdakin in #634
|
||||
* some floating point instructions by @ye-yeshun in #637
|
||||
* Fix Typo in readme x86_64 -> x86 by @Jai-JAP in #642
|
||||
* Fix grammar by @Jai-JAP in #645
|
||||
* Test wine preload by @ptitSeb in #649
|
||||
* Align address when call mprotect by @wannacu in #651
|
||||
* Added 66 0F 7D HSUBPD opcode by @wannacu in #652
|
||||
* add TEGRAX1 and TEGRAX1ARM32 targets on ubuntu-18.04 by @theofficialgman in #654
|
||||
* automatically install 32 bit libraries if 64 bit OS is detected in install_steam.sh by @Moldytzu in #659
|
||||
* mention gcc-arm-linux-gnueabihf in compile.md by @Moldytzu in #660
|
||||
* Add libc6:armhf install to RPi4 aarch64 build info by @WheezyE in #685
|
||||
* Updated wine install for RPiOS bullseye 32/64bit by @WheezyE in #689
|
||||
* Add atomic add opcodes by @Trass3r in #695
|
||||
* steam: disable modern login and pass arguments to client by @Moldytzu in #700
|
||||
* Modify sizeof(instsize_t) to 1 byte by @liuli0217 in #721
|
||||
* Add MOV GS:od, AL by @liuli0217 in #722
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 17 Nov 2022 11:20:33 -0500
|
||||
|
||||
box86 (0.2.6) unstable; urgency=low
|
||||
|
||||
* Added an option to get generated -NAN on SSE2 operation
|
||||
* Many small fixes and improvement to get steam and SteamPlay working (along with box64)
|
||||
* Added some workaround for program calling uname to mimic x86 system
|
||||
* Added some more Vulkan extensions
|
||||
* Added some granularity to mmap64, and generic memory protection tracking improvment, to mimic x86 system (for wine stagging and proton)
|
||||
* Better clone syscall and libc implementation
|
||||
* Improved wrapping of GTK libs
|
||||
* More wrapped libs (more gtk libs, like gstreamer-1.0 among other non-gtk libs too)
|
||||
* More wrapped functions(with some tricky one, like dladdr1)
|
||||
* Some fixes and improvment to some wrapped functions
|
||||
* Refactor Dynarec:
|
||||
* - better handling of SSE/x87 registers
|
||||
* - optimisation to limit float/double conversion
|
||||
* - better handling of "internal" jump inside a dynablock
|
||||
* Improved elfloader
|
||||
* Improved some tests
|
||||
* A few fixes in some Dynarec opcodes
|
||||
* Don't quit on unsupported syscall, return -1 / ENOSYS error
|
||||
* A bit more optimisation in some Dynarec opcodes
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Tue, 18 Jan 2022 11:20:33 -0500
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
11
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
Source: box86
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Ryan Fortner <[email protected]>
|
||||
Build-Depends: cmake, debhelper (>=11~)
|
||||
Standards-Version: 4.1.4
|
||||
Homepage: https://github.com/ptitSeb/box86
|
||||
|
||||
Package: box86
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices
|
||||
Box86 lets you run x86 Linux programs (such as games) on non-x86 Linux systems, like ARM (host system needs to be 32bit little-endian).
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
Format-Specification: http://dep.debian.net/deps/dep5/
|
||||
|
||||
Files: *
|
||||
Copyright: © 2022 Sebastien Chevalier
|
||||
License: MIT
|
||||
|
||||
License: MIT
|
||||
Copyright (c) 2018-2021 Sebastien Chevalier ("ptitSeb")
|
||||
.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
box86: no-manual-page
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DARM_DYNAREC=1 \
|
||||
-DNOGIT=1
|
||||
|
||||
override_dh_shlibdeps:
|
||||
dh_shlibdeps --exclude=libgcc_s.so.1 --exclude=libpng12.so.0 --exclude=libstdc++.so.5 --exclude=libstdc++.so.6
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
Bug-Database: https://github.com/ptitSeb/box86/issues
|
||||
Bug-Submit: https://github.com/ptitSeb/box86/issues/new
|
||||
Repository: https://github.com/ptitSeb/box86.git
|
||||
Repository-Browse: https://github.com/ptitSeb/box86
|
||||
Security-Contact: [email protected]
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
version=3
|
||||
Executable
+225
@@ -0,0 +1,225 @@
|
||||
v0.3.2
|
||||
======
|
||||
* Better syscall handling
|
||||
* Fixed some wrapped functions, added some others
|
||||
* Introduced another wrapper helper
|
||||
* Added some more opcodes
|
||||
* Added a cosimulation mode (to compare the behaviour of the dynarec against the interpreter)
|
||||
* Added support of FASTNAN for some more opcodes
|
||||
* Reduced memory footprint
|
||||
* Added BOX86_NOSANDBOX (adds an argument to the command line)
|
||||
* Added an ukrainian translation
|
||||
=> Mostly a stability update with improved elfloader, fixed opcodes and refined profiles
|
||||
|
||||
v0.3.0
|
||||
======
|
||||
* Added rcfile handling: box86 now read `/etc/box86.box86rc` and `~/.box86rc` and apply per process parameters
|
||||
=> Every program can be finetuned, for speed or just to make them work
|
||||
* Added BOX86_DYNAREC_FORWARD to allow bigger Dynarec block to be build
|
||||
* Refactored Strong Memory Model emulation (faster and more accurate)
|
||||
* Box86 now return a custom name for the CPU instal of P4, build with Box86 and the cpu name it's running on
|
||||
* Improved memory protection tracking and signal handling, again
|
||||
* More wrapped libs (especially on the gtk familly)
|
||||
* More wrapped functions
|
||||
* Added support for CreateDeviceEx in d3dadapter9, for better gallium nine support
|
||||
* Improved dladdr/dladdr1 wrapped function
|
||||
* Some fixes to flags handling in the Dynarec on some special cases
|
||||
* Added specific suppport for RK3588 board (needed some hack in signal handling, probably due to the use of a non mainlined kernel)
|
||||
* Lots of improvment in the Rounding of float & double (Dynarec and Interpretor), and proper handling of denormals when converting to/from 80 bits long double
|
||||
* Added specific suppport for RK3588 board (needed some hack in signal handling, probably due to the use of a non mainlined kernel)
|
||||
|
||||
|
||||
v0.2.8
|
||||
======
|
||||
* Wrapped more vulkan function, dxvk 2.0 now works
|
||||
* Added support for overriden malloc/free functions
|
||||
* Improved elf loader
|
||||
* Improved dlsym handling with RTLD_NEXT
|
||||
* Added BOX86_DYNAREC_SAFEFLAGS to allow finetuning Dynarec generated code handling of flags accross function calls and returns.
|
||||
* Added BOX86_BASH to setup x86 bash binary, so shell script can be run in x86 world
|
||||
* Added BOX86_ROLLING_LOG to have details log only on crash
|
||||
* Improved TLS Size handling (Unity3D games now works)
|
||||
* Improved `execv` family of function to have better box86 integration
|
||||
* Added a few more wrapped libs, like FAudio
|
||||
* Improved gtk, SDL2, GL, vulkan (and more) wrapping
|
||||
* Improved Signal Handling and memory protection traking
|
||||
* Added some basic support for statically linked program. Thread are not working yet, but memory allocation and file access does.
|
||||
=> with the use of the new SafeFlags, some C# Windows program now runs fine (it's forced when the Vara family of software is detected)
|
||||
=> With the basic support of statcaly linked program, old emulator like modeler for linux works. Program with threads like mugen for linux still doesn't
|
||||
=> The bash integration is usefull for device with no binfmt integration or for script that check the machine it's running on
|
||||
|
||||
v0.2.6
|
||||
======
|
||||
* Added an option to get generated -NAN on SSE2 operation
|
||||
* Many small fixes and improvement to get steam and SteamPlay working (along with box64)
|
||||
* Added some workaround for program calling uname to mimic x86 system
|
||||
* Added some more Vulkan extensions
|
||||
* Added some granularity to mmap64, and generic memory protection tracking improvment, to mimic x86 system (for wine stagging and proton)
|
||||
* Better clone syscall and libc implementation
|
||||
* Improved wrapping of GTK libs
|
||||
* More wrapped libs (more gtk libs, like gstreamer-1.0 among other non-gtk libs too)
|
||||
* More wrapped functions(with some tricky one, like dladdr1)
|
||||
* Some fixes and improvment to some wrapped functions
|
||||
* Refactor Dynarec:
|
||||
* better handling of SSE/x87 registers
|
||||
* optimisation to limit float/double conversion
|
||||
* better handling of "internal" jump inside a dynablock
|
||||
* Improved elfloader
|
||||
* Improved some tests
|
||||
* A few fixes in some Dynarec opcodes
|
||||
* Don't quit on unsupported syscall, return -1 / ENOSYS error
|
||||
* A bit more optimisation in some Dynarec opcodes
|
||||
|
||||
v0.2.4
|
||||
======
|
||||
* Some work on Dynarec to limit the number of mutex use, and also allow smaller block to be built (for JIT'd programs)
|
||||
* Introduce BOX86_DYNAREC_STRONGMEM, like with box64 (not found any program that needs that yet)
|
||||
* More vulkan wrapped function (so dkvk works, at least with RX550)
|
||||
* Reworked Elfloader part, with better handling of versionned symbols
|
||||
* Improve speed for x87 code (by avoiding many float<->double conversion)
|
||||
* Improve speed of the custom allocator used by dynarec and Hash (speedup loading)
|
||||
* Added a detection of box64 in uname call, to expose an x86_64 system instead of i386 one
|
||||
* Added a fix for linking box86 on system using glibc 2.34+
|
||||
* A few more wrapped libs
|
||||
* More ARM hardware option in CMake (Phytium, SD845)
|
||||
* Changed a bit struture of Dynarec, switching some operations from Pass1 to Pass0
|
||||
* Small fixes to elfloader
|
||||
* Some fixes and improvments on wrapped libs (mainly gtk2, gtk3 and d3dadpter)
|
||||
* Better VSyscall implementation
|
||||
* Fixed the "Alternate" handling (address shadowing on x86 side)
|
||||
* A few opcodes border case fixes
|
||||
* Improved wrapper helpers (from rajdakin)
|
||||
* Added a mecanism to cancel a Dynarec block construction if it triggers a segfault (instead of a crash)
|
||||
* Improvment to the handling of longjmp inside signal handlers
|
||||
|
||||
v0.2.2
|
||||
======
|
||||
* Reworked some elfloader relocation mecanism
|
||||
* Removed old "smart linker" and replace with a simple "jump table"
|
||||
* Also removed CALL/RET optomisation from Dynarec, simple Jump Table is faster
|
||||
* Reworked all memory protection tracking
|
||||
* A few more wrapped libs and wrapped functions
|
||||
* A few more opcodes
|
||||
* A few more dynarec opcodes
|
||||
* Some optimisation in Dynarec around ZF and CF flags handlings, and LL/GE/LE/G conditionnal opcodes
|
||||
* Some changes to the "cancel threads" handling
|
||||
* Some changes to the "thread once" handling
|
||||
|
||||
v0.2.0
|
||||
======
|
||||
* Improvements on x86 Flags handling.
|
||||
* A few more opcode has been added.
|
||||
* A few potential BusError are now fixed.
|
||||
* Added the BOX86_NOVULKAN en. var. . This is used to disable the wrapping of vulkan libraries.
|
||||
* Improvments on libc O_XXXX flags handling.
|
||||
* Box86 now uses a custom allocator for Dynarec and Hash tables.
|
||||
* Improved the wrapping of pulse audio.
|
||||
* Optimisation to a few Dynarec opcode (like SHRD/SHLD).
|
||||
* Improved the tracking of memory protection.
|
||||
* A few more wrapping of libraries (like libgssapi_krb5).
|
||||
* More function wrapping on libturbojpeg
|
||||
* Preliminary support for POWER9 (ppcle) build
|
||||
* Many contributions to remove typos and rephrase the README, COMPILE and USAGE documents
|
||||
|
||||
v0.1.8
|
||||
======
|
||||
* Fixes on some float to int x86 convertions opcodes.
|
||||
* Reworked all callback mecanisms.
|
||||
* Added libturbojpeg wrapping (and a hack for zoom to force using native one).
|
||||
* Added the BOX86_SAFEMMAP env. var.
|
||||
* Reworked Dynarec's memory manager.
|
||||
* Added a few opcodes.
|
||||
* Improve elfloader to not force PltResolver all the time (fixing SuperHexagon and maybe other)
|
||||
* Reworked Exet and Cancel Thread mecanism.
|
||||
* Added wrapped libldap_r and liblber library (used by wine)
|
||||
* Reworked Dynarec block handling, and remove the "AddMark" mecanism that wasn't efficient enough
|
||||
* Added TokiTori 2+ detection and runtime patch on the Raspberry Pi platform
|
||||
* Fixes on elfloader with TLS object.
|
||||
|
||||
v0.1.6
|
||||
======
|
||||
* Changes in Dynarec to make flags optimizations before CALL and RET opcode less aggressive.
|
||||
* Added a Vulkan wrapper.
|
||||
* Improved wrapping of SDL_mixer/ SDL2_mixer libraries.
|
||||
* Improved wrapping of some GTK structures.
|
||||
* Added a quick and dirty wrapping of GTK3 (based on current GTK2).
|
||||
* Improved the signal handling, should be more stable now (the signal handler from syscall still need some works).
|
||||
* Added the RK3399 profile, and some hints to build 32bits box86 on 64bits OS.
|
||||
* Fixed some wrapped printf formating not handled correctly.
|
||||
* Fixed some buserror with the new LOCK mecanism handling.
|
||||
* A few more Dynarec opcodes added.
|
||||
* If winedbg is tried to be launched, exit without launching it (it doesn't work anyways).
|
||||
|
||||
v0.1.4
|
||||
======
|
||||
* Change in Dynarec's memory handling, to simplify it (and hopefully optimized it).
|
||||
* Even more opcodes added.
|
||||
* And some more Dynarec opcodes.
|
||||
* Fixed some issue were PltResolver was injected but should not be.
|
||||
* Fixed many Dynarec and non dynarec opcodes.
|
||||
* Improved Signal handling.
|
||||
* Added a few more wrapped libraries (like curl).
|
||||
* Gallium9 is now wrapped (thx @icecream95).
|
||||
* Fixed and simplied many wrapped functions (especialy the one where a callback is involved).
|
||||
* Fixed Dynarec "freeing" a Dynablock sometimes causing a corruption of the heap (generally happens in case of JIT code).
|
||||
* Optimized the way LOCK prefix work when using Dynarec on ARM.
|
||||
* improvements to the ARM opcode Printer (for dumping Dynarec blocks) improvement (thx @rajdakin).
|
||||
|
||||
v0.1.2
|
||||
======
|
||||
* The Dynarec now handle JIT code
|
||||
* Added support for Unity games (not perfect yet).
|
||||
* Added support for Wine (not perfect yet). You need an x86 build of Wine to use it.
|
||||
* Added support for Steam (not perfect yet). Note that Steam have limited functionalities on 32bits (only mini-mode is available).
|
||||
* More wrapped libs
|
||||
* Added support for the "PltResolver". This makes the order of libraries less important and many symbols are now resolved at runtime.
|
||||
* Added an option to build Box86 as a library (to wrap dynamic library).
|
||||
* Better Signal handling (not perfect yet).
|
||||
* More opcodes added, more opcode fixes.
|
||||
* More Dynarec opcodes.
|
||||
* Added support for FS:, and creating custom selector (needed by Wine).
|
||||
* There is now 1 x86emu_t structure per thread (simplifying/optimising many callback handling).
|
||||
* Box86 now has a logo!
|
||||
* Added options handling (only version and help for now). Now it's much usefull exept for version printing.
|
||||
|
||||
|
||||
v0.1.0
|
||||
=======
|
||||
* Dynarec!!! Only for ARM (note that Dynarec doesn't support JITed code for now).
|
||||
* Added real support for getcontext/set/context/makecontext/swapcontext.
|
||||
* Preliminary signal handling.
|
||||
* Fixes to SDL(1/2) Image and SDL1 Mixer, and to SDL1.2 RWops usage.
|
||||
* Fixed numerous issues in opcodes (both interpretor and dynarec). FTL works fine now, among many others.
|
||||
* Added wrapped GTK support (still ongoing, many libraries involved).
|
||||
* Make loading of libraries more configurable.
|
||||
* If a wrapped native library is not found, try to use an emulated one.
|
||||
* Added an env. var. to force the use of emulated libraries for certain libraries.
|
||||
* Added an env. var. to precise which libGL to use.
|
||||
* Added Install / Uninstall target (using systemd binfmt).
|
||||
* Added more hardware targets (RPis, GameShell...).
|
||||
* Wrapped more libraries (including FreeType, smpeg, ncurses, sndfile...).
|
||||
|
||||
v0.0.4
|
||||
=======
|
||||
* Improved the initialisation of dependent libraries. More things work now.
|
||||
* Added a lot of wrapped functions.
|
||||
* Added a few wrapped libraries (like libz or some other x11 related library).
|
||||
* For trace enabled build, Trace can be enabled only after a certain amount of opcodes (still, a debugger would be better).
|
||||
* Some fixes in a few opcodes, and implemented x87 rounding (SuperMeatBoy behaves better now).
|
||||
* FTL 1.6.9 still has corrupted music, but older 1.5.13 seems fine (different set of libraries).
|
||||
|
||||
v0.0.2
|
||||
=======
|
||||
* A full commercial games runs fine on the Pandora platform: Airline Tycoon Deluxe.
|
||||
* Implemented all planned subparts of Box86 except JIT support.
|
||||
* CPU Emulation is at roughly 75%. This includes x87 and SSE/SSE2. MMX is barely implemented (but barely used anyway).
|
||||
* x87 emulation is simplified, no real x87 State handling (but should not be mandatory, as the native libm library is used)
|
||||
* No Signal handling yet
|
||||
* ELF Loader is crude and probably full of bugs. Also, the initialisation of libraries are defered after all symbols are resolved for now.
|
||||
* Wrapped libraries include libc, libm, rt, pthread, libdl, dllinux, libasound, GL, GLU, SDL1/mixer/image, SDL2/mixer/image/smpeg, OpenAL/ALUT, libz, libpng16, vorbisfile, x11/xrandr/xxf86vm.
|
||||
* Most wrapped libraries are still partially implemented ( the SDL1 & GL libraries should be complete).
|
||||
* Implemented specific mecanism for SDL(1/2) RWops, to be able to used them both in Native and x86 world.
|
||||
* WorldOfGoo works, but is painfully slow on the Pandora platform (there is too much double math, and lack of JIT).
|
||||
* FTL works, but sound is broken (issue with thread? asound? or CPU core?)
|
||||
* Limbo launches but crashes before main menu.
|
||||
|
||||
Executable
+198
@@ -0,0 +1,198 @@
|
||||
Compiling/Installing
|
||||
----
|
||||
|
||||
#### Debian-based Linux
|
||||
You can use [@Itai-Nelken](https://github.com/Itai-Nelken)'s apt repository to install precompiled box86 debs, updated weekly.
|
||||
|
||||
```
|
||||
sudo wget https://itai-nelken.github.io/weekly-box86-debs/debian/box86.list -O /etc/apt/sources.list.d/box86.list
|
||||
wget -qO- https://itai-nelken.github.io/weekly-box86-debs/debian/KEY.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/box86-debs-archive-keyring.gpg
|
||||
sudo apt update && sudo apt install box86 -y
|
||||
```
|
||||
|
||||
**Note:** On a 64bit OS, install the `box86:armhf` package.
|
||||
|
||||
Alternatively, you can generate your own package using the [instructions below](https://github.com/ptitSeb/box86/blob/master/docs/COMPILE.md#debian-packaging).
|
||||
|
||||
#### for Pandora
|
||||
|
||||
`mkdir build; cd build; cmake .. -DPANDORA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
|
||||
|
||||
#### for Pyra
|
||||
|
||||
`mkdir build; cd build; cmake .. -DPYRA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
|
||||
|
||||
#### for Gameshell
|
||||
|
||||
`mkdir build; cd build; cmake .. -DGAMESHELL=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
|
||||
|
||||
#### for Raspberry Pi
|
||||
|
||||
_A build for model 2, 3 and 4 can be done. Model 1 and 0 cannot (at least not with Dynarec, as they lack NEON support)_
|
||||
|
||||
```
|
||||
git clone https://github.com/ptitSeb/box86
|
||||
cd box86
|
||||
mkdir build; cd build; cmake .. -DRPI4=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo # -DRPI4=1 for Pi4 (use `-DRPI2=1` etc for other models)
|
||||
make # can use `make -j2`, `make -j3`, etc to speed up 1st build (but beware of running out of memory if going too high)
|
||||
sudo make install
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
|
||||
#### for Raspberry Pi on 64bit OS
|
||||
|
||||
_armhf multiarch or chroot required for running box86 (armhf) on aarch64_
|
||||
|
||||
```
|
||||
# example of enabling multiarch & installing libc6:armhf (to run box86:armhf on aarch64)
|
||||
# (running i386-wine on aarch64 requires more armhf libraries)
|
||||
sudo dpkg --add-architecture armhf && sudo apt-get update
|
||||
sudo apt-get install libc6:armhf -y
|
||||
```
|
||||
_Build box86:armhf on RPiOS 64-bit ARM (aarch64)_
|
||||
```
|
||||
sudo apt install gcc-arm-linux-gnueabihf # building 32-bit ARM code on aarch64 requires this armhf gcc cross-compiler toolchain
|
||||
git clone https://github.com/ptitSeb/box86
|
||||
cd box86
|
||||
mkdir build; cd build; cmake .. -DRPI4ARM64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo # -DRPI4ARM64=1 for Pi4 aarch64 (use `-DRPI3ARM64=1` for a PI3 model)
|
||||
make -j2
|
||||
sudo make install
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
|
||||
#### for ODROID
|
||||
|
||||
`mkdir build; cd build; cmake .. -DODROID=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
#### for RK3399
|
||||
|
||||
`mkdir build; cd build; cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
As most RK3399 devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for RK3588 / RK3588S
|
||||
|
||||
`mkdir build; cd build; cmake .. -DRK3588=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j4`
|
||||
|
||||
As most RK3588 devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for ODROID N2/N2+
|
||||
|
||||
`mkdir build; cd build; cmake .. -DODROIDN2=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
As most ODROID N2/N2+ devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for Tinker Board (1/1S) or RK3288
|
||||
|
||||
`mkdir build; cd build; cmake .. -DRK3288=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
#### for Allwinner A64
|
||||
|
||||
`mkdir build; cd build; cmake .. -DA64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
As most Allwinner A64 devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for Snapdragon 845
|
||||
|
||||
`mkdir build; cd build; cmake .. -DSD845=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j4`
|
||||
|
||||
As most Snapdragon 845 devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On mobian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
#### for Phytium
|
||||
|
||||
`mkdir build; cd build; cmake .. -DPHYTIUM=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j4`
|
||||
|
||||
As most Phytium (D2000 or FT2000/4) devices run an AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for Other ARM64 64bits Linux platform
|
||||
|
||||
`mkdir build; cd build; cmake .. -DARM64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on Linux Kernel mixed with Android, like on RK3588 or maybe Termux
|
||||
|
||||
You'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
Also, on armbian, you may need to install `libc6-dev-armhf-cross` or you may have an issue with `crt1.o` and a few other files not included with box86.
|
||||
|
||||
#### for Other ARM Linux platforms
|
||||
|
||||
`mkdir build; cd build; cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on Linux Kernel mixed with Android, like on RK3588 or maybe Termux
|
||||
|
||||
#### for x86 Linux
|
||||
|
||||
`mkdir build; cd build; cmake .. -DCMAKE_C_FLAGS="-m32" -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j3`
|
||||
|
||||
### use ccmake
|
||||
|
||||
Alternatively, you can use the curses-bases ccmake (or any other gui frontend for cmake) to select wich platform to use interactively.
|
||||
|
||||
### Customize your build
|
||||
|
||||
#### use ccache if you have it
|
||||
|
||||
Add `-DUSE_CCACHE=1` if you have ccache (it's better if you plan to touch the sources)
|
||||
|
||||
#### To have some debug info
|
||||
|
||||
The `-DCMAKE_BUILD_TYPE=RelWithDebInfo` argument makes a build that is both optimized for speed, and has debug information embedded. That way, if you have a crash or try to analyse performance, you'll have some symbols.
|
||||
|
||||
#### To have a Trace Enabled build
|
||||
|
||||
To have a trace enabled build (***the interpreter will be slightly slower***), add `-DHAVE_TRACE=1`. But you will need the [Zydis library](https://github.com/zyantific/zydis) in your `LD_LIBRARY_PATH` or in the system library folders at runtime.
|
||||
|
||||
#### to have ARM Dynarec
|
||||
|
||||
###### *Note: VFPv3 and NEON are required for Dynarec.*
|
||||
|
||||
###### *Note: Compiling with `ARM_DYNAREC` without selecting a hardware profile is not advised.*
|
||||
|
||||
Dynarec is only available on the ARM architecture (for the meantime anyways). Activate it by using `-DARM_DYNAREC=1`.
|
||||
|
||||
You will most likely need `-marm` in compilation flags (Many compilers default to the Thumb instruction set and Dynarec does not support this).
|
||||
|
||||
###### *Note: If you get error building that "target CPU does not support ARM mode", then try to pick a hardware profile (like ODROID for armv7 or PI4 for armv8).*
|
||||
|
||||
##### 64bit OS with Dynarec
|
||||
|
||||
If you are using a 64bit OS with armhf multiarch, it's much easier to pick one of the hardware profiles.
|
||||
|
||||
`RPI4ARM64`, `RK3399`, `PHYTIUM` or `SD845`.
|
||||
|
||||
#### Not building from a git clone
|
||||
If you are not building from a git clone (for example, downloading a release source code zip from github), you need to use `-DNOGIT=1` from cmake to be able to build (box86 uses git SHA1 to show last commit in version number).
|
||||
|
||||
----
|
||||
|
||||
Testing
|
||||
----
|
||||
A few tests are included with box86.
|
||||
|
||||
They can be launched using the `ctest` command.
|
||||
|
||||
The tests are very basic and only tests some functionality for now.
|
||||
|
||||
----
|
||||
|
||||
Note about devices with Tegra X1 and newer.
|
||||
|
||||
NVIDIA doesn't provide armhf libraries for their GPU drivers at this time. There is no special variable to compile box86 for them, as it would be misleading to many people. If you still want to use it wihout GPU acceleration, building it with RPI4 configuration should work just fine. Installation of Mesa can break the NVIDIA driver, so the safest option is to use a chroot environment.
|
||||
|
||||
----
|
||||
|
||||
Debian Packaging
|
||||
----
|
||||
Box86 can also be packaged into a .deb file ***using the source code zip from the releases page*** with `DEB_BUILD_OPTIONS=nostrip dpkg-buildpackage -us -uc -nc`. Configure any additional cmake options you might want in `debian/rules`.
|
||||
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||

|
||||
|
||||
Linux Userspace x86 Emulator with a twist
|
||||
|
||||
[View changelog](https://github.com/ptitSeb/box86/blob/master/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box86/blob/master/docs/README_CN.md) | [Українська](https://github.com/ptitSeb/box86/blob/master/docs/README_UK.md) | [Report an error](https://github.com/ptitSeb/box86/issues/new)
|
||||
|
||||
     
|
||||
|
||||
----
|
||||
|
||||
Box86 lets you run x86 Linux programs (such as games) on non-x86 Linux systems, like ARM (host system needs to be 32bit little-endian).
|
||||
|
||||
You *NEED* a 32-bit subsystem to run and build Box86. Box86 is useless on 64-bit only systems. Also, you *NEED* a 32-bit toolchain to build Box86. A toolchain that only supports 64-bit will not compile Box86, and you'll get errors (typically on aarch64, you get "-marm" not recognized, and you'll need a multiarch or chroot environment).
|
||||
|
||||
Because Box86 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use with most applications, and performance can be surprisingly high in many cases. Take a look at those bench analysis for an example [here](https://box86.org/index.php/2021/06/game-performances/). That also means that you will need a 32bits userspace on 64bits OS, like `armhf` on top an `aarch64` 64bits OS.
|
||||
|
||||
Most x86 Games need OpenGL, so on ARM platforms a solution like [gl4es](https://github.com/ptitSeb/gl4es) might be necessary. (Some ARM platforms only support OpenGL ES and/or their OpenGL implementation is dodgy. (see OpenGL on Android))
|
||||
|
||||
Box86 now integrates a DynaRec (dynamic recompiler) for the ARM platform, providing a speed boost between 5 to 10 times faster than only using the interpreter. Some high level information on how the Dynarec work can be found [here](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
|
||||
|
||||
Many games just work without much tweaking, for example: WorldOfGoo, Airline Tycoon Deluxe, and FTL. Many of the GameMaker Linux games also run fine. (there's a long list, among them are UNDERTALE, A Risk of Rain, and Cook Serve Delicious). Unity3D games also works fine, but the OpenGL requirement might be an issue on some ARM platforms.
|
||||
|
||||
If you are serious about developing Box86, you should install ccache and build Box86 with it. (Use ccmake for example.)
|
||||
To enable TRACE (i.e. dumping to stdout all individual x86 instructions executed, with dump of registers), you'll also need [Zydis library](https://github.com/zyantific/zydis) available on your system.
|
||||
|
||||
Some x86 internal opcodes use parts of "Realmode X86 Emulator Library", see [x86primop.c](../src/emu/x86primop.c) for copyright details
|
||||
|
||||
----
|
||||
Compiling/Installation
|
||||
----
|
||||
> Compilation instructions can be found [here](COMPILE.md)
|
||||
> Instructions for installing Wine for Box86 can be found [here](X86WINE.md)
|
||||
|
||||
----
|
||||
|
||||
Here are 6 videos, the first 2 videos are videos of "Airline Tycoon Deluxe" and "Heretic 2" running on a GigaHertz OpenPandora (the second one is using the dynarec), and the next 2 videos are videos of of "Bit.Trip.Runner" and "Neverwinter Night" running on an ODroid XU4 (without dynarec), and the last 2 videos are on on a Pi4: Shovel Knight (video from @ITotalJustice) and Freedom Planet (video from @djazz), also without dynarec.
|
||||
|
||||
[](https://www.youtube.com/watch?v=bLt0hMoFDLk) [](https://www.youtube.com/watch?v=MM7kWYts7IA) [](https://www.youtube.com/watch?v=8hr71S029Hg) [](https://www.youtube.com/watch?v=B4YN37z3-ws) [](https://www.youtube.com/watch?v=xk8Q30mxqPg) [](https://www.youtube.com/watch?v=_QMRMVvYrqU)
|
||||
|
||||
You can find many more Box86 videos on the [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) or [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA) YouTube channels.
|
||||
|
||||
Compatibility list is here: https://github.com/ptitSeb/box86-compatibility-list/issues
|
||||
|
||||
<img src="img/Box86Icon.png" width="96" height="96">
|
||||
|
||||
Logo and Icon made by @grayduck, thanks!
|
||||
|
||||
Note that this project is not to be mistaken with [86box](https://github.com/86Box/86Box), a nice "Full system" emulator specialized in early (to fairly recent) PC hardware.
|
||||
|
||||
----
|
||||
|
||||
Usage
|
||||
----
|
||||
|
||||
There are a few environment variables to control the behaviour of Box86.
|
||||
|
||||
See [here](USAGE.md) for all environment variables and what they do.
|
||||
|
||||
Note: Box86's Dynarec uses a mechanism with Memory Protection and a SegFault signal handler to handle JIT code. In simpler terms, if you want to use GDB to debug a running program that use JIT'd code (like mono/Unity3D), you will still have many "normal" segfaults triggering. It is suggested to use something like `handle SIGSEGV nostop` in GDB to not stop at each segfault, and maybe put a breakpoint inside `my_box86signalhandler` in `signals.c` if you want to trap SegFaults.
|
||||
|
||||
----
|
||||
|
||||
Version history
|
||||
----
|
||||
|
||||
The change log is available [here](CHANGELOG.md)
|
||||
|
||||
----
|
||||
|
||||
Notes about 64-bit platforms
|
||||
----
|
||||
|
||||
Because Box86 works by directly translating function calls from x86 to host system, the host system (the one Box86 is running on) needs to have 32-bit libraries. Box86 doesn't include any 32-bit <-> 64-bit translation. So basically, to run Box86 on, for example, an ARM64 platform, you will need to build Box86 for ARM 32-bit, and also need to have a chroot with 32-bit libraries.
|
||||
|
||||
If you look at a 64bits version of box86, look at [Box64](https://github.com/ptitSeb/box64): this one is able to run x86_64 binaries on 64-bit platforms. But note that you still need Box86 (and a 32-bit chroot) to run x86 binaries (as it also happens on actual x86_64 Linux that need x86 libs and binary on multiarch to run).
|
||||
|
||||
----
|
||||
|
||||
Notes about Box86 configuration
|
||||
----
|
||||
|
||||
Box86 now have configurations files. There are 2 files loaded. `/etc/box4.box86rc` and `~/.box86rc`. Both files have the same syntax, and is basicaly an ini files. Section in square brakets define the process name, and the rest is the env. var. to set. Looke at [Usage](USAGE.md) for detail on what parameters can be put. Box86 comes with a default file that should be installed for better stability. The file in in `system/box86.box86rc` and should be installed to `/etc/box86.box86rc` If, for some reasons, you don't want to install that file here, at least copy it to `~/.box86rc` or some game may not function correctly.
|
||||
Note that the priority is: `~/.bashrc` > `/etc/box86.box86rc` > command line
|
||||
So, your settings in `~/.bashrc` may override the setting from your command line...
|
||||
|
||||
----
|
||||
|
||||
Notes about Unity game emulation
|
||||
----
|
||||
|
||||
Running Unity games should generaly work now, but you should also note that many Unity3D games require OpenGL 3+ which can be tricky to provide on ARM SBC (single-board computers) for now.
|
||||
Hint: on Pi4, use `MESA_GL_VERSION_OVERRIDE=3.2` and with Panfrost use `PAN_MESA_DEBUG=gl3` to use higher profile if the game starts then quits before showing anything.
|
||||
|
||||
----
|
||||
|
||||
Notes about Steam
|
||||
----
|
||||
|
||||
Linux Steam's can run now with box86. but you also need box64 for it to completly usable.
|
||||
It is advised to run steam in the Small mode, as it use the less memory, but steamwebhelper (a 64bits process) will still be loaded even if not used.
|
||||
The login screen cannot run without steamwebhelper, and will just show a blank windows without box64 properly setup in the system.
|
||||
File note, Steam will use a lot of memory, and barely fit on system with 4GB of RAM. It will not work anymore on system with less memory (as a workaround, create a swap file, login and check "remember me", the use box64rc to disable steamwebhelper and run only in small mode without swap after the 1st login)
|
||||
Final note: the Steam BigPicture will work, but also need steamwebhelper (and so box64), and lots of memory. It will not start on system with only 4GB of RAM without swap.
|
||||
- If you have trouble installing Steam, you can find `install_steam.sh` in the root folder of the box86 repo. This simple script will download and install steam in your home folder, and then create a shortcut to steam in `/usr/local/bin` (and for this it will ask for sudo permission). Simply use `steam` to launch once it's installed. Note that the installation, being in the Home folder, will only work for a single user. Don't use this script if you need a multi-user installation.
|
||||
- To avoid the "libc.so.6 is absent" message, you can use `STEAMOS=1` and `STEAM_RUNTIME=1` as environment variables (it's automatically there if you used the `install_steam.sh` script)
|
||||
|
||||
to disable `steamwebhelper` when box64 installed and running, create (or edit) `~/.box64rc` and add:
|
||||
```
|
||||
[steamwebhelper]
|
||||
BOX64_EXIT=1
|
||||
```
|
||||
in it and it will be disable. Comment with a `#` those 2 lines to enable it again
|
||||
|
||||
----
|
||||
|
||||
Notes about Wine
|
||||
----
|
||||
|
||||
Wine is now supported. Wine integrated program all runs, and many windows programs and games also runs fine. Don't forget most Windows games use Direct3D, this may require a complete OpenGL driver and a as high profile as possible (and gl4es with ES2 backend have issue with Wine for now).
|
||||
Note: if you plan to use box86 with Wine on Raspberry Pi 3 or earlier, those models use a default OS that have a kernel with a 2/2 Split (meaning 2G of space for user program, and 2G of space for the Kernel). This is not compatible with Wine programs that needs to access memory > 2Gb address. So you'll need to reconfigure your kernel for a 3G/1G split.
|
||||
|
||||
----
|
||||
|
||||
Notes about Vulkan
|
||||
----
|
||||
|
||||
Box86 already wrap Vulkan. If your system has a 32bits Vulkan driver, box86 will use it when needed. Profile 1.0, 1.1, 1.2 and 1.3, with some extensions, should be OK. DXVK, including the 2.0, works. I know some demos work on Pi4 (Sascha Willems demos build for x86 work the same as if build on armhf directly). Note that the Vulkan driver of the Pi4 DOES NOT support dxvk for now (wine DirectX->Vulkan wrapper). It's not a box86 issue, it's missing extensions (hardware support) and a few other things that make dxvk not working on pi4. On Panfrost side, PanVK is a bit young and I haven't tested dxvk with it yet.
|
||||
|
||||
----
|
||||
Final word
|
||||
----
|
||||
|
||||
I want to thank everyone who has contributed to box86 development.
|
||||
There are many ways to contribute: code, financial, hardware and advertisement!
|
||||
So, in no particular order, I want to thank:
|
||||
* For their major code contribution: rajdakin, icecream95, M-HT
|
||||
* For their major financial contribution: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
|
||||
* For their hardware contribution: [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [DragonBox](https://pyra-handheld.com/), [Novaspirit](https://www.youtube.com/channel/UCrjKdwxaQMSV_NDywgKXVmw), [HardKernel](https://www.hardkernel.com/), [TwisterOS team](https://twisteros.com/)
|
||||
* For their continuous advertisement of box86 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS team](https://twisteros.com/), [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg)
|
||||
|
||||
And I also thank the many other people who participated even once in the project.
|
||||
|
||||
(If you use Box86 in your project, please don't forget to mention it!)
|
||||
@@ -0,0 +1,135 @@
|
||||

|
||||
|
||||
Linux用户空间的x86应用模拟器
|
||||
|
||||
[更新历史](https://github.com/ptitSeb/box86/blob/master/docs/CHANGELOG.md) | [English](https://github.com/ptitSeb/box86/blob/master/docs/README.md) | [Українська](https://github.com/ptitSeb/box86/blob/master/docs/README_UK.md) | [报告错误](https://github.com/ptitSeb/box86/issues/new)
|
||||
|
||||
     
|
||||
|
||||
----
|
||||
|
||||
使用Box86可以在ARM或其他非x86架构的Linux操作系统上运行x86 Linux程序(例如游戏),请注意,主机系统需要是**32位小端**的。
|
||||
|
||||
你需要一个**32位**的子系统来运行Box86,因为Box86在纯64位系统上无法使用,同时你也需要一个**32位**的Linux编译工具链来编译Box86,例如**arm-linux-gnueabihf-gcc**, 否则你将无法编译Box86 (一般的64位ARM编译工具链如 aarch64-linux-gnu-gcc 不支持"-marm"编译选项,会编译失败并报错)。
|
||||
|
||||
因为Box86使用了一些“系统”库的原生版本,例如libc、libm、SDL和OpenGL,所以在很多情况下性能很不错,也可以方便地与其他应用集成使用。点击[此处](https://box86.org/index.php/2021/06/game-performances/)查看Benchmark示例。
|
||||
|
||||
大多数x86游戏都用到了OpenGL,所以在ARM平台上类似于[gl4es](https://github.com/ptitSeb/gl4es)的解决方案通常是必要的。(许多ARM平台仅提供OpenGL ES支持,又或者他们的OpenGL实现很不可靠(例如Android上的OpenGL)。)
|
||||
|
||||
Box86为ARM平台集成了DynaRec(动态重编译器),比仅使用解释器提升5到10倍性能。关于Dynarec如何工作的更多信息,可以在[这里](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/)找到。
|
||||
|
||||
许多游戏已可在不做多少改动的情况下直接运行,例如:《粘粘世界》(WorldOfGoo)、《航空大亨豪华版》(Airline Tycoon Deluxe)、《超越光速》(FTL)等、基于GameMaker的游戏(《传说之下》(UNDERTALE)等)。
|
||||
|
||||
如果你想开发Box86,最好安装ccache,以缓存编译结果。
|
||||
如果你需要启用Trace跟踪(例如输出寄存器值与各条被执行的x86指令),你也需要安装[Zydis](https://github.com/zyantific/zydis)。
|
||||
|
||||
一些x86内部操作码使用“Realmode X86 Emulator Library”的部分内容,请参阅[x86primop.c](../src/emu/x86primop.c)了解版权详情
|
||||
|
||||
----
|
||||
|
||||
编译与安装
|
||||
----
|
||||
> [Box86编译指南](COMPILE.md)
|
||||
>
|
||||
> [Box86 Wine安装指南](X86WINE.md)
|
||||
|
||||
一些示例视频
|
||||
----
|
||||
|
||||
[](https://www.youtube.com/watch?v=bLt0hMoFDLk) [](https://www.youtube.com/watch?v=MM7kWYts7IA) [](https://www.youtube.com/watch?v=8hr71S029Hg) [](https://www.youtube.com/watch?v=B4YN37z3-ws) [](https://www.youtube.com/watch?v=xk8Q30mxqPg) [](https://www.youtube.com/watch?v=_QMRMVvYrqU)
|
||||
|
||||
在这几个Youtube频道可以找到更多Box86的相关视频
|
||||
|
||||
[MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)
|
||||
|
||||
[Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)
|
||||
|
||||
[The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
|
||||
|
||||
程序兼容性列表: https://github.com/ptitSeb/box86-compatibility-list/issues
|
||||
|
||||
<img src="img/Box86Icon.png" width="96" height="96">
|
||||
|
||||
感谢制作Logo和图标的grayduck!
|
||||
|
||||
注意:
|
||||
不要把本项目和[86box](https://github.com/86Box/86Box)搞混了,后者是一个"**全量**"的x86 PC模拟器。
|
||||
|
||||
----
|
||||
|
||||
使用方法
|
||||
----
|
||||
|
||||
有若干环境变量可以设置Box86的行为。
|
||||
|
||||
点击[这里](USAGE.md)了解所有的环境变量和它们的作用。
|
||||
|
||||
请注意:Box86的Dynarec提供了一种包含"内存保护"和段错误信号处理程序的机制来处理JIT代码。简单来说,如果你想用GDB来调试一个使用JIT代码的运行程序(比如mono/Unity3D),就会触发很多“正常”的段错误。建议在GDB中使用类似于`handle SIGSEGV nostop`的命令,来防止在每个段错误时都停止程序运行,如果你想捕获段错误,可以在`signals.c`中的`my_memprotectionhandler`中放置一个断点。
|
||||
|
||||
----
|
||||
|
||||
关于64位平台的注意事项
|
||||
----
|
||||
|
||||
Box86的工作原理是直接将函数调用从x86_转换到主机系统,主机系统(Box86运行的系统)需要有32位的库。Box86并不包括任何64位<->32位的转换。所以如果你需要在64位平台上运行Box86,那么你需要建立一个32位的库环境,并以32位ARM为目标系统编译Box86(例如使用arm-linux-gnueabihf-gcc工具链交叉编译或直接在armhf chroot环境中编译运行)。
|
||||
|
||||
如果你需要运行64位应用,请考虑使用[Box64](https://github.com/ptitSeb/box64),它可以在64位平台上运行x86_64程序,但请再一次注意运行x86程序需要Box86与32位库环境(就像在x86_64的Linux上运行x86程序需要x86 multiarch库一样)。
|
||||
|
||||
----
|
||||
|
||||
关于Unity游戏的注意事项
|
||||
----
|
||||
|
||||
当前对于Unity游戏的模拟仍不完善。Unity使用Mono,但它所使用的信号机制还没有被完美模拟。理论上可以使用原生Mono库(在[这里](https://github.com/Unity-Technologies/mono)可以找到),但Mono的封装比较麻烦,现在还没完成,所以我们使用了模拟的Mono库,目前Mono的JIT动态编译代码已由"内存保护"(Protected memory)机制实现,应该能正常运行。
|
||||
|
||||
同时,一些Unity3D游戏需要OpenGL 3+,目前在大部分Arm开发板上提供OpenGL 3+是很困难的。
|
||||
|
||||
所以,并不是所有的Unity游戏都能运行,尤其是那些需要提供很高的OpenGL配置(3.2+)的游戏更有可能不行,但除此之外应该问题不大,而且能运行的游戏的性能应该不错。
|
||||
|
||||
提示:如果游戏开始后在显示任何东西之前退出,在Raspberry Pi4上使用`MESA_GL_VERSION_OVERRIDE=3.2`,在Panfrost上使用`PAN_MESA_DEBUG=gl3`来使用更高的配置文件。
|
||||
|
||||
----
|
||||
|
||||
关于Steam的注意事项
|
||||
----
|
||||
|
||||
Linux Steam 现在可以在Box86上运行,但还是有点不稳定,而且有些功能可能不正常:
|
||||
- 如果Steam在显示登录界面后崩溃,你可能需要安装libappindicator库,例如运行`sudo apt install libappindicator1`。
|
||||
- 如果你选择记住密码,而Steam在下次启动时崩溃,你可能需要安装libnm库,例如运行`sudo apt install libnm0`。
|
||||
- Steam不能在正常的大界面模式下工作,因为Steam在浏览器模式使用的一些组件只能在64位平台上运行。所以请在查看选项卡中选择"小模式",否则Steam将无法正常显示列表。或者在启动Steam添加`+open steam://open/minigameslist`参数,这样Steam将会直接在小模式下启动。
|
||||
- 为了避免"libc.so.6 is absent"的错误,请添加环境变量`STEAMOS=1` 与 `STEAM_RUNTIME=1`。
|
||||
- 一些游戏(例如基于起源引擎的游戏:《传送门》、《半衰期2》)使用了libtcmalloc库,Box86会尝试检测它们并通过LD_PRELOAD预加载它们来获得更好的兼容性,虽然应该可以在没有上述功能的情况下工作,但保险起见,我们还是建议你安装它,例如运行`sudo apt install libtcmalloc-minimal4`。
|
||||
|
||||
Windows Steam 可以安装但目前不能运行。
|
||||
|
||||
----
|
||||
|
||||
关于Wine的注意事项
|
||||
----
|
||||
|
||||
Box86现在已经支持Wine。Wine的内建程序全部能运行,许多Windows 程序和游戏也运行良好。但是不要忘记大多数 Windows 游戏都使用 Direct3D,这可能需要完整的 OpenGL 驱动程序和尽可能高的配置文件(基于 ES2 后端的 gl4es 现在不能运行 Wine 的Direct3D组件)。
|
||||
注意:如果你想在 Raspberry Pi 3 或更早版本上用 Box86 运行 Wine,由于这些设备的内核默认使用 2G/2G 虚拟内存分配(2G 空间用于用户态程序,2G 空间用于内核),与需要访问内存地址 > 2G 的 Wine 程序不兼容。 因此,你需要重新配置内核以使用 3G/1G 的内存分配方式。
|
||||
|
||||
----
|
||||
|
||||
关于Vulkan的注意事项
|
||||
----
|
||||
|
||||
Box86已经封装了Vulkan。如果设备的系统有32位的Vulkan驱动程序,Box86会在需要时使用它。但请注意,由于作者目前拥有的硬件上的Vulkan支持有限,因此Vulkan封装库尚未经过太多测试。 Vulkan 1.0、1.1与一些扩展应该能工作。 但Vulkan 1.2还没有被实现。已经有一些在树莓派4上的Vulkan演示 (Sascha Willems 的演示中,为x86构建的demo与与直接为armhf构建的demo工作均正常)。但请注意,Pi4的Vulkan驱动程序目前不支持 dxvk(wine DirectX->Vulkan 兼容层),这不是Box86的问题,而是由于缺少扩展(硬件支持)与一些其他驱动问题。而在Panfrost上,PanVK尚不成熟,暂时没有用它测试dxvk。
|
||||
|
||||
----
|
||||
|
||||
结语
|
||||
----
|
||||
|
||||
我要感谢所有为 box86 开发做出贡献的人。
|
||||
贡献方式有很多种:代码贡献、财务帮助、捐赠捐赠和广告合作!
|
||||
以下感谢不分先后:
|
||||
* 代码贡献:rajdakin, icecream95, M-HT
|
||||
* 财务帮助:FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
|
||||
* 硬件捐赠:[Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [DragonBox](https://pyra-handheld.com/), [Novaspirit](https://www.youtube.com/channel/UCrjKdwxaQMSV_NDywgKXVmw), [HardKernel](https://www.hardkernel.com/), [TwisterOS team](https://twisteros.com/)
|
||||
* 为本项目持续的宣传:([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS team](https://twisteros.com/), [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg)
|
||||
|
||||
我还要感谢很多人,即使他们只参与了一次本项目。
|
||||
|
||||
(如果你的项目中使用了Box86,请不要忘记提及!)
|
||||
@@ -0,0 +1,143 @@
|
||||

|
||||
|
||||
Емулятор простіра користувача x86_64 із родзинкою
|
||||
|
||||
[Дивитись журнал змін](https://github.com/ptitSeb/box86/blob/master/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box86/blob/master/docs/README_CN.md) | [Українська](https://github.com/ptitSeb/box86/blob/master/docs/README_UK.md) | [Повідомити про помилку](https://github.com/ptitSeb/box86/issues/new)
|
||||
|
||||
     
|
||||
|
||||
----
|
||||
|
||||
Box86 дозволяє запускати x86 Linux програми (наприклад, ігри) на системах Linux відмінних від x86, наприклад ARM (хост-система має мати 32-розрядний порядок редагування).
|
||||
|
||||
Вам *ПОТРІБНА* 32-розрядна підсистема для запуску та створення Box86. Box86 марний лише на 64-розрядних системах. Крім того, вам *ПОТРІБЕН* 32-розрядний інструментарій для створення Box86. Ланцюжок інструментів, який підтримує лише 64-розрядні версії, не компілює Box86, і ви отримаєте помилки (зазвичай на aarch64 ви отримуєте що «-marm» не розпізнається, і вам знадобиться середовище з мультиархітектурою або chroot).
|
||||
|
||||
Оскільки Box86 використовує рідні версії деяких «системних» бібліотек, таких як libc, libm, SDL і OpenGL, його легко інтегрувати та використовувати з більшістю програм, а продуктивність у багатьох випадках може бути напрочуд високою. Подивіться на цей стендовий аналіз для прикладу [тут](https://box86.org/index.php/2021/06/game-performances/). Це також означає, що вам знадобиться 32-бітний простір користувача на 64-бітній ОС, наприклад `armhf` поверх `aarch64` 64-бітної ОС.
|
||||
|
||||
Більшість x86-ігор потребують OpenGL, тому на платформах ARM може знадобитися таке рішення, як [gl4es](https://github.com/ptitSeb/gl4es). (Деякі платформи ARM підтримують лише OpenGL ES і/або їх реалізація OpenGL хитра. (див. OpenGL на Android))
|
||||
|
||||
Box86 інтегрується з DynaRec (динамічний рекомпілятор) для платформ ARM64 і RV64 забезпечуючи підвищення швидкості в 5-10 разів, ніж використання лише інтерпретатора. Деякі високорівневі відомості про те, як працює DynaRec, можна знайти [тут](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
|
||||
|
||||
Багато ігор просто працюють без особливих налаштувань, наприклад: WorldOfGoo, Airline Tycoon Deluxe і FTL. Багато ігор GameMaker Linux також працюють нормально. (є довгий список, серед них UNDERTALE, A Risk of Rain і Cook Serve Delicious). Ігри Unity3D також працюють добре, але вимога OpenGL може бути проблемою на деяких платформах ARM.
|
||||
|
||||
Якщо ви серйозно ставитеся до розробки Box86, вам слід встановити ccache та створити Box86 з ним. (Використовуйте, наприклад, ccmake.)
|
||||
Щоб увімкнути TRACE (тобто скидання в stdout усіх окремих виконаних інструкцій x86 із дампом регістрів), вам також знадобиться [бібліотека Zydis](https://github.com/zyantific/zydis), доступна у вашій системі.
|
||||
|
||||
Деякі внутрішні коди операцій x86 використовують частини «Бібліотеки емулятора Realmode X86», дивіться [x86primop.c](../src/emu/x86primop.c) для детальної інформації про авторські права.
|
||||
|
||||
----
|
||||
Компіляція/Встановлення
|
||||
----
|
||||
> Інструкцію зі складання Box86 можна знайти [тут](COMPILE.md).\
|
||||
> Інструкцію з встановлення Wine для Box86 можна знайти [тут](X86WINE.md).
|
||||
|
||||
----
|
||||
|
||||
Ось 6 відео, перші 2 відео – це відео "Airline Tycoon Deluxe" і "Heretic 2", які працюють на GigaHertz OpenPandora (друге використовує Dynarec), а наступні 2 відео – це відео "Bit.Trip.Runner" і "Neverwinter Night", які працюють на ODroid XU4 (без dynarec), а останні 2 відео на Pi4: Shovel Knight (відео від @ITotalJustice) і Freedom Planet (відео від @djazz), також без Dynarec.
|
||||
|
||||
|
||||
[](https://www.youtube.com/watch?v=bLt0hMoFDLk) [](https://www.youtube.com/watch?v=MM7kWYts7IA) [](https://www.youtube.com/watch?v=8hr71S029Hg) [](https://www.youtube.com/watch?v=B4YN37z3-ws) [](https://www.youtube.com/watch?v=xk8Q30mxqPg) [](https://www.youtube.com/watch?v=_QMRMVvYrqU)
|
||||
|
||||
Ви можете знайти багато інших відео про Box86 у YouTube каналах [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) або [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA).
|
||||
|
||||
Список сумісності доступний тут: https://github.com/ptitSeb/box86-compatibility-list/issues
|
||||
|
||||
<img src="img/Box86Icon.png" width="96" height="96">
|
||||
|
||||
Логотип і піктограма зроблені @grayduck, дякую!
|
||||
|
||||
Зауважте, що цей проект не слід плутати з [86box](https://github.com/86Box/86Box), гарним емулятором "повної системи", що спеціалізується на ранньому (до відносно недавньому) апаратному забезпеченні ПК.
|
||||
|
||||
----
|
||||
|
||||
Використання
|
||||
----
|
||||
|
||||
Є кілька змінних середовища для керування поведінкою Box86.
|
||||
|
||||
Дивіться [тут](USAGE.md) для перегляду всіх змінних середовища та того, що вони роблять.
|
||||
|
||||
Примітка: Dynarec від Box86 використовує механізм із захистом пам’яті та обробником сигналу помилки сегментів для обробки JIT коду. Простіше кажучи, якщо ви хочете використовувати GDB для налагодження запущеної програми, яка використовує JIT-код (наприклад, mono/Unity3D), ви все одно матимете багато «звичайних» помилок сегментів. Пропонується використовувати щось на зразок `handle SIGSEGV nostop` в GDB, щоб не зупинятися на кожній помилці сегмента, і, можливо, поставити точку зупину всередині `my_memprotectionhandler` в `signals.c`, якщо ви хочете перехопити помилки сегментів.
|
||||
|
||||
----
|
||||
|
||||
Історія версій/Журнал змін
|
||||
----
|
||||
|
||||
Історія версій доступна [тут](docs/CHANGELOG.md).
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо 64-розрядних платформ
|
||||
----
|
||||
|
||||
Оскільки Box86 працює шляхом прямого перекладу викликів функцій із x86 на хост-систему, хост-система (на якій працює Box86) повинна мати 32-розрядні бібліотеки. Box86 не містить 32-біт <-> 64-біт перекладу. Отже, щоб запустити Box86, наприклад, на платформі ARM64, вам потрібно буде зібрати Box86 для 32-бітної ARM, а також потрібно мати chroot з 32-бітними бібліотеками.
|
||||
|
||||
Якщо ви дивитесь на 64-розрядну версію box86, подивіться на [Box64](https://github.com/ptitSeb/box64): він може запускати двійкові файли x86_64 на 64-розрядних платформах. Але зауважте, що вам все одно потрібен Box86 (і 32-розрядний chroot) для запуску бінарних файлів x86 (як це також трапляється в реальному Linux x86_64, для запуску якого потрібні бібліотеки x86 і двійковий файл в multiarch).
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо конфігурації Box86
|
||||
----
|
||||
|
||||
Box86 тепер має конфігураційні файли. Завантажуються 2 файли: `/etc/box4.box86rc` і `~/.box86rc`. Обидва файли мають однаковий синтаксис і в основному є файлами ini. Розділ у квадратних дужках визначає назву процесу, а решта — встановлють змінну середовища. Подивіться на [використання](docs/USAGE.md), щоб дізнатися, які параметри можна використовувати. Box86 поставляється з файлом за замовчуванням, який слід інсталювати для кращої стабільності. Файл знаходиться в `system/box86.box86rc` і має бути встановлено в `/etc/box86.box86rc`. Якщо з певних причин ви не хочете встановлювати цей файл у `/etc`, принаймні скопіюйте його в `~/.box86rc` або гра може не працювати належним чином. Зауважте, що пріоритетом є: `~/.bashrc` > `/etc/box86.box86rc` > командний рядок
|
||||
Таким чином, ваші налаштування в `~/.bashrc` можуть замінити налаштування з вашого командного рядка...
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо емуляції ігор Unity
|
||||
----
|
||||
|
||||
Запуск ігор Unity має працювати, але ви також повинні зауважити, що для багатьох ігор Unity3D потрібен OpenGL 3+, який може бути складно забезпечити на ARM SBC (одноплатних комп’ютерах). Крім того, багато нових ігор Unity3D (наприклад, KSP) використовують стиснуті текстури BC7, які не підтримуються багатьма інтегрованими GPU ARM.
|
||||
Підказка: в Pi4 використовуйте `MESA_GL_VERSION_OVERRIDE=3.2`, а в Panfrost — `PAN_MESA_DEBUG=gl3`, щоб використовувати вищий профіль, якщо гра запускається, а потім завершується, перш ніж щось показує.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Steam
|
||||
----
|
||||
|
||||
Linux версія Steam тепер може працювати з Box86, але вам також потрібен Box64, щоб його можна було повністю використовувати.
|
||||
Рекомендується запускати Steam у small режимі, оскільки він використовує менше пам’яті, але steamwebhelper (64-бітний процес) усе одно завантажуватиметься, навіть якщо він не використовується.
|
||||
Екран входу не може працювати без steamwebhelper, і буде показувати лише порожні вікна без належного налаштування box64 у системі.
|
||||
Зауважте, що Steam використовуватиме багато пам’яті та ледве поміститься в систему з 4 ГБ оперативної пам’яті. Він більше не працюватиме в системі з меншим об’ємом пам’яті (як обхідний шлях, створіть файл підкачки, увійдіть і поставте прапорець «запам’ятати мене», використовуйте box64rc, щоб вимкнути steamwebhelper і запускати лише в малому режимі без підкачки після першого входу в систему)
|
||||
Останнє зауваження: Steam BigPicture працюватиме, але також потрібен steamwebhelper (і box64) і багато пам’яті. Він не запуститься в системі лише з 4 ГБ оперативної пам’яті без файлу підкачки.
|
||||
- Якщо у вас виникли проблеми зі встановленням Steam, ви можете знайти `install_steam.sh` у кореневій папці сховища box86. Цей простий скрипт завантажить і встановить Steam у вашу домашню папку, а потім створить ярлик steam у `/usr/local/bin` (для цього він запитає дозвіл sudo). Просто використовуйте `steam` для запуску після встановлення. Зауважте, що інсталяція, яка знаходиться в папці Home, працюватиме лише для одного користувача. Не використовуйте цей скрипт, якщо вам потрібна багатокористувацька інсталяція.
|
||||
- Щоб уникнути повідомлення «libc.so.6 відсутній», ви можете використовувати `STEAMOS=1` і `STEAM_RUNTIME=1` як змінні середовища (воно автоматично з’являється, якщо ви використовували сценарій `install_steam.sh`)
|
||||
|
||||
Щоб вимкнути `steamwebhelper`, коли Box64 встановлений і працює, створіть (або відредагуйте) `~/.box64rc` і додайте у ньому:
|
||||
```
|
||||
[steamwebhelper]
|
||||
BOX64_EXIT=1
|
||||
```
|
||||
І тоді `steamwebhelper` буде вимкнено. Прокоментуйте `#` ці 2 рядки, щоб увімкнути його знову.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Wine
|
||||
----
|
||||
|
||||
Wine тепер підтримується. Інтегровани програми Wine працює як і багато програм та ігор для Windows. Не забувайте, що більшість ігор для Windows використовують Direct3D, для цього може знадобитися повний драйвер OpenGL і якомога більш високий профіль (і gl4es з бекендом ES2 наразі мають проблеми з Wine).
|
||||
Примітка: якщо ви плануєте використовувати box86 з Wine на Raspberry Pi 3 або ранішої версії, ці моделі використовують ОС за замовчуванням, яка має ядро з розділенням 2/2 (тобто 2G місця для програми користувача та 2 Г місця для ядра). Це несумісно з програмами Wine, яким потрібен доступ до пам’яті > 2 Гб адреси. Тож вам потрібно буде переналаштувати ядро для розділення 3G/1G.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Vulkan
|
||||
----
|
||||
|
||||
Box86 вже використовує Vulkan. Якщо у вашій системі є 32-розрядний драйвер Vulkan, Box86 використовуватиме його за потреби. Профіль 1.0, 1.1, 1.2 і 1.3, з деякими розширеннями, має бути в порядку. DXVK, включаючи 2.0, працює. Я знаю, що деякі демонстраційні версії працюють на Pi4 (демонстраційні версії Sascha Willems для x86 працюють так само, як якщо б створювати безпосередньо на armhf). Зауважте, що драйвер Vulkan для Pi4 наразі НЕ підтримує DXVK (обгортка Wine DirectX->Vulkan). Це не проблема Box86, у драйвері відсутні розширення (підтримка апаратного забезпечення) та кілька інших речей, через які DXVK не працює на pi4. З боку Panfrost, PanVK трохи молодий, і я ще не тестував DXVK з ним.
|
||||
|
||||
----
|
||||
Останнє слово
|
||||
----
|
||||
|
||||
Я хочу подякувати всім, хто зробив внесок у розвиток box86.
|
||||
Є багато способів зробити свій внесок: код, фінанси, апаратне забезпечення та реклама!
|
||||
Отже, без особливого порядку, я хочу подякувати:
|
||||
* За основний внесок у код: rajdakin, icecream95, M-HT
|
||||
* За великий фінансовий внесок: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
|
||||
* За внесок у апаратне забезпечення: [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [DragonBox](https://pyra-handheld.com/), [Novaspirit](https://www.youtube.com/channel/UCrjKdwxaQMSV_NDywgKXVmw), [HardKernel](https://www.hardkernel.com/), [Команда TwisterOS](https://twisteros.com/)
|
||||
* За постійну рекламу Box86: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[Команда TwisterOS](https://twisteros.com/), [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg)
|
||||
|
||||
І я також дякую багатьом іншим людям, які хоч раз брали участь у проекті.
|
||||
|
||||
(Якщо ви використовуєте Box86 у своєму проекті, будь ласка, не забудьте згадати про це!)
|
||||
Executable
+313
@@ -0,0 +1,313 @@
|
||||
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variables to control Box86 behaviour.
|
||||
Env. var with * can also be put inside box64rc files
|
||||
|
||||
#### BOX86_LOG *
|
||||
Controls the Verbosity level of the logs
|
||||
* 0: NONE : No message (except some fatal error). (Default.)
|
||||
* 1: INFO : Show some minimum log (Example: librairies not found)
|
||||
* 2: DEBUG : Details a lot of stuff (Example: relocations or functions called).
|
||||
* 3: DUMP : All DEBUG plus DUMP of all ELF Info (so same as `BOX86_LOG=2 BOX86_DUMP=1`)
|
||||
|
||||
#### BOX86_DUMP *
|
||||
Controls the Dump of elf content
|
||||
* 0: No dump of elf information (Default)
|
||||
* 1: Dump elf sections and relocations and other information (also active if using `BOX86_LOG=3`)
|
||||
|
||||
#### BOX86_ROLLING_LOG *
|
||||
Show last few wrapped function call when a Signal is caught
|
||||
* 0: No last function call printed (Default.)
|
||||
* 1: Last 16 wrapped functions calls printed when a signal is printed. Incompatible with BOX86_LOG>1 (may need BOX86_SHOWSEGV=1 also)
|
||||
* N: Last N wrapped functions calls printed when a signal is printed. Incompatible with BOX86_LOG>1 (may need BOX86_SHOWSEGV=1 also)
|
||||
|
||||
#### BOX86_NOBANNER
|
||||
Disables Box86 printing its version and build
|
||||
* 0 : Enable printing its banner. (Default.)
|
||||
* 1 : Disable printing its banner.
|
||||
|
||||
#### BOX86_LD_LIBRARY_PATH *
|
||||
Path to look for x86 libraries. Default is current folder and `lib` in current folder.
|
||||
Also, `/usr/lib/i386-linux-gnu` and `/lib/i386-linux-gnu` are added if they exist.
|
||||
|
||||
#### BOX86_PATH *
|
||||
Path to look for x86 executable. Default is current folder and `bin` in current folder.
|
||||
|
||||
#### BOX86_DLSYM_ERROR *
|
||||
Enables/Disables the logging of `dlsym` errors.
|
||||
* 0 : Don't log `dlsym` errors. (Default.)
|
||||
* 1 : Log dlsym errors.
|
||||
|
||||
#### BOX86_TRACE_FILE *
|
||||
Send all log and trace to a file instead of `stdout`
|
||||
Also, if name contains `%pid` then this is replaced by the actual PID of box86 instance
|
||||
Use `stderr` to use this instead of default `stdout`
|
||||
|
||||
#### BOX86_TRACE *
|
||||
Only on build with trace enabled. Trace allow the logging of all instruction executed, along with register dump
|
||||
* 0 : No trace. (Default.)
|
||||
* 1 : Trace enabled. Trace start after the initialisation of all depending libraries is done.
|
||||
* symbolname : Trace only `symbolname` (trace is disable if the symbol is not found).
|
||||
* 0xXXXXXXX-0xYYYYYYY : Trace only between the 2 addresses.
|
||||
|
||||
#### BOX86_TRACE_INIT *
|
||||
Use BOX86_TRACE_INIT instead of BOX_TRACE to start trace before the initialisation of libraries and the running program
|
||||
* 0 : No trace. (Default.)
|
||||
* 1 : Trace enabled. The trace start with the initialisation of all depending libraries is done.
|
||||
|
||||
#### BOX86_TRACE_START *
|
||||
Only on builds with trace enabled.
|
||||
* NNNNNNN : Start trace only after NNNNNNNN opcode execute (number is an `uint64_t`).
|
||||
|
||||
#### BOX86_TRACE_XMM *
|
||||
Only on builds with trace enabled.
|
||||
* 0 : The XMM (i.e. SSE/SSE2) register will not be logged with the general and x86 registers. (Default.)
|
||||
* 1 : Dump the XMM registers.
|
||||
|
||||
#### BOX86_TRACE_EMM *
|
||||
Only on builds with trace enabled.
|
||||
* 0 : The EMM (i.e. MMX) register will not be logged with the general and x86 registers. (Default.)
|
||||
* 1 : Dump the EMM registers.
|
||||
|
||||
#### BOX86_LOAD_ADDR *
|
||||
Try to load at 0xXXXXXX main binary (if binary is a PIE)
|
||||
* 0xXXXXXXXX : The load address . (Only active on PIE programs.)
|
||||
|
||||
#### BOX86_NOSIGSEGV *
|
||||
Disable handling of SigSEGV. (Very useful for debugging.)
|
||||
* 0 : Let the x86 program set sighandler for SEGV (Default.)
|
||||
* 1 : Disable the handling of SigSEGV.
|
||||
|
||||
#### BOX86_NOSIGILL *
|
||||
Disable handling of SigILL (to ease debugging mainly).
|
||||
* 0 : Let x86 program set sighandler for Illegal Instruction
|
||||
* 1 : Disables the handling of SigILL
|
||||
|
||||
#### BOX86_X11COLOR16 *
|
||||
PANDORA only: Try converting X11 color from 32 bits to 16 bits (to avoid light green on light cyan windows).
|
||||
* 0 : Don't touch X11 colors. (Default.)
|
||||
* 1 : Change colors arguments in XSetForeground, XSetBackground and XCreateGC.
|
||||
|
||||
#### BOX86_X11THREADS *
|
||||
Call XInitThreads when loading X11. (This is mostly for old Loki games with the Loki_Compat library.)
|
||||
* 0 : Don't force call XInitThreads. (Default.)
|
||||
* 1 : Call XInitThreads as soon as libX11 is loaded.
|
||||
|
||||
#### BOX86_X11GLX *
|
||||
Force libX11's GLX extension to be present.
|
||||
* 0 : Do not force libX11's GLX extension to be present.
|
||||
* 1 : GLX will always be present when using XQueryExtension. (Default.)
|
||||
|
||||
#### BOX86_DYNAREC_DUMP *
|
||||
Enables/disables Box86's Dynarec's dump.
|
||||
* 0 : Disable Dynarec's blocks dump. (Default.)
|
||||
* 1 : Enable Dynarec's blocks dump.
|
||||
* 2 : Enable Dynarec's blocks dump with some colors.
|
||||
|
||||
#### BOX86_DYNAREC_LOG *
|
||||
Set the level of DynaRec's logs.
|
||||
* 0 : NONE : No Logs for DynaRec. (Default.)
|
||||
* 1 :INFO : Minimum Dynarec Logs (only unimplemented OpCode).
|
||||
* 2 : DEBUG : Debug Logs for Dynarec (with details on block created / executed).
|
||||
* 3 : VERBOSE : All of the above plus more.
|
||||
|
||||
#### BOX86_DYNAREC *
|
||||
Enables/Disables Box86's Dynarec.
|
||||
* 0 : Disables Dynarec.
|
||||
* 1 : Enable Dynarec. (Default.)
|
||||
|
||||
#### BOX86_DYNAREC_TRACE *
|
||||
Enables/Disables trace for generated code.
|
||||
* 0 : Disable trace for generated code. (Default.)
|
||||
* 1 : Enable trace for generated code (like regular Trace, this will slow down the program a lot and generate huge logs).
|
||||
|
||||
#### BOX86_NODYNAREC *
|
||||
Forbid dynablock creation in the interval specified (helpfull for debugging behaviour difference between Dynarec and Interpretor)
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : define the interval where dynablock cannot start (inclusive-exclusive)
|
||||
|
||||
#### BOX86_DYNAREC_TEST *
|
||||
Dynarec will compare it's execution with the interpreter (super slow, only for testing)
|
||||
* 0 : No comparison
|
||||
* 1 : Each opcode runs on interepter and on Dynarec, and regs and memory are compared and print if different
|
||||
|
||||
#### BOX86_DYNAREC_BIGBLOCK *
|
||||
Enables/Disables Box86's Dynarec building BigBlock.
|
||||
* 0 : Don't try to build block as big as possible (can help program using lots of thread and a JIT, like C#/Unity) (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 1 : Build Dynarec block as big as possible (Default.)
|
||||
* 2 : Build Dynarec block bigger (don't stop when block overlaps)
|
||||
|
||||
#### BOX86_DYNAREC_FORWARD *
|
||||
Define Box86's Dynarec max allowed forward value when building Block.
|
||||
* 0 : No forward value. When current block end, don't try to go further even if there are previous forward jumps
|
||||
* XXX : Allow up to XXXX bytes of gap when building a Block after the block end to next forward jump (Default: 128)
|
||||
|
||||
#### BOX86_DYNAREC_STRONGMEM *
|
||||
Enable/Disable simulation of Strong Memory model
|
||||
* 0 : Don't try anything special (Default.)
|
||||
* 1 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model
|
||||
|
||||
#### BOX86_DYNAREC_X87DOUBLE *
|
||||
Force the use of Double for x87 emulation
|
||||
* 0 : Try to use float when possible for x87 emulation (faster, Default)
|
||||
* 1 : Only use Double for x87 emulation (slower, may be needed for some specific games, like Crysis were it's enable automatically)
|
||||
|
||||
#### BOX86_DYNAREC_FASTNAN *
|
||||
Enable/Disable generation of -NAN
|
||||
* 0 : Generate -NAN like on x86 (slower, more x86 accurate)
|
||||
* 1 : Don't do anything special with NAN, to go as fast as possible (Default)
|
||||
|
||||
#### BOX86_DYNAREC_FASTROUND *
|
||||
Enable/Disable generation of precise x86 rounding
|
||||
* 0 : Generate float/double -> int rounding like on x86
|
||||
* 1 : Don't do anything special with edge case Rounding, to go as fast as possible (no INF/NAN/Overflow -> MIN_INT conversion) (faster, Default)
|
||||
|
||||
#### BOX86_DYNAREC_SAFEFLAGS *
|
||||
Handling of flags on CALL/RET opcodes
|
||||
* 0 : Treat CALL/RET as if it never needs any flags (faster but may have side-effects)
|
||||
* 1 : most of RET will need flags, most of CALLS will not (Default)
|
||||
* 2 : All CALL/RET will need flags (slower, but might be needed. Automatically enabled for Vara.exe)
|
||||
|
||||
#### BOX86_DYNAREC_HOTPAGE *
|
||||
Handling of HotPage (Page beeing both executed and writen)
|
||||
* 0 : Don't track hotpage
|
||||
* 1-255 : Trak HotPage, and disable execution of a page beeing writen for N attempts (default is 16)
|
||||
|
||||
#### BOX86_DYNAREC_FASTPAGE *
|
||||
Will use a faster handling of HotPage (Page being both executed and written)
|
||||
* 0 : use regular hotpage (Default)
|
||||
* 1 : Use faster hotpage, taking the risk of running obsolete JIT code (might be faster, but more prone to crash)
|
||||
|
||||
#### BOX86_DYNAREC_BLEEDING_EDGE *
|
||||
Detect MonoBleedingEdge and apply conservative settings
|
||||
* 0 : Don't detect MonoBleedingEdge
|
||||
* 1 : Detect MonoBleedingEdge, and apply BIGBLOCK=0 STRONGMEM=1 if detected (Default)
|
||||
|
||||
#### BOX86_DYNAREC_JVM *
|
||||
Detect libjvm and apply conservative settings
|
||||
* 0 : Don't detect libjvm
|
||||
* 1 : Detect libjvm, and apply BIGBLOCK=0 STRONGMEM=1 if detected (Default)
|
||||
|
||||
#### BOX86_DYNAREC_WAIT *
|
||||
Behavior with FillBlock is not availble (FillBlock build Dynarec blocks and is not multithreaded)
|
||||
* 0 : Dynarec will not wait for FillBlock to ready and use Interpreter instead (might speedup a bit massive multithread or JIT programs)
|
||||
* 1 : Dynarec will wait for FillBlock to be ready (Default)
|
||||
|
||||
#### BOX86_SSE_FLUSHTO0 *
|
||||
Handling of SSE Flush to 0 flags
|
||||
* 0 : Just track the flag (Default)
|
||||
* 1 : Direct apply of SSE Flush to 0 flag
|
||||
|
||||
#### BOX86_X87_NO80BITS *
|
||||
Handling of x87 80bits long double
|
||||
* 0 : Try to handle 80bits long double as precise as possible (Default)
|
||||
* 1 : Handle them as double
|
||||
|
||||
#### BOX86_LIBCEF *
|
||||
Detect libcef and apply malloc_hack settings
|
||||
* 0 : Don't detect libcef
|
||||
* 1 : Detect libcef, and apply MALLOC_HACK=2 if detected (Default)
|
||||
|
||||
#### BOX86_LIBGL *
|
||||
* libXXXX set the name for libGL (defaults to libGL.so.1).
|
||||
* /PATH/TO/libGLXXX : Sets the name and path for libGL
|
||||
You can also use SDL_VIDEO_GL_DRIVER
|
||||
|
||||
#### BOX86_LD_PRELOAD *
|
||||
* XXXX[:YYYYY] force loading XXXX (and YYYY...) libraries with the binary
|
||||
PreLoaded libs can be emulated or native, and are treated the same way as if they were comming from the binary (not that using this inside a rcfile might not work if the process needs to be renamed, for example for Wine process)
|
||||
|
||||
#### BOX86_EMULATED_LIBS *
|
||||
* XXXX[:YYYYY] force lib XXXX (and YYYY...) to be emulated (and not wrapped)
|
||||
Some games uses an old version of some libraries, with an ABI incompatible with native version.
|
||||
Note that LittleInferno for example is auto detected, and libvorbis.so.0 is automatical added to emulated libs, and same for Don't Starve (and Together / Server variant) that use an old SDL2 too
|
||||
|
||||
#### BOX86_ALLOWMISSING_LIBS *
|
||||
Allow Box86 to continue even if a library is missing (renamed from BOX86_ALLOWMISSINGLIBS).
|
||||
* 0 : Box86 will stop if a library cannot be loaded. (Default.)
|
||||
* 1 : Continue even if a needed library cannot be loaded. Unadvised, this will, in most cases, crash later on.
|
||||
|
||||
#### BOX86_ALLOWMISSING_SYMBOLS *
|
||||
Allow dlopen with RTLD_NOW flag to not resolve all symbols.
|
||||
* 0 : Box86 will stop if a library have unresolved symbols. (Default.)
|
||||
* 1 : Continue even if a needed library have unresolved symbols (like symbols not yet wrapped).
|
||||
|
||||
#### BOX86_PREFER_WRAPPED *
|
||||
Box86 will use wrapped libs even if the lib is specified with absolute path
|
||||
* 0 : Try to use emulated libs when they are defined with absolute path (Default.)
|
||||
* 1 : Use Wrapped native libs even if path is absolute
|
||||
|
||||
#### BOX86_PREFER_EMULATED *
|
||||
Box86 will prefer emulated libs first (execpt for glibc, alsa, pulse, GL, vulkan and X11
|
||||
* 0 : Native libs are prefered (Default.)
|
||||
* 1 : Emulated libs are prefered (Default for program running inside pressure-vessel)
|
||||
|
||||
#### BOX86_NOPULSE *
|
||||
Disables the load of pulseaudio libraries.
|
||||
* 0 : Load pulseaudio libraries if found. (Default.)
|
||||
* 1 : Disables the load of pulse audio libraries (libpulse and libpulse-simple), both the native library and the x86 library
|
||||
|
||||
#### BOX86_NOGTK *
|
||||
Disables the loading of wrapped GTK libraries.
|
||||
* 0 : Load wrapped GTK libraries if found. (Default.)
|
||||
* 1 : Disables loading wrapped GTK libraries.
|
||||
|
||||
#### BOX86_NOVULKAN *
|
||||
Disables the load of vulkan libraries.
|
||||
* 0 : Load vulkan libraries if found.
|
||||
* 1 : Disables the load of vulkan libraries, both the native and the i386 version (can be useful on Pi4, where the vulkan driver is not quite there yet.)
|
||||
|
||||
#### BOX86_ENV
|
||||
* XXX=yyyy
|
||||
will add XXX=yyyy env. var.
|
||||
|
||||
#### BOX86_ENV1
|
||||
* XXX=yyyy
|
||||
will add XXX=yyyy env. var. and continue with BOX86_ENV2 ... until var doesn't exist
|
||||
|
||||
#### BOX86_FIX_64BIT_INODES *
|
||||
Fix/Don't fix 64bit inodes
|
||||
* 0 : Don't fix 64bit inodes. (Default.)
|
||||
* 1 : Fix 64bit inodes. Helps when running on Filesystems with 64bit inodes. Is useful when a program uses API functions which doesn't support it and the program doesn't use inodes information.
|
||||
|
||||
#### BOX86_SHOWSEGV *
|
||||
Show Segfault signal even if a signal handler is present
|
||||
* 0 : Don't force segfault details when a signal handler is install (Default, to limit message spamming)
|
||||
* 1 : Show segfault details
|
||||
|
||||
#### BOX86_SHOWBT *
|
||||
Show a backtrace (native and emulated) on Signal
|
||||
* 0 : Don't show any backtrace (Default.)
|
||||
* 1 : Show native backtrace when a signal is dumped (not available on Andoid build)
|
||||
|
||||
#### BOX86_BASH *
|
||||
Define x86 bash to launch script
|
||||
* yyyy
|
||||
Will use yyyy as x86 bash to launch script. yyyy needs to be a full path to a valid x86 version of bash. Note that is Box64 is available, an x86_64 version of bash can also be used. Also, BOX64_BASH env. var. will also be read if BOX86_BASH is not defined.
|
||||
|
||||
#### BOX86_BOX64
|
||||
Define where to find box64 binary
|
||||
* yyyy
|
||||
Will use yyyy as x86_64 interpretor, to launch x64_64 binaries
|
||||
|
||||
#### BOX86_JITGDB *
|
||||
|
||||
* 0 : Just print the Segfault message on segfault (default)
|
||||
* 1 : Launch `gdb` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process and go in an endless loop, waiting.
|
||||
When in gdb, you need to find the correct thread yourself (the one with `my_box86signalhandler` in is stack)
|
||||
then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box86signalhandler`,
|
||||
just before the printf of the Segfault message. Then simply
|
||||
`set waiting=0` to exit the infinite loop.
|
||||
* 2 : Launch `gdbserver` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process, and go in an endless loop, waiting.
|
||||
Use `gdb /PATH/TO/box86` and then `target remote 127.0.0.1:1234` to connect to the gdbserver (or use actual IP if not on the machine). After that, the procedure is the same as with ` BOX86_JITGDB=1`.
|
||||
This mode can be usefullwhen programs redirect all console output to a file (like Unity3D Games)
|
||||
|
||||
#### BOX86_NORCFILES
|
||||
If the env var exist, no rc files (like /etc/box86.box86rc and ~/.box86rc) will be loaded
|
||||
|
||||
#### BOX86_NOSANDBOX
|
||||
* 0 : Nothing special
|
||||
* 1 : Added "--no-sandbox" to command line arguments (usefull for chrome based programs)
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
# Installing Wine (and winetricks)
|
||||
_TwisterOS users: Wine, winetricks, and Box86 are already installed in TwisterOS. You do not have to install anything._
|
||||
|
||||
_Raspberry Pi users: Wine requires a 3G/1G split memory kernel. Raspberry Pi OS for the Pi 4 already has a 3G/1G split kernel and works with Wine, but **the Pi 3B+ and earlier models have a 2G/2G kernel and require a custom-compiled 3G/1G kernel to get Wine working.**_
|
||||
|
||||
See installation steps below (in the [Examples](#examples) section).
|
||||
|
||||
Using Wine with Box86 allows (x86) Windows programs to run on ARM Linux computers (for x64, use [box64](https://github.com/ptitSeb/box64) & wine-amd64 with an `aarch64` processor).
|
||||
|
||||
Box86 needs `wine-i386` to be installed **manually** on ARM devices. Even though `wine-armhf` is available in many repo's on ARM devices (ie using _apt-get_ will attempt to install `wine-armhf` by default), `wine-armhf` will not work with Box86. Note that manual installation is required since using `multiarch` will result in your ARM device thinking it needs to install lots of i386 dependencies to make `wine-i386` work. The "twist" in Box86 is that Box86 "wraps" many of Wine's core Linux i386 libraries (.so files) so that their calls are interpretable by your ARM device's other armhf Linux system libraries. Also note that wrapping libraries is an ongoing process throughout Box86 development and that some programs may not run properly until all of their i386 library dependencies are wrapped.
|
||||
|
||||
Installation files for Wine can be found in the [WineHQ repository](https://dl.winehq.org/wine-builds/debian/dists/buster/main/binary-i386/), the [TwisterOS FAQ](https://twisteros.com/faq.html) page, or the [PlayOnLinux website repository](https://www.playonlinux.com/wine/). Box86 requires the "i386" (x86) version of Wine even though we are installing it on an ARM processor.
|
||||
|
||||
## Overview
|
||||
The general procedure for installing Wine for Box86 is to...
|
||||
- Download all the install files (.deb, .zip, or even .pol files) for the version of Wine you wish to install
|
||||
- Unzip or dpkg the install files into one folder
|
||||
- Move that folder to the directory that you wish Wine to run from (in TwisterOS, this is `~/wine/` by default)
|
||||
- If you are running box86/i386-wine on a 64bit ARM OS (aarch64), you will also have to install some extra armhf libraries.
|
||||
- Go to `/usr/local/bin` and make symlinks or scripts that will point to your main wine binaries (`wine`, `winecfg`, and `wineserver`).
|
||||
- Boot wine to create a new wineprefix (`wine wineboot`).
|
||||
- Download winetricks (which is simply a very complicated bash script), make it executable, then copy it to `/usr/local/bin`.
|
||||
|
||||
## Examples
|
||||
### Installing Wine for Box86 on Raspberry Pi OS from Twister OS FAQ .tgz files
|
||||
_Links from the [TwisterOS FAQ](https://twisteros.com/faq.html)_
|
||||
|
||||
This installs Wine v5.13 (which is the version of Wine that comes pre-installed in TwisterOS). When submitting bug reports, other Box86 users may assume you are using this version of Wine unless you specify otherwise.
|
||||
```
|
||||
# Backup any old wine installations
|
||||
sudo mv ~/wine ~/wine-old
|
||||
sudo mv ~/.wine ~/.wine-old
|
||||
sudo mv /usr/local/bin/wine /usr/local/bin/wine-old
|
||||
sudo mv /usr/local/bin/wineboot /usr/local/bin/wineboot-old
|
||||
sudo mv /usr/local/bin/winecfg /usr/local/bin/winecfg-old
|
||||
sudo mv /usr/local/bin/wineserver /usr/local/bin/wineserver-old
|
||||
|
||||
# Download, extract wine, and install wine (last I checked, the Twister OS FAQ page had Wine 5.13-devel)
|
||||
wget https://twisteros.com/wine.tgz -O ~/wine.tgz
|
||||
tar -xzvf ~/wine.tgz
|
||||
rm ~/wine.tgz # clean up
|
||||
|
||||
# Install shortcuts (make launcher & symlinks. Credits: grayduck, Botspot)
|
||||
echo -e '#!/bin/bash\nsetarch linux32 -L '"$HOME/wine/bin/wine "'"$@"' | sudo tee -a /usr/local/bin/wine >/dev/null # Create a script to launch wine programs as 32bit only
|
||||
#sudo ln -s ~/wine/bin/wine /usr/local/bin/wine # You could also just make a symlink, but box86 only works for 32bit apps at the moment
|
||||
sudo ln -s ~/wine/bin/wineboot /usr/local/bin/wineboot
|
||||
sudo ln -s ~/wine/bin/winecfg /usr/local/bin/winecfg
|
||||
sudo ln -s ~/wine/bin/wineserver /usr/local/bin/wineserver
|
||||
sudo chmod +x /usr/local/bin/wine /usr/local/bin/wineboot /usr/local/bin/winecfg /usr/local/bin/wineserver
|
||||
|
||||
# Boot wine (make fresh wineprefix in ~/.wine )
|
||||
wine wineboot
|
||||
```
|
||||
|
||||
### Installing Wine for Box86 on Raspberry Pi OS from WineHQ .deb files
|
||||
_Links from the [WineHQ repo](https://dl.winehq.org/wine-builds/debian/dists/buster/main/binary-i386/)_
|
||||
|
||||
This install method allows you to install different versions of Wine. You may install any version/branch of Wine that you wish.
|
||||
```
|
||||
### User-defined Wine version variables ################
|
||||
# - Replace the variables below with your system's info.
|
||||
# - Note that we need the i386 version for Box86 even though we're installing it on our ARM processor.
|
||||
# - Wine download links from WineHQ: https://dl.winehq.org/wine-builds/
|
||||
|
||||
wbranch="devel" #example: devel, staging, or stable (wine-staging 4.5+ requires libfaudio0:i386 - see below)
|
||||
wversion="7.1" #example: 7.1
|
||||
wid="debian" #example: debian, ubuntu
|
||||
wdist="bullseye" #example (for debian): bullseye, buster, jessie, wheezy, etc
|
||||
wtag="-1" #example: -1 (some wine .deb files have -1 tag on the end and some don't)
|
||||
|
||||
########################################################
|
||||
|
||||
# Clean up any old wine instances
|
||||
wineserver -k # stop any old wine installations from running
|
||||
rm -rf ~/.cache/wine # remove old wine-mono/wine-gecko install files
|
||||
rm -rf ~/.local/share/applications/wine # remove old program shortcuts
|
||||
|
||||
# Backup any old wine installations
|
||||
sudo mv ~/wine ~/wine-old
|
||||
sudo mv ~/.wine ~/.wine-old
|
||||
sudo mv /usr/local/bin/wine /usr/local/bin/wine-old
|
||||
sudo mv /usr/local/bin/wineboot /usr/local/bin/wineboot-old
|
||||
sudo mv /usr/local/bin/winecfg /usr/local/bin/winecfg-old
|
||||
sudo mv /usr/local/bin/wineserver /usr/local/bin/wineserver-old
|
||||
|
||||
# Download, extract wine, and install wine
|
||||
cd ~/Downloads
|
||||
wget https://dl.winehq.org/wine-builds/${wid}/dists/${wdist}/main/binary-i386/wine-${wbranch}-i386_${wversion}~${wdist}${wtag}_i386.deb # download
|
||||
wget https://dl.winehq.org/wine-builds/${wid}/dists/${wdist}/main/binary-i386/wine-${wbranch}_${wversion}~${wdist}${wtag}_i386.deb # (required for wine_i386 if no wine64 / CONFLICTS WITH wine64 support files)
|
||||
dpkg-deb -x wine-${wbranch}-i386_${wversion}~${wdist}${wtag}_i386.deb wine-installer # extract
|
||||
dpkg-deb -x wine-${wbranch}_${wversion}~${wdist}${wtag}_i386.deb wine-installer
|
||||
mv wine-installer/opt/wine* ~/wine # install
|
||||
rm wine*.deb # clean up
|
||||
rm -rf wine-installer # clean up
|
||||
|
||||
# Install shortcuts (make 32bit launcher & symlinks. Credits: grayduck, Botspot)
|
||||
echo -e '#!/bin/bash\nsetarch linux32 -L '"$HOME/wine/bin/wine "'"$@"' | sudo tee -a /usr/local/bin/wine >/dev/null # Create a script to launch wine programs as 32bit only
|
||||
#sudo ln -s ~/wine/bin/wine /usr/local/bin/wine # You could aslo just make a symlink, but box86 only works for 32bit apps at the moment
|
||||
sudo ln -s ~/wine/bin/wineboot /usr/local/bin/wineboot
|
||||
sudo ln -s ~/wine/bin/winecfg /usr/local/bin/winecfg
|
||||
sudo ln -s ~/wine/bin/wineserver /usr/local/bin/wineserver
|
||||
sudo chmod +x /usr/local/bin/wine /usr/local/bin/wineboot /usr/local/bin/winecfg /usr/local/bin/wineserver
|
||||
|
||||
# These packages are needed for running wine on a 64-bit RPiOS via multiarch
|
||||
karch=$(uname -m)
|
||||
if [ "$karch" = "aarch64" ] || [ "$karch" = "aarch64-linux-gnu" ] || [ "$karch" = "arm64" ] || [ "$karch" = "aarch64_be" ]; then
|
||||
sudo dpkg --add-architecture armhf && sudo apt-get update # enable multi-arch
|
||||
sudo apt-get install -y libasound2:armhf libc6:armhf libglib2.0-0:armhf libgphoto2-6:armhf libgphoto2-port12:armhf \
|
||||
libgstreamer-plugins-base1.0-0:armhf libgstreamer1.0-0:armhf libldap-2.4-2:armhf libopenal1:armhf libpcap0.8:armhf \
|
||||
libpulse0:armhf libsane1:armhf libudev1:armhf libusb-1.0-0:armhf libvkd3d1:armhf libx11-6:armhf libxext6:armhf \
|
||||
libasound2-plugins:armhf ocl-icd-libopencl1:armhf libncurses6:armhf libncurses5:armhf libcap2-bin:armhf libcups2:armhf \
|
||||
libdbus-1-3:armhf libfontconfig1:armhf libfreetype6:armhf libglu1-mesa:armhf libglu1:armhf libgnutls30:armhf \
|
||||
libgssapi-krb5-2:armhf libkrb5-3:armhf libodbc1:armhf libosmesa6:armhf libsdl2-2.0-0:armhf libv4l-0:armhf \
|
||||
libxcomposite1:armhf libxcursor1:armhf libxfixes3:armhf libxi6:armhf libxinerama1:armhf libxrandr2:armhf \
|
||||
libxrender1:armhf libxxf86vm1 libc6:armhf libcap2-bin:armhf # to run wine-i386 through box86:armhf on aarch64
|
||||
# This list found by downloading...
|
||||
# wget https://dl.winehq.org/wine-builds/debian/dists/bullseye/main/binary-i386/wine-devel-i386_7.1~bullseye-1_i386.deb
|
||||
# wget https://dl.winehq.org/wine-builds/debian/dists/bullseye/main/binary-i386/winehq-devel_7.1~bullseye-1_i386.deb
|
||||
# wget https://dl.winehq.org/wine-builds/debian/dists/bullseye/main/binary-i386/wine-devel_7.1~bullseye-1_i386.deb
|
||||
# then `dpkg-deb -I package.deb`. Read output, add `:armhf` to packages in dep list, then try installing them on Pi aarch64.
|
||||
fi
|
||||
|
||||
# These packages are needed for running wine-staging on RPiOS (Credits: chills340)
|
||||
sudo apt install libstb0 -y
|
||||
cd ~/Downloads
|
||||
wget -r -l1 -np -nd -A "libfaudio0_*~bpo10+1_i386.deb" http://ftp.us.debian.org/debian/pool/main/f/faudio/ # Download libfaudio i386 no matter its version number
|
||||
dpkg-deb -xv libfaudio0_*~bpo10+1_i386.deb libfaudio
|
||||
sudo cp -TRv libfaudio/usr/ /usr/
|
||||
rm libfaudio0_*~bpo10+1_i386.deb # clean up
|
||||
rm -rf libfaudio # clean up
|
||||
|
||||
# Boot wine (make fresh wineprefix in ~/.wine )
|
||||
wine wineboot
|
||||
```
|
||||
|
||||
## Installing winetricks
|
||||
Winetricks is a bash script which makes it easier to install & configure any desired Windows core system software packages which may be dependencies for certain Windows programs. You can either install it with `apt`, or manually using the steps below.
|
||||
|
||||
```
|
||||
sudo apt-get install cabextract -y # winetricks needs this installed
|
||||
sudo mv /usr/local/bin/winetricks /usr/local/bin/winetricks-old # Backup old winetricks
|
||||
cd ~/Downloads && wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks # Download
|
||||
sudo chmod +x winetricks && sudo mv winetricks /usr/local/bin/ # Install
|
||||
```
|
||||
|
||||
Whenever we run winetricks, we must tell Box86 to supress its info banner, otherwise winetricks will crash. Box86's info banner can be suppressed using the `BOX86_NOBANNER=1` environment variable before invoking winetricks (example: `BOX86_NOBANNER=1 winetricks`).
|
||||
|
||||
If `apt` installed a desktop menu shortcut for winetricks (or if you make your own desktop shortcut for winetricks) then you may need to edit that shortcut to include Box86's BOX86_NOBANNER=1 env var. With your favorite text editor, edit `/usr/share/applications/winetricks.desktop` and change `Exec=winetricks --gui` to `Exec=env BOX86_NOBANNER=1 winetricks --gui`.
|
||||
|
||||
## Example commands
|
||||
Here is an example of how we should run a winetricks command with box86:
|
||||
`BOX86_NOBANNER=1 winetricks -q corefonts vcrun2010 dotnet20sp1`
|
||||
_This command will silently install three packages in series: Windows core fonts, VC++ 2010 Runtimes, and .NET 2.0 SP1. `-q` is the "install silent/quiet" command._
|
||||
|
||||
Whenever we run winetricks, we must suppress Box86's banner by typing `BOX86_NOBANNER=1` to prevent winetricks from crashing. Invoking Box86's logging features (with `BOX86_LOG=1` or similar) will also cause winetricks to crash. (If Box86 logging is necessary though, we can patch winetricks to avoid these crashes - see the *Troubleshooting* section) # future work.
|
||||
|
||||
For a list of all the different Windows packages & libraries that winetricks can help you install, run `winetricks list-all`
|
||||
|
||||
## Other notes
|
||||
|
||||
### Wineprefixes (and Wine initialization)
|
||||
When you first run or boot Wine (`wine wineboot`), Wine will create a new user environment within which to install Windows software. This user environment is called a "wineprefix" (or "wine bottle") and is located (by default) in `~/.wine` (note that Linux folders with a `.` in front of them are "hidden" folders). Think of a wineprefix as Wine's virtual 'harddrive' where it installs software and saves settings. Wineprefixes are portable and deletable. For more Wine documentation, see [WineHQ](https://www.winehq.org/documentation).
|
||||
|
||||
If you at any point corrupt something inside your default wineprefix, you can start "fresh" by deleting your `~/.wine` directory (with the `rm -rf ~/.wine` command) and boot wine again to create a new default wineprefix.
|
||||
|
||||
### Transplanting wineprefixes (side-loading)
|
||||
If software isn't installing in Wine with Box86, but is installing for you in Wine on a regular x86 Linux computer, you can copy a wineprefix from your x86 Linux computer to the device you're running Box86 on. This is most easily done by tarring the `~/.wine` folder on your x86 Linux computer (`tar -cvf winebottle.tar ~/.wine`), transferring the tar file to your device, then un-tarring the tar file (`tar -xf winebottle.tar`) on your device running Box86 & Wine. Tarring the wineprefix preserves any symlinks that are inside it.
|
||||
|
||||
### Swapping out different versions of Wine
|
||||
Some versions of Wine work better with certain software. It is best to install a version of Wine that is known to work with the software you would like to run. There are three main development branches of Wine you can pick from, referred to as wine-stable, wine-devel, and wine-staging. _Note that the wine-staging branch requires extra installation steps on Raspberry Pi._
|
||||
|
||||
Your entire Wine installation can reside within a single folder on your Linux computer. TwisterOS assumes that your Wine installation is located inside the `~/wine/` directory. The actual directory where you put your `wine` folder doesn't matter as long as you have symlinks within the `/usr/local/bin/` directory which point to the `wine` folder so that Linux can find Wine when you type `wine` into the terminal).
|
||||
|
||||
You can change which version of Wine you are running simply by renaming your old `wine` and `.wine` folders to something else, then putting a new `wine` folder (containing your new version of Wine) in its place. Running `wine wineboot` again will migrate a wineprefix from an older version of Wine to be usable by the newer version of Wine you just installed. You can check which version of Wine you're running with the `wine --version` command.
|
||||
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-hacker
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
# create necessary directories
|
||||
mkdir -p ~/steam
|
||||
mkdir -p ~/steam/tmp
|
||||
cd ~/steam/tmp
|
||||
|
||||
# download latest deb and unpack
|
||||
wget https://cdn.cloudflare.steamstatic.com/client/installer/steam.deb
|
||||
ar x steam.deb
|
||||
tar xf data.tar.xz
|
||||
|
||||
# remove deb archives, not needed anymore
|
||||
rm ./*.tar.xz ./steam.deb
|
||||
|
||||
# move deb contents to steam folder
|
||||
mv ./usr/* ../
|
||||
cd ../ && rm -rf ./tmp/
|
||||
|
||||
# create run script
|
||||
echo "#!/bin/bash
|
||||
export STEAMOS=1
|
||||
export STEAM_RUNTIME=1
|
||||
export DBUS_FATAL_WARNINGS=0
|
||||
~/steam/bin/steam steam://open/minigameslist $@" > steam
|
||||
|
||||
# make script executable and move
|
||||
chmod +x steam
|
||||
sudo mv steam /usr/local/bin/
|
||||
|
||||
# detect if we're running on 64 bit Debian (maybe this can be moved in another script then mentioned in documentation for the people that don't use steam but don't want a headache)
|
||||
MACHINE_TYPE=`uname -m`
|
||||
if [ ${MACHINE_TYPE} == 'aarch64' ] && [ -f '/etc/debian_version' ]; then
|
||||
echo "Detected 64 bit ARM Debian. Installing 32 bit libraries"
|
||||
sudo dpkg --add-architecture armhf # enable installation of armhf libraries
|
||||
sudo apt update # update package lists with the newly added arch
|
||||
# install the libraries that Steam requires
|
||||
sudo apt install libc6:armhf libncurses5:armhf libsdl2-2.0-0:armhf libsdl2-image-2.0-0:armhf libsdl2-mixer-2.0-0:armhf libsdl2-ttf-2.0-0:armhf libopenal1:armhf libpng16-16:armhf libfontconfig1:armhf libxcomposite1:armhf libbz2-1.0:armhf libxtst6:armhf libsm6:armhf libice6:armhf libgl1:armhf libxinerama1:armhf libxdamage1:armhf
|
||||
|
||||
# install mesa for armhf if already installed
|
||||
if dpkg-query -W libgl1-mesa-dri 2>/dev/null; then
|
||||
echo "Detected mesa driver for 64 bit ARM. Installing complementary 32 bit one"
|
||||
sudo apt install libgl1-mesa-dri:armhf
|
||||
fi
|
||||
|
||||
echo "Don't forget to compile/install Box64!"
|
||||
fi
|
||||
|
||||
echo "Script complete."
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-a64-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-a64-git}-git" "${pkgname%-a64-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-a64-git}-git" "${pkgname%-a64-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-a64-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-a64-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DA64=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-a64-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-a64-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-arm-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-arm-git}-git" "${pkgname%-arm-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-arm-git}-git" "${pkgname%-arm-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-arm-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-arm-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-arm-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-arm-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-arm64-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-arm64-git}-git" "${pkgname%-arm64-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-arm64-git}-git" "${pkgname%-arm64-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-arm64-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-arm64-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DARM64=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-arm64-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-arm64-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-gameshell-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-gameshell-git}-git" "${pkgname%-gameshell-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-gameshell-git}-git" "${pkgname%-gameshell-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-gameshell-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-gameshell-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DGAMESHELL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-gameshell-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-gameshell-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-goaclone-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-goaclone-git}-git" "${pkgname%-goaclone-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-goaclone-git}-git" "${pkgname%-goaclone-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-goaclone-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-goaclone-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DGOA_CLONE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-goaclone-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-goaclone-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-lx2610a-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-lx2610a-git}-git" "${pkgname%-lx2610a-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-lx2610a-git}-git" "${pkgname%-lx2610a-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-lx2610a-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-lx2610a-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DLX2610A=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-lx2610a-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-lx2610a-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-odroid-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-odroid-git}-git" "${pkgname%-odroid-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-odroid-git}-git" "${pkgname%-odroid-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-odroid-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-odroid-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DODROID=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-odroid-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-odroid-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-odroidn2-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-odroidn2-git}-git" "${pkgname%-odroidn2-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-odroidn2-git}-git" "${pkgname%-odroidn2-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-odroidn2-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-odroidn2-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DODROID=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-odroidn2-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-odroidn2-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-pandora-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-pandora-git}"-git "${pkgname%-pandora-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-pandora-git}"-git "${pkgname%-pandora-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-pandora-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-pandora-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DPANDORA=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-pandora-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-pandora-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-phytium-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-phytium-git}"-git "${pkgname%-phytium-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-phytium-git}"-git "${pkgname%-phytium-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-phytium-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-phytium-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DPHYTIUM=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-phytium-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-phytium-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-pyra-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-pyra-git}-git" "${pkgname%-pyra-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-pyra-git}-git" "${pkgname%-pyra-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-pyra-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-pyra-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DPYRA=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-pyra-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-pyra-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-rpi-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%-rpi-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%-rpi-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
_pimodel=`tr -d '\0' < /sys/firmware/devicetree/base/model`
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-rpi-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-rpi-git}"
|
||||
# Check for Pi version number
|
||||
if [[ ${_pimodel} =~ "Raspberry Pi 4" ]]; then
|
||||
_piversion=4
|
||||
elif [[ ${_pimodel} =~ "Raspberry Pi 3" ]]; then
|
||||
_piversion=3
|
||||
elif [[ ${_pimodel} =~ "Raspberry Pi 2" ]]; then
|
||||
_piversion=2
|
||||
else
|
||||
# This RPI is not supported or this device is not a pi.
|
||||
# We should cancel then the build.
|
||||
echo -e "\033[01m\033[01;31m==> ERROR:\033[00;01m Your device is not supported! This script is for RPi model 4/3/2 (1/0 isn't supported).\033[00m"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\033[01m\033[01;34m==> INFO:\033[00;01m Your detected Pi verion number is: \033[01;31m${_piversion}\033[01m.\033[00m"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DRPI${_piversion}=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-rpi-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-rpi-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-rk3xxx-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-rk3xxx-git}-git" "${pkgname%-rk3xxx-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-rk3xxx-git}-git" "${pkgname%-rk3xxx-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-rk3xxx-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-rk3xxx-git}"
|
||||
# Check for RockChip version number
|
||||
if [[ ${_rkmodel} =~ "rk3288"]]; then
|
||||
_rksuffix=3288
|
||||
elif [[ ${_rkmodel} =~ "rk3399" ]]; then
|
||||
_rksuffix=3399
|
||||
elif [[ ${_rkmodel} =~ "rk3588" ]]; then
|
||||
_rksuffix=3588
|
||||
else
|
||||
# This RKxxxx is not supported or this device is not RockChip based.
|
||||
# We should cancel then the build.
|
||||
echo -e "\033[01m\033[01;31m==> ERROR:\033[00;01m Your device is not supported! This script is for RockChip model 3399/3588.\033[00m"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\033[01m\033[01;34m==> INFO:\033[00;01m Your detected RockChip verion number is: \033[01;31m${_rksuffix}\033[01m.\033[00m"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DRK${_rksuffix}=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-rk3xxx-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-rk3xxx-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-sd845-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-sd845-git}-git" "${pkgname%-sd845-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-sd845-git}-git" "${pkgname%-sd845-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-sd845-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-sd845-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DSD845=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-sd845-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-sd845-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-tegra-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-tegra-git}"-git "${pkgname%-tegra-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-tegra-git}"-git "${pkgname%-tegra-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-tegra-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-tegra-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DTEGRAX1ARM32=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-tegra-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-tegra-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>, SpacingBat3 <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-x86-git
|
||||
pkgver=r4581.d698861
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('i386')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-x86-git}-git" "${pkgname%-x86-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-x86-git}-git" "${pkgname%-x86-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-x86-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-x86-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DLD80BITS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-x86-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-x86-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
# The directory containing all PKGBUILDs for BOX86
|
||||
## FAQ
|
||||
### 1. How to use it?
|
||||
Just download the `PKGBUILD-<your-platform>` (no need to download the whole repository), go to directory where you downloaded and type:
|
||||
```sh
|
||||
mv ./PKGBUILD-<your-platform> ./PKGBUILD
|
||||
cd ..
|
||||
makepkg -si
|
||||
```
|
||||
This will copy the PKGBUILD for your platform (where you type your platform name instead of `<your-platform>`), build it and install the PKGBUILD on 32-bit Archlinux ARM.
|
||||
|
||||
In the future, I might try to do an unified PKGBUILD for all platforms that will recognize your platform automatically.
|
||||
|
||||
### 2. What platforms are currently supported.
|
||||
Most specified in [COMPILE.md](../docs/COMPILE.md). Except PowerPC based.
|
||||
|
||||
### 3. Any advantages with that sollution?
|
||||
This might give you some advantages like those:
|
||||
- automatic updates (with some AUR frontends like [`pamac-aur`](https://aur.archlinux.org/packages/pamac-aur/) or [`yay`](https://aur.archlinux.org/packages/yay));
|
||||
- easily uninstall with `pacman -R` when no needed (no need other scripts nor Makefile to do this);
|
||||
- your `box86` installation is recognized as a package (where it wasn't when installing with `make install`).
|
||||
|
||||
|
||||
### Note: You can use [makedeb](https://github.com/makedeb/makedeb) (or) [pkgbuild2spec](https://github.com/prozum/pkgbuild2spec) to compile box86 to .deb or .rpm installer files.
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
if [ -d '/run/systemd/system' ]; then
|
||||
systemctl restart systemd-binfmt || :
|
||||
fi
|
||||
Executable
+1985
File diff suppressed because it is too large.
Load diff
+1391
-199
File diff suppressed because it is too large.
Load diff
+21
-1
@@ -13,6 +13,15 @@ if( NOT TEST_REFERENCE )
|
||||
endif( NOT TEST_REFERENCE )
|
||||
|
||||
set(ENV{BOX86_LOG} 0)
|
||||
set(ENV{BOX86_NOBANNER} 1)
|
||||
if( EXISTS ${CMAKE_SOURCE_DIR}/x86lib )
|
||||
# we are inside box86 folder
|
||||
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x86lib)
|
||||
else()
|
||||
# we are inside build folder
|
||||
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/../x86lib)
|
||||
endif( EXISTS ${CMAKE_SOURCE_DIR}/x86lib )
|
||||
|
||||
# run the test program, capture the stdout/stderr and the result var
|
||||
execute_process(
|
||||
COMMAND ${TEST_PROGRAM} ${TEST_ARGS} ${TEST_ARGS2}
|
||||
@@ -23,19 +32,30 @@ execute_process(
|
||||
|
||||
# if the return value is !=0 bail out
|
||||
if( TEST_RESULT )
|
||||
get_filename_component(TESTNAME "${TEST_ARGS}" NAME)
|
||||
file(RENAME "${TEST_OUTPUT}" "${CMAKE_BINARY_DIR}/${TESTNAME}.out")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/${TESTNAME}.err" ${TEST_ERROR})
|
||||
message( FATAL_ERROR "Failed: Test program ${TEST_PROGRAM} exited != 0.\n${TEST_ERROR}" )
|
||||
endif( TEST_RESULT )
|
||||
|
||||
# now compare the output with the reference
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files ${TEST_OUTPUT} ${TEST_REFERENCE}
|
||||
COMMAND "${CMAKE_COMMAND}" -E compare_files "${TEST_OUTPUT}" "${TEST_REFERENCE}"
|
||||
RESULT_VARIABLE TEST_RESULT
|
||||
)
|
||||
|
||||
# again, if return value is !=0 scream and shout
|
||||
if( TEST_RESULT )
|
||||
get_filename_component(TESTNAME "${TEST_ARGS}" NAME)
|
||||
file(RENAME "${TEST_OUTPUT}" "${CMAKE_BINARY_DIR}/${TESTNAME}.out")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/${TESTNAME}.err" ${TEST_ERROR})
|
||||
message( FATAL_ERROR "Failed: The output of ${TEST_PROGRAM} did not match ${TEST_REFERENCE}")
|
||||
endif( TEST_RESULT )
|
||||
|
||||
# remove the temporary files if they exist
|
||||
if( EXISTS ${TEST_OUTPUT} )
|
||||
file(REMOVE "${TEST_OUTPUT}")
|
||||
endif()
|
||||
|
||||
# everything went fine...
|
||||
message( "Passed: The output of ${TEST_PROGRAM} matches ${TEST_REFERENCE}" )
|
||||
+381
-58
@@ -1,8 +1,9 @@
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "box86context.h"
|
||||
#include "elfloader.h"
|
||||
@@ -13,102 +14,424 @@
|
||||
#include "bridge.h"
|
||||
#include "library.h"
|
||||
#include "callback.h"
|
||||
#include "wrapper.h"
|
||||
#include "myfts.h"
|
||||
#include "threads.h"
|
||||
#include "x86trace.h"
|
||||
#include "signals.h"
|
||||
#include <sys/mman.h>
|
||||
#include "custommem.h"
|
||||
#include "dictionnary.h"
|
||||
#include "rcfile.h"
|
||||
#include "gltools.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynablock.h"
|
||||
#include "dynarec/arm_lock_helper.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
EXPORTDYN
|
||||
void initAllHelpers(box86context_t* context)
|
||||
{
|
||||
static int inited = 0;
|
||||
if(inited)
|
||||
return;
|
||||
my_context = context;
|
||||
init_pthread_helper();
|
||||
init_bridge_helper();
|
||||
init_signal_helper(context);
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
EXPORTDYN
|
||||
void finiAllHelpers(box86context_t* context)
|
||||
{
|
||||
static int finied = 0;
|
||||
if(finied)
|
||||
return;
|
||||
DeleteParams();
|
||||
fini_pthread_helper(context);
|
||||
fini_signal_helper();
|
||||
fini_bridge_helper();
|
||||
fini_custommem_helper(context);
|
||||
finied = 1;
|
||||
}
|
||||
|
||||
void x86Syscall(x86emu_t *emu);
|
||||
|
||||
/// maxval not inclusive
|
||||
int getrand(int maxval)
|
||||
{
|
||||
if(maxval<1024) {
|
||||
return ((random()&0x7fff)*maxval)/0x7fff;
|
||||
}
|
||||
uint64_t r = random();
|
||||
r = (r*maxval) / RAND_MAX;
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
void free_tlsdatasize(void* p)
|
||||
{
|
||||
if(!p)
|
||||
return;
|
||||
tlsdatasize_t *data = (tlsdatasize_t*)p;
|
||||
box_free(data->ptr);
|
||||
box_free(p);
|
||||
}
|
||||
|
||||
int unlockMutex()
|
||||
{
|
||||
int ret = unlockCustommemMutex();
|
||||
int i;
|
||||
#ifdef DYNAREC
|
||||
void* tid = (void*)GetTID();
|
||||
#define GO(A, B) \
|
||||
i = (arm_lock_storeifref2(&A, NULL, tid)==tid); \
|
||||
if(i) { \
|
||||
ret|=(1<<B); \
|
||||
}
|
||||
#else
|
||||
#define GO(A, B) \
|
||||
i = checkUnlockMutex(&A); \
|
||||
if(i) { \
|
||||
ret|=(1<<B); \
|
||||
}
|
||||
#endif
|
||||
|
||||
GO(my_context->mutex_once, 5)
|
||||
GO(my_context->mutex_once2, 6)
|
||||
GO(my_context->mutex_trace, 7)
|
||||
#ifdef DYNAREC
|
||||
GO(my_context->mutex_dyndump, 8)
|
||||
#else
|
||||
GO(my_context->mutex_lock, 8)
|
||||
#endif
|
||||
GO(my_context->mutex_tls, 9)
|
||||
GO(my_context->mutex_thread, 10)
|
||||
GO(my_context->mutex_bridge, 11)
|
||||
#undef GO
|
||||
return ret;
|
||||
}
|
||||
|
||||
void relockMutex(int locks)
|
||||
{
|
||||
#define GO(A, B) \
|
||||
if(locks&(1<<B)) \
|
||||
mutex_lock(&A); \
|
||||
|
||||
GO(my_context->mutex_once, 5)
|
||||
GO(my_context->mutex_once2, 6)
|
||||
GO(my_context->mutex_trace, 7)
|
||||
#ifdef DYNAREC
|
||||
GO(my_context->mutex_dyndump, 8)
|
||||
#else
|
||||
GO(my_context->mutex_lock, 8)
|
||||
#endif
|
||||
GO(my_context->mutex_tls, 9)
|
||||
GO(my_context->mutex_thread, 10)
|
||||
GO(my_context->mutex_bridge, 11)
|
||||
#undef GO
|
||||
relockCustommemMutex(locks);
|
||||
}
|
||||
|
||||
static void init_mutexes(box86context_t* context)
|
||||
{
|
||||
|
||||
#ifdef DYNAREC
|
||||
arm_lock_stored(&context->mutex_dyndump, 0);
|
||||
arm_lock_stored(&context->mutex_once, 0);
|
||||
arm_lock_stored(&context->mutex_once2, 0);
|
||||
arm_lock_stored(&context->mutex_trace, 0);
|
||||
arm_lock_stored(&context->mutex_tls, 0);
|
||||
arm_lock_stored(&context->mutex_thread, 0);
|
||||
arm_lock_stored(&context->mutex_bridge, 0);
|
||||
pthread_mutex_init(&context->mutex_lock, NULL);
|
||||
#else
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
pthread_mutex_init(&context->mutex_once, &attr);
|
||||
pthread_mutex_init(&context->mutex_once2, &attr);
|
||||
pthread_mutex_init(&context->mutex_trace, &attr);
|
||||
pthread_mutex_init(&context->mutex_tls, &attr);
|
||||
pthread_mutex_init(&context->mutex_thread, &attr);
|
||||
pthread_mutex_init(&context->mutex_bridge, &attr);
|
||||
pthread_mutex_init(&context->mutex_lock, &attr);
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void atfork_child_box64context(void)
|
||||
{
|
||||
// (re)init mutex if it was lock before the fork
|
||||
init_mutexes(my_context);
|
||||
}
|
||||
|
||||
void freeCycleLog(box86context_t* ctx)
|
||||
{
|
||||
if(cycle_log) {
|
||||
for(int i=0; i<cycle_log; ++i) {
|
||||
box_free(ctx->log_call[i]);
|
||||
box_free(ctx->log_ret[i]);
|
||||
}
|
||||
box_free(ctx->log_call);
|
||||
box_free(ctx->log_ret);
|
||||
ctx->log_call = NULL;
|
||||
ctx->log_ret = NULL;
|
||||
}
|
||||
}
|
||||
void initCycleLog(box86context_t* context)
|
||||
{
|
||||
if(cycle_log) {
|
||||
context->log_call = (char**)box_calloc(cycle_log, sizeof(char*));
|
||||
context->log_ret = (char**)box_calloc(cycle_log, sizeof(char*));
|
||||
for(int i=0; i<cycle_log; ++i) {
|
||||
context->log_call[i] = (char*)box_calloc(256, 1);
|
||||
context->log_ret[i] = (char*)box_calloc(128, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPORTDYN
|
||||
box86context_t *NewBox86Context(int argc)
|
||||
{
|
||||
#ifdef BUILD_DYNAMIC
|
||||
if(my_context) {
|
||||
++my_context->count;
|
||||
return my_context;
|
||||
}
|
||||
#endif
|
||||
// init and put default values
|
||||
box86context_t *context = (box86context_t*)calloc(1, sizeof(box86context_t));
|
||||
box86context_t *context = my_context = (box86context_t*)box_calloc(1, sizeof(box86context_t));
|
||||
|
||||
context->deferedInit = 1;
|
||||
initCycleLog(context);
|
||||
|
||||
context->maplib = NewLibrarian(context);
|
||||
#ifdef BUILD_LIB
|
||||
context->deferedInit = 0;
|
||||
#else
|
||||
context->deferredInit = 1;
|
||||
#endif
|
||||
context->sel_serial = 1;
|
||||
|
||||
init_custommem_helper(context);
|
||||
|
||||
context->maplib = NewLibrarian(context, 1);
|
||||
context->local_maplib = NewLibrarian(context, 1);
|
||||
context->versym = NewDictionnary();
|
||||
context->system = NewBridge();
|
||||
// Cannot use Bridge name as the map is not initialized yet
|
||||
// create vsyscall
|
||||
context->vsyscall = AddBridge(context->system, vFv, x86Syscall, 0);
|
||||
|
||||
context->vsyscall = AddBridge(context->system, iFEv, x86Syscall, 0, NULL);
|
||||
addAlternate((void*)0xffffe400, (void*)context->vsyscall);
|
||||
// create exit bridge
|
||||
context->exit_bridge = AddBridge(context->system, NULL, NULL, 0, NULL);
|
||||
#ifdef BUILD_LIB
|
||||
context->box86lib = RTLD_DEFAULT; // not ideal
|
||||
#else
|
||||
context->box86lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
|
||||
#endif
|
||||
context->dlprivate = NewDLPrivate();
|
||||
|
||||
context->callbacks = NewCallbackList();
|
||||
|
||||
context->argc = argc;
|
||||
context->argv = (char**)calloc(context->argc, sizeof(char*));
|
||||
context->argv = (char**)box_calloc(context->argc+1, sizeof(char*));
|
||||
|
||||
pthread_mutex_init(&context->mutex_once, NULL);
|
||||
pthread_mutex_init(&context->mutex_once2, NULL);
|
||||
init_mutexes(context);
|
||||
pthread_atfork(NULL, NULL, atfork_child_box64context);
|
||||
|
||||
pthread_key_create(&context->tlskey, free_tlsdatasize);
|
||||
|
||||
InitFTSMap(context);
|
||||
|
||||
for (int i=0; i<4; ++i) context->canary[i] = 1 + getrand(255);
|
||||
context->canary[/*getrand(4)*/0] = 0;
|
||||
printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)context->canary);
|
||||
|
||||
context->globdata = NewMapSymbols();
|
||||
|
||||
initAllHelpers(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void freeALProcWrapper(box86context_t* context);
|
||||
EXPORTDYN
|
||||
void FreeBox86Context(box86context_t** context)
|
||||
{
|
||||
#ifdef BUILD_DYNAMIC
|
||||
if(--(*context)->count)
|
||||
return;
|
||||
#endif
|
||||
if(!context)
|
||||
return;
|
||||
|
||||
if(--(*context)->forked >= 0)
|
||||
return;
|
||||
|
||||
if((*context)->emu)
|
||||
FreeX86Emu(&(*context)->emu);
|
||||
box86context_t* ctx = *context; // local copy to do the cleanning
|
||||
|
||||
FreeCollection(&(*context)->box86_path);
|
||||
FreeCollection(&(*context)->box86_ld_lib);
|
||||
if((*context)->zydis)
|
||||
DeleteX86Trace(*context);
|
||||
if(ctx->local_maplib)
|
||||
FreeLibrarian(&ctx->local_maplib, NULL);
|
||||
if(ctx->maplib)
|
||||
FreeLibrarian(&ctx->maplib, NULL);
|
||||
FreeDictionnary(&ctx->versym);
|
||||
|
||||
if((*context)->deferedInitList)
|
||||
free((*context)->deferedInitList);
|
||||
|
||||
if((*context)->box86lib)
|
||||
dlclose((*context)->box86lib);
|
||||
|
||||
FreeDLPrivate(&(*context)->dlprivate);
|
||||
|
||||
if((*context)->maplib)
|
||||
FreeLibrarian(&(*context)->maplib);
|
||||
|
||||
for(int i=0; i<(*context)->argc; ++i)
|
||||
free((*context)->argv[i]);
|
||||
free((*context)->argv);
|
||||
|
||||
for (int i=0; i<(*context)->envc; ++i)
|
||||
free((*context)->envv[i]);
|
||||
free((*context)->envv);
|
||||
|
||||
for(int i=0; i<(*context)->elfsize; ++i) {
|
||||
FreeElfHeader(&(*context)->elfs[i]);
|
||||
for(int i=0; i<ctx->elfsize; ++i) {
|
||||
FreeElfHeader(&ctx->elfs[i]);
|
||||
}
|
||||
free((*context)->elfs);
|
||||
box_free(ctx->elfs);
|
||||
|
||||
free((*context)->stack);
|
||||
FreeFTSMap(ctx);
|
||||
|
||||
FreeBridge(&(*context)->system);
|
||||
FreeCollection(&ctx->box86_path);
|
||||
FreeCollection(&ctx->box86_ld_lib);
|
||||
FreeCollection(&ctx->box86_emulated_libs);
|
||||
// stop trace now
|
||||
if(ctx->dec)
|
||||
DeleteX86TraceDecoder(&ctx->dec);
|
||||
if(ctx->zydis)
|
||||
DeleteX86Trace(ctx);
|
||||
|
||||
if((*context)->glwrappers)
|
||||
freeProcWrapper(&(*context)->glwrappers);
|
||||
if((*context)->alwrappers)
|
||||
freeProcWrapper(&(*context)->alwrappers);
|
||||
if(ctx->deferredInitList)
|
||||
box_free(ctx->deferredInitList);
|
||||
|
||||
FreeCallbackList(&(*context)->callbacks);
|
||||
/*box_free(ctx->argv);*/
|
||||
|
||||
/*for (int i=0; i<ctx->envc; ++i)
|
||||
box_free(ctx->envv[i]);
|
||||
box_free(ctx->envv);*/
|
||||
|
||||
pthread_mutex_destroy(&(*context)->mutex_once);
|
||||
pthread_mutex_destroy(&(*context)->mutex_once2);
|
||||
if(ctx->atfork_sz) {
|
||||
box_free(ctx->atforks);
|
||||
ctx->atforks = NULL;
|
||||
ctx->atfork_sz = ctx->atfork_cap = 0;
|
||||
}
|
||||
|
||||
free(*context);
|
||||
*context = NULL;
|
||||
for(int i=0; i<MAX_SIGNAL; ++i)
|
||||
if(ctx->signals[i]!=0 && ctx->signals[i]!=1) {
|
||||
signal(i, SIG_DFL);
|
||||
}
|
||||
|
||||
*context = NULL; // bye bye my_context
|
||||
|
||||
CleanStackSize(ctx);
|
||||
|
||||
#ifndef BUILD_LIB
|
||||
if(ctx->box86lib)
|
||||
dlclose(ctx->box86lib);
|
||||
#endif
|
||||
|
||||
FreeDLPrivate(&ctx->dlprivate);
|
||||
|
||||
// box_free(ctx->stack); // don't free the stack, it's owned by main emu!
|
||||
|
||||
box_free(ctx->fullpath);
|
||||
box_free(ctx->box86path);
|
||||
box_free(ctx->bashpath);
|
||||
|
||||
FreeBridge(&ctx->system);
|
||||
|
||||
freeGLProcWrapper(ctx);
|
||||
freeALProcWrapper(ctx);
|
||||
|
||||
if(ctx->stack_clone)
|
||||
box_free(ctx->stack_clone);
|
||||
|
||||
void* ptr;
|
||||
if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) {
|
||||
free_tlsdatasize(ptr);
|
||||
pthread_setspecific(ctx->tlskey, NULL);
|
||||
}
|
||||
pthread_key_delete(ctx->tlskey);
|
||||
|
||||
if(ctx->tlsdata)
|
||||
box_free(ctx->tlsdata);
|
||||
|
||||
for(int i=0; i<3; ++i) {
|
||||
if(ctx->segtls[i].present) {
|
||||
// key content not handled by box86, so not doing anything with it
|
||||
pthread_key_delete(ctx->segtls[i].key);
|
||||
}
|
||||
}
|
||||
|
||||
free_neededlib(ctx->neededlibs);
|
||||
ctx->neededlibs = NULL;
|
||||
|
||||
if(ctx->emu_sig)
|
||||
FreeX86Emu(&ctx->emu_sig);
|
||||
|
||||
FreeMapSymbols(&ctx->globdata);
|
||||
|
||||
finiAllHelpers(ctx);
|
||||
|
||||
#ifdef DYNAREC
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
#else
|
||||
pthread_mutex_destroy(&ctx->mutex_once);
|
||||
pthread_mutex_destroy(&ctx->mutex_once2);
|
||||
pthread_mutex_destroy(&ctx->mutex_trace);
|
||||
pthread_mutex_destroy(&ctx->mutex_tls);
|
||||
pthread_mutex_destroy(&ctx->mutex_thread);
|
||||
pthread_mutex_destroy(&ctx->mutex_bridge);
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
#endif
|
||||
|
||||
freeCycleLog(ctx);
|
||||
|
||||
box_free(ctx);
|
||||
}
|
||||
|
||||
int AddElfHeader(box86context_t* ctx, elfheader_t* head) {
|
||||
int idx = ctx->elfsize;
|
||||
if(idx==ctx->elfcap) {
|
||||
// resize...
|
||||
ctx->elfcap += 16;
|
||||
ctx->elfs = (elfheader_t**)realloc(ctx->elfs, sizeof(elfheader_t*) * ctx->elfcap);
|
||||
int idx = 0;
|
||||
while(idx<ctx->elfsize && ctx->elfs[idx]) idx++;
|
||||
if(idx == ctx->elfsize) {
|
||||
if(idx==ctx->elfcap) {
|
||||
// resize...
|
||||
ctx->elfcap += 16;
|
||||
ctx->elfs = (elfheader_t**)box_realloc(ctx->elfs, sizeof(elfheader_t*) * ctx->elfcap);
|
||||
}
|
||||
ctx->elfs[idx] = head;
|
||||
ctx->elfsize++;
|
||||
} else {
|
||||
ctx->elfs[idx] = head;
|
||||
}
|
||||
ctx->elfs[idx] = head;
|
||||
ctx->elfsize++;
|
||||
printf_log(LOG_DEBUG, "Adding \"%s\" as #%d in elf collection\n", ElfName(head), idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
void RemoveElfHeader(box86context_t* ctx, elfheader_t* head) {
|
||||
if(GetTLSBase(head)) {
|
||||
// should remove the tls info
|
||||
int tlsbase = GetTLSBase(head);
|
||||
/*if(tlsbase == -ctx->tlssize) {
|
||||
// not really correct, but will do for now
|
||||
ctx->tlssize -= GetTLSSize(head);
|
||||
if(!(++ctx->sel_serial))
|
||||
++ctx->sel_serial;
|
||||
}*/
|
||||
}
|
||||
for(int i=0; i<ctx->elfsize; ++i)
|
||||
if(ctx->elfs[i] == head) {
|
||||
ctx->elfs[i] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int AddTLSPartition(box86context_t* context, int tlssize) {
|
||||
int oldsize = context->tlssize;
|
||||
// should in fact first try to map a hole, but rewinding all elfs and checking filled space, like with the mapmem utilities
|
||||
context->tlssize += tlssize;
|
||||
context->tlsdata = box_realloc(context->tlsdata, context->tlssize);
|
||||
memmove(context->tlsdata+tlssize, context->tlsdata, oldsize); // move to the top, using memmove as regions will probably overlap
|
||||
memset(context->tlsdata, 0, tlssize); // fill new space with 0 (not mandatory)
|
||||
// clean GS segment for current emu
|
||||
if(my_context) {
|
||||
ResetSegmentsCache(thread_get_emu());
|
||||
if(!(++context->sel_serial))
|
||||
++context->sel_serial;
|
||||
}
|
||||
|
||||
return -context->tlssize; // negative offset
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
#ifndef __BOX86CONTEXT_H_
|
||||
#define __BOX86CONTEXT_H_
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include "pathcoll.h"
|
||||
|
||||
typedef struct elfheader_s elfheader_t;
|
||||
|
||||
typedef struct x86emu_s x86emu_t;
|
||||
typedef struct zydis_s zydis_t;
|
||||
typedef struct lib_s lib_t;
|
||||
typedef struct bridge_s bridge_t;
|
||||
typedef struct dlprivate_s dlprivate_t;
|
||||
typedef struct kh_symbolmap_s kh_symbolmap_t;
|
||||
typedef struct callbacklist_s callbacklist_t;
|
||||
typedef struct library_s library_t;
|
||||
|
||||
typedef void* (*procaddess_t)(const char* name);
|
||||
|
||||
typedef struct box86context_s {
|
||||
path_collection_t box86_path; // PATH env. variable
|
||||
path_collection_t box86_ld_lib; // LD_LIBRARY_PATH env. variable
|
||||
|
||||
int x86trace;
|
||||
zydis_t *zydis; // dlopen the zydis dissasembler
|
||||
void* box86lib; // dlopen on box86 itself
|
||||
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
int envc;
|
||||
char** envv;
|
||||
|
||||
char* fullpath;
|
||||
|
||||
uint32_t stacksz;
|
||||
int stackalign;
|
||||
void* stack; // alocated stack
|
||||
|
||||
elfheader_t **elfs; // elf headers and memory
|
||||
int elfcap;
|
||||
int elfsize; // number of elf loaded
|
||||
|
||||
uintptr_t ep; // entry point
|
||||
|
||||
x86emu_t *emu; // CPU / FPU / MMX&SSE regs
|
||||
|
||||
lib_t *maplib; // lib and symbols handling
|
||||
|
||||
bridge_t *threads; // threads
|
||||
bridge_t *system; // other bridges
|
||||
uintptr_t vsyscall; // vsyscall bridge value
|
||||
dlprivate_t *dlprivate; // dlopen library map
|
||||
kh_symbolmap_t *glwrappers; // the map of wrapper for glProcs (for GLX or SDL1/2)
|
||||
procaddess_t glxprocaddress;
|
||||
kh_symbolmap_t *alwrappers; // the map of wrapper for alGetProcAddress
|
||||
|
||||
callbacklist_t *callbacks; // all callbacks
|
||||
|
||||
pthread_mutex_t mutex_once;
|
||||
pthread_mutex_t mutex_once2;
|
||||
|
||||
library_t *libclib; // shortcut to libc library (if loaded, so probably yes)
|
||||
library_t *sdl1lib; // shortcut to SDL1 library (if loaded)
|
||||
library_t *sdl1mixerlib;
|
||||
library_t *sdl1imagelib;
|
||||
library_t *sdl2lib; // shortcut to SDL2 library (if loaded)
|
||||
library_t *sdl2mixerlib;
|
||||
library_t *sdl2imagelib;
|
||||
library_t *zlib;
|
||||
library_t *vorbisfile;
|
||||
|
||||
int deferedInit;
|
||||
elfheader_t **deferedInitList;
|
||||
int deferedInitSz;
|
||||
int deferedInitCap;
|
||||
|
||||
int forked; // how many forks... cleanup only when < 0
|
||||
} box86context_t;
|
||||
|
||||
box86context_t *NewBox86Context(int argc);
|
||||
void FreeBox86Context(box86context_t** context);
|
||||
|
||||
int AddElfHeader(box86context_t* ctx, elfheader_t* head); // return the index of header
|
||||
|
||||
#endif //__BOX86CONTEXT_H_
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
#define __BOX86_VERSION_H_
|
||||
|
||||
#define BOX86_MAJOR 0
|
||||
#define BOX86_MINOR 0
|
||||
#define BOX86_REVISION 4
|
||||
#define BOX86_MINOR 3
|
||||
#define BOX86_REVISION 2
|
||||
|
||||
#endif //__BOX86_VERSION_H_
|
||||
@@ -1,86 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bridge.h"
|
||||
#include "bridge_private.h"
|
||||
#include "wrapper.h"
|
||||
#include "khash.h"
|
||||
|
||||
KHASH_MAP_INIT_INT(bridgemap, uintptr_t)
|
||||
|
||||
#define NBRICK 16
|
||||
typedef struct brick_s brick_t;
|
||||
typedef struct brick_s {
|
||||
onebridge_t b[NBRICK];
|
||||
int sz;
|
||||
brick_t *next;
|
||||
} brick_t;
|
||||
|
||||
typedef struct bridge_s {
|
||||
brick_t *head;
|
||||
brick_t *last; // to speed up
|
||||
kh_bridgemap_t *bridgemap;
|
||||
} bridge_t;
|
||||
|
||||
|
||||
bridge_t *NewBridge()
|
||||
{
|
||||
bridge_t *b = (bridge_t*)calloc(1, sizeof(bridge_t));
|
||||
b->head = (brick_t*)calloc(1, sizeof(brick_t));
|
||||
b->last = b->head;
|
||||
b->bridgemap = kh_init(bridgemap);
|
||||
|
||||
return b;
|
||||
}
|
||||
void FreeBridge(bridge_t** bridge)
|
||||
{
|
||||
brick_t *b = (*bridge)->head;
|
||||
while(b) {
|
||||
brick_t *n = b->next;
|
||||
free(b);
|
||||
b = n;
|
||||
}
|
||||
kh_destroy(bridgemap, (*bridge)->bridgemap);
|
||||
free(*bridge);
|
||||
*bridge = NULL;
|
||||
}
|
||||
|
||||
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
|
||||
{
|
||||
brick_t *b = bridge->last;
|
||||
if(b->sz == NBRICK) {
|
||||
b->next = (brick_t*)calloc(1, sizeof(brick_t));
|
||||
b = b->next;
|
||||
bridge->head = b;
|
||||
}
|
||||
b->b[b->sz].CC = 0xCC;
|
||||
b->b[b->sz].S = 'S'; b->b[b->sz].C='C';
|
||||
b->b[b->sz].w = w;
|
||||
b->b[b->sz].f = (uintptr_t)fnc;
|
||||
b->b[b->sz].C3 = N?0xC2:0xC3;
|
||||
b->b[b->sz].N = N;
|
||||
// add bridge to map, for fast recovery
|
||||
int ret;
|
||||
khint_t k = kh_put(bridgemap, bridge->bridgemap, (uintptr_t)fnc, &ret);
|
||||
kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[b->sz].CC;
|
||||
|
||||
return (uintptr_t)&b->b[b->sz++].CC;
|
||||
}
|
||||
|
||||
uintptr_t CheckBridged(bridge_t* bridge, void* fnc)
|
||||
{
|
||||
// check if function alread have a bridge (the function wrapper will not be tested)
|
||||
khint_t k = kh_get(bridgemap, bridge->bridgemap, (uint32_t)fnc);
|
||||
if(k==kh_end(bridge->bridgemap))
|
||||
return 0;
|
||||
return kh_value(bridge->bridgemap, k);
|
||||
}
|
||||
|
||||
void* GetNativeFnc(uintptr_t fnc)
|
||||
{
|
||||
onebridge_t *b = (onebridge_t*)fnc;
|
||||
if(b->CC != 0xCC || b->S!='S' || b->C!='C' || (b->C3!=0xC3 && b->C3!=0xC2))
|
||||
return NULL; // not a bridge?!
|
||||
return (void*)b->f;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef __BRIDGE_H_
|
||||
#define __BRIDGE_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
typedef struct x86emu_s x86emu_t;
|
||||
typedef struct bridge_s bridge_t;
|
||||
|
||||
bridge_t *NewBridge();
|
||||
void FreeBridge(bridge_t** bridge);
|
||||
|
||||
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N);
|
||||
uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
|
||||
void* GetNativeFnc(uintptr_t fnc);
|
||||
|
||||
#endif //__BRIDGE_H_
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "box86version.h"
|
||||
#ifdef NOGIT
|
||||
#define GITREV "nogit"
|
||||
#else
|
||||
#include "git_head.h"
|
||||
#endif
|
||||
|
||||
void PrintBox86Version()
|
||||
{
|
||||
printf("Box86%s%s v%d.%d.%d %s built on %s %s\n",
|
||||
#ifdef HAVE_TRACE
|
||||
" with trace",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
#ifdef DYNAREC
|
||||
" with Dynarec",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
BOX86_MAJOR, BOX86_MINOR, BOX86_REVISION,
|
||||
GITREV,
|
||||
__DATE__, __TIME__);
|
||||
}
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#ifndef __BUILD_INFO_H__
|
||||
#define __BUILD_INFO_H__
|
||||
|
||||
void PrintBox86Version();
|
||||
|
||||
#endif //__BUILD_INFO_H__
|
||||
-216
@@ -1,216 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "x86emu.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu_private.h"
|
||||
#include "x86run_private.h"
|
||||
#include "box86context.h"
|
||||
#include "stack.h"
|
||||
#include "khash.h"
|
||||
|
||||
typedef struct onecallback_s {
|
||||
x86emu_t *emu;
|
||||
uintptr_t fnc;
|
||||
int nb_args;
|
||||
void* arg[10];
|
||||
int shared;
|
||||
} onecallback_t;
|
||||
|
||||
KHASH_MAP_INIT_INT(callbacks, onecallback_t*)
|
||||
|
||||
typedef struct callbacklist_s {
|
||||
kh_callbacks_t *list;
|
||||
int cap;
|
||||
int sz;
|
||||
} callbacklist_t;
|
||||
|
||||
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
|
||||
{
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
int stsize = 2*1024*1024; // 2MB stack (1MB is not enough for Xenonauts)
|
||||
void* stack = malloc(stsize);
|
||||
if(!stack) {
|
||||
printf_log(LOG_NONE, "BOX86: Error, cannot allocate 2MB Stack for callback\n");
|
||||
}
|
||||
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize, 1);
|
||||
SetupX86Emu(newemu, emu->shared_global, emu->globals);
|
||||
newemu->trace_start = emu->trace_start;
|
||||
newemu->trace_end = emu->trace_end;
|
||||
|
||||
onecallback_t * cb;
|
||||
int ret;
|
||||
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
|
||||
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
|
||||
|
||||
cb->emu = newemu;
|
||||
cb->fnc = fnc;
|
||||
cb->nb_args = nb_args;
|
||||
cb->arg[0] = arg1;
|
||||
cb->arg[1] = arg2;
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
|
||||
cb->shared = 0;
|
||||
|
||||
return newemu;
|
||||
}
|
||||
|
||||
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
|
||||
{
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
int stsize = 64*1024; // 64KB stack
|
||||
void* stack = malloc(stsize);
|
||||
if(!stack) {
|
||||
printf_log(LOG_NONE, "BOX86: Error, cannot allocate 64KB Stack for small callback\n");
|
||||
}
|
||||
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize, 1);
|
||||
SetupX86Emu(newemu, emu->shared_global, emu->globals);
|
||||
newemu->trace_start = emu->trace_start;
|
||||
newemu->trace_end = emu->trace_end;
|
||||
|
||||
onecallback_t * cb;
|
||||
int ret;
|
||||
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
|
||||
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
|
||||
|
||||
cb->emu = newemu;
|
||||
cb->fnc = fnc;
|
||||
cb->nb_args = nb_args;
|
||||
cb->arg[0] = arg1;
|
||||
cb->arg[1] = arg2;
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
|
||||
cb->shared = 0;
|
||||
|
||||
return newemu;
|
||||
}
|
||||
|
||||
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4) //__attribute__((alias("AddCallback")));
|
||||
{
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
x86emu_t * newemu = emu;
|
||||
|
||||
onecallback_t * cb;
|
||||
int ret;
|
||||
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
|
||||
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
|
||||
|
||||
cb->emu = newemu;
|
||||
cb->fnc = fnc;
|
||||
cb->nb_args = nb_args;
|
||||
cb->arg[0] = arg1;
|
||||
cb->arg[1] = arg2;
|
||||
cb->arg[2] = arg3;
|
||||
cb->arg[3] = arg4;
|
||||
cb->shared = 1;
|
||||
|
||||
return newemu;
|
||||
}
|
||||
|
||||
onecallback_t* FindCallback(x86emu_t* emu)
|
||||
{
|
||||
// find the callback first
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
khint_t k = kh_get(callbacks, callbacks->list, (uintptr_t)emu);
|
||||
if(k==kh_end(callbacks->list))
|
||||
return NULL;
|
||||
return kh_value(callbacks->list, k);
|
||||
}
|
||||
|
||||
void FreeCallback(x86emu_t* emu)
|
||||
{
|
||||
// find the callback first
|
||||
callbacklist_t *callbacks = emu->context->callbacks;
|
||||
khint_t k = kh_get(callbacks, callbacks->list, (uintptr_t)emu);
|
||||
if(k==kh_end(callbacks->list))
|
||||
return;
|
||||
onecallback_t* cb = kh_value(callbacks->list, k);
|
||||
if(!cb->shared)
|
||||
FreeX86Emu(&cb->emu);
|
||||
free(cb);
|
||||
kh_del(callbacks, callbacks->list, k);
|
||||
}
|
||||
|
||||
uint32_t RunCallback(x86emu_t* emu)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
for (int i=cb->nb_args-1; i>=0; --i) // reverse order
|
||||
Push(emu, (uint32_t)cb->arg[i]);
|
||||
EmuCall(emu, cb->fnc);
|
||||
R_ESP+=(cb->nb_args*4);
|
||||
return R_EAX;
|
||||
}
|
||||
printf_log(LOG_INFO, "Warning, Callback not found?!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetCallbackArg(x86emu_t* emu, int arg, void* val)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
cb->arg[arg] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCallbackNArg(x86emu_t* emu, int narg)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
cb->nb_args = narg;
|
||||
}
|
||||
}
|
||||
|
||||
void* GetCallbackArg(x86emu_t* emu, int arg)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
return cb->arg[arg];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetCallbackAddress(x86emu_t* emu, uintptr_t address)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
cb->fnc = address;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t GetCallbackAddress(x86emu_t* emu)
|
||||
{
|
||||
onecallback_t *cb = FindCallback(emu);
|
||||
if(cb) {
|
||||
return cb->fnc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
callbacklist_t* NewCallbackList()
|
||||
{
|
||||
callbacklist_t* callbacks = (callbacklist_t*)calloc(1, sizeof(callbacklist_t));
|
||||
callbacks->list = kh_init(callbacks);
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
void FreeCallbackList(callbacklist_t** callbacks)
|
||||
{
|
||||
if(!callbacks)
|
||||
return;
|
||||
if(!*callbacks)
|
||||
return;
|
||||
onecallback_t* cb;
|
||||
kh_foreach_value((*callbacks)->list, cb,
|
||||
FreeX86Emu(&cb->emu);
|
||||
free(cb);
|
||||
);
|
||||
kh_destroy(callbacks, (*callbacks)->list);
|
||||
free(*callbacks);
|
||||
*callbacks = NULL;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef __CALLBACK_H__
|
||||
#define __CALLBACK_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct callbacklist_s callbacklist_t;
|
||||
typedef struct x86emu_s x86emu_t;
|
||||
|
||||
callbacklist_t* NewCallbackList();
|
||||
void FreeCallbackList(callbacklist_t** callbacks);
|
||||
|
||||
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
|
||||
void FreeCallback(x86emu_t* emu);
|
||||
uint32_t RunCallback(x86emu_t* emu);
|
||||
void SetCallbackArg(x86emu_t* emu, int arg, void* val);
|
||||
void* GetCallbackArg(x86emu_t* emu, int arg);
|
||||
void SetCallbackNArg(x86emu_t* emu, int narg);
|
||||
void SetCallbackAddress(x86emu_t* emu, uintptr_t address);
|
||||
uintptr_t GetCallbackAddress(x86emu_t* emu);
|
||||
|
||||
#endif //__CALLBACK_H__
|
||||
+1304
File diff suppressed because it is too large.
Load diff
-18
@@ -1,18 +0,0 @@
|
||||
#ifndef __DEBUG_H_
|
||||
#define __DEBUG_H_
|
||||
|
||||
extern int box86_log; // log level
|
||||
extern int dlsym_error; // log dlsym error
|
||||
extern int trace_xmm; // include XMM reg in trace?
|
||||
#define LOG_NONE 0
|
||||
#define LOG_INFO 1
|
||||
#define LOG_DEBUG 2
|
||||
#define LOG_DUMP 3
|
||||
|
||||
extern FILE* ftrace;
|
||||
|
||||
#define printf_log(L, ...) if(L<=box86_log) fprintf(ftrace, __VA_ARGS__)
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
|
||||
#endif //__DEBUG_H_
|
||||
Executable
+1395
File diff suppressed because it is too large.
Load diff
Executable
+27
@@ -0,0 +1,27 @@
|
||||
//arm epilog for dynarec
|
||||
//Save stuff, prepare stack and register
|
||||
//called with pointer to emu as 1st parameter
|
||||
//and address to jump to as 2nd parameter
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.global arm_epilog
|
||||
arm_epilog:
|
||||
//update register -> emu
|
||||
//pop {r0}
|
||||
stm r0, {r4-r12,r14} // put back reg value in emu, including EIP (so r14 must be Flags now)
|
||||
//restore all used register
|
||||
vpop {d8-d15}
|
||||
pop {r4-r12, pc}
|
||||
//end, return...
|
||||
//bx lr
|
||||
|
||||
|
||||
.global arm_epilog_fast
|
||||
arm_epilog_fast:
|
||||
//restore all used register
|
||||
vpop {d8-d15}
|
||||
pop {r4-r12, pc}
|
||||
//end, return...
|
||||
//bx lr
|
||||
@@ -0,0 +1,655 @@
|
||||
; TYPE fields separated by spaces Assembler syntax
|
||||
; When there are mutiple assembler syntax (like for LDR (immediate)), separate them based on the bytes
|
||||
; E.G. for LDR (immediate), there are 3 lines with the 3 different asm syntaxes
|
||||
|
||||
# Field options:
|
||||
# --------------
|
||||
# Syntax: ... field/coption1(coption2)* ... (inside fields)
|
||||
# Where each c correspond to the option character
|
||||
# and optionN to the Nth option value
|
||||
# ---
|
||||
# c = '0'..'9'/'A'..'F': option=[01]
|
||||
# Force the cth bit (hex) of the field (starting from LSB) to be <option>
|
||||
# c = '=': option=[01x]{field_len}
|
||||
# Force the field to have the given bits (where x = anything, starts from MSB)
|
||||
|
||||
# Post-fields option:
|
||||
# -------------------
|
||||
# Syntax: [fields] @ typeoption1 args1 typeoption2 args2 @ [Assembler syntax]
|
||||
# ---
|
||||
# typeoption contains '=' (l=r): args1=((.*) )?([^, ]*),([^, ]*),([^, ]*)@
|
||||
# Changes a value between two other depending on whether l == r
|
||||
|
||||
# \2 is init (suffixed by ';', optional), \3 is set to \4 if true or \5 if false
|
||||
# (cf VMOV/VORR aka V\op\, VEOR/VBIF/VBIT/VBSL aka V\op\)
|
||||
|
||||
# The 'true regex' is typeoption=([^= ]*)(=([^= ]*))+
|
||||
# args1=((.*) )?([^, ]*),(([^, ]*),)+([^, ]*)@
|
||||
# with the number of typeoption:\2 being equal to the number of args1:\4
|
||||
# <a>=<b>[=<c>...] <initialization> <variable-changed>,<changed-into-if-a=b>[,<changed-into-if-a=c>...],<changed-into-else>@
|
||||
|
||||
# OR
|
||||
|
||||
# typeoption is discarded and must be set to '=', args1=((.*) )?(@@ (( ?.*[^@])*)@ )+([^, ]*),(([^, ]*),)+([^, ]*)
|
||||
# \2 is init (suffixed by ';', optional), \6 is set to \7 if true or \8 if false
|
||||
# The difference with the simple switch is that \4 is the test (inside the `if`)
|
||||
# If there are multiple @@s, there are multiple `if`s (separated by `else`s)
|
||||
|
||||
# The 'true regex' is [DISCARDED]typeoption==
|
||||
# args1=((.*) )?(@@ (( ?.*[^@])*)@ )+([^, ]*),([^, ]*),([^, ]*)
|
||||
# <.>=<.>[=<c>...] <initialization> @@ <test>@[ @@ <test2>@...] <variable-changed>,<changed-into-if-a=b>,<changed-into-else>
|
||||
|
||||
# OR
|
||||
|
||||
# args1=((.*) )?!@(( [^%]*[^%@])*)%(( ?[^%]*[^%@])*)@(( .*[^@])*)@(( .*[^@])*)@
|
||||
# Replaced by '\1; if (<equality>) { \3\7\5; } else { \3\9\5; }'
|
||||
# Meaning, <.=.> <initialization> !@ <common-left-part>%<common-right-part>@ <substitute-true>@ <substitute-false>@ <...>
|
||||
# (cf VMOV/VORR, aka V\op\ with the lastop variable)
|
||||
# You can also add more '=' with corresponding substitutes.
|
||||
# You can also add more '%' with corresponding substitutes.
|
||||
|
||||
# ----
|
||||
# Inside the assembler syntax, you can add \var\ to mark a variable to be replaced
|
||||
# (Meaning, %s and `var` as argument to printf)
|
||||
# Full syntax: \\(%[0-9+]*.)?(.*)\\
|
||||
# If \1 != "", add \1 to the string in printf, and in any case append \2 as argument to printf
|
||||
|
||||
! HACKS: (list of notable differences between the doc and this file)
|
||||
! ------
|
||||
! In theory, (0) and (1) bits are as important as 0 and 1:
|
||||
! > An instruction is UNPREDICTABLE if:
|
||||
! > • It is declared as UNPREDICTABLE in an instruction description or in this chapter.
|
||||
! > • The pseudocode for that encoding does not indicate that a different special case applies, and a bit marked (0)
|
||||
! or (1) in the encoding diagram of an instruction is not 0 or 1 respectively.
|
||||
! - ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition
|
||||
! In practice, they are ignored here.
|
||||
|
||||
! SWP, SWPB, VMOV (VFPU): Rt2 (field and assembly) -> Rn (field and assembly)
|
||||
! BKPT: must be AL, so cond (field) -> cond/=1110 (constrained field)
|
||||
! PKHBT and PKHTB: {, LSL/ASR #<imm>} (assembly) -> {, <shift>} (assembly)
|
||||
! PKHBT and PKHTB: immediate shift but shift & 1 -> ARMs (type)
|
||||
! All NEON operations (advanced SIMD): limited, so multiply the lines
|
||||
! VMOV (register): Vm ... Vm VMOV (field, assembly) -> Vn ... Vm @ m=n ...@ @ V\op\ (field, switchable var, assembly)
|
||||
! VMOV is VORR constrained -> (removed VORR)
|
||||
! VEOR, VBSL, VBIT, VBIF differ only depending on 2 bits: 0/1 0/1 ... VEOR -> @<2> ... @ ... @ V\op\ (field, switchable var, assembly)
|
||||
! Three registers of different lengths (when having L and W variants): op (field) -> Q (field)
|
||||
! MRS: always APSR since program is always in userspace
|
||||
! DBG: option (field and assembly) -> imm (field and assembly)
|
||||
|
||||
; ========== BEGINNING OF REGISTERED INSTRUCTIONS =========
|
||||
|
||||
# This instruction changes the instruction set to Thumb! Disabled (but valid)
|
||||
#ARM_ 1 1 1 1 1 0 1 @<1> imm24 @ set imm24 = (imm24 << 2) + (param << 1)@ @ BLX <label>
|
||||
|
||||
# CPS marked as invalid (in userspace, treated as NOP)
|
||||
;INVALIDATE 1 1 1 1 0 0 0 1 0 0 0 0 <4> <8> <2> 0 <1> <4>
|
||||
ARM_ 1 1 1 1 0 0 0 1 0 0 0 0 (0) (0) (0) 1 (0) (0) (0) (0) (0) (0) @<1> (0) 0 0 0 0 (0) (0) (0) (0) SETEND \%cparam ? 'B' : 'L'\E
|
||||
;INVALIDATE 1 1 1 1 0 0 0 1 0 0 1 0 <4> <8> 0 1 1 1 <4>
|
||||
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 0 op 0 N Q M 0 Vm VH\(op ? "SUB" : "ADD")\<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 0 0 0 N Q M 1 Vm VQADD<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 0 0 1 N Q M 0 Vm VRHADD<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 0 0 Vn Vd 0 0 0 1 N Q M 1 Vm VAND<c> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 0 1 Vn Vd 0 0 0 1 N Q M 1 Vm VBIC<c> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 1 0 Vn Vd 0 0 0 1 N Q M 1 Vm @ m=n const char* op op,"MOV","ORR"@ m=n char lastop[6] !@ %@ lastop[0] = '\0'@ sprintf(lastop, ", %s", vecname[(q << 5) + 0x20 + n])@ @ V\op\<c> <Qd>, <Qm>\lastop\
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 1 1 Vn Vd 0 0 0 1 N Q M 1 Vm VORN<c> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D @<2> Vn Vd 0 0 0 1 N Q M 1 Vm @ param=0b00=0b01=0b10 const char* op op,"EOR","BSL","BIT","BIF"@ @ V\op\<c> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 0 1 0 N Q M 1 Vm VQSUB<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 0 1 1 N Q M op Vm @ op=0 const char* strict strict,"T","E"@ @ VCG\strict\<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 0 0 N Q M 0 Vm VSHL<c>.<dt> <Qd>, <Qm>, <Qn>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 0 0 N Q M 1 Vm VQSHL<c>.<dt> <Qd>, <Qm>, <Qn>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 0 1 N Q M 0 Vm VRSHL<c>.<dt> <Qd>, <Qm>, <Qn>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 0 1 N Q M 1 Vm VQRSHL<c>.<dt> <Qd>, <Qm>, <Qn>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 1 0 N Q M op Vm @ op=0 const char* opname opname,"MAX","MIN"@ @ V\opname\<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 1 1 N Q M 0 Vm VABD<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 0 1 1 1 N Q M 1 Vm VABA<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 op 0 D size Vn Vd 1 0 0 0 N Q M 0 Vm @ op=0 const char* opname opname,"ADD","SUB"@ @ V\opname\<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D size Vn Vd 1 0 0 0 N Q M 1 Vm VTST<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D size Vn Vd 1 0 0 0 N Q M 1 Vm VCEQ<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 1 0 0 1 N Q M 0 Vm @ set size = 8 << size@ @ VML\(u ? "S" : "A")\<c>.I\%dsize\ <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 1 0 0 1 N Q M 1 Vm VMUL<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 0 D size Vn Vd 1 0 1 0 N Q M op Vm @ op=0 const char* opname opname,"MAX","MIN"@ @ VP\opname\<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D size Vn Vd 1 0 1 1 N Q M 0 Vm VQDMULH<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D size Vn Vd 1 0 1 1 N Q M 0 Vm VQRDMULH<c>.<dt> <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D size Vn Vd 1 0 1 1 N Q/=0 M 1 Vm VPADD<c>.<dt> <Dd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D U sz/=0 Vn Vd 1 1 0 0 N Q M 1 Vm @ u=0 const char* y y,"A","S"@ @ VFM\y\<c>.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D U sz/=0 Vn Vd 1 1 0 1 N Q M 0 Vm @ u=0 const char* op op,"ADD","SUB"@ @ V\op\<c>.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D 0 sz/=0 Vn Vd 1 1 0 1 N Q/=0 M 0 Vm VPADD.F32 <Dd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D 1 sz/=0 Vn Vd 1 1 0 1 N Q M 0 Vm VABD.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D op sz/=0 Vn Vd 1 1 0 1 N Q M 1 Vm VML\(op ? "S" : "A")\<c>.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D 0 sz/=0 Vn Vd 1 1 0 1 N Q M 1 Vm VMUL.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 0 sz/=0 Vn Vd 1 1 1 0 N Q M 0 Vm VCEQ.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D op sz/=0 Vn Vd 1 1 1 0 N Q M 0 Vm @ op=1 const char* strict strict,"T","E"@ @ VCG\strict\.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D op sz/=0 Vn Vd 1 1 1 0 N Q M 1 Vm @ op=1 const char* strict strict,"T","E"@ @ VACG\strict\.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D op sz/=0 Vn Vd 1 1 1 1 N Q M 0 Vm @ op=0 const char* opname opname,"MAX","MIN"@ @ V\opname\.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 0 D op sz/=0 Vn Vd 1 1 1 1 N Q M 0 Vm @ op=0 const char* opname opname,"MAX","MIN"@ @ VP\opname\.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 0 sz/=0 Vn Vd 1 1 1 1 N Q M 1 Vm VRECPS.F32 <Qd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 0 0 D 1 sz/=0 Vn Vd 1 1 1 1 N Q M 1 Vm VRSQRTS.F32 <Qd>, <Qn>, <Qm>
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 0 <23>
|
||||
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=0xx0 0 Q op/=0 1 imm4 VMOV<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=0xx1 0 Q op/=0 1 imm4 VORR<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=10x0 0 Q op/=0 1 imm4 VMOV<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=10x1 0 Q op/=0 1 imm4 VORR<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=11xx 0 Q op/=0 1 imm4 VMOV<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=0xx0 0 Q op/=1 1 imm4 VMVN<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=0xx1 0 Q op/=1 1 imm4 VBIC<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=10x0 0 Q op/=1 1 imm4 VMVN<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=10x1 0 Q op/=1 1 imm4 BIC<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=110x 0 Q op/=1 1 imm4 VMVN<c>.<dt> <Qd>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 i 1 D 0 0 0 imm3 Vd cmode/=1110 0 Q op/=1 1 imm4 VMOV<c>.<dt> <Qd>, #<imm>
|
||||
;INVALIDATE 1 1 1 1 0 0 1 <1> 1 <1> 0 0 0 <3> <4> <4>/=1111 0 <1> <1>/=1 1 <4>
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <1> 0 0 0 <11> 0 <2> 1 <4>
|
||||
|
||||
# Special case for VMOVL (harder to do it on the documented place)
|
||||
NEON 1 1 1 1 0 0 1 0 1 D 0 0 1 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.S8 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D 0 1 0 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.S16 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D 1 0 0 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.S32 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 0 0 1 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.U8 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 0 1 0 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.U16 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 0 0 0 0 0 Vd 1 0 1 0 0 0 M 1 Vm VMOVL<c>.U32 <Qd>, <Dm>
|
||||
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 0 0 0 0 L Q M 1 Vm VSHR<c>.<dt> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 0 0 0 1 L Q M 1 Vm VSRA<c>.<dt> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 0 0 1 0 L Q M 1 Vm VRSHR<c>.<dt> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 0 0 1 1 L Q M 1 Vm VRSRA<c>.<dt> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D imm6 Vd 0 1 0 0 L Q M 1 Vm VSRI<c>.<size> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D Imm6 Vd 0 1 0 1 L Q M 1 Vm VSHL<c>.I<size> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D Imm6 Vd 0 1 0 1 L Q M 1 Vm VSLI<c>.<size> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D Imm6 Vd 0 1 1 op L Q M 1 Vm VQSHL\((u & op) ? "U" : "")\<c>.<dt> <Qd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D imm6 Vd 1 0 0 0 0 0 M 1 Vm @ set ++size@ @ VSHRN<c>.I<size> <Dd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D imm6 Vd 1 0 0 0 0 1 M 1 Vm VRSHRN<c>.I<size> <Dd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 1 0 0 op 0 0 M 1 Vm VQSHR\((u & op) ? "U" : "")\N<c>.<dt> <Dd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D imm6 Vd 1 0 0 op 0 1 M 1 Vm VQRSHR\((u & op) ? "U" : "")\N<c>.<dt> <Dd>, <Qm>, #<imm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 1 1 0 0 M 1 Vm VSHLL<c>.<dt> <Qd>, <Dm>, #\%d8 &l&l size\
|
||||
NEON 1 1 1 1 0 0 1 U 1 D Imm6 Vd 1 0 1 0 0 0 M 1 Vm VSHLL<c>.<dt> <Qd>, <Dm>, #<imm>
|
||||
; VCVT: if imm6 IN "0xxxxx" then UNDEFINED;
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <1> 0 <9> 1 1 1 <1> 0 <2> 1 <4>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D IMM6 Vd 1 1 1 0 0 Q M 1 Vm VCVT<c>.F32.S32 <Qd>, <Qm>, #<fbits>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D IMM6 Vd 1 1 1 1 0 Q M 1 Vm VCVT<c>.S32.F32 <Qd>, <Qm>, #<fbits>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D IMM6 Vd 1 1 1 0 0 Q M 1 Vm VCVT<c>.F32.U32 <Qd>, <Qm>, #<fbits>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D IMM6 Vd 1 1 1 1 0 Q M 1 Vm VCVT<c>.U32.F32 <Qd>, <Qm>, #<fbits>
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <18> 1 <4>
|
||||
|
||||
NEON 1 1 1 1 0 0 1 0 1 D 1 1 Vn Vd IMM4 N Q M 0 Vm VEXT<c>.8 <Qd>, <Qn>, <Qm>, #<imm>
|
||||
|
||||
# size + param < 3
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <2>/=11 0 0 <4> 0 0 0 <2> <2> 0 <4>
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <2>/=10 0 0 <4> 0 0 0 <2>/11 <2> 0 <4>
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <2>/=10 0 0 <4> 0 0 0 <2>/01 <2> 0 <4>
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <2>/=01 0 0 <4> 0 0 0 <2>/11 <2> 0 <4>
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <2>/=00 0 0 <4> 0 0 0 <2>/=11 <2> 0 <4>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 0 0 @<2> Q M 0 Vm VREV\%d64 &g&g param\<c>.\%d8 &l&l size\ <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 0 1 0 U Q M 0 Vm VPADDL<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 1 0 0 0 Q M 0 Vm VCLS<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 1 0 0 1 Q M 0 Vm VCLZ<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=00 0 0 Vd 0 1 0 1 0 Q M 0 Vm VCNT<c>.8 <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=00 0 0 Vd 0 1 0 1 1 Q M 0 Vm VMVN<c> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 1 1 0 U Q M 0 Vm VPADAL<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 1 1 1 0 Q M 0 Vm VQABS<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 0 Vd 0 1 1 1 1 Q M 0 Vm VQNEG<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 0 0 0 Q M 0 Vm VCGT<c>.<dt> <Qd>, <Qm>, #0
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 0 0 1 Q M 0 Vm VCGE<c>.<dt> <Qd>, <Qm>, #0
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 0 1 0 Q M 0 Vm VCEQ<c>.<dt> <Qd>, <Qm>, #0
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 0 1 1 Q M 0 Vm VCLE<c>.<dt> <Qd>, <Qm>, #0
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 1 0 0 Q M 0 Vm VCLT<c>.<dt> <Qd>, <Qm>, #0
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 1 1 0 Q M 0 Vm VABS<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 0 1 Vd 0 F 1 1 1 Q M 0 Vm VNEG<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=00 1 0 Vd 0 0 0 0 0 Q M 0 Vm VSWP<c> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 0 0 1 Q M 0 Vm VTRN<c>.\%d8 &l&l size\ <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 0 1 0 Q M 0 Vm VUZP<c>.\%d8 &l&l size\ <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 0 1 1 Q M 0 Vm VZIP<c>.\%d8 &l&l size\ <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 1 0 0 0 M 0 Vm VMOVN<c>.<dt> <Dd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 1 0 0 1 M 0 Vm VQMOVUN<c>.S\%d16 &l&l size\ <Dd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 1 0 1 U M 0 Vm @ set ++size@ @ VQMOVN<c>.<dt> <Dd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 0 Vd 0 0 1 1 0 0 M 0 Vm VSHLL<c>.I\%d8 &l&l size\ <Qd>, <Dm>, #\%d8 &l&l size\
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=01 1 0 Vd 0 1 1 0 0 0 M 0 Vm VCVT<c>.F16.F32 <Dd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=01 1 0 Vd 0 1 1 1 0 0 M 0 Vm VCVT<c>.F32.F16 <Qd>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 1 Vd 0 1 0 F 0 Q M 0 Vm VRECPE<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size 1 1 Vd 0 1 0 F 1 Q M 0 Vm VRSQRTE<c>.<dt> <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=10 1 1 Vd 0 1 1 0 0 Q M 0 Vm VCVT<c>.F32.S32 <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=10 1 1 Vd 0 1 1 0 1 Q M 0 Vm VCVT<c>.S32.F32 <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=10 1 1 Vd 0 1 1 1 0 Q M 0 Vm VCVT<c>.F32.U32 <Qd>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 size/=10 1 1 Vd 0 1 1 1 1 Q M 0 Vm VCVT<c>.U32.F32 <Qd>, <Qm>
|
||||
INVALIDATE 1 1 1 1 0 0 1 1 1 <1> 1 1 <8> 0 <6> 0 <4>
|
||||
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 Vn Vd 1 0 @<2> N op M 0 Vm @ param=0b00 char list[10] !@ sprintf(list, %)@ "{%s}", vecname[0x20 + n]@ "{%s-%s}", vecname[0x20 + n], vecname[0x20 + n + param]@ @ VTB\(op ? "X" : "L")\<c>.8 <Dd>, \list\, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D 1 1 imm4 Vd 1 1 0 0 0 Q M 0 Vm VDUP<c>.\%dsize\ <Qd>, <Dm[x]>
|
||||
|
||||
; size != 11
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <1> 1 1 <13> 0 <1> 0 <4>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 0 0 0 Q N 0 M 0 Vm VADD\(q ? "W" : "L")\<c>.<dt> <qd>, <Qn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 0 0 1 Q N 0 M 0 Vm VSUB\(q ? "W" : "L")\<c>.<dt> <qd>, <Qn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 0 1 0 0 N 0 M 0 Vm @ set size = 16 << size@ @ VADDHN<c>.I\%dsize\ <Dd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D size Vn Vd 0 1 0 0 N 0 M 0 Vm VRADDHN<c>.<dt> <Dd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 0 1 0 1 N 0 M 0 Vm VABAL<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 0 1 1 0 N 0 M 0 Vm VSUBHN<c>.<dt> <Dd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 1 1 D size Vn Vd 0 1 1 0 N 0 M 0 Vm VRSUBHN<c>.<dt> <Dd>, <Qn>, <Qm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 0 1 1 1 N 0 M 0 Vm VABDL<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 1 0 op 0 N 0 M 0 Vm VML\(op ? "S" : "A")\L<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 1 0 op 1 N 0 M 0 Vm VQDML\(op ? "S" : "A")\L<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 1 1 0 0 N 0 M 0 Vm VMULL<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 1 1 0 1 N 0 M 0 Vm VQDMULL<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
NEON 1 1 1 1 0 0 1 U/=0 1 D size/=00 Vn Vd 1 1 1 0 N 0 M 0 Vm @ set uint8_t size = 0@ @ VMULL<c>.<dt> <Qd>, <Dn>, <Dm>
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <16> 0 <1> 0 <4>
|
||||
|
||||
; Put after, otherwise some instructions are shadowed
|
||||
NEON 1 1 1 1 0 0 1 Q 1 D size Vn Vd 0 op 0 F N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VML\(op ? "S" : "A")\<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 0 op 1 0 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VML\(op ? "S" : "A")\L<c>.<dt> <Qd>, <Dn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 0 op 1 1 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VQDML\(op ? "S" : "A")\L<c>.<dt> <Qd>, <Dn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 Q 1 D size Vn Vd 1 0 0 F N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VMUL<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 U 1 D size Vn Vd 1 0 1 0 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VMULL<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 0 1 D size Vn Vd 1 0 1 1 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VQDMULL<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 Q 1 D size Vn Vd 1 1 0 0 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VQDMULH<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
NEON 1 1 1 1 0 0 1 Q 1 D size Vn Vd 1 1 0 1 N 1 M 0 Vm @ size=0b01=0b10 unsigned int decodedImm !@ decodedImm = m >> %; m %@ 3@ &= 0x7@ 4@ &= 0xF@ 5@ = 0x21@ @ VQRDMULH<c>.<dt> <Qd>, <Qn>, <Dm[x]>
|
||||
INVALIDATE 1 1 1 1 0 0 1 <1> 1 <16> 0 <1> 0 <4>
|
||||
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 0 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 0 1 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 0 size @<2> Rm @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 0 1 size @<2> Rm @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 0 1 1 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 0 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 0 0 Rn Vd 1 0 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\, \vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 0 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\, \vecname[0x26 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 0 1 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x23 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 0 size @<2> Rm @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 0 1 size @<2> Rm @ param=0b00 char align[4] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 63 + param)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\, \vecname[0x24 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\-\vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 0 1 1 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 1 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 1 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 0 1 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x22 + d]\}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 1 0 size @<2> 1 1 0 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 1 0 size @<2> 1 1 1 1 @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 0 D 1 0 Rn Vd 1 0 1 0 size @<2> Rm @ param=0b00 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 32 << param)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\, \vecname[0x21 + d]\}, [<Rn>\align\], <Rm>
|
||||
INVALIDATE 1 1 1 1 0 1 0 0 1 <1> 0 0 <8> 1 1 <10>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 0 @<4> 1 1 0 1 @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 0 @<4> 1 1 1 1 @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 0 @<4> Rm @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VST1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 1 @<4> 1 1 0 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 1 @<4> 1 1 1 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 0 1 @<4> Rm @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 0 @<4> 1 1 0 1 @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 0 @<4> 1 1 1 1 @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 0 @<4> Rm @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VST3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 1 @<4> 1 1 0 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 1 @<4> 1 1 1 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 0 0 Rn Vd size 1 1 @<4> Rm @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VST4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
INVALIDATE 1 1 1 1 0 1 0 0 1 <1> 1 0 <8> 1 1 <2> 1 1 <6>
|
||||
INVALIDATE 1 1 1 1 0 1 0 0 1 <1> 1 0 <8> 1 1 <2> 0 0 <1> 1 <4>
|
||||
INVALIDATE 1 1 1 1 0 1 0 0 1 <1> 1 0 <8> 1 1 1 0 <3> 1 <4>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 0 @<1> 1 1 0 1 @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 0 @<1> 1 1 1 1 @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 0 @<1> Rm @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 1 @<1> 1 1 0 1 @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + d]\[]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 1 @<1> 1 1 1 1 @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + d]\[]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 0 size 1 @<1> Rm @ param=1 char align[4] !@ %@ sprintf(align, ":%d", 8 << size)@ align[0] = '\0'@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + d]\[]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 0 @<4> 1 1 0 1 @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 0 @<4> 1 1 1 1 @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 0 @<4> Rm @ set uint8_t temp = (2 << size) - 1@ set uint8_t temp2 = param & temp@ temp2=0=param>>1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 8 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ @ VLD1<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 1 size @<1> @<1> 1 1 0 1 @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 16 << size)@ align[0] = '\0'@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 1 size @<1> @<1> 1 1 1 1 @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 16 << size)@ align[0] = '\0'@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 0 1 size @<1> @<1> Rm @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 16 << size)@ align[0] = '\0'@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 1 @<4> 1 1 0 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 1 @<4> 1 1 1 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 0 1 @<4> Rm @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0=1 char align[5] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", 16 << size)@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD2<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 0 size @<1> @<1> 1 1 0 1 VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[]}, [<Rn>]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 0 size @<1> @<1> 1 1 1 1 VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[]}, [<Rn>]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 0 size @<1> @<1> Rm VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[]}, [<Rn>], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 0 @<4> 1 1 0 1 @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 0 @<4> 1 1 1 1 @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 0 @<4> Rm @ set uint8_t temp = param & (1 << size)@ temp=0 uint8_t spacing spacing,0,1@ set uint8_t x = param >> (size + 1)@ @ VLD3<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\]}, [<Rn>], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 1 size @<1> @<1> 1 1 0 1 @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 32 << size)@ align[0] = '\0'@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[], \vecname[0x23 + param1_1+param1_1+param1_1 + d]\[]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 1 size @<1> @<1> 1 1 1 1 @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 32 << size)@ align[0] = '\0'@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[], \vecname[0x23 + param1_1+param1_1+param1_1 + d]\[]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd 1 1 1 1 size @<1> @<1> Rm @ param2_1=1 char align[5] !@ %@ sprintf(align, ":%d", 32 << size)@ align[0] = '\0'@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[], \vecname[0x21 + param1_1 + d]\[], \vecname[0x22 + param1_1+param1_1 + d]\[], \vecname[0x23 + param1_1+param1_1+param1_1 + d]\[]}, [<Rn>\align\], <Rm>
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 1 @<4> 1 1 0 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\]!
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 1 @<4> 1 1 1 1 @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\]
|
||||
NEON 1 1 1 1 0 1 0 0 1 D 1 0 Rn Vd size 1 1 @<4> Rm @ size=0b00=0b01 uint8_t temp temp,1,1,3@ set uint8_t temp2 = param & temp@ temp2=0b0=0b1=0b10 char align[6] !@ %@ align[0] = '\0'@ sprintf(align, ":%d", (size ? 64 : 32))@ sprintf(align, ":128")@ sprintf(align, "???")@ set uint8_t x = param >> (size + 1)@ set int spacing = size ? ((param >> size) & 1) : 0@ @ VLD4<c>.\%d8 &l&l size\ {\vecname[0x20 + d]\[\%dx\], \vecname[0x21 + d + spacing]\[\%dx\], \vecname[0x22 + d + 2*spacing]\[\%dx\], \vecname[0x23 + d + 3*spacing]\[\%dx\]}, [<Rn>\align\], <Rm>
|
||||
INVALIDATE 1 1 1 1 0 1 0 0 <3> 0 <20>
|
||||
|
||||
ARM_ 1 1 1 1 0 1 0 0 @<1> 0 0 1 Rn @<8> @<4> @<4> 'NOP'
|
||||
ARM_ 1 1 1 1 0 1 0 0 U 1 0 1 Rn (1) (1) (1) (1) imm12 PLI [<Rn>, #+/-<imm12>]
|
||||
;INVALIDATE 1 1 1 1 0 1 0 0 <2> 1 1 <4> <8> <4> <4>
|
||||
ARM_ 1 1 1 1 0 1 0 1 U @<1> 0 1 Rn (1) (1) (1) (1) imm12 PLD\param ? "W" : ""\ [<Rn>, #+/-<imm12>]
|
||||
ARM_ 1 1 1 1 0 1 0 1 U (1) 0 1 1 1 1 1 (1) (1) (1) (1) imm12 PLD [PC, #+/-<imm>]
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 0 1 1 <4> <8> <4> <4>
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 1 1 1 <4> <8> 0 0 0 0 <4>
|
||||
ARM_ 1 1 1 1 0 1 0 1 0 1 1 1 (1) (1) (1) (1) (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 1 (1) (1) (1) (1) CLREX
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 1 1 1 <4> <8> 0 0 1 <1> <4>
|
||||
ARM_ 1 1 1 1 0 1 0 1 0 1 1 1 (1) (1) (1) (1) (1) (1) (1) (1) (0) (0) (0) (0) 0 1 0 0 @<4> @ param=0b1111=0b1110=0b1011=0b1010=0b0111=0b0110=0b0011=0b0010 const char* option option,"SY","ST","ISH","ISHST","NSH","NSHST","OSH","OSHST","!!!"@ @ DSB \option\
|
||||
ARM_ 1 1 1 1 0 1 0 1 0 1 1 1 (1) (1) (1) (1) (1) (1) (1) (1) (0) (0) (0) (0) 0 1 0 1 @<4> @ param=0b1111=0b1110=0b1011=0b1010=0b0111=0b0110=0b0011=0b0010 const char* option option,"SY","ST","ISH","ISHST","NSH","NSHST","OSH","OSHST","!!!"@ @ DMB \option\
|
||||
ARM_ 1 1 1 1 0 1 0 1 0 1 1 1 (1) (1) (1) (1) (1) (1) (1) (1) (0) (0) (0) (0) 0 1 1 0 @<4> @ param=0b1111 const char* option option,"SY","!!!"@ @ ISB \option\
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 1 1 1 <4> <8> 0 1 1 1 <4>
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 1 1 1 <4> <8> 1 <3> <4>
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 0 1 1 1 <4> <8> <4> <4>
|
||||
;INVALIDATE 1 1 1 1 0 1 0 1 1 <1> 1 1 <4> <8> <4> <4>
|
||||
ARM_ 1 1 1 1 0 1 1 0 @<1> 0 0 1 Rn @<8> @<3> 0 @<4> 'NOP'
|
||||
ARMs 1 1 1 1 0 1 1 0 U 1 0 1 Rn (1) (1) (1) (1) imm5 type 0 Rm PLI [<Rn>, +/-<Rm>{, <shift>}]
|
||||
ARMs 1 1 1 1 0 1 1 1 U @<1> 0 1 Rn (1) (1) (1) (1) imm5 type 0 Rm PLD\param ? "W" : ""\ [<Rn>, +/-<Rm>{, <shift>}]
|
||||
;INVALIDATE 1 1 1 1 0 1 1 <3> 1 1 <4> <8> <3> 0 <4>
|
||||
# Permanently undefined
|
||||
INVALIDATE 1 1 1 1 0 1 1 1 1 1 1 1 <4> <8> 1 1 1 1 <4>
|
||||
;INVALIDATE 1 1 1 1 0 <7> <4> <8> <4> <4>
|
||||
|
||||
; ===== No more 1 1 1 1 ..., so invalidate all of them ====
|
||||
INVALIDATE 1 1 1 1 <28>
|
||||
|
||||
|
||||
ARMS cond 0 0 0 0 0 0 0 S Rn Rd imm5 type 0 Rm AND{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 0 0 0 S Rd (0) (0) (0) (0) Rm 1 0 0 1 Rn MUL{S}<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 0 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm STRH<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 0 Rn Rt (0) (0) (0) (0) 1 1 0 1 Rm LDRD<c> <Rt>, <Rt2>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 0 Rn Rt (0) (0) (0) (0) 1 1 1 1 Rm STRD<c> <Rt>, <Rt2>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 1 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm LDRH<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 1 Rn Rt (0) (0) (0) (0) 1 1 0 1 Rm LDRSB<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 0 1 Rn Rt (0) (0) (0) (0) 1 1 1 1 Rm LDRSH<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARMS cond 0 0 0 0 0 0 1 S Rn Rd imm5 type 0 Rm EOR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 0 0 1 S Rd Ra Rm 1 0 0 1 Rn MLA{S}<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 0 U 0 1 0 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm STRHT<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 1 1 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm LDRHT<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 1 1 Rn Rt (0) (0) (0) (0) 1 1 0 1 Rm LDRSBT<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARM_ cond 0 0 0 0 U 0 1 1 Rn Rt (0) (0) (0) (0) 1 1 1 1 Rm LDRSHT<c> <Rt>, [<Rn>], +/-<Rm>
|
||||
ARMS cond 0 0 0 0 0 1 0 S Rn Rd imm5 type 0 Rm SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 0 1 0 0 RdHi RdLo Rm 1 0 0 1 Rn UMAAL<c> <RdLo>, <RdHi>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 0 U 1 0 0 Rn Rt imm4H 1 0 1 1 imm4L STRH<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 0 0 Rn Rt imm4H 1 1 0 1 imm4L LDRD<c> <Rt>, <Rt2>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 0 0 Rn Rt imm4H 1 1 1 1 imm4L STRD<c> <Rt>, <Rt2>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 0 1 Rn Rt imm4H 1 0 1 1 imm4L LDRH<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 0 1 Rn Rt imm4H 1 1 0 1 imm4L LDRSB<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 0 1 Rn Rt imm4H 1 1 1 1 imm4L LDRSH<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARMS cond 0 0 0 0 0 1 1 S Rn Rd imm5 type 0 Rm RSB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 0 1 1 0 Rd Ra Rm 1 0 0 1 Rn MLS<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 0 U 1 1 0 Rn Rt imm4H 1 0 1 1 imm4L STRHT<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 1 1 Rn Rt imm4H 1 0 1 1 imm4L LDRHT<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 1 1 Rn Rt imm4H 1 1 0 1 imm4L LDRSBT<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARM_ cond 0 0 0 0 U 1 1 1 Rn Rt imm4H 1 1 1 1 imm4L LDRSHT<c> <Rt>, [<Rn>], #+/-<imm8>
|
||||
ARMS cond 0 0 0 0 1 0 0 S Rn Rd imm5 type 0 Rm ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 1 0 0 S RdHi RdLo Rm 1 0 0 1 Rn UMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
|
||||
ARMS cond 0 0 0 0 1 0 1 S Rn Rd imm5 type 0 Rm ADC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 1 0 1 S RdHi RdLo Rm 1 0 0 1 Rn UMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
|
||||
ARMS cond 0 0 0 0 1 1 0 S Rn Rd imm5 type 0 Rm SBC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 1 1 0 S RdHi RdLo Rm 1 0 0 1 Rn SMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
|
||||
ARMS cond 0 0 0 0 1 1 1 S Rn Rd imm5 type 0 Rm RSC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 0 1 1 1 S RdHi RdLo Rm 1 0 0 1 Rn SMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 Rd Ra Rm 1 0 0 0 Rn SMLABB<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 Rd Ra Rm 1 0 1 0 Rn SMLATB<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 Rd Ra Rm 1 1 0 0 Rn SMLABT<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 Rd Ra Rm 1 1 1 0 Rn SMLATT<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 Rn Rt (0) (0) (0) (0) 1 0 0 1 Rm SWP<c> <Rt>, <Rm>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 U 0 W 0 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm STRH<c> <Rt>, [<Rn>, +/-<Rm>]{!}
|
||||
ARM_ cond 0 0 0 1 U 0 W 0 Rn Rt (0) (0) (0) (0) 1 1 0 1 Rm LDRD<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}
|
||||
ARM_ cond 0 0 0 1 U 0 W 0 Rn Rt (0) (0) (0) (0) 1 1 1 1 Rm STRD<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}
|
||||
ARMS cond 0 0 0 1 0 0 0 1 Rn (0) (0) (0) (0) imm5 type 0 Rm TST<c> <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 U 0 W 1 Rn Rt (0) (0) (0) (0) 1 0 1 1 Rm LDRH<c> <Rt>, [<Rn>, +/-<Rm>]{!}
|
||||
ARM_ cond 0 0 0 1 U 0 W 1 Rn Rt (0) (0) (0) (0) 1 1 0 1 Rm LDRSB<c> <Rt>, [<Rn>, +/-<Rm>]{!}
|
||||
ARM_ cond 0 0 0 1 U 0 W 1 Rn Rt (0) (0) (0) (0) 1 1 1 1 Rm LDRSH<c> <Rt>, [<Rn>, +/-<Rm>]{!}
|
||||
ARM_ cond 0 0 0 1 0 0 0 0 (1) (1) (1) (1) Rd (0) (0) 0 (0) 0 0 0 0 (0) (0) (0) (0) MRS<c> <Rd>, APSR
|
||||
ARM_ cond 0 0 0 1 0 0 1 0 @<2> 0 0 (1) (1) (1) (1) (0) (0) 0 (0) 0 0 0 0 Rn @ param=0b01=0b10 const char* spec_reg spec_reg,"APSR_g","APSR_nzcvq","APSR_nzcvqg"@ @ MSR<c> \spec_reg\, <Rn>
|
||||
ARM_ cond 0 0 0 1 0 0 1 0 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 0 0 0 1 Rm BX<c> <Rm>
|
||||
ARM_ cond 0 0 0 1 0 0 1 0 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 0 0 1 0 Rm BXJ<c> <Rm>
|
||||
ARM_ cond 0 0 0 1 0 0 1 0 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 0 0 1 1 Rm BLX<c> <Rm>
|
||||
ARM_ cond/=1110 0 0 0 1 0 0 1 0 imm12 0 1 1 1 imm4 BKPT #<imm16>
|
||||
ARMS cond 0 0 0 1 0 0 1 1 Rn (0) (0) (0) (0) imm5 type 0 Rm TEQ<c> <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 0 1 0 0 Rn Rt (0) (0) (0) (0) 1 0 0 1 Rm SWPB<c> <Rt>, <Rm>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 0 1 1 0 (1) (1) (1) (1) Rd (1) (1) (1) (1) 0 0 0 1 Rm CLZ<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 0 0 1 U 1 W 0 Rn Rt imm4H 1 0 1 1 imm4L STRH<c> <Rt>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARM_ cond 0 0 0 1 U 1 W 0 Rn Rt imm4H 1 1 0 1 imm4L LDRD<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARM_ cond 0 0 0 1 U 1 W 0 Rn Rt imm4H 1 1 1 1 imm4L STRD<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARMS cond 0 0 0 1 0 1 0 1 Rn (0) (0) (0) (0) imm5 type 0 Rm CMP<c> <Rn>, <Rm>{, <shift>}
|
||||
ARMS cond 0 0 0 1 0 1 1 1 Rn (0) (0) (0) (0) imm5 type 0 Rm CMN<c> <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 U 1 W 1 Rn Rt imm4H 1 0 1 1 imm4L LDRH<c> <Rt>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARM_ cond 0 0 0 1 U 1 W 1 Rn Rt imm4H 1 1 0 1 imm4L LDRSB<c> <Rt>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARM_ cond 0 0 0 1 U 1 W 1 Rn Rt imm4H 1 1 1 1 imm4L LDRSH<c> <Rt>, [<Rn>, #+/-<imm8>]{!}
|
||||
ARMS cond 0 0 0 1 1 0 0 S Rn Rd imm5 type 0 Rm ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 1 0 0 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREX<c> <Rd>, <Rt>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 1 0 0 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREX<c> <Rt>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd 0 0 0 0 0 0 0 0 Rm MOV{S}<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd imm5 0 0 0 Rm LSL{S}<c> <Rd>, <Rm>, #<imm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd Rm 0 0 0 1 Rn LSL{S}<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd imm5 0 1 0 Rm LSR{S}<c> <Rd>, <Rm>, #<imm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd Rm 0 0 1 1 Rn LSR{S}<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd imm5 1 0 0 Rm ASR{S}<c> <Rd>, <Rm>, #<imm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd Rm 0 1 0 1 Rn ASR{S}<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd 0 0 0 0 0 1 1 0 Rm RRX{S}<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd imm5 1 1 0 Rm ROR{S}<c> <Rd>, <Rm>, #<imm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 S (0) (0) (0) (0) Rd Rm 0 1 1 1 Rn ROR{S}<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 0 0 1 1 0 1 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREXD<c> <Rd>, <Rt>, <Rt2>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 1 0 1 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREXD<c> <Rt>, <Rt2>, [<Rn>]
|
||||
ARMS cond 0 0 0 1 1 1 0 S Rn Rd imm5 type 0 Rm BIC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 1 1 0 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREXB<c> <Rd>, <Rt>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 1 1 0 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREXB<c> <Rt>, [<Rn>]
|
||||
ARMS cond 0 0 0 1 1 1 1 S (0) (0) (0) (0) Rd imm5 type 0 Rm MVN{S}<c> <Rd>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 0 0 1 1 1 1 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREXH<c> <Rd>, <Rt>, [<Rn>]
|
||||
ARM_ cond 0 0 0 1 1 1 1 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREXH<c> <Rt>, [<Rn>]
|
||||
ARM_ cond 0 0 1 0 0 0 0 S Rn Rd imm12 AND{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 0 0 1 S Rn Rd imm12 EOR{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 0 1 0 S Rn Rd imm12 SUB{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 0 1 1 S Rn Rd imm12 RSB{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 1 0 0 S Rn Rd imm12 ADD{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 1 0 1 S Rn Rd imm12 ADC{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 1 1 0 S Rn Rd imm12 SBC{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 0 1 1 1 S Rn Rd imm12 RSC{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 0 0 0 0 imm4 Rd imm12 MOVW<c> <Rd>, #<imm16>
|
||||
ARM_ cond 0 0 1 1 0 0 0 1 Rn (0) (0) (0) (0) imm12 TST<c> <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 0 0 0 0 0 NOP<c>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 0 0 0 0 1 YIELD<c>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 0 0 0 1 0 WFE<c>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 0 0 0 1 1 WFI<c>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 0 0 1 0 0 SEV<c>
|
||||
ARM_ cond/=1110 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 1 0 1 0 0 CSDB<c>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 1 1 1 1 imm4 DBG<c> #<imm>
|
||||
INVALIDATE <4> 0 0 1 1 0 0 1 0 0 0 0 0 <8> <8>
|
||||
ARM_ cond 0 0 1 1 0 0 1 0 @<2> 0 0 (1) (1) (1) (1) imm12 @ param=0b01=0b10 const char* spec_reg spec_reg,"APSR_g","APSR_nzcvq","APSR_nzcvqg"@ @ MSR<c> \spec_reg\, #<imm>
|
||||
# MSR in system level is invalid/useless in application level
|
||||
INVALIDATE <4> 0 0 1 1 0 0 1 0 <2> 0 1 <8> <8>
|
||||
INVALIDATE <4> 0 0 1 1 0 0 1 0 <2> 1 <1> <8> <8>
|
||||
INVALIDATE <4> 0 0 1 1 0 1 1 0 <4> <8> <8>
|
||||
ARM_ cond 0 0 1 1 0 0 1 1 Rn (0) (0) (0) (0) imm12 TEQ<c> <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 0 1 0 0 imm4 Rd imm12 MOVT<c> <Rd>, #<imm16>
|
||||
ARM_ cond 0 0 1 1 0 1 0 1 Rn (0) (0) (0) (0) imm12 CMP<c> <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 0 1 1 1 Rn (0) (0) (0) (0) imm12 CMN<c> <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 1 0 0 S Rn Rd imm12 ORR{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 1 0 1 S (0) (0) (0) (0) Rd imm12 MOV{S}<c> <Rd>, #<const>
|
||||
ARM_ cond 0 0 1 1 1 1 0 S Rn Rd imm12 BIC{S}<c> <Rd>, <Rn>, #<const>
|
||||
ARM_ cond 0 0 1 1 1 1 1 S (0) (0) (0) (0) Rd imm12 MVN{S}<c> <Rd>, #<const>
|
||||
ARM_ cond 0 1 0 0 1 0 0 1 1 1 0 1 Rt 0 0 0 0 0 0 0 0 0 1 0 0 POP<c> {<Rt>}
|
||||
ARM_ cond 0 1 0 0 U 0 0 0 Rn Rt imm12 STR<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 0 0 1 Rn Rt imm12 LDR<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 0 1 0 Rn Rt imm12 STRT<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 0 1 1 Rn Rt imm12 LDRT<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 1 0 0 Rn Rt imm12 STRB<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 1 0 1 Rn Rt imm12 LDRB<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 1 1 0 Rn Rt imm12 STRBT<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 0 U 1 1 1 Rn Rt imm12 LDRBT<c> <Rt>, [<Rn>], #+/-<imm12>
|
||||
ARM_ cond 0 1 0 1 0 0 1 0 1 1 0 1 Rt 0 0 0 0 0 0 0 0 0 1 0 0 PUSH<c> {<Rt>}
|
||||
ARM_ cond 0 1 0 1 U 0 W 0 Rn Rt imm12 STR<c> <Rt>, [<Rn>, #+/-<imm12>]{!}
|
||||
ARM_ cond 0 1 0 1 U 0 W 1 Rn Rt imm12 LDR<c> <Rt>, [<Rn>, #+/-<imm12>]{!}
|
||||
ARM_ cond 0 1 0 1 U 1 W 0 Rn Rt imm12 STRB<c> <Rt>, [<Rn>, #+/-<imm12>]{!}
|
||||
ARM_ cond 0 1 0 1 U 1 W 1 Rn Rt imm12 LDRB<c> <Rt>, [<Rn>, #+/-<imm12>]{!}
|
||||
ARM_ cond 0 1 1 0 0 0 0 1 Rn Rd (1) (1) (1) (1) 0 1 0 1 Rm SSAX<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 0 0 0 0 1 Rn Rd (1) (1) (1) (1) 0 1 1 1 Rm SSUB16<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 0 0 0 0 1 Rn Rd (1) (1) (1) (1) 1 1 1 1 Rm SSUB8<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 0 0 1 0 1 Rn Rd (1) (1) (1) (1) 0 1 0 1 Rm USAX<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 0 0 1 0 1 Rn Rd (1) (1) (1) (1) 0 1 1 1 Rm USUB16<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 0 0 1 0 1 Rn Rd (1) (1) (1) (1) 1 1 1 1 Rm USUB8<c> <Rd>, <Rn>, <Rm>
|
||||
ARMs cond 0 1 1 0 1 0 0 0 Rn Rd imm5 0 0 1 Rm PKHBT<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 1 0 0 0 Rn Rd imm5 1 0 1 Rm PKHTB<c> <Rd>, <Rn>, <Rm>{, <shift>}
|
||||
ARM_ cond 0 1 1 0 1 0 0 0 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm SXTB16<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 0 0 0 Rn Rd rotate (0) (0) 0 1 1 1 Rm SXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARMs cond 0 1 1 0 1 0 1 sat_imm Rd imm5 sh 0 1 Rn SSAT<c> <Rd>, #<imm>, <Rn>{, <shift>}
|
||||
ARM_ cond 0 1 1 0 1 0 1 0 sat_imm Rd (1) (1) (1) (1) 0 0 1 1 Rn SSAT16<c> <Rd>, #<imm>, <Rn>
|
||||
ARM_ cond 0 1 1 0 1 0 1 0 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm SXTB<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 0 1 0 Rn Rd rotate (0) (0) 0 1 1 1 Rm SXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 0 1 1 (1) (1) (1) (1) Rd (1) (1) (1) (1) 0 0 1 1 Rm REV<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 1 1 0 1 0 1 1 (1) (1) (1) (1) Rd (1) (1) (1) (1) 1 0 1 1 Rm REV16<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 1 1 0 1 0 1 1 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm SXTH<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 0 1 1 Rn Rd rotate (0) (0) 0 1 1 1 Rm SXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 1 0 0 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm UXTB16<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 1 0 0 Rn Rd rotate (0) (0) 0 1 1 1 Rm UXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARMs cond 0 1 1 0 1 1 1 sat_imm Rd imm5 sh 0 1 Rn USAT<c> <Rd>, #<imm>, <Rn>{, <shift>}
|
||||
ARM_ cond 0 1 1 0 1 1 1 0 sat_imm Rd (1) (1) (1) (1) 0 0 1 1 Rn USAT16<c> <Rd>, #<imm>, <Rn>
|
||||
ARM_ cond 0 1 1 0 1 1 1 0 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm UXTB<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 1 1 0 Rn Rd rotate (0) (0) 0 1 1 1 Rm UXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 1 1 1 (1) (1) (1) (1) Rd (1) (1) (1) (1) 0 0 1 1 Rm RBIT<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 1 1 0 1 1 1 1 1 1 1 1 Rd rotate (0) (0) 0 1 1 1 Rm UXTH<c> <Rd>, <Rm>{, <rotation>}
|
||||
ARM_ cond 0 1 1 0 1 1 1 1 (1) (1) (1) (1) Rd (1) (1) (1) (1) 1 0 1 1 Rm REVSH<c> <Rd>, <Rm>
|
||||
ARM_ cond 0 1 1 0 1 1 1 1 Rn Rd rotate (0) (0) 0 1 1 1 Rm UXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
ARMs cond 0 1 1 0 U 0 0 0 Rn Rt imm5 type 0 Rm STR<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 0 0 1 Rn Rt imm5 type 0 Rm LDR<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 0 1 0 Rn Rt imm5 type 0 Rm STRT<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 0 1 1 Rn Rt imm5 type 0 Rm LDRT<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 1 0 0 Rn Rt imm5 type 0 Rm STRB<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 1 0 1 Rn Rt imm5 type 0 Rm LDRB<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 1 1 0 Rn Rt imm5 type 0 Rm STRBT<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARMs cond 0 1 1 0 U 1 1 1 Rn Rt imm5 type 0 Rm LDRBT<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
|
||||
ARM_ cond 0 1 1 1 0 0 0 1 Rd (1) (1) (1) (1) Rm 0 0 0 1 Rn SDIV<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 1 0 0 1 1 Rd (1) (1) (1) (1) Rm 0 0 0 1 Rn UDIV<c> <Rd>, <Rn>, <Rm>
|
||||
ARMs cond 0 1 1 1 U 0 W 0 Rn Rt imm5 type 0 Rm STR<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
|
||||
ARMs cond 0 1 1 1 U 0 W 1 Rn Rt imm5 type 0 Rm LDR<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
|
||||
ARMs cond 0 1 1 1 U 1 W 0 Rn Rt imm5 type 0 Rm STRB<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
|
||||
ARMs cond 0 1 1 1 U 1 W 1 Rn Rt imm5 type 0 Rm LDRB<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
|
||||
ARM_ cond 0 1 1 1 1 0 0 0 Rd 1 1 1 1 Rm 0 0 0 1 Rn USAD8<c> <Rd>, <Rn>, <Rm>
|
||||
ARM_ cond 0 1 1 1 1 0 0 0 Rd Ra Rm 0 0 0 1 Rn USADA8<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||
ARM_ cond 0 1 1 1 1 1 0 msb Rd lsb 0 0 1 1 1 1 1 BFC<c> <Rd>, #<lsb>, #<width>
|
||||
ARM_ cond 0 1 1 1 1 1 0 msb Rd lsb 0 0 1 Rn BFI<c> <Rd>, <Rn>, #<lsb>, #<width>
|
||||
ARM_ cond 0 1 1 1 1 1 1 widthm1 Rd lsb 1 0 1 Rn UBFX<c> <Rd>, <Rn>, #<lsb>, #<width>
|
||||
ARM_ cond/=1110 0 1 1 1 1 1 1 1 imm12 1 1 1 1 imm4 UDF<c> #<imm16>
|
||||
ARM_ cond 1 0 0 0 0 0 W 0 Rn/=1101 register_list STMED<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 0 0 W 0 Rn register_list STMDA<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 0 0 W 1 Rn/=1101 register_list LDMED<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 0 0 W 1 Rn register_list LDMDA<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 1 0 W 0 Rn/=1101 register_list STMEA<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 1 0 W 0 Rn register_list STM<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 0 1 0 0 1 Rn/=1101 register_list LDMEA<c> <Rn>, <registers>
|
||||
ARM_ cond 1 0 0 0 1 0 1 1 1 1 0 1 register_list @ = const char* op @@ (reglist != 0) && ((reglist & (reglist - 1)) == 0)@ op,"POP","LDMEA"@ @ \op\<c> <registers>
|
||||
ARM_ cond 1 0 0 0 1 0 W 1 Rn register_list LDM<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 0 0 0 0 Rn/=1101 register_list STMFD<c> <Rn>, <registers>
|
||||
ARM_ cond 1 0 0 1 0 0 1 0 1 1 0 1 register_list @ = const char* op @@ (reglist != 0) && ((reglist & (reglist - 1)) == 0)@ op,"PUSH","STMFD"@ @ \op\<c> <registers>
|
||||
ARM_ cond 1 0 0 1 0 0 W 0 Rn register_list STMDB<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 0 0 W 1 Rn/=1101 register_list LDMFD<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 0 0 W 1 Rn register_list LDMDB<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 1 0 W 0 Rn/=1101 register_list STMFA<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 1 0 W 0 Rn register_list STMIB<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 1 0 W 1 Rn/=1101 register_list LDMFA<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 0 1 1 0 W 1 Rn register_list LDMIB<c> <Rn>{!}, <registers>
|
||||
ARM_ cond 1 0 1 0 imm24 B<c> <label>
|
||||
ARM_ cond 1 0 1 1 imm24 BL<c> <label>
|
||||
|
||||
VFPU cond 1 1 0 0 0 1 0 0 Rn Rt 1 0 1 0 0 0 M 1 Vm VMOV<c> <Sm>, <Sm1>, <Rt>, <Rn>
|
||||
VFPU cond 1 1 0 0 0 1 0 1 Rn Rt 1 0 1 0 0 0 M 1 Vm VMOV<c> <Rt>, <Rn>, <Sm>, <Sm1>
|
||||
VFPU cond 1 1 0 0 0 1 0 0 Rn Rt 1 0 1 1 0 0 M 1 Vm VMOV<c> <Dm>, <Rt>, <Rn>
|
||||
VFPU cond 1 1 0 0 0 1 0 1 Rn Rt 1 0 1 1 0 0 M 1 Vm VMOV<c> <Rt>, <Rn>, <Dm>
|
||||
;INVALIDATE <4> 1 1 0 0 0 1 0 <9> 1 0 1 <9>
|
||||
|
||||
INVALIDATE <4> 1 1 0 0 0 <11> 1 0 1 <9>
|
||||
INVALIDATE <4> 1 1 0 0 0 <11> 1 0 1 <9>
|
||||
INVALIDATE <4> 1 1 0 1 1 <1> 1 <9> 1 0 1 <9>
|
||||
INVALIDATE <4> 1 1 0 1 1 <1> 1 <9> 1 0 1 <9>
|
||||
VFPU cond 1 1 0 1 0 D 1 0 1 1 0 1 Vd 1 0 1 1 imm8/01 @ set --imm8@ @ FSTMX<c> <LIst>
|
||||
VFPU cond 1 1 0 1 0 D 1 0 1 1 0 1 Vd 1 0 1 sz imm8 VPUSH<c> <list>
|
||||
VFPU cond 1 1 0 1 U D 0 0 Rn Vd 1 0 1 sz imm8 @ set imm8*=4@ @ VSTR<c> <Dd>, [<Rn>{, #+/-<imm>}]
|
||||
VFPU cond 1 1 0 @<2> D W 0 Rn Vd 1 0 1 1 imm8/01 @ set --imm8@ @ FSTM\(param == 0b01 ? "IA" : "DB")\X<c> <Rn>{!}, <LIst>
|
||||
VFPU cond 1 1 0 @<2> D W 0 Rn Vd 1 0 1 sz imm8 VSTM\(param == 0b01 ? "IA" : "DB")\<c> <Rn>{!}, <list>
|
||||
VFPU cond 1 1 0 0 1 D 1 1 1 1 0 1 Vd 1 0 1 1 imm8/01 @ set --imm8@ @ FLDMX<c> <LIst>
|
||||
VFPU cond 1 1 0 0 1 D 1 1 1 1 0 1 Vd 1 0 1 sz imm8 VPOP<c> <list>
|
||||
VFPU cond 1 1 0 1 0 D 0 1 1 1 1 1 Vd 1 0 1 sz 0 0 0 0 0 0 0 0 VLDR<c> <Dd>, [PC, #-0]
|
||||
VFPU cond 1 1 0 1 U D 0 1 1 1 1 1 Vd 1 0 1 sz imm8 VLDR<c> <Dd>, <label>
|
||||
VFPU cond 1 1 0 1 U D 0 1 Rn Vd 1 0 1 sz imm8 @ set imm8*=4@ @ VLDR<c> <Dd>, [<Rn>{, #+/-<imm>}]
|
||||
VFPU cond 1 1 0 @<2> D W 1 Rn Vd 1 0 1 1 imm8/01 @ set --imm8@ @ FLDM\(param == 0b01 ? "IA" : "DB")\X<c> <Rn>{!}, <LIst>
|
||||
VFPU cond 1 1 0 @<2> D W 1 Rn Vd 1 0 1 sz imm8 VLDM\(param == 0b01 ? "IA" : "DB")\<c> <Rn>{!}, <list>
|
||||
INVALIDATE <4> 1 1 0 <25>
|
||||
|
||||
INVALIDATE <4> 1 1 1 0 0 0 <1> 0 <8> 1 0 1 1 <1> 1 0 1 (0) (0) (0) (0)
|
||||
;INVALIDATE <4> 1 1 1 0 1 <2> 0 <8> 1 0 1 1 <1> 0 <1> 1 (0) (0) (0) (0)
|
||||
VFPU cond 1 1 1 0 0 0 0 0 Vn Rt 1 0 1 0 N (0) (0) 1 (0) (0) (0) (0) VMOV<c> <Sn>, <Rt>
|
||||
VFPU cond 1 1 1 0 1 1 1 0 0 0 0 1 Rt 1 0 1 0 (0) (0) (0) 1 (0) (0) (0) (0) VMSR<c> FPSCR, <Rt>
|
||||
VFPU cond 1 1 1 0 0 @<2> 0 Vd Rt 1 0 1 1 D @<2> 1 (0) (0) (0) (0) @ set uint8_t opc = (param1_2 << 2) + param2_2@ = uint8_t shift @@ (opc & 0b1000) == 0b1000@ @@ (opc & 0b1001) == 0b0001@ @@ (opc & 0b1011) == 0b0000@ shift,0,1,2,0xFF@ set uint8_t decodedImm = (opc & 0x7) >> shift@ @ VMOV<c>.\%d8 &l&l shift\ <Dd[x]>, <Rt>
|
||||
VFPU cond 1 1 1 0 1 0 Q 0 Vd Rt 1 0 1 1 D 0 0 1 (0) (0) (0) (0) VDUP<c>.32 <Qd>, <Rt>
|
||||
VFPU cond 1 1 1 0 1 0 Q 0 Vd Rt 1 0 1 1 D 0 1 1 (0) (0) (0) (0) VDUP<c>.16 <Qd>, <Rt>
|
||||
VFPU cond 1 1 1 0 1 1 Q 0 Vd Rt 1 0 1 1 D 0 0 1 (0) (0) (0) (0) VDUP<c>.8 <Qd>, <Rt>
|
||||
VFPU cond 1 1 1 0 0 0 0 1 Vn Rt 1 0 1 0 N (0) (0) 1 (0) (0) (0) (0) VMOV<c> <Rt>, <Sn>
|
||||
VFPU cond 1 1 1 0 1 1 1 1 0 0 0 1 Rt/=1111 1 0 1 0 (0) (0) (0) 1 (0) (0) (0) (0) VMRS<c> APSR_nzcv, FPSCR
|
||||
VFPU cond 1 1 1 0 1 1 1 1 0 0 0 1 Rt 1 0 1 0 (0) (0) (0) 1 (0) (0) (0) (0) VMRS<c> <Rt>, FPSCR
|
||||
VFPU cond 1 1 1 0 U @<2> 1 Vn Rt 1 0 1 1 N @<2> 1 (0) (0) (0) (0) @ set uint8_t opc = (u << 4) + (param1_2 << 2) + param2_2@ = uint8_t shift, size @@ (opc & 0b01000) == 0b01000@ @@ (opc & 0b01001) == 0b00001@ @@ (opc & 0b11011) == 0b00000@ shift,0,1,2,0xFF;size,0,1,2,4@ set uint8_t decodedImm = (opc & 0x7) >> shift@ @ VMOV<c>.<dt> <Rt>, <Dn[x]>
|
||||
INVALIDATE <4> 1 1 1 0 <12> 1 0 1 <4> 1 <4>
|
||||
|
||||
VFPU cond 1 1 1 0 0 D 0 0 Vn Vd 1 0 1 sz N op M 0 Vm VML\(op ? "S" : "A")\<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 0 D 0 1 Vn Vd 1 0 1 sz N op M 0 Vm VNML\(op ? "S" : "A")\<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 0 D 1 0 Vn Vd 1 0 1 sz N 0 M 0 Vm VMUL<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 0 D 1 0 Vn Vd 1 0 1 sz N 1 M 0 Vm VNMUL<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 0 D 1 1 Vn Vd 1 0 1 sz N 0 M 0 Vm VADD<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 0 D 1 1 Vn Vd 1 0 1 sz N 1 M 0 Vm VSUB<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 0 0 Vn Vd 1 0 1 sz N 0 M 0 Vm VDIV<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 0 1 Vn Vd 1 0 1 sz N op M 0 Vm VFNM\(op ? "A" : "S")\<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 0 Vn Vd 1 0 1 sz N op M 0 Vm VFM\(op ? "S" : "A")\<c>.F\(size ? "64" : "32")\ <Dd>, <Dn>, <Dm>
|
||||
|
||||
!/VFPU cond 1 1 1 0 1 x 1 1 opc2 <4> 1 0 1 <1> - - <1> 0 opc4 Table A7-17
|
||||
VFPU cond 1 1 1 0 1 D 1 1 @<4> Vd 1 0 1 0 (0) 0 (0) 0 @<4> @ set int8_t sign = (param1_4 >> 3) ? -1 : 1@ set uint8_t exp = ((param1_4 & 0b111) ^ 0b100)@ set float mantissa = 16 + param2_4@ set float imm = sign * (1 << exp) * mantissa / 128.@ @ VMOV<c>.F32 <Sd>, #\%fimm\
|
||||
VFPU cond 1 1 1 0 1 D 1 1 @<4> Vd 1 0 1 1 (0) 0 (0) 0 @<4> @ set int8_t sign = (param1_4 >> 3) ? -1 : 1@ set uint8_t exp = ((param1_4 & 0b111) ^ 0b100)@ set double mantissa = 16 + param2_4@ set double imm = sign * (1 << exp) * mantissa / 128.@ @ VMOV<c>.F64 <Dd>, #\%fimm\
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 0 0 Vd 1 0 1 sz 0 1 M 0 Vm VMOV<c>.F\(size ? "64" : "32")\ <Dd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 0 0 Vd 1 0 1 sz 1 1 M 0 Vm VABS<c>.F\(size ? "64" : "32")\ <Dd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 0 1 Vd 1 0 1 sz 0 1 M 0 Vm VNEG<c>.F\(size ? "64" : "32")\ <Dd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 0 1 Vd 1 0 1 sz 1 1 M 0 Vm VSQRT<c>.F\(size ? "64" : "32")\ <Dd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 1 0 Vd 1 0 1 (0) @<1> 1 M 0 Vm VCVT\(param ? "T" : "B")\<c>.F32.F16 <Sd>, <Sm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 0 1 1 Vd 1 0 1 (0) @<1> 1 M 0 Vm VCVT\(param ? "T" : "B")\<c>.F16.F32 <Sd>, <Sm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 1 0 0 Vd 1 0 1 sz op 1 M 0 Vm VCMP\(op ? "E" : "")\<c>.F\(size ? "64" : "32")\ <Dd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 1 0 1 Vd 1 0 1 sz op 1 (0) 0 (0) (0) (0) (0) VCMP\(op ? "E" : "")\<c>.F\(size ? "64" : "32")\ <Dd>, #0.0
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 1 1 1 Vd 1 0 1 0 1 1 M 0 Vm VCVT<c>.F64.F32 <Dd>, <Sm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 0 1 1 1 Vd 1 0 1 1 1 1 M 0 Vm VCVT<c>.F32.F64 <Sd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 1 0 0 0 Vd 1 0 1 sz op 1 M 0 Vm VCVT<c>.F\(size ? "64" : "32")\.\(op ? "S" : "U")\32 <Dd>, <Sm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 1 0 1 U Vd 1 0 1 sz op 1 i 0 imm4 @ set uint8_t td = (u << 2) + op + 1@ td=0b001=0b010=0b101 const char* Td Td,"S16","U16","S32","U32"@ set imm5 = (16 << op) - (imm5 >> 4) - ((imm5 & 0xF) << 1)@ @ VCVT<c>.F\(size ? "64" : "32")\.\Td\ <Dd>, <Dd>, #<imm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 1 1 U 1 Vd 1 0 1 sz op 1 M 0 Vm VCVT\(op ? "" : "R")\<c>.\(u ? "U" : "S")\32.F\(size ? "64" : "32")\ <Sd>, <Dm>
|
||||
VFPU cond 1 1 1 0 1 D 1 1 1 1 1 U Vd 1 0 1 sz op 1 i 0 imm4 @ set uint8_t td = (u << 2) + op + 1@ td=0b001=0b010=0b101 const char* Td Td,"S16","U16","S32","U32"@ set imm5 = (16 << op) - (imm5 >> 4) - ((imm5 & 0xF) << 1)@ @ VCVT<c>.\Td\.F\(size ? "64" : "32")\ <Dd>, <Dd>, #<imm>
|
||||
;INVALIDATE <4> 1 1 1 0 1 <1> 1 1 <8> 1 0 1 <4> 0 <4>
|
||||
;INVALIDATE <4> 1 1 1 0 <12> 1 0 1 <4> 0 <4>
|
||||
|
||||
; ============= END OF REGISTERED INSTRUCTIONS ============
|
||||
INVALIDATE <32>
|
||||
Executable
+206
@@ -0,0 +1,206 @@
|
||||
// arm lock helper
|
||||
// there is 2 part: read and write
|
||||
// write return 0 on success, 1 on fail (value has been changed)
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.global arm_lock_read_b
|
||||
.global arm_lock_write_b
|
||||
.global arm_lock_read_h
|
||||
.global arm_lock_write_h
|
||||
.global arm_lock_read_d
|
||||
.global arm_lock_write_d
|
||||
.global arm_lock_read_dd
|
||||
.global arm_lock_write_dd
|
||||
.global arm_lock_xchg
|
||||
.global arm_lock_storeifnull
|
||||
.global arm_lock_storeifref
|
||||
.global arm_lock_storeifref2
|
||||
.global arm_lock_decifnot0b
|
||||
.global arm_lock_incb
|
||||
.global arm_lock_incif0b
|
||||
.global arm_lock_stored
|
||||
.global arm_lock_storeb
|
||||
.global arm_lock_storeif0b
|
||||
.global arm_lock_readb
|
||||
|
||||
arm_lock_read_b:
|
||||
// address is r0, return is r0
|
||||
dmb ish
|
||||
ldrexb r0, [r0]
|
||||
bx lr
|
||||
|
||||
arm_lock_write_b:
|
||||
// address is r0, value is r1, return is r0
|
||||
mov r2, r0
|
||||
strexb r0, r1, [r2]
|
||||
bx lr
|
||||
|
||||
arm_lock_read_h:
|
||||
// address is r0, return is r0
|
||||
dmb ish
|
||||
ldrexh r0, [r0]
|
||||
bx lr
|
||||
|
||||
arm_lock_write_h:
|
||||
// address is r0, value is r1, return is r0
|
||||
mov r2, r0
|
||||
strexh r0, r1, [r2]
|
||||
bx lr
|
||||
|
||||
arm_lock_read_d:
|
||||
// address is r0, return is r0
|
||||
// r0 needs to be aligned
|
||||
dmb ish
|
||||
ldrex r0, [r0]
|
||||
bx lr
|
||||
|
||||
arm_lock_write_d:
|
||||
// address is r0, value is r1, return is r0
|
||||
// r0 needs to be aligned
|
||||
mov r2, r0
|
||||
strex r0, r1, [r2]
|
||||
bx lr
|
||||
|
||||
arm_lock_read_dd:
|
||||
// address is r2, return is r0, r1
|
||||
dmb ish
|
||||
ldrexd r2, r3, [r2]
|
||||
str r2, [r0]
|
||||
str r3, [r1]
|
||||
bx lr
|
||||
|
||||
arm_lock_write_dd:
|
||||
// address is r2, value is r0, r1, return is r0
|
||||
// r0 needs to be aligned
|
||||
strexd r3, r0, r1, [r2]
|
||||
mov r0, r3
|
||||
bx lr
|
||||
|
||||
arm_lock_xchg:
|
||||
// address is r0, value is r1, return old value in r0
|
||||
// r0 needs to be aligned
|
||||
dmb ish
|
||||
ldrex r2, [r0]
|
||||
strex r3, r1, [r0]
|
||||
cmp r3, #1
|
||||
beq arm_lock_xchg
|
||||
mov r0, r2
|
||||
bx lr
|
||||
|
||||
arm_lock_storeifnull:
|
||||
// address is r0, value is r1, r1 store to r0 only if [r0] is 0. return old [r0] value
|
||||
// r0 needs to be aligned
|
||||
dmb ish
|
||||
ldrex r2, [r0]
|
||||
cmp r2, #0
|
||||
bne arm_lock_storeifnull_exit
|
||||
strex r3, r1, [r0]
|
||||
cmp r3, #1
|
||||
beq arm_lock_storeifnull
|
||||
arm_lock_storeifnull_exit:
|
||||
mov r0, r2
|
||||
bx lr
|
||||
|
||||
arm_lock_storeifref2:
|
||||
dmb ish
|
||||
arm_lock_storeifref2_loop:
|
||||
// address is r0, value is r1, r1 store to r0 only if [r0] is r2. return old [r0] value (so r2 or old value)
|
||||
ldrex r3, [r0]
|
||||
cmp r3, r2
|
||||
movne r0, r3
|
||||
bne arm_lock_storeifref2_exit
|
||||
strex r3, r1, [r0]
|
||||
cmp r3, #1
|
||||
beq arm_lock_storeifref_loop
|
||||
mov r0, r2
|
||||
arm_lock_storeifref2_exit:
|
||||
bx lr
|
||||
|
||||
arm_lock_storeifref:
|
||||
dmb ish
|
||||
arm_lock_storeifref_loop:
|
||||
// address is r0, value is r1, r1 store to r0 only if [r0] is r2. return new [r0] value (so r1 or old value)
|
||||
ldrex r3, [r0]
|
||||
cmp r3, r2
|
||||
movne r0, r3
|
||||
bne arm_lock_storeifref_exit
|
||||
strex r3, r1, [r0]
|
||||
cmp r3, #1
|
||||
beq arm_lock_storeifref_loop
|
||||
mov r0, r1
|
||||
arm_lock_storeifref_exit:
|
||||
bx lr
|
||||
|
||||
arm_lock_decifnot0b:
|
||||
dmb ish
|
||||
arm_lock_decifnot0b_0:
|
||||
ldrexb r1, [r0]
|
||||
cmp r1, #0
|
||||
subne r3, r1, #1
|
||||
moveq r3, r1
|
||||
strexb r2, r3, [r0]
|
||||
cmp r2, #1
|
||||
beq arm_lock_decifnot0b_0
|
||||
dmb ish
|
||||
mov r0, r1
|
||||
bx lr
|
||||
|
||||
arm_lock_incb:
|
||||
dmb ish
|
||||
arm_lock_incb_0:
|
||||
ldrexb r1, [r0]
|
||||
add r1, r1, #1
|
||||
strexb r2, r1, [r0]
|
||||
cmp r2, #1
|
||||
beq arm_lock_incb_0
|
||||
arm_lock_incb_exit:
|
||||
dmb ish
|
||||
bx lr
|
||||
|
||||
arm_lock_incif0b:
|
||||
dmb ish
|
||||
arm_lock_incif0b_0:
|
||||
ldrexb r1, [r0]
|
||||
cmp r1, #0
|
||||
addeq r3, r1, #1
|
||||
movne r3, r1
|
||||
strexb r2, r3, [r0]
|
||||
cmp r2, #1
|
||||
beq arm_lock_incif0b_0
|
||||
dmb ish
|
||||
mov r0, r1
|
||||
bx lr
|
||||
|
||||
arm_lock_stored:
|
||||
dmb ish
|
||||
str r1, [r0]
|
||||
dmb ish
|
||||
bx lr
|
||||
|
||||
arm_lock_storeb:
|
||||
dmb ish
|
||||
strb r1, [r0]
|
||||
dmb ish
|
||||
bx lr
|
||||
|
||||
arm_lock_storeif0b:
|
||||
dmb ish
|
||||
arm_lock_storeif0b_0:
|
||||
ldrexb r2, [r0]
|
||||
cmp r2, #0
|
||||
bne arm_lock_storeif0b_exit
|
||||
strexb r3, r1, [r0]
|
||||
cmp r3, #1
|
||||
beq arm_lock_storeif0b_0
|
||||
mov r2, #0
|
||||
dmb ish
|
||||
arm_lock_storeif0b_exit:
|
||||
mov r0, r2
|
||||
bx lr
|
||||
|
||||
arm_lock_readb:
|
||||
dmb ish
|
||||
ldrb r0, [r0]
|
||||
bx lr
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#ifndef __ARM_LOCK_HELPER__H__
|
||||
#define __ARM_LOCK_HELPER__H__
|
||||
#include <stdint.h>
|
||||
|
||||
// LDREXB of ADDR
|
||||
extern uint8_t arm_lock_read_b(void* addr);
|
||||
// STREXB of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm_lock_write_b(void* addr, uint8_t val);
|
||||
|
||||
// LDREXH of ADDR
|
||||
extern uint16_t arm_lock_read_h(void* addr);
|
||||
// STREXH of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm_lock_write_h(void* addr, uint16_t val);
|
||||
|
||||
// LDREX of ADDR
|
||||
extern uint32_t arm_lock_read_d(void* addr);
|
||||
// STREX of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm_lock_write_d(void* addr, uint32_t val);
|
||||
|
||||
// LDREXD of ADDR
|
||||
extern void arm_lock_read_dd(uint32_t* a, uint32_t* b, void* addr);
|
||||
// STREX of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm_lock_write_dd(uint32_t a, uint32_t b, void* addr);
|
||||
|
||||
// Atomically exchange value at [p] with val, return old p
|
||||
extern uintptr_t arm_lock_xchg(void* p, uintptr_t val);
|
||||
|
||||
// Atomically store value to [p] only if [p] is NULL. Return old [p] value
|
||||
extern void* arm_lock_storeifnull(void* p, void* val);
|
||||
|
||||
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
|
||||
extern void* arm_lock_storeifref(void* p, void* val, void* ref);
|
||||
|
||||
// Atomically store value to [p] only if [p] is ref. Return old [p] value
|
||||
extern void* arm_lock_storeifref2(void* p, void* val, void* ref);
|
||||
|
||||
// decrement atomicaly the byte at [p] (but only if p not 0). Return old [p] value
|
||||
extern int arm_lock_decifnot0b(void*p);
|
||||
|
||||
// increment atomicaly the byte at [p]
|
||||
extern void arm_lock_incb(void*p);
|
||||
|
||||
// increment atomicaly the byte at [p] only if it was 0. Return the old value of [p]
|
||||
extern int arm_lock_incif0b(void*p);
|
||||
|
||||
// atomic store (with memory barrier)
|
||||
extern void arm_lock_stored(void*p, uint32_t d);
|
||||
|
||||
// atomic store (with memory barrier)
|
||||
extern void arm_lock_storeb(void*p, uint8_t b);
|
||||
|
||||
// atomic store (with memory barrier) only if it was 0. Return the old value of [p]
|
||||
extern int arm_lock_storeif0b(void*p, uint8_t b);
|
||||
|
||||
// atomic load (with memory barrier)
|
||||
extern int arm_lock_readb(void*p);
|
||||
|
||||
#endif //__ARM_LOCK_HELPER__H__
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
//arm update linker table for dynarec
|
||||
//called with pointer to emu as 1st parameter
|
||||
//and address of table to as 2nd parameter
|
||||
//ip is at r12
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.extern LinkNext
|
||||
|
||||
.global arm_next
|
||||
.4byte 0 // NULL pointer before arm64_next, for getDB
|
||||
arm_next:
|
||||
// emu is r0
|
||||
//stm r0, {r4-r12,r14} // don't put put back reg value in emu, faster but more tricky to debug
|
||||
// IP address is r1
|
||||
push {r0, r1, r12, r14}
|
||||
// call the function
|
||||
bl LinkNext
|
||||
// return offset is jump address
|
||||
mov r3, r0
|
||||
pop {r0, r1, r12, r14}
|
||||
bx r3
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,6 @@
|
||||
#ifndef _ARM_PRINTER_H_
|
||||
#define _ARM_PRINTER_H_
|
||||
|
||||
const char* arm_print(uint32_t opcode);
|
||||
|
||||
#endif //_ARM_PRINTER_H_
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
//arm prologue for dynarec
|
||||
//Save stuff, prepare stack and register
|
||||
//called with pointer to emu as 1st parameter
|
||||
//and address to jump to as 2nd parameter
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.global arm_prolog
|
||||
arm_prolog:
|
||||
//save all used register
|
||||
push {r4-r12, lr}
|
||||
vpush {d8-d15}
|
||||
//setup emu -> register
|
||||
//push {r0}
|
||||
ldm r0, {r4-r12} // all 8 register in direct access, plus flags, no EIP (so r14 can be used as scratch)
|
||||
//TODO
|
||||
//jump to function
|
||||
bx r1
|
||||
Executable
+344
@@ -0,0 +1,344 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "tools/bridge_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynablock.h"
|
||||
#include "dynablock_private.h"
|
||||
#include "dynarec_private.h"
|
||||
#include "elfloader.h"
|
||||
#include "bridge.h"
|
||||
#ifdef ARM
|
||||
#include "dynarec_arm.h"
|
||||
#include "arm_lock_helper.h"
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
|
||||
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
|
||||
|
||||
uint32_t X31_hash_code(void* addr, int len)
|
||||
{
|
||||
if(!len) return 0;
|
||||
uint8_t* p = (uint8_t*)addr;
|
||||
int32_t h = *p;
|
||||
for (--len, ++p; len; --len, ++p) h = (h << 5) - h + (int32_t)*p;
|
||||
return (uint32_t)h;
|
||||
}
|
||||
|
||||
dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock)
|
||||
{
|
||||
if(db) {
|
||||
if(db->gone)
|
||||
return NULL; // already in the process of deletion!
|
||||
dynarec_log(LOG_DEBUG, "InvalidDynablock(%p), db->block=%p x86=%p:%p already gone=%d\n", db, db->block, db->x86_addr, db->x86_addr+db->x86_size-1, db->gone);
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
// remove jumptable
|
||||
setJumpTableDefault(db->x86_addr);
|
||||
db->done = 0;
|
||||
db->gone = 1;
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
void FreeInvalidDynablock(dynablock_t* db, int need_lock)
|
||||
{
|
||||
if(db) {
|
||||
if(!db->gone)
|
||||
return; // already in the process of deletion!
|
||||
dynarec_log(LOG_DEBUG, "FreeInvalidDynablock(%p), db->block=%p x86=%p:%p already gone=%d\n", db, db->block, db->x86_addr, db->x86_addr+db->x86_size-1, db->gone);
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
FreeDynarecMap((uintptr_t)db->actual_block);
|
||||
customFree(db);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeDynablock(dynablock_t* db, int need_lock)
|
||||
{
|
||||
if(db) {
|
||||
if(db->gone)
|
||||
return; // already in the process of deletion!
|
||||
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x86=%p:%p already gone=%d\n", db, db->block, db->x86_addr, db->x86_addr+db->x86_size-1, db->gone);
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
// remove jumptable
|
||||
setJumpTableDefault(db->x86_addr);
|
||||
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size);
|
||||
db->done = 0;
|
||||
db->gone = 1;
|
||||
if(db->previous)
|
||||
FreeInvalidDynablock(db->previous, 0);
|
||||
FreeDynarecMap((uintptr_t)db->actual_block);
|
||||
customFree(db);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MarkDynablock(dynablock_t* db)
|
||||
{
|
||||
if(db) {
|
||||
dynarec_log(LOG_DEBUG, "MarkDynablock %p %p-%p\n", db, db->x86_addr, db->x86_addr+db->x86_size-1);
|
||||
if(!setJumpTableIfRef(db->x86_addr, db->jmpnext, db->block)) {
|
||||
dynablock_t* old = db;
|
||||
db = getDB((uintptr_t)old->x86_addr);
|
||||
if(!old->gone && db!=old) {
|
||||
printf_log(LOG_INFO, "Warning, couldn't mark block as dirty for %p, block=%p, current_block=%p\n", old->x86_addr, old, db);
|
||||
// the block is lost, need to invalidate it...
|
||||
old->gone = 1;
|
||||
old->done = 0;
|
||||
if(!db || db->previous)
|
||||
FreeInvalidDynablock(old, 1);
|
||||
else
|
||||
db->previous = old;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintptr_t end2)
|
||||
{
|
||||
if(start1 > end2 || start2 > end1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int MarkedDynablock(dynablock_t* db)
|
||||
{
|
||||
if(db) {
|
||||
if(getNeedTest((uintptr_t)db->x86_addr))
|
||||
return 1; // already done
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MarkRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size)
|
||||
{
|
||||
// Mark will try to find *any* blocks that intersect the range to mark
|
||||
if(!db)
|
||||
return;
|
||||
dynarec_log(LOG_DEBUG, "MarkRangeDynablock %p-%p .. startdb=%p, sizedb=%p\n", (void*)addr, (void*)addr+size-1, (void*)db->x86_addr, (void*)db->x86_size);
|
||||
if(IntervalIntersects((uintptr_t)db->x86_addr, (uintptr_t)db->x86_addr+db->x86_size-1, addr, addr+size+1))
|
||||
MarkDynablock(db);
|
||||
}
|
||||
|
||||
int FreeRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size)
|
||||
{
|
||||
if(!db)
|
||||
return 1;
|
||||
|
||||
int need_lock = my_context?1:0;
|
||||
if(IntervalIntersects((uintptr_t)db->x86_addr, (uintptr_t)db->x86_addr+db->x86_size-1, addr, addr+size+1)) {
|
||||
FreeDynablock(db, need_lock);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dynablock_t *AddNewDynablock(uintptr_t addr)
|
||||
{
|
||||
dynablock_t* block;
|
||||
#if 0
|
||||
// check if memory as the correct flags
|
||||
int prot = getProtection(addr);
|
||||
if(!(prot&(PROT_EXEC|PROT_DYNAREC|PROT_DYNAREC_R))) {
|
||||
dynarec_log(LOG_VERBOSE, "Block asked on a memory with no execution flags 0x%02X\n", prot);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
// create and add new block
|
||||
dynarec_log(LOG_VERBOSE, "Ask for DynaRec Block creation @%p\n", (void*)addr);
|
||||
block = (dynablock_t*)customCalloc(1, sizeof(dynablock_t));
|
||||
return block;
|
||||
}
|
||||
|
||||
//TODO: move this to dynrec_arm.c and track allocated structure to avoid memory leak
|
||||
static __thread struct __jmp_buf_tag dynarec_jmpbuf;
|
||||
|
||||
void cancelFillBlock()
|
||||
{
|
||||
longjmp(&dynarec_jmpbuf, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
return NULL if block is not found / cannot be created.
|
||||
Don't create if create==0
|
||||
*/
|
||||
static dynablock_t* internalDBGetBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, int need_lock)
|
||||
{
|
||||
if(hasAlternate((void*)addr))
|
||||
return NULL;
|
||||
dynablock_t* block = getDB(addr);
|
||||
if(block || !create)
|
||||
return block;
|
||||
|
||||
if(need_lock) {
|
||||
if(box86_dynarec_wait) {
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
} else {
|
||||
if(mutex_trylock(&my_context->mutex_dyndump)) // FillBlock not available for now
|
||||
return NULL;
|
||||
}
|
||||
block = getDB(addr); // just in case
|
||||
if(block) {
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
block = AddNewDynablock(addr);
|
||||
|
||||
// fill the block
|
||||
block->x86_addr = (void*)addr;
|
||||
if(sigsetjmp(&dynarec_jmpbuf, 1)) {
|
||||
printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, cancelling\n", (void*)addr);
|
||||
FreeDynablock(block, 0);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
return NULL;
|
||||
}
|
||||
void* ret = FillBlock(block, filladdr);
|
||||
if(!ret) {
|
||||
dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
|
||||
customFree(block);
|
||||
block = NULL;
|
||||
}
|
||||
// check size
|
||||
if(block) {
|
||||
int blocksz = block->x86_size;
|
||||
if(blocksz>my_context->max_db_size)
|
||||
my_context->max_db_size = blocksz;
|
||||
// fill-in jumptable
|
||||
if(!addJumpTableIfDefault(block->x86_addr, block->dirty?block->jmpnext:block->block)) {
|
||||
FreeDynablock(block, 0);
|
||||
block = getDB(addr);
|
||||
MarkDynablock(block); // just in case...
|
||||
} else {
|
||||
if(block->x86_size)
|
||||
block->done = 1; // don't validate the block if the size is null, but keep the block
|
||||
}
|
||||
}
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
|
||||
dynarec_log(LOG_DEBUG, "%04d| --- DynaRec Block created @%p:%p (%p, 0x%x bytes)\n", GetTID(), (void*)addr, (void*)(addr+((block)?block->x86_size:1)-1), (block)?block->block:0, (block)?block->size:0);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
dynablock_t* DBGetBlock(x86emu_t* emu, uintptr_t addr, int create)
|
||||
{
|
||||
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1);
|
||||
if(db && db->done && db->block && getNeedTest(addr)) {
|
||||
if(db->always_test)
|
||||
sched_yield(); // just calm down...
|
||||
if(AreaInHotPage((uintptr_t)db->x86_addr, (uintptr_t)db->x86_addr + db->x86_size - 1)) {
|
||||
emu->test.test = 0;
|
||||
if(box86_dynarec_fastpage) {
|
||||
uint32_t hash = X31_hash_code(db->x86_addr, db->x86_size);
|
||||
if(hash==db->hash) { // seems ok, run it without reprotecting it
|
||||
setJumpTableIfRef(db->x86_addr, db->block, db->jmpnext);
|
||||
return db;
|
||||
}
|
||||
db->done = 0; // invalidating the block, it's already not good
|
||||
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x86_addr, db->x86_addr+db->x86_size-1, hash, db->hash, (void*)addr);
|
||||
// Free db, it's now invalid!
|
||||
FreeDynablock(db, 1);
|
||||
return NULL; // not building a new one, it's still a hotpage
|
||||
} else {
|
||||
dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x86_addr, db->x86_addr+db->x86_size-1, (void*)addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
uint32_t hash = X31_hash_code(db->x86_addr, db->x86_size);
|
||||
int need_lock = mutex_trylock(&my_context->mutex_dyndump);
|
||||
if(hash!=db->hash) {
|
||||
db->done = 0; // invalidating the block
|
||||
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x86_addr, db->x86_addr+db->x86_size-1, hash, db->hash, (void*)addr);
|
||||
// Free db, it's now invalid!
|
||||
dynablock_t* old = InvalidDynablock(db, need_lock);
|
||||
// start again... (will create a new block)
|
||||
db = internalDBGetBlock(emu, addr, addr, create, need_lock);
|
||||
if(db) {
|
||||
if(db->previous)
|
||||
FreeInvalidDynablock(db->previous, need_lock);
|
||||
db->previous = old;
|
||||
} else
|
||||
FreeInvalidDynablock(old, need_lock);
|
||||
} else {
|
||||
dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X) for %p\n", db, db->x86_addr, db->x86_addr+db->x86_size-1, db->hash, (void*)addr);
|
||||
protectDB((uintptr_t)db->x86_addr, db->x86_size);
|
||||
// fill back jumptable
|
||||
if(isprotectedDB((uintptr_t)db->x86_addr, db->x86_size) && !db->always_test) {
|
||||
setJumpTableIfRef(db->x86_addr, db->block, db->jmpnext);
|
||||
}
|
||||
}
|
||||
if(!need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
if(!db || !db->block || !db->done)
|
||||
emu->test.test = 0;
|
||||
return db;
|
||||
}
|
||||
|
||||
dynablock_t* DBAlternateBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p\n", (void*)addr, (void*)filladdr);
|
||||
int create = 1;
|
||||
dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1);
|
||||
if(db && db->done && db->block && getNeedTest(filladdr)) {
|
||||
if(db->always_test)
|
||||
sched_yield(); // just calm down...
|
||||
int need_lock = mutex_trylock(&my_context->mutex_dyndump);
|
||||
uint32_t hash = X31_hash_code(db->x86_addr, db->x86_size);
|
||||
if(hash!=db->hash) {
|
||||
db->done = 0; // invalidating the block
|
||||
dynarec_log(LOG_DEBUG, "Invalidating alt block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x86_addr, db->x86_addr+db->x86_size, hash, db->hash, (void*)addr);
|
||||
// Free db, it's now invalid!
|
||||
dynablock_t* old = InvalidDynablock(db, need_lock);
|
||||
// start again... (will create a new block)
|
||||
db = internalDBGetBlock(emu, addr, filladdr, create, need_lock);
|
||||
if(db) {
|
||||
if(db->previous)
|
||||
FreeInvalidDynablock(db->previous, need_lock);
|
||||
db->previous = old;
|
||||
} else
|
||||
FreeInvalidDynablock(old, need_lock);
|
||||
} else {
|
||||
protectDB((uintptr_t)db->x86_addr, db->x86_size);
|
||||
// fill back jumptable
|
||||
if(isprotectedDB((uintptr_t)db->x86_addr, db->x86_size) && !db->always_test) {
|
||||
setJumpTableIfRef(db->x86_addr, db->block, db->jmpnext);
|
||||
}
|
||||
}
|
||||
if(!need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
if(!db || !db->block || !db->done)
|
||||
emu->test.test = 0;
|
||||
return db;
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#ifndef __DYNABLOCK_PRIVATE_H_
|
||||
#define __DYNABLOCK_PRIVATE_H_
|
||||
|
||||
typedef struct instsize_s {
|
||||
unsigned char x86:4;
|
||||
unsigned char nat:4;
|
||||
} instsize_t;
|
||||
|
||||
typedef struct dynablock_s {
|
||||
void* block; // block-sizeof(void*) == self
|
||||
void* actual_block; // the actual start of the block (so block-sizeof(void*))
|
||||
struct dynablock_s* previous; // a previous block that might need to be freed
|
||||
int size;
|
||||
void* x86_addr;
|
||||
uintptr_t x86_size;
|
||||
uint32_t hash;
|
||||
uint8_t done;
|
||||
uint8_t gone;
|
||||
uint8_t always_test;
|
||||
uint8_t dirty; // if need to be tested as soon as it's created
|
||||
int isize;
|
||||
instsize_t* instsize;
|
||||
void* jmpnext; // a branch jmpnext code when block is marked
|
||||
} dynablock_t;
|
||||
|
||||
#endif //__DYNABLOCK_PRIVATE_H_
|
||||
Executable
+266
@@ -0,0 +1,266 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "tools/bridge_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "threads.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynablock.h"
|
||||
#include "dynablock_private.h"
|
||||
#include "bridge.h"
|
||||
void x86test_check(x86emu_t* ref, uintptr_t ip);
|
||||
#endif
|
||||
|
||||
#ifdef ARM
|
||||
void arm_prolog(x86emu_t* emu, void* addr) EXPORTDYN;
|
||||
void arm_epilog() EXPORTDYN;
|
||||
void arm_epilog_fast() EXPORTDYN;
|
||||
#endif
|
||||
|
||||
#ifdef DYNAREC
|
||||
#ifdef HAVE_TRACE
|
||||
#include "elfloader.h"
|
||||
uintptr_t getX86Address(dynablock_t* db, uintptr_t arm_addr);
|
||||
#endif
|
||||
void* LinkNext(x86emu_t* emu, uintptr_t addr, void* x2)
|
||||
{
|
||||
#ifdef HAVE_TRACE
|
||||
if(!addr) {
|
||||
x2-=8; // actual PC is 2 instructions ahead
|
||||
dynablock_t* db = FindDynablockFromNativeAddress(x2);
|
||||
void* x86addr = db?(void*)getX86Address(db, (uintptr_t)x2):NULL;
|
||||
const char* pcname = getAddrFunctionName((uintptr_t)x86addr);
|
||||
printf_log(LOG_NONE, "Warning, jumping to NULL address from %p (db=%p, x86addr=%p/%s)\n", x2, db, x86addr, pcname);
|
||||
}
|
||||
#endif
|
||||
void * jblock;
|
||||
dynablock_t* block = NULL;
|
||||
if(hasAlternate((void*)addr)) {
|
||||
printf_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
|
||||
addr = (uintptr_t)getAlternate((void*)addr);
|
||||
R_EIP = addr;
|
||||
printf_log(LOG_INFO, " -> %p\n", (void*)addr);
|
||||
block = DBGetBlock(emu, addr, 1);
|
||||
} else
|
||||
block = DBGetBlock(emu, addr, 1);
|
||||
if(!block) {
|
||||
// no block, let link table as is...
|
||||
#ifdef HAVE_TRACE
|
||||
if(LOG_INFO<=box86_dynarec_log) {
|
||||
dynablock_t* db = FindDynablockFromNativeAddress(x2);
|
||||
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2);
|
||||
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s))\n", (void*)addr, x2, db, db?(void*)getX86Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
|
||||
}
|
||||
#endif
|
||||
//tableupdate(arm_epilog, addr, table);
|
||||
return arm_epilog;
|
||||
}
|
||||
if(!block->done) {
|
||||
// not finished yet... leave linker
|
||||
//tableupdate(arm_linker, addr, table);
|
||||
return arm_epilog;
|
||||
}
|
||||
if(!(jblock=block->block)) {
|
||||
// null block, but done: go to epilog, no linker here
|
||||
return arm_epilog;
|
||||
}
|
||||
//dynablock_t *father = block->father?block->father:block;
|
||||
return jblock;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DynaCall(x86emu_t* emu, uintptr_t addr)
|
||||
{
|
||||
// prepare setjump for signal handling
|
||||
emu_jmpbuf_t *ejb = NULL;
|
||||
int jmpbuf_reset = 0;
|
||||
int skip = 0;
|
||||
if(emu->type == EMUTYPE_MAIN) {
|
||||
ejb = GetJmpBuf();
|
||||
if(!ejb->jmpbuf_ok) {
|
||||
ejb->emu = emu;
|
||||
ejb->jmpbuf_ok = 1;
|
||||
jmpbuf_reset = 1;
|
||||
if((skip=sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1))) {
|
||||
printf_log(LOG_DEBUG, "Setjmp DynaCall %d, fs=0x%x\n", skip, ejb->emu->segs[_FS]);
|
||||
addr = R_EIP; // not sure if it should still be inside DynaCall!
|
||||
#ifdef DYNAREC
|
||||
if(box86_dynarec_test) {
|
||||
if(emu->test.clean)
|
||||
x86test_check(emu, R_EIP);
|
||||
emu->test.clean = 0;
|
||||
}
|
||||
#endif
|
||||
if(skip!=2)
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DYNAREC
|
||||
if(!box86_dynarec)
|
||||
#endif
|
||||
EmuCall(emu, addr);
|
||||
#ifdef DYNAREC
|
||||
else {
|
||||
uint32_t old_esp = R_ESP;
|
||||
uint32_t old_ebx = R_EBX;
|
||||
uint32_t old_edi = R_EDI;
|
||||
uint32_t old_esi = R_ESI;
|
||||
uint32_t old_ebp = R_EBP;
|
||||
uint32_t old_eip = R_EIP;
|
||||
PushExit(emu);
|
||||
R_EIP = addr;
|
||||
emu->df = d_none;
|
||||
dynablock_t* block = NULL;
|
||||
dynablock_t* current = NULL;
|
||||
while(!emu->quit) {
|
||||
block = (skip==2)?NULL:DBGetBlock(emu, R_EIP, 1);
|
||||
current = block;
|
||||
if(!block || !block->block || !block->done) {
|
||||
skip = 0;
|
||||
// no block, of block doesn't have DynaRec content (yet, temp is not null)
|
||||
// Use interpreter (should use single instruction step...)
|
||||
dynarec_log(LOG_DEBUG, "%04d|Calling Interpretor @%p, emu=%p\n", GetTID(), (void*)R_EIP, emu);
|
||||
if(box86_dynarec_test)
|
||||
emu->test.clean = 0;
|
||||
Run(emu, 1);
|
||||
} else {
|
||||
dynarec_log(LOG_DEBUG, "%04d|Calling DynaRec Block @%p (%p) of %d x86 instructions emu=%p\n", GetTID(), (void*)R_EIP, block->block, block->isize ,emu);
|
||||
CHECK_FLAGS(emu);
|
||||
// block is here, let's run it!
|
||||
#ifdef ARM
|
||||
arm_prolog(emu, block->block);
|
||||
#endif
|
||||
}
|
||||
if(emu->fork) {
|
||||
int forktype = emu->fork;
|
||||
emu->quit = 0;
|
||||
emu->fork = 0;
|
||||
emu = x86emu_fork(emu, forktype);
|
||||
if(emu->type == EMUTYPE_MAIN) {
|
||||
ejb = GetJmpBuf();
|
||||
ejb->emu = emu;
|
||||
ejb->jmpbuf_ok = 1;
|
||||
jmpbuf_reset = 1;
|
||||
if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1)) {
|
||||
printf_log(LOG_DEBUG, "Setjmp inner DynaCall, fs=0x%x\n", ejb->emu->segs[_FS]);
|
||||
addr = R_EIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emu->quit = 0; // reset Quit flags...
|
||||
emu->df = d_none;
|
||||
if(emu->quitonlongjmp && emu->longjmp) {
|
||||
emu->longjmp = 0; // don't change anything because of the longjmp
|
||||
} else {
|
||||
R_EBX = old_ebx;
|
||||
R_EDI = old_edi;
|
||||
R_ESI = old_esi;
|
||||
R_EBP = old_ebp;
|
||||
R_ESP = old_esp;
|
||||
R_EIP = old_eip; // and set back instruction pointer
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// clear the setjmp
|
||||
if(ejb && jmpbuf_reset)
|
||||
ejb->jmpbuf_ok = 0;
|
||||
}
|
||||
|
||||
int my_setcontext(x86emu_t* emu, void* ucp);
|
||||
int DynaRun(x86emu_t* emu)
|
||||
{
|
||||
// prepare setjump for signal handling
|
||||
emu_jmpbuf_t *ejb = NULL;
|
||||
int skip = 0;
|
||||
#ifdef DYNAREC
|
||||
int jmpbuf_reset = 1;
|
||||
#endif
|
||||
if(emu->type == EMUTYPE_MAIN) {
|
||||
ejb = GetJmpBuf();
|
||||
if(!ejb->jmpbuf_ok) {
|
||||
ejb->emu = emu;
|
||||
ejb->jmpbuf_ok = 1;
|
||||
int a;
|
||||
#ifdef DYNAREC
|
||||
jmpbuf_reset = 1;
|
||||
#endif
|
||||
if((skip=sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1))) {
|
||||
printf_log(LOG_DEBUG, "Setjmp DynaRun %d, fs=0x%x\n", skip, ejb->emu->segs[_FS]);
|
||||
#ifdef DYNAREC
|
||||
if(box86_dynarec_test) {
|
||||
if(emu->test.clean)
|
||||
x86test_check(emu, R_EIP);
|
||||
emu->test.clean = 0;
|
||||
}
|
||||
#endif
|
||||
if(skip!=2)
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DYNAREC
|
||||
if(!box86_dynarec)
|
||||
#endif
|
||||
return Run(emu, 0);
|
||||
#ifdef DYNAREC
|
||||
else {
|
||||
dynablock_t* block = NULL;
|
||||
dynablock_t* current = NULL;
|
||||
while(!emu->quit) {
|
||||
block = (skip==2)?NULL:DBGetBlock(emu, R_EIP, 1);
|
||||
current = block;
|
||||
if(!block || !block->block || !block->done) {
|
||||
skip = 0;
|
||||
// no block, of block doesn't have DynaRec content (yet, temp is not null)
|
||||
// Use interpreter (should use single instruction step...)
|
||||
dynarec_log(LOG_DEBUG, "%04d|Running Interpretor @%p, emu=%p\n", GetTID(), (void*)R_EIP, emu);
|
||||
if(box86_dynarec_test)
|
||||
emu->test.clean = 0;
|
||||
Run(emu, 1);
|
||||
} else {
|
||||
dynarec_log(LOG_DEBUG, "%04d|Running DynaRec Block @%p (%p) of %d x86 insts emu=%p\n", GetTID(), (void*)R_EIP, block->block, block->isize, emu);
|
||||
// block is here, let's run it!
|
||||
#ifdef ARM
|
||||
arm_prolog(emu, block->block);
|
||||
#endif
|
||||
}
|
||||
if(emu->fork) {
|
||||
int forktype = emu->fork;
|
||||
emu->quit = 0;
|
||||
emu->fork = 0;
|
||||
emu = x86emu_fork(emu, forktype);
|
||||
if(emu->type == EMUTYPE_MAIN) {
|
||||
ejb = GetJmpBuf();
|
||||
ejb->emu = emu;
|
||||
ejb->jmpbuf_ok = 1;
|
||||
jmpbuf_reset = 1;
|
||||
if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1))
|
||||
printf_log(LOG_DEBUG, "Setjmp inner DynaRun, fs=0x%x\n", ejb->emu->segs[_FS]);
|
||||
}
|
||||
}
|
||||
else if(emu->quit && emu->uc_link) {
|
||||
emu->quit = 0;
|
||||
my_setcontext(emu, emu->uc_link);
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear the setjmp
|
||||
if(ejb && jmpbuf_reset)
|
||||
ejb->jmpbuf_ok = 0;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
Executable
+593
@@ -0,0 +1,593 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "custommem.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "tools/bridge_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynablock.h"
|
||||
#include "dynablock_private.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "elfloader.h"
|
||||
|
||||
void printf_x86_instruction(zydis_dec_t* dec, instruction_x86_t* inst, const char* name) {
|
||||
uint8_t *ip = (uint8_t*)inst->addr;
|
||||
if(ip[0]==0xcc && ip[1]=='S' && ip[2]=='C') {
|
||||
uint32_t a = *(uint32_t*)(ip+3);
|
||||
if(a==0) {
|
||||
dynarec_log(LOG_NONE, "%s%p: Exit x86emu%s\n", (box86_dynarec_dump>1)?"\e[01;33m":"", (void*)ip, (box86_dynarec_dump>1)?"\e[m":"");
|
||||
} else {
|
||||
dynarec_log(LOG_NONE, "%s%p: Native call to %p%s\n", (box86_dynarec_dump>1)?"\e[01;33m":"", (void*)ip, (void*)a, (box86_dynarec_dump>1)?"\e[m":"");
|
||||
}
|
||||
} else {
|
||||
if(dec) {
|
||||
dynarec_log(LOG_NONE, "%s%p: %s", (box86_dynarec_dump>1)?"\e[01;33m":"", ip, DecodeX86Trace(dec, inst->addr));
|
||||
} else {
|
||||
dynarec_log(LOG_NONE, "%s%p: ", (box86_dynarec_dump>1)?"\e[01;33m":"", ip);
|
||||
for(int i=0; i<inst->size; ++i) {
|
||||
dynarec_log(LOG_NONE, "%02X ", ip[i]);
|
||||
}
|
||||
dynarec_log(LOG_NONE, " %s", name);
|
||||
}
|
||||
// print Call function name if possible
|
||||
if(ip[0]==0xE8 || ip[0]==0xE9) { // Call / Jmp
|
||||
uintptr_t nextaddr = (uintptr_t)ip + 5 + *((int32_t*)(ip+1));
|
||||
printFunctionAddr(nextaddr, "=> ");
|
||||
} else if(ip[0]==0xFF) {
|
||||
if(ip[1]==0x25) {
|
||||
uintptr_t nextaddr = (uintptr_t)ip + 6 + *((int32_t*)(ip+2));
|
||||
printFunctionAddr(nextaddr, "=> ");
|
||||
}
|
||||
}
|
||||
// end of line and colors
|
||||
dynarec_log(LOG_NONE, "%s\n", (box86_dynarec_dump>1)?"\e[m":"");
|
||||
}
|
||||
}
|
||||
|
||||
void add_next(dynarec_arm_t *dyn, uintptr_t addr) {
|
||||
if(!box86_dynarec_bigblock)
|
||||
return;
|
||||
// exist?
|
||||
for(int i=0; i<dyn->next_sz; ++i)
|
||||
if(dyn->next[i]==addr)
|
||||
return;
|
||||
// put in a free slot
|
||||
for(int i=0; i<dyn->next_sz; ++i)
|
||||
if(!dyn->next[i]) {
|
||||
dyn->next[i] = addr;
|
||||
return;
|
||||
}
|
||||
// add slots
|
||||
if(dyn->next_sz == dyn->next_cap) {
|
||||
dyn->next_cap += 64;
|
||||
dyn->next = (uintptr_t*)dynaRealloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
|
||||
}
|
||||
dyn->next[dyn->next_sz++] = addr;
|
||||
}
|
||||
uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr) {
|
||||
// get closest, but no addresses befores
|
||||
uintptr_t best = 0;
|
||||
int i = 0;
|
||||
while((i<dyn->next_sz) && (best!=addr)) {
|
||||
if(dyn->next[i]) {
|
||||
if(dyn->next[i]<addr) { // remove the address, it's before current address
|
||||
dyn->next[i] = 0;
|
||||
} else {
|
||||
if((dyn->next[i]<best) || !best)
|
||||
best = dyn->next[i];
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
#define PK(A) (*((uint8_t*)(addr+(A))))
|
||||
int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n)
|
||||
{
|
||||
if(!n)
|
||||
return 1;
|
||||
if(PK(0)==0x90)
|
||||
return is_nops(dyn, addr+1, n-1);
|
||||
if(n>1 && PK(0)==0x2E) // if opcode start with 0x2E, and there is more after, than this *can* be a NOP
|
||||
return is_nops(dyn, addr+1, n-1);
|
||||
if(n>1 && PK(0)==0x66) // if opcode start with 0x66, and there is more after, than this *can* be a NOP
|
||||
return is_nops(dyn, addr+1, n-1);
|
||||
if(n>2 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x00)
|
||||
return is_nops(dyn, addr+3, n-3);
|
||||
if(n>2 && PK(0)==0x8d && PK(1)==0x76 && PK(2)==0x00) // lea esi, [esi]
|
||||
return is_nops(dyn, addr+3, n-3);
|
||||
if(n>3 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x40 && PK(3)==0x00)
|
||||
return is_nops(dyn, addr+4, n-4);
|
||||
if(n>3 && PK(0)==0x8d && PK(1)==0x74 && PK(2)==0x26 && PK(3)==0x00)
|
||||
return is_nops(dyn, addr+4, n-4);
|
||||
if(n>4 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x44 && PK(3)==0x00 && PK(4)==0x00)
|
||||
return is_nops(dyn, addr+5, n-5);
|
||||
if(n>5 && PK(0)==0x8d && PK(1)==0xb6 && PK(2)==0x00 && PK(3)==0x00 && PK(4)==0x00 && PK(5)==0x00)
|
||||
return is_nops(dyn, addr+6, n-6);
|
||||
if(n>6 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x80 && PK(3)==0x00 && PK(4)==0x00 && PK(5)==0x00 && PK(6)==0x00)
|
||||
return is_nops(dyn, addr+7, n-7);
|
||||
if(n>6 && PK(0)==0x8d && PK(1)==0xb4 && PK(2)==0x26 && PK(3)==0x00 && PK(4)==0x00 && PK(5)==0x00 && PK(6)==0x00) // lea esi, [esi+0]
|
||||
return is_nops(dyn, addr+7, n-7);
|
||||
if(n>7 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x84 && PK(3)==0x00 && PK(4)==0x00 && PK(5)==0x00 && PK(6)==0x00 && PK(7)==0x00)
|
||||
return is_nops(dyn, addr+8, n-8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return size of next instuciton, -1 is unknown
|
||||
// not all instrction are setup
|
||||
int next_instruction(dynarec_arm_t *dyn, uintptr_t addr)
|
||||
{
|
||||
uint8_t opcode = PK(0);
|
||||
uint8_t nextop;
|
||||
switch (opcode) {
|
||||
case 0x66:
|
||||
opcode = PK(1);
|
||||
switch(opcode) {
|
||||
case 0x90:
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case 0x81:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr + 4;
|
||||
case 0x83:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr + 1;
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8A:
|
||||
case 0x8B:
|
||||
case 0x8C:
|
||||
case 0x8D:
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr;
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5A:
|
||||
case 0x5B:
|
||||
case 0x5C:
|
||||
case 0x5D:
|
||||
case 0x5E:
|
||||
case 0x5F:
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0x92:
|
||||
case 0x93:
|
||||
case 0x94:
|
||||
case 0x95:
|
||||
case 0x96:
|
||||
case 0x97:
|
||||
case 0x98:
|
||||
case 0x99:
|
||||
case 0x9B:
|
||||
case 0x9C:
|
||||
case 0x9D:
|
||||
case 0x9E:
|
||||
case 0x9F:
|
||||
return 1;
|
||||
case 0xA0:
|
||||
case 0xA1:
|
||||
case 0xA2:
|
||||
case 0xA3:
|
||||
return 5;
|
||||
case 0xB0:
|
||||
case 0xB1:
|
||||
case 0xB2:
|
||||
case 0xB3:
|
||||
case 0xB4:
|
||||
case 0xB5:
|
||||
case 0xB6:
|
||||
case 0xB7:
|
||||
return 2;
|
||||
case 0xB8:
|
||||
case 0xB9:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBC:
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF:
|
||||
return 5;
|
||||
case 0xFF:
|
||||
nextop = PK(1);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: // INC Ed
|
||||
case 1: // DEC Ed
|
||||
case 2: // CALL Ed
|
||||
case 4: // JMP Ed
|
||||
case 6: // Push Ed
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#undef PK
|
||||
|
||||
int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n)
|
||||
{
|
||||
int i = 0;
|
||||
while(i<n) {
|
||||
int j=next_instruction(dyn, addr+i);
|
||||
if(j<=0) return 0;
|
||||
i+=j;
|
||||
}
|
||||
return (i==n)?1:0;
|
||||
}
|
||||
|
||||
void addInst(instsize_t* insts, size_t* size, int x86_size, int native_size)
|
||||
{
|
||||
// x86 instruction is <16 bytes
|
||||
int toadd;
|
||||
if(x86_size>native_size)
|
||||
toadd = 1 + x86_size/15;
|
||||
else
|
||||
toadd = 1 + native_size/15;
|
||||
while(toadd) {
|
||||
if(x86_size>15)
|
||||
insts[*size].x86 = 15;
|
||||
else
|
||||
insts[*size].x86 = x86_size;
|
||||
x86_size -= insts[*size].x86;
|
||||
if(native_size>15)
|
||||
insts[*size].nat = 15;
|
||||
else
|
||||
insts[*size].nat = native_size;
|
||||
native_size -= insts[*size].nat;
|
||||
++(*size);
|
||||
--toadd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fillPredecessors(dynarec_arm_t* dyn)
|
||||
{
|
||||
int pred_sz = 1; // to be safe
|
||||
// compute total size of predecessor to alocate the array
|
||||
// first compute the jumps
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
if(dyn->insts[i].x86.jmp && dyn->insts[i].x86.jmp_insts!=-1) {
|
||||
++pred_sz;
|
||||
++dyn->insts[dyn->insts[i].x86.jmp_insts].pred_sz;
|
||||
}
|
||||
}
|
||||
// remove "has_next" from orphean branch
|
||||
for(int i=0; i<dyn->size-1; ++i) {
|
||||
if(!dyn->insts[i].x86.has_next) {
|
||||
if(dyn->insts[i+1].x86.has_next && !dyn->insts[i+1].pred_sz)
|
||||
dyn->insts[i+1].x86.has_next = 0;
|
||||
}
|
||||
}
|
||||
// second the "has_next"
|
||||
for(int i=0; i<dyn->size-1; ++i) {
|
||||
if(dyn->insts[i].x86.has_next) {
|
||||
++pred_sz;
|
||||
++dyn->insts[i+1].pred_sz;
|
||||
}
|
||||
}
|
||||
dyn->predecessor = (int*)dynaMalloc(pred_sz*sizeof(int));
|
||||
// fill pred pointer
|
||||
int* p = dyn->predecessor;
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
dyn->insts[i].pred = p;
|
||||
p += dyn->insts[i].pred_sz;
|
||||
dyn->insts[i].pred_sz=0; // reset size, it's reused to actually fill pred[]
|
||||
}
|
||||
// fill pred
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
if((i!=dyn->size-1) && dyn->insts[i].x86.has_next)
|
||||
dyn->insts[i+1].pred[dyn->insts[i+1].pred_sz++] = i;
|
||||
if(dyn->insts[i].x86.jmp && (dyn->insts[i].x86.jmp_insts!=-1)) {
|
||||
int j = dyn->insts[i].x86.jmp_insts;
|
||||
dyn->insts[j].pred[dyn->insts[j].pred_sz++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updateNeed goes backward, from last intruction to top
|
||||
static int updateNeed(dynarec_arm_t* dyn, int ninst, uint8_t need) {
|
||||
while (ninst>=0) {
|
||||
// need pending but instruction is only a subset: remove pend and use an X_ALL instead
|
||||
need |= dyn->insts[ninst].x86.need_after;
|
||||
if((need&X_PEND) && (dyn->insts[ninst].x86.state_flags==SF_SUBSET)) {
|
||||
need &=~X_PEND;
|
||||
need |= X_ALL;
|
||||
}
|
||||
if((need&X_PEND) && (dyn->insts[ninst].x86.state_flags==SF_SET)) {
|
||||
need &=~X_PEND;
|
||||
need |= dyn->insts[ninst].x86.set_flags; // SF_SET will compute all flags, it's not SUBSET!
|
||||
}
|
||||
if((need&X_PEND) && dyn->insts[ninst].x86.state_flags==SF_SUBSET_PENDING) {
|
||||
need |= X_ALL&~(dyn->insts[ninst].x86.set_flags);
|
||||
}
|
||||
dyn->insts[ninst].x86.gen_flags = need&dyn->insts[ninst].x86.set_flags;
|
||||
if((need&X_PEND) && (dyn->insts[ninst].x86.state_flags&SF_PENDING))
|
||||
dyn->insts[ninst].x86.gen_flags |= X_PEND;
|
||||
dyn->insts[ninst].x86.need_after = need;
|
||||
need = dyn->insts[ninst].x86.need_after&~dyn->insts[ninst].x86.gen_flags;
|
||||
if(dyn->insts[ninst].x86.may_set)
|
||||
need |= dyn->insts[ninst].x86.gen_flags; // forward the flags
|
||||
// Consume X_PEND if relevant
|
||||
if((need&X_PEND) && (dyn->insts[ninst].x86.set_flags&SF_PENDING))
|
||||
need &=~X_PEND;
|
||||
need |= dyn->insts[ninst].x86.use_flags;
|
||||
if(dyn->insts[ninst].x86.need_before == need)
|
||||
return ninst - 1;
|
||||
dyn->insts[ninst].x86.need_before = need;
|
||||
if(dyn->insts[ninst].x86.barrier&BARRIER_FLAGS) {
|
||||
need = need?X_PEND:0;
|
||||
}
|
||||
int ok = 0;
|
||||
for(int i=0; i<dyn->insts[ninst].pred_sz; ++i) {
|
||||
if(dyn->insts[ninst].pred[i] == ninst-1)
|
||||
ok = 1;
|
||||
else
|
||||
updateNeed(dyn, dyn->insts[ninst].pred[i], need);
|
||||
}
|
||||
--ninst;
|
||||
if(!ok)
|
||||
return ninst;
|
||||
}
|
||||
return ninst;
|
||||
}
|
||||
|
||||
void* current_helper = NULL;
|
||||
|
||||
void CancelBlock(int need_lock)
|
||||
{
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
dynarec_arm_t* helper = (dynarec_arm_t*)current_helper;
|
||||
current_helper = NULL;
|
||||
if(helper) {
|
||||
dynaFree(helper->next);
|
||||
dynaFree(helper->insts);
|
||||
dynaFree(helper->predecessor);
|
||||
if(helper->dynablock && helper->dynablock->actual_block) {
|
||||
FreeDynarecMap((uintptr_t)helper->dynablock->actual_block);
|
||||
helper->dynablock->actual_block = NULL;
|
||||
}
|
||||
}
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
|
||||
uintptr_t arm_pass0(dynarec_arm_t* dyn, uintptr_t addr);
|
||||
uintptr_t arm_pass1(dynarec_arm_t* dyn, uintptr_t addr);
|
||||
uintptr_t arm_pass2(dynarec_arm_t* dyn, uintptr_t addr);
|
||||
uintptr_t arm_pass3(dynarec_arm_t* dyn, uintptr_t addr);
|
||||
void arm_epilog();
|
||||
void arm_next();
|
||||
|
||||
void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
|
||||
block->isize = 0;
|
||||
block->done = 0;
|
||||
size_t sz = 8*sizeof(void*);
|
||||
void* actual_p = (void*)AllocDynarecMap(sz);
|
||||
void* p = actual_p + sizeof(void*);
|
||||
if(actual_p==NULL) {
|
||||
dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, cancelling block\n", block, sz);
|
||||
CancelBlock(0);
|
||||
return NULL;
|
||||
}
|
||||
block->size = sz;
|
||||
block->actual_block = actual_p;
|
||||
block->block = p;
|
||||
block->jmpnext = p;
|
||||
*(dynablock_t**)actual_p = block;
|
||||
*(void**)(p+4*sizeof(void*)) = arm_epilog;
|
||||
CreateJmpNext(block->jmpnext, p+4*sizeof(void*));
|
||||
// all done...
|
||||
__clear_cache(actual_p, actual_p+sz); // need to clear the cache before execution...
|
||||
return block;
|
||||
}
|
||||
|
||||
void* FillBlock(dynablock_t* block, uintptr_t addr) {
|
||||
/*
|
||||
A Block must have this layout:
|
||||
|
||||
0x0000..0x0003 : dynablock_t* : self
|
||||
0x0004..4+4*n : actual Native instructions, (n is the total number)
|
||||
B .. B+3 : dynablock_t* : self (as part of JmpNext, that simulate another block)
|
||||
B+4 .. B+15 : 3 Native code for jmpnext (or jmp epilog in case of empty block)
|
||||
B+16 .. B+19 : jmpnext (or jmp_epilog) address
|
||||
B+20 .. B+31 : empty (in case an architecture needs more than 3 opcodes)
|
||||
B+32 .. B+32+sz : instsize (compressed array with each instruction lenght on x86 and native side)
|
||||
|
||||
*/
|
||||
dynarec_log(LOG_DEBUG, "Asked to Fill block %p with %p\n", block, (void*)addr);
|
||||
if(IsInHotPage(addr)) {
|
||||
dynarec_log(LOG_DEBUG, "Cancelling dynarec FillBlock on hotpage for %p\n", (void*)addr);
|
||||
return NULL;
|
||||
}
|
||||
if(addr>=box86_nodynarec_start && addr<box86_nodynarec_end) {
|
||||
dynarec_log(LOG_DEBUG, "Asked to fill a block in fobidden zone\n");
|
||||
return CreateEmptyBlock(block, addr);
|
||||
}
|
||||
if(current_helper) {
|
||||
dynarec_log(LOG_DEBUG, "Cancelling dynarec FillBlock at %p as anothor one is going on\n", (void*)addr);
|
||||
return NULL;
|
||||
}
|
||||
// protect the 1st page
|
||||
protectDB(addr, 1);
|
||||
// init the helper
|
||||
dynarec_arm_t helper = {0};
|
||||
current_helper = &helper;
|
||||
helper.dynablock = block;
|
||||
helper.start = addr;
|
||||
uintptr_t start = addr;
|
||||
helper.cap = 64; // needs epilog handling
|
||||
helper.insts = (instruction_arm_t*)dynaCalloc(helper.cap, sizeof(instruction_arm_t));
|
||||
// pass 0, addresses, x86 jump addresses, overall size of the block
|
||||
uintptr_t end = arm_pass0(&helper, addr);
|
||||
// no need for next anymore
|
||||
dynaFree(helper.next);
|
||||
helper.next_sz = helper.next_cap = 0;
|
||||
helper.next = NULL;
|
||||
// basic checks
|
||||
if(!helper.size) {
|
||||
dynarec_log(LOG_DEBUG, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
|
||||
CancelBlock(0);
|
||||
return CreateEmptyBlock(block, addr);
|
||||
}
|
||||
if(!isprotectedDB(addr, 1)) {
|
||||
dynarec_log(LOG_INFO, "Warning, write on current page on pass0, aborting dynablock creation (%p)\n", (void*)addr);
|
||||
AddHotPage(addr);
|
||||
CancelBlock(0);
|
||||
return NULL;
|
||||
}
|
||||
// already protect the block and compute hash signature
|
||||
// protect the block of it goes over the 1st page
|
||||
if((addr&~box86_pagesize)!=(end&~box86_pagesize)) // need to protect some other pages too
|
||||
protectDB(addr, end-addr); //end is 1byte after actual end
|
||||
uint32_t hash = X31_hash_code((void*)addr, end-addr);
|
||||
// calculate barriers
|
||||
for(int i=0; i<helper.size; ++i)
|
||||
if(helper.insts[i].x86.jmp) {
|
||||
uintptr_t j = helper.insts[i].x86.jmp;
|
||||
if(j<start || j>=end || j==helper.insts[i].x86.addr) {
|
||||
if(j==helper.insts[i].x86.addr) // if there is a loop on some opcode, make the block "always to tested"
|
||||
helper.always_test = 1;
|
||||
helper.insts[i].x86.jmp_insts = -1;
|
||||
helper.insts[i].x86.need_after |= X_PEND;
|
||||
} else {
|
||||
// find jump address instruction
|
||||
int k=-1;
|
||||
for(int i2=0; i2<helper.size && k==-1; ++i2) {
|
||||
if(helper.insts[i2].x86.addr==j)
|
||||
k=i2;
|
||||
}
|
||||
if(k!=-1 && !helper.insts[i].barrier_maybe)
|
||||
helper.insts[k].x86.barrier |= BARRIER_FULL;
|
||||
helper.insts[i].x86.jmp_insts = k;
|
||||
}
|
||||
}
|
||||
// fill predecessors with the jump address
|
||||
fillPredecessors(&helper);
|
||||
|
||||
int pos = helper.size;
|
||||
while (pos>=0)
|
||||
pos = updateNeed(&helper, pos, 0);
|
||||
|
||||
// pass 1, float optimisations, first pass for flags
|
||||
arm_pass1(&helper, addr);
|
||||
|
||||
// pass 2, instruction size
|
||||
arm_pass2(&helper, addr);
|
||||
// ok, now allocate mapped memory, with executable flag on
|
||||
size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
|
||||
insts_rsize = (insts_rsize+7)&~7; // round the size...
|
||||
size_t arm_size = (helper.arm_size+7)&~7; // round the size...
|
||||
// ok, now allocate mapped memory, with executable flag on
|
||||
size_t sz = sizeof(void*) + arm_size + 8*sizeof(void*) + insts_rsize;
|
||||
// dynablock_t* block (arm insts) jmpnext code instsize
|
||||
void* actual_p = (void*)AllocDynarecMap(sz);
|
||||
void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*));
|
||||
void* next = p + arm_size;
|
||||
void* instsize = next + 8*sizeof(void*);
|
||||
if(actual_p==NULL) {
|
||||
dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, cancelling block\n", block, sz);
|
||||
CancelBlock(0);
|
||||
return NULL;
|
||||
}
|
||||
helper.block = p;
|
||||
block->actual_block = actual_p;
|
||||
helper.arm_start = (uintptr_t)p;
|
||||
helper.jmp_next = (uintptr_t)next+sizeof(void*);
|
||||
helper.instsize = (instsize_t*)instsize;
|
||||
*(dynablock_t**)actual_p = block;
|
||||
// pass 3, emit (log emit native opcode)
|
||||
if(box86_dynarec_dump) {
|
||||
dynarec_log(LOG_NONE, "%s%04d|Emitting %d bytes for %d x86 bytes", (box86_dynarec_dump>1)?"\e[01;36m":"", GetTID(), helper.arm_size, helper.isize);
|
||||
printFunctionAddr(helper.start, " => ");
|
||||
dynarec_log(LOG_NONE, "%s\n", (box86_dynarec_dump>1)?"\e[m":"");
|
||||
}
|
||||
size_t oldarmsize = helper.arm_size;
|
||||
size_t oldinstsize = helper.insts_size;
|
||||
helper.arm_size = 0;
|
||||
helper.insts_size = 0; // reset
|
||||
arm_pass3(&helper, addr);
|
||||
// keep size of instructions for signal handling
|
||||
block->instsize = instsize;
|
||||
// ok, free the helper now
|
||||
dynaFree(helper.insts);
|
||||
helper.insts = NULL;
|
||||
helper.instsize = NULL;
|
||||
dynaFree(helper.predecessor);
|
||||
helper.predecessor = NULL;
|
||||
block->size = sz;
|
||||
block->isize = helper.size;
|
||||
block->block = p;
|
||||
block->jmpnext = next+sizeof(void*);
|
||||
block->always_test = helper.always_test;
|
||||
block->dirty = block->always_test;
|
||||
*(dynablock_t**)next = block;
|
||||
*(void**)(next+5*sizeof(void*)) = arm_next;
|
||||
CreateJmpNext(block->jmpnext, next+5*sizeof(void*));
|
||||
//block->x86_addr = (void*)start;
|
||||
block->x86_size = end-start;
|
||||
// all done...
|
||||
__clear_cache(actual_p, actual_p+sz); // need to clear the cache before execution...
|
||||
block->hash = X31_hash_code(block->x86_addr, block->x86_size);
|
||||
// Check if something changed, to abbort if it as
|
||||
if((block->hash != hash)) {
|
||||
dynarec_log(LOG_DEBUG, "Warning, a block changed while being processed hash(%p:%zu)=%x/%x\n", block->x86_addr, block->x86_size, block->hash, hash);
|
||||
AddHotPage(addr);
|
||||
CancelBlock(0);
|
||||
return NULL;
|
||||
}
|
||||
if((oldarmsize!=helper.arm_size)) {
|
||||
printf_log(LOG_NONE, "BOx86: Warning, size difference in block between pass2 (%zu) & pass3 (%zu)!\n", sz, helper.arm_size);
|
||||
uint8_t *dump = (uint8_t*)helper.start;
|
||||
printf_log(LOG_NONE, "Dump of %d x86 opcodes:\n", helper.size);
|
||||
for(int i=0; i<helper.size; ++i) {
|
||||
printf_log(LOG_NONE, "%p:", dump);
|
||||
for(; dump<(uint8_t*)helper.insts[i+1].x86.addr; ++dump)
|
||||
printf_log(LOG_NONE, " %02X", *dump);
|
||||
printf_log(LOG_NONE, "\t%d -> %d\n", helper.insts[i].size2, helper.insts[i].size);
|
||||
}
|
||||
printf_log(LOG_NONE, " ------------\n");
|
||||
CancelBlock(0);
|
||||
return NULL;
|
||||
}
|
||||
if(insts_rsize/sizeof(instsize_t)<helper.insts_size) {
|
||||
printf_log(LOG_NONE, "BOX86: Warning, ists_size difference in block between pass2 (%zu) and pass3 (%zu), allocated: %zu\n", oldinstsize, helper.insts_size, insts_rsize/sizeof(instsize_t));
|
||||
}
|
||||
if(!isprotectedDB(addr, end-addr)) {
|
||||
dynarec_log(LOG_DEBUG, "Warning, block unprotected while being processed %p:%zu, marking as need_test\n", block->x86_addr, block->x86_size);
|
||||
AddHotPage(addr);
|
||||
block->dirty = 1;
|
||||
//protectDB(addr, end-addr);
|
||||
}
|
||||
current_helper = NULL;
|
||||
//block->done = 1;
|
||||
return (void*)block;
|
||||
}
|
||||
Executable
+2911
File diff suppressed because it is too large.
Load diff
Executable
+2747
File diff suppressed because it is too large.
Load diff
Executable
+358
@@ -0,0 +1,358 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
int32_t i32, j32;
|
||||
uint32_t u32;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, u8;
|
||||
int fixedaddress;
|
||||
|
||||
MAYUSE(j32);
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x03:
|
||||
INST_NAME("ADD Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
INST_NAME("SUB Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
INST_NAME("XOR Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x39:
|
||||
INST_NAME("CMP FS:Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, ed, gd, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x3B:
|
||||
INST_NAME("CMP Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
// reduced EA size...
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ew16, Gw");
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD; // don't need GETGW here
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
if(ed!=gd) {
|
||||
BFI(ed, gd, 0, 16);
|
||||
}
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STRH_REG(gd, x14, ed);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
SMREAD();
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP1(xEAX+(nextop&7)); // 67 ignored
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, x1, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX, FS:Ow");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
u32 = F16;
|
||||
if(u32) {
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
}
|
||||
SMREAD();
|
||||
LDR_IMM9(xEAX, x1, 0);
|
||||
break;
|
||||
|
||||
case 0xA3:
|
||||
INST_NAME("MOV FS:Ow, EAX");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
u32 = F16;
|
||||
if(u32) {
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
}
|
||||
STR_IMM9(xEAX, x1, 0);
|
||||
SMWRITE2();
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ew");
|
||||
if((nextop&0xC0)==0xC0) { // reg
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
SMREAD();
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ed, Gd");
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(xEAX+(nextop&7), gd);
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
STR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ed");
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ed");
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP1(xEAX+(nextop&7));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
INST_NAME("MOV AL, FS:Id");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
i32 = F32S;
|
||||
if(i32>-4096 && i32<4096) {
|
||||
LDRB_IMM9(xEAX, x1, i32);
|
||||
} else {
|
||||
MOV32(x2, i32);
|
||||
SMREAD();
|
||||
LDRB_REG_LSL_IMM5(xEAX, x1, x2, 0);
|
||||
}
|
||||
break;
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX, FS:Id");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
i32 = F32S;
|
||||
if(i32>-4096 && i32<4096) {
|
||||
LDR_IMM9(xEAX, x1, i32);
|
||||
} else {
|
||||
MOV32(x2, i32);
|
||||
SMREAD();
|
||||
LDR_REG_LSL_IMM5(xEAX, x1, x2, 0);
|
||||
}
|
||||
break;
|
||||
case 0xA2:
|
||||
INST_NAME("MOV FS:Od, AL");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
i32 = F32S;
|
||||
if(i32>-4096 && i32<4096) {
|
||||
STRB_IMM9(xEAX, x1, i32);
|
||||
} else {
|
||||
MOV32(x2, i32);
|
||||
STRB_REG_LSL_IMM5(xEAX, x1, x2, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0xA3:
|
||||
INST_NAME("MOV FS:Od, EAX");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
i32 = F32S;
|
||||
if(i32>-4096 && i32<4096) {
|
||||
STR_IMM9(xEAX, x1, i32);
|
||||
SMWRITE2();
|
||||
} else {
|
||||
MOV32(x2, i32);
|
||||
STR_REG_LSL_IMM5(xEAX, x2, x1, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA8:
|
||||
INST_NAME("TEST AL, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
UXTB(x1, xEAX, 0);
|
||||
u8 = F8;
|
||||
MOVW(x2, u8);
|
||||
emit_test8(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
|
||||
case 0xC7:
|
||||
INST_NAME("MOV FS:Ed, Id");
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= i32
|
||||
i32 = F32S;
|
||||
ed = xEAX+(nextop&7);
|
||||
MOV32(ed, i32);
|
||||
} else { // mem <= i32
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
i32 = F32S;
|
||||
MOV32(x3, i32);
|
||||
STR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE9:
|
||||
case 0xEB:
|
||||
INST_NAME("(ignored) FS:");
|
||||
--addr;
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 2: // CALL Ed
|
||||
INST_NAME("CALL FS:Ed");
|
||||
PASS2IF((box86_dynarec_safeflags>1) ||
|
||||
((ninst && dyn->insts[ninst-1].x86.set_flags)
|
||||
|| ((ninst>1) && dyn->insts[ninst-2].x86.set_flags)), 1)
|
||||
{
|
||||
READFLAGS(X_PEND); // that's suspicious
|
||||
} else {
|
||||
SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state
|
||||
}
|
||||
if((nextop&0xC0)==0xC0) { // reg
|
||||
MOV_REG(xEIP, xEAX+(nextop&7));
|
||||
} else { // mem
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_REG_LSL_IMM5(xEIP, ed, x14, 0);
|
||||
}
|
||||
BARRIER(BARRIER_FULL);
|
||||
*need_epilog = 0;
|
||||
*ok = 0;
|
||||
MOV32(x2, addr);
|
||||
PUSH1(x2);
|
||||
jump_to_next(dyn, 0, xEIP, ninst);
|
||||
break;
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ed");
|
||||
if((nextop&0xC0)==0xC0) { // reg
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+672
@@ -0,0 +1,672 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
int32_t i32, j32;
|
||||
uint32_t u32;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, wb1, wb2, wb, eb1, eb2;
|
||||
uint8_t u8;
|
||||
int fixedaddress;
|
||||
|
||||
MAYUSE(j32);
|
||||
MAYUSE(wback);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(wb);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x01:
|
||||
INST_NAME("ADD GS:Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO2(x14);
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
INST_NAME("ADD Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x0F: // more opcodes
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
|
||||
case 0xAF:
|
||||
INST_NAME("IMUL Gd, Ed");
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
UFLAG_IF {
|
||||
SMULL(x3, gd, gd, ed);
|
||||
UFLAG_OP1(x3);
|
||||
UFLAG_RES(gd);
|
||||
UFLAG_DF(x3, d_imul32);
|
||||
} else {
|
||||
MUL(gd, gd, ed);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
INST_NAME("AND Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO2(x14);
|
||||
emit_and32(dyn, ninst, ed, gd, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
INST_NAME("AND Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_and32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x29:
|
||||
INST_NAME("SUB GS:Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO2(x14);
|
||||
emit_sub32(dyn, ninst, ed, gd, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
INST_NAME("SUB Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
INST_NAME("XOR GS:Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO2(x14);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
INST_NAME("XOR Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x39:
|
||||
INST_NAME("CMP GS:Ed, Gd");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, ed, gd, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x3B:
|
||||
INST_NAME("CMP Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
INST_NAME("IMUL Gd, GS:Ed, Id");
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x14);
|
||||
i32 = F32S;
|
||||
MOV32(x14, i32);
|
||||
UFLAG_IF {
|
||||
SMULL(x3, gd, x14, ed);
|
||||
UFLAG_OP1(x3);
|
||||
UFLAG_RES(gd);
|
||||
UFLAG_DF(x3, d_imul32);
|
||||
} else {
|
||||
MUL(gd, ed, x14);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x82:
|
||||
nextop = F8;
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: //ADD
|
||||
INST_NAME("ADD GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_add8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 1: //OR
|
||||
INST_NAME("OR GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_or8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 2: //ADC
|
||||
INST_NAME("ADC GS:Eb, Ib");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_adc8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 3: //SBB
|
||||
INST_NAME("SBB GS:Eb, Ib");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_sbb8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 4: //AND
|
||||
INST_NAME("AND GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_and8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 5: //SUB
|
||||
INST_NAME("SUB GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_sub8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 6: //XOR
|
||||
INST_NAME("XOR GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_xor8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK2;
|
||||
break;
|
||||
case 7: //CMP
|
||||
INST_NAME("CMP GS:Eb, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
if(u8) {
|
||||
MOVW(x2, u8);
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x14);
|
||||
} else {
|
||||
emit_cmp8_0(dyn, ninst, x1, x3, x14);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x81:
|
||||
case 0x83:
|
||||
nextop = F8;
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: //ADD
|
||||
if(opcode==0x81) {
|
||||
INST_NAME("ADD Ed, Id");
|
||||
} else {
|
||||
INST_NAME("ADD Ed, Ib");
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_add32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 1: //OR
|
||||
if(opcode==0x81) {INST_NAME("OR Ed, Id");} else {INST_NAME("OR Ed, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_or32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 2: //ADC
|
||||
if(opcode==0x81) {INST_NAME("ADC Ed, Id");} else {INST_NAME("ADC Ed, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_adc32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 3: //SBB
|
||||
if(opcode==0x81) {INST_NAME("SBB Ed, Id");} else {INST_NAME("SBB Ed, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_sbb32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 4: //AND
|
||||
if(opcode==0x81) {INST_NAME("AND Ed, Id");} else {INST_NAME("AND Ed, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_and32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 5: //SUB
|
||||
if(opcode==0x81) {INST_NAME("SUB Ed, Id");} else {INST_NAME("SUB Ed, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_sub32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 6: //XOR
|
||||
if(opcode==0x81) {INST_NAME("XOR Ed, Id");} else {INST_NAME("XOR Ed, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
emit_xor32c(dyn, ninst, ed, i32, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 7: //CMP
|
||||
if(opcode==0x81) {INST_NAME("CMP Ed, Id");} else {INST_NAME("CMP Ed, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
GETEDO2(x14);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
if(i32) {
|
||||
MOV32(x2, i32);
|
||||
emit_cmp32(dyn, ninst, ed, x2, x3, x14);
|
||||
} else {
|
||||
emit_cmp32_0(dyn, ninst, ed, x3, x14);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV GS:Ed, Gd");
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(xEAX+(nextop&7), gd);
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
STR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, GS:Ed");
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP GS:Ed");
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP1((xEAX+(nextop&7)));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX, GS:Id");
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
i32 = F32S;
|
||||
SMREAD();
|
||||
if(i32>-4096 && i32<4096) {
|
||||
LDR_IMM9(xEAX, x1, i32);
|
||||
} else {
|
||||
MOV32(x2, i32);
|
||||
ADD_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(xEAX, x1, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA2:
|
||||
INST_NAME("MOV GS:Od, AL");
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
u32 = F32;
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
STRB_IMM9(xEAX, x2, 0);
|
||||
SMWRITE2();
|
||||
break;
|
||||
|
||||
case 0xA3:
|
||||
INST_NAME("MOV GS:Od, EAX");
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
u32 = F32;
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
STR_IMM9(xEAX, x2, 0);
|
||||
SMWRITE2();
|
||||
break;
|
||||
|
||||
case 0xC6:
|
||||
INST_NAME("MOV GS:Eb, Ib");
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= u8
|
||||
u8 = F8;
|
||||
ed = (nextop&7);
|
||||
eb1 = xEAX+(ed&3); // Ax, Cx, Dx or Bx
|
||||
eb2 = (ed&4)>>2; // L or H
|
||||
MOVW(x3, u8);
|
||||
BFI(eb1, x3, eb2*8, 8);
|
||||
} else { // mem <= u8
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
u8 = F8;
|
||||
MOVW(x3, u8);
|
||||
STRB_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0xC7:
|
||||
INST_NAME("MOV GS:Ed, Id");
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= i32
|
||||
i32 = F32S;
|
||||
ed = xEAX+(nextop&7);
|
||||
MOV32(ed, i32);
|
||||
} else { // mem <= i32
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
i32 = F32S;
|
||||
MOV32(x3, i32);
|
||||
STR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD1:
|
||||
nextop = F8;
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("ROL Ed, 1");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
|
||||
GETEDO2(x14);
|
||||
emit_rol32c(dyn, ninst, ed, 1, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("ROR Ed, 1");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
|
||||
GETEDO2(x14);
|
||||
emit_ror32c(dyn, ninst, ed, 1, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("RCL Ed, 1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
MOVW(x2, 1);
|
||||
GETEDO2(x14);
|
||||
if(ed!=x1) {MOV_REG(x1, ed); wb = x1;}
|
||||
CALL_(rcl32, ed, (1<<x2));
|
||||
WBACK2;
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("RCR Ed, 1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
MOVW(x2, 1);
|
||||
if(ed!=x1) {MOV_REG(x1, ed); wb = x1;}
|
||||
CALL_(rcr32, ed, (1<<x2));
|
||||
WBACK2;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
INST_NAME("SHL Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO2(x14);
|
||||
emit_shl32c(dyn, ninst, ed, 1, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("SHR Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO2(x14);
|
||||
emit_shr32c(dyn, ninst, ed, 1, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("SAR Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO2(x14);
|
||||
emit_sar32c(dyn, ninst, ed, 1, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xD3:
|
||||
nextop = F8;
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("ROL Ed, CL");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
AND_IMM8(x3, xECX, 0x1f);
|
||||
TSTS_REG_LSL_IMM5(x3, x3, 0);
|
||||
B_MARK2(cEQ);
|
||||
RSB_IMM8(x3, x3, 0x20);
|
||||
GETEDO2(x14);
|
||||
MOV_REG_ROR_REG(ed, ed, x3);
|
||||
WBACK2;
|
||||
UFLAG_IF { // calculate flags directly
|
||||
CMPS_IMM8(x3, 31);
|
||||
B_MARK(cNE);
|
||||
MOV_REG_LSR_IMM5(x1, ed, 31);
|
||||
ADD_REG_LSL_IMM5(x1, x1, ed, 0);
|
||||
BFI(xFlags, x1, F_OF, 1);
|
||||
MARK;
|
||||
BFI(xFlags, ed, F_CF, 1);
|
||||
UFLAG_DF(x2, d_none);
|
||||
}
|
||||
MARK2;
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("ROR Ed, CL");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
AND_IMM8(x3, xECX, 0x1f);
|
||||
TSTS_REG_LSL_IMM5(x3, x3, 0);
|
||||
B_MARK2(cEQ);
|
||||
GETEDO2(x14);
|
||||
MOV_REG_ROR_REG(ed, ed, x3);
|
||||
WBACK2;
|
||||
UFLAG_IF { // calculate flags directly
|
||||
CMPS_IMM8(x3, 1);
|
||||
B_MARK(cNE);
|
||||
MOV_REG_LSR_IMM5(x2, ed, 30); // x2 = d>>30
|
||||
XOR_REG_LSR_IMM8(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
|
||||
BFI(xFlags, x2, F_OF, 1);
|
||||
MARK;
|
||||
MOV_REG_LSR_IMM5(x2, ed, 31);
|
||||
BFI(xFlags, x2, F_CF, 1);
|
||||
UFLAG_DF(x2, d_none);
|
||||
}
|
||||
MARK2;
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("RCL Ed, CL");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
AND_IMM8(x2, xECX, 0x1f);
|
||||
if(ed!=x1) {MOV_REG(x1, ed); wb = x1;}
|
||||
CALL_(rcl32, ed, (1<<x2));
|
||||
WBACK2;
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("RCR Ed, CL");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
AND_IMM8(x2, xECX, 0x1f);
|
||||
if(ed!=x1) {MOV_REG(x1, ed); wb = x1;}
|
||||
CALL_(rcr32, ed, (1<<x14));
|
||||
WBACK2;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
INST_NAME("SHL Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
AND_IMM8(x3, xECX, 0x1f);
|
||||
GETEDO2(x14);
|
||||
emit_shl32(dyn, ninst, ed, x3, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("SHR Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
AND_IMM8(x3, xECX, 0x1f);
|
||||
GETEDO2(x14);
|
||||
emit_shr32(dyn, ninst, ed, x3, x3, x14);
|
||||
WBACK2;
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("SAR Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
AND_IMM8(x3, xECX, 0x1f);
|
||||
GETEDO2(x14);
|
||||
UFLAG_OP12(ed, x3);
|
||||
MOV_REG_ASR_REG(ed, ed, x3);
|
||||
WBACK2;
|
||||
UFLAG_RES(ed);
|
||||
UFLAG_DF(x3, d_sar32);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE9:
|
||||
case 0xEB:
|
||||
INST_NAME("(ignored) GS:");
|
||||
--addr;
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH GS:Ed");
|
||||
if((nextop&0xC0)==0xC0) { // reg
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+1141
File diff suppressed because it is too large.
Load diff
Executable
+2385
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,188 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarec66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop, opcode = F8;
|
||||
uint8_t wback, wb1, wb2, gb1, gb2;
|
||||
uint8_t ed, gd, u8;
|
||||
int fixedaddress;
|
||||
int32_t i32, j32;
|
||||
int16_t i16;
|
||||
MAYUSE(i32);
|
||||
MAYUSE(j32);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
switch(opcode) {
|
||||
case 0x81:
|
||||
case 0x83:
|
||||
nextop = F8;
|
||||
SMDMB();
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: //ADD
|
||||
if(opcode==0x81) {
|
||||
INST_NAME("LOCK ADD Ew, Iw");
|
||||
} else {
|
||||
INST_NAME("LOCK ADD Ew, Ib");
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
SMDMB();
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_add16c(dyn, ninst, ed, i16, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, 1, LOCK_LOCK);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
if(!fixedaddress) {
|
||||
TSTS_IMM8(wback, 0x1);
|
||||
B_MARK(cNE);
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && !(fixedaddress&1))) {
|
||||
MARKLOCK;
|
||||
LDREXH(x1, wback);
|
||||
emit_add16c(dyn, ninst, x1, i16, x3, x14);
|
||||
STREXH(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
if(!fixedaddress) {
|
||||
SMDMB();
|
||||
B_NEXT(c__);
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && (fixedaddress&1))) {
|
||||
MARK; // unaligned! also, not enough
|
||||
LDRH_IMM8(x1, wback, 0);
|
||||
LDREXB(x14, wback);
|
||||
BFI(x1, x14, 0, 8); // re-inject
|
||||
emit_add16c(dyn, ninst, x1, i16, x3, x14);
|
||||
STREXB(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
STRH_IMM8(x1, wback, 0); // put the whole value
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
SMDMB();
|
||||
break;
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
SMDMB();
|
||||
switch((nextop>>3)&7)
|
||||
{
|
||||
case 0: // INC Ew
|
||||
INST_NAME("INC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
GETEW(x1);
|
||||
emit_inc16(dyn, ninst, ed, x3, x14);
|
||||
EWBACK(x1);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, 1, LOCK_LOCK);
|
||||
if(!fixedaddress) {
|
||||
TSTS_IMM8(wback, 1);
|
||||
B_MARK(cNE); // unaligned
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && !(fixedaddress&1))) {
|
||||
MARKLOCK;
|
||||
LDREXH(x1, wback);
|
||||
emit_inc16(dyn, ninst, x1, x3, x14);
|
||||
STREXH(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
if(!fixedaddress) {
|
||||
SMDMB();
|
||||
B_NEXT(c__);
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && (fixedaddress&1))) {
|
||||
MARK;
|
||||
LDRH_IMM8(x1, wback, 0);
|
||||
LDREXB(x3, wback);
|
||||
BFI(x1, x3, 0, 8);
|
||||
emit_inc16(dyn, ninst, x1, x3, x14);
|
||||
STREXB(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
STRH_IMM8(x1, wback, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: //DEC Ew
|
||||
INST_NAME("DEC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
GETEW(x1);
|
||||
emit_dec32(dyn, ninst, ed, x3, x14);
|
||||
EWBACK(x1);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, 1, LOCK_LOCK);
|
||||
if(!fixedaddress) {
|
||||
TSTS_IMM8(wback, 1);
|
||||
B_MARK(cNE); // unaligned
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && !(fixedaddress&1))) {
|
||||
MARKLOCK;
|
||||
LDREXH(x1, wback);
|
||||
emit_dec16(dyn, ninst, x1, x3, x14);
|
||||
STREXH(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
if(!fixedaddress) {
|
||||
SMDMB();
|
||||
B_NEXT(c__);
|
||||
}
|
||||
if(!fixedaddress || (fixedaddress && (fixedaddress&3))) {
|
||||
MARK;
|
||||
LDRH_IMM8(x1, wback, 0);
|
||||
LDREXB(x3, wback);
|
||||
BFI(x1, x3, 0, 8);
|
||||
emit_dec16(dyn, ninst, x1, x3, x14);
|
||||
STREXB(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
STRH_IMM8(x1, wback, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// default to NO LOCK
|
||||
addr-=2;
|
||||
}
|
||||
SMDMB();
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
Executable
+210
@@ -0,0 +1,210 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop, opcode;
|
||||
int8_t i8;
|
||||
int32_t i32, j32;
|
||||
uint32_t u32;
|
||||
uint8_t gd, ed;
|
||||
int fixedaddress;
|
||||
int cacheupd;
|
||||
|
||||
MAYUSE(i32);
|
||||
MAYUSE(j32);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
nextop = F8;
|
||||
|
||||
switch(nextop) {
|
||||
|
||||
|
||||
case 0x64:
|
||||
// reduced EA size...
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ew16, Gw");
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD; // don't need GETGW here
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
if(ed!=gd) {
|
||||
BFI(ed, gd, 0, 16);
|
||||
}
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STRH_REG(gd, x14, ed);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
ed = xEAX+(nextop&7);
|
||||
if(ed!=gd) {
|
||||
BFI(gd, ed, 0, 16);
|
||||
}
|
||||
} else { // mem <= reg
|
||||
SMREAD();
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, x14, ed, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP1(xEAX+(nextop&7)); // 67 ignored
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, x14, ed, 0);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX, FS:Ow");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
u32 = F16;
|
||||
if(u32) {
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
}
|
||||
SMREAD();
|
||||
LDR_IMM9(xEAX, x1, 0);
|
||||
break;
|
||||
|
||||
case 0xA3:
|
||||
INST_NAME("MOV FS:Ow, EAX");
|
||||
grab_fsdata(dyn, addr, ninst, x1);
|
||||
u32 = F16;
|
||||
if(u32) {
|
||||
MOV32(x2, u32);
|
||||
ADD_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
}
|
||||
STR_IMM9(xEAX, x1, 0);
|
||||
SMWRITE2();
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ew");
|
||||
if((nextop&0xC0)==0xC0) { // reg
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
SMREAD();
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
#define GO(NO, YES) \
|
||||
BARRIER(BARRIER_MAYBE); \
|
||||
JUMP(addr+i8, 1); \
|
||||
if(dyn->insts[ninst].x86.jmp_insts==-1 || \
|
||||
CHECK_CACHE()) { \
|
||||
/* out of the block */ \
|
||||
i32 = dyn->insts[ninst].epilog-(dyn->arm_size+8); \
|
||||
Bcond(NO, i32); \
|
||||
if(dyn->insts[ninst].x86.jmp_insts==-1) { \
|
||||
if(!(dyn->insts[ninst].x86.barrier&BARRIER_FLOAT)) \
|
||||
fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
|
||||
jump_to_next(dyn, addr+i8, 0, ninst); \
|
||||
} else { \
|
||||
CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
|
||||
i32 = dyn->insts[dyn->insts[ninst].x86.jmp_insts].address-(dyn->arm_size+8);\
|
||||
Bcond(c__, i32); \
|
||||
} \
|
||||
} else { \
|
||||
/* inside the block */ \
|
||||
i32 = dyn->insts[dyn->insts[ninst].x86.jmp_insts].address-(dyn->arm_size+8); \
|
||||
Bcond(YES, i32); \
|
||||
}
|
||||
case 0xE0:
|
||||
INST_NAME("LOOPNZ (16bits)");
|
||||
READFLAGS(X_ZF);
|
||||
i8 = F8S;
|
||||
UXTH(x1, xECX, 0);
|
||||
SUBS_IMM8(x1, x1, 1);
|
||||
BFI(xECX, x1, 0, 16);
|
||||
B_NEXT(cEQ); // CX is 0, no LOOP
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
GO(cNE, cEQ);
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("LOOPZ (16bits)");
|
||||
READFLAGS(X_ZF);
|
||||
i8 = F8S;
|
||||
UXTH(x1, xECX, 0);
|
||||
SUBS_IMM8(x1, x1, 1);
|
||||
BFI(xECX, x1, 0, 16);
|
||||
B_NEXT(cEQ); // CX is 0, no LOOP
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
GO(cEQ, cNE);
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("LOOP (16bits)");
|
||||
i8 = F8S;
|
||||
UXTH(x1, xECX, 0);
|
||||
SUBS_IMM8(x1, x1, 1);
|
||||
BFI(xECX, x1, 0, 16);
|
||||
GO(cEQ, cNE);
|
||||
break;
|
||||
case 0xE3:
|
||||
INST_NAME("JCXZ");
|
||||
i8 = F8S;
|
||||
UXTH(x1, xECX, 0);
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
GO(cNE, cEQ);
|
||||
break;
|
||||
#undef GO
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+355
@@ -0,0 +1,355 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarecD8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t ed;
|
||||
uint8_t wback;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
int d1;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(ed);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FADD ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VADD_F32(v1, v1, v2);
|
||||
} else {
|
||||
VADD_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FMUL ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VMUL_F32(v1, v1, v2);
|
||||
} else {
|
||||
VMUL_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FCOM ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FCOMP ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
INST_NAME("FSUB ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, v1, v2);
|
||||
} else {
|
||||
VSUB_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FSUBR ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, v2, v1);
|
||||
} else {
|
||||
VSUB_F64(v1, v2, v1);
|
||||
}
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
INST_NAME("FDIV ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, v1, v2);
|
||||
} else {
|
||||
VDIV_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
INST_NAME("FDIVR ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, v2, v1);
|
||||
} else {
|
||||
VDIV_F64(v1, v2, v1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FADD ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VADD_F32(v1, v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VADD_F64(v1, v1, d1);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FMUL ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VMUL_F32(v1, v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VMUL_F64(v1, v1, d1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FCOM ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VCMP_F64(v1, d1);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FCOMP ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VCMP_F64(v1, d1);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FSUB ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VSUB_F64(v1, v1, d1);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FSUBR ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, s0, v1);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VSUB_F64(v1, d1, v1);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FDIV ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, v1, s0);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VDIV_F64(v1, v1, d1);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FDIVR ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, s0, v1);
|
||||
} else {
|
||||
VCVT_F64_F32(d1, s0);
|
||||
VDIV_F64(v1, d1, v1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+670
@@ -0,0 +1,670 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
static const double d_l2t = L2T;
|
||||
static const double d_l2e = L2E;
|
||||
static const double d_pi = PI;
|
||||
static const double d_lg2 = LG2;
|
||||
static const double d_ln2 = LN2;
|
||||
static const float f_l2t = L2T;
|
||||
static const float f_l2e = L2E;
|
||||
static const float f_pi = PI;
|
||||
static const float f_lg2 = LG2;
|
||||
static const float f_ln2 = LN2;
|
||||
|
||||
extern int arm_v8;
|
||||
|
||||
static const void* round_map[4] = {nearbyint, floor, ceil, trunc};
|
||||
uintptr_t dynarecD9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t ed;
|
||||
uint8_t wback, wb1;
|
||||
uint8_t u8;
|
||||
int fixedaddress;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
int i1, i2, i3;
|
||||
int j32;
|
||||
int parity;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(j32);
|
||||
(void)u8;
|
||||
|
||||
switch(nextop) {
|
||||
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FLD STx");
|
||||
v2 = x87_do_push(dyn, ninst, x3, X87_ST(nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, (nextop&7)+1, X87_COMBINE(0, (nextop&7)+1));
|
||||
if(ST_IS_F(0)) {
|
||||
VMOV_32(v2, v1);
|
||||
} else {
|
||||
VMOV_64(v2, v1);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
|
||||
case 0xC8:
|
||||
INST_NAME("FXCH ST0");
|
||||
break;
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FXCH STx");
|
||||
// swap the cache value, not the double value itself :p
|
||||
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
INST_NAME("FNOP");
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
INST_NAME("FCHS");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
VNEG_F32(v1, v1);
|
||||
} else {
|
||||
VNEG_F64(v1, v1);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("FABS");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
VABS_F32(v1, v1);
|
||||
} else {
|
||||
VABS_F64(v1, v1);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
|
||||
case 0xE4:
|
||||
INST_NAME("FTST");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32_0(v1);
|
||||
} else {
|
||||
VCMP_F64_0(v1);
|
||||
}
|
||||
FCOM(x1, x2); // same flags...
|
||||
break;
|
||||
case 0xE5:
|
||||
INST_NAME("FXAM");
|
||||
#if 1
|
||||
i1 = x87_get_current_cache(dyn, ninst, 0, NEON_CACHE_ST_D);
|
||||
// value put in x14
|
||||
if(i1==-1) {
|
||||
// not in cache, so check Empty status and load it
|
||||
// x14 will be the actual top
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, top));
|
||||
i2 = -dyn->n.x87stack;
|
||||
if(i2) {
|
||||
if(i2<0) {
|
||||
SUB_IMM8(x14, x14, -i2);
|
||||
} else {
|
||||
ADD_IMM8(x14, x14, i2);
|
||||
}
|
||||
AND_IMM8(x14, x14, 7); // (emu->top + i)&7
|
||||
}
|
||||
ADD_REG_LSL_IMM5(x1, xEmu, x14, 3);
|
||||
LDRD_IMM8(x2, x1, offsetof(x86emu_t, x87)); // load r2/r3 with ST0 anyway, for sign extraction
|
||||
ADD_REG_LSL_IMM5(x1, xEmu, x14, 2);
|
||||
LDR_IMM9(x1, x1, offsetof(x86emu_t, p_regs));
|
||||
CMPS_IMM8(x1, 0b11);
|
||||
MOVW_COND(cEQ, x14, 0b100000100000000); // empty: C3,C2,C0 = 101
|
||||
B_MARK3(cEQ);
|
||||
} else {
|
||||
// simply move from cache reg to r2/r3
|
||||
v1 = dyn->n.x87reg[i1];
|
||||
VMOVfrV_D(x2, x3, v1);
|
||||
}
|
||||
// get exponant in r1
|
||||
MOV_REG_LSR_IMM5(x1, x3, 20);
|
||||
MOVW(x14, 0x7ff);
|
||||
ANDS_REG_LSL_IMM5(x1, x1, x14, 0);
|
||||
B_MARK(cNE); // not zero or denormal
|
||||
BIC_IMM8_ROR(x1, x3, 0b10, 1); // remove sign bit
|
||||
ORRS_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
MOVW_COND(cEQ, x14, 0b100000000000000); // Zero: C3,C2,C0 = 100
|
||||
MOVW_COND(cNE, x14, 0b100010000000000); // Denormal: C3,C2,C0 = 110
|
||||
B_MARK3(c__);
|
||||
MARK;
|
||||
CMPS_REG_LSL_IMM5(x1, x14, 0); // infinite/NaN?
|
||||
MOVW_COND(cNE, x14, 0b000010000000000); // normal: C3,C2,C0 = 010
|
||||
B_MARK3(cNE);
|
||||
ORR_IMM8(x1, x1, 0x08, 12); //prepare mask, 0x7ff | 0x800 => 0xfff
|
||||
BIC_REG_LSL_IMM5(x1, x3, x1, 20);
|
||||
ORRS_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
MOVW_COND(cEQ, x14, 0b000010100000000); // infinity: C3,C2,C0 = 011
|
||||
MOVW_COND(cNE, x14, 0b000000100000000); // NaN: C3,C2,C0 = 001
|
||||
MARK3;
|
||||
// Extract signa & Update SW
|
||||
MOV_REG_LSR_IMM5(x1, x3, 31);
|
||||
BFI(x14, x1, 9, 1); //C1
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
BIC_IMM8(x1, x1, 0b01000111, 12);
|
||||
ORR_REG_LSL_IMM5(x14, x14, x1, 0);
|
||||
STRH_IMM8(x14, xEmu, offsetof(x86emu_t, sw));
|
||||
#else
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_refresh(dyn, ninst, x1, x2, 0);
|
||||
CALL(fpu_fxam, -1, 0); // should be possible inline, but is it worth it?
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xE8:
|
||||
INST_NAME("FLD1");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOV_i_32(v1, 0b01110000);
|
||||
} else {
|
||||
VMOV_i_64(v1, 0b01110000);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xE9:
|
||||
INST_NAME("FLDL2T");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
MOV32(x2, (&f_l2t));
|
||||
VLDR_32(v1, x2, 0);
|
||||
} else {
|
||||
MOV32(x2, (&d_l2t));
|
||||
VLDR_64(v1, x2, 0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xEA:
|
||||
INST_NAME("FLDL2E");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
MOV32(x2, (&f_l2e));
|
||||
VLDR_32(v1, x2, 0);
|
||||
} else {
|
||||
MOV32(x2, (&d_l2e));
|
||||
VLDR_64(v1, x2, 0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xEB:
|
||||
INST_NAME("FLDPI");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
MOV32(x2, (&f_pi));
|
||||
VLDR_32(v1, x2, 0);
|
||||
} else {
|
||||
MOV32(x2, (&d_pi));
|
||||
VLDR_64(v1, x2, 0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xEC:
|
||||
INST_NAME("FLDLG2");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
MOV32(x2, (&f_lg2));
|
||||
VLDR_32(v1, x2, 0);
|
||||
} else {
|
||||
MOV32(x2, (&d_lg2));
|
||||
VLDR_64(v1, x2, 0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xED:
|
||||
INST_NAME("FLDLN2");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
MOV32(x2, (&f_ln2));
|
||||
VLDR_32(v1, x2, 0);
|
||||
} else {
|
||||
MOV32(x2, (&d_ln2));
|
||||
VLDR_64(v1, x2, 0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xEE:
|
||||
INST_NAME("FLDZ");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOV_8(v1/2, 0); // float is *2...
|
||||
} else {
|
||||
VMOV_8(v1, 0); // cannot use VMOV_i_F64
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
|
||||
case 0xF0:
|
||||
INST_NAME("F2XM1");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
CALL(arm_f2xm1, -1, 0);
|
||||
#else
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
//if(ST0.d!=0.0)
|
||||
// ST0.d = exp2(ST0.d)-1.0;
|
||||
VMOV_64(0, v1);
|
||||
CALL_1D(exp2, 0); // return is d0
|
||||
if((PK(0)==0xD9 && PK(1)==0xE8) && // next inst is FLD1
|
||||
(PK(2)==0xDE && PK(3)==0xC1)) {
|
||||
MESSAGE(LOG_DUMP, "Hack for fld1 / faddp st1, st0\n");
|
||||
VMOV_64(v1, 0);
|
||||
addr+=4;
|
||||
} else {
|
||||
VMOV_i_64(v1, 0b01110000); // 1.0
|
||||
VSUB_F64(v1, 0, v1);
|
||||
}
|
||||
#endif
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xF1:
|
||||
INST_NAME("FYL2X");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v1); // prepare call to log2
|
||||
CALL_1D(log2, 0);
|
||||
VMUL_F64(v2, v2, 0); //ST(1).d = log2(ST0.d)*ST(1).d
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xF2:
|
||||
INST_NAME("FPTAN");
|
||||
v2 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v1); // prepare call to tan
|
||||
CALL_1D(tan, 0);
|
||||
VMOV_64(v1, 0);
|
||||
//emu->sw.f.F87_C2 = 0;
|
||||
//emu->sw.f.F87_C1 = 0;
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
BFC(x1, 9, 2); //C1 C2 = 0 0
|
||||
STRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
// so here: F64: Imm8 = abcd efgh that gives => aBbbbbbb bbcdefgh 0000000 00000000 00000000...
|
||||
// and want 1.0 = 0x3ff0000000000000
|
||||
// so 00111111 11110000 00000000 00000000....
|
||||
// a = 0, b = 1, c = 1, d = 1, efgh=0
|
||||
// 0b01110000
|
||||
if(ST_IS_F(0)) {
|
||||
VMOV_i_32(v2, 0b01110000);
|
||||
} else {
|
||||
VMOV_i_64(v2, 0b01110000);
|
||||
}
|
||||
break;
|
||||
case 0xF3:
|
||||
INST_NAME("FPATAN");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v2); // prepare call to atan2
|
||||
VMOV_64(1, v1);
|
||||
CALL_2D(atan2, 0);
|
||||
VMOV_64(v2, 0); //ST(1).d = atan2(ST1.d, ST0.d);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xF4:
|
||||
INST_NAME("FXTRACT");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_do_push_empty(dyn, ninst, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(arm_fxtract, -1, 0);
|
||||
// C1 set only if stack under/overflow occurs
|
||||
break;
|
||||
case 0xF5:
|
||||
INST_NAME("FPREM1");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(arm_fprem1, -1, 0);
|
||||
#else
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
s0 = fpu_get_scratch_double(dyn);
|
||||
VDIV_F64(s0, v1, v2);
|
||||
// set rounding to Nearest
|
||||
MOVW(x2, 1); // Nearest
|
||||
VMRS(x1); // get fpscr
|
||||
MOV_REG(x14, x1);
|
||||
BFI(x1, x2, 22, 2); // inject new round
|
||||
VMSR(x1); // put new fpscr
|
||||
VCVTR_S32_F64(s0*2, s0); // => Q
|
||||
// set back rounding
|
||||
VMSR(x14);
|
||||
// get Q
|
||||
VMOVfrV(x14, s0*2);
|
||||
// Put back Q in a double
|
||||
VCVT_F64_S32(s0, s0*2);
|
||||
VMUL_F64(s0, s0, v2);
|
||||
VSUB_F64(v1, v1, s0);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
// set C2 = 0
|
||||
BFC(x1, 10, 1);
|
||||
// set C1 = Q0
|
||||
BFI(x1, x14, 9, 1);
|
||||
// set C3 = Q1
|
||||
MOV_REG_LSR_IMM5(x14, x14, 1);
|
||||
BFI(x1, x14, 14, 1);
|
||||
// Set C0 = Q2
|
||||
MOV_REG_LSR_IMM5(x14, x14, 1);
|
||||
BFI(x1, x14, 8, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
#endif
|
||||
break;
|
||||
case 0xF6:
|
||||
INST_NAME("FDECSTP");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
SUB_IMM8(x2, x2, 1);
|
||||
AND_IMM8(x2, x2, 7);
|
||||
STR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xF7:
|
||||
INST_NAME("FINCSTP");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
ADD_IMM8(x2, x2, 1);
|
||||
AND_IMM8(x2, x2, 7);
|
||||
STR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xF8:
|
||||
INST_NAME("FPREM");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(arm_fprem, -1, 0);
|
||||
#else
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
s0 = fpu_get_scratch_double(dyn);
|
||||
VDIV_F64(s0, v1, v2);
|
||||
VCVT_S32_F64(s0*2, s0); // => Q
|
||||
// get Q
|
||||
VMOVfrV(x14, s0*2);
|
||||
// Put back Q in a double
|
||||
VCVT_F64_S32(s0, s0*2);
|
||||
VMUL_F64(s0, s0, v2);
|
||||
VSUB_F64(v1, v1, s0);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
// set C2 = 0
|
||||
BFC(x1, 10, 1);
|
||||
// set C1 = Q0
|
||||
BFI(x1, x14, 9, 1);
|
||||
// set C3 = Q1
|
||||
MOV_REG_LSR_IMM5(x14, x14, 1);
|
||||
BFI(x1, x14, 14, 1);
|
||||
// Set C0 = Q2
|
||||
MOV_REG_LSR_IMM5(x14, x14, 1);
|
||||
BFI(x1, x14, 8, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
#endif
|
||||
break;
|
||||
case 0xF9:
|
||||
INST_NAME("FYL2XP1");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
VMOV_i_64(0, 0b01110000); // D0 = 1.0
|
||||
VADD_F64(0, 0, v1); // prepare call to log2
|
||||
CALL_1D(log2, 0);
|
||||
VMUL_F64(v2, v2, 0); //ST(1).d = log2(ST0.d + 1.0)*ST(1).d;
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xFA:
|
||||
INST_NAME("FSQRT");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
VSQRT_F32(v1, v1);
|
||||
} else {
|
||||
VSQRT_F64(v1, v1);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xFB:
|
||||
INST_NAME("FSINCOS");
|
||||
v2 = x87_do_push(dyn, ninst, x3, NEON_CACHE_ST_D);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v1);
|
||||
CALL_1D(sin, 0);
|
||||
VSWP(v1, 0);
|
||||
CALL_1D(cos, 0); // would it be faster to do sqrt(1-sin()²) ???
|
||||
VMOV_64(v2, 0);
|
||||
//emu->sw.f.F87_C2 = 0; C1 too
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
BFC(x1, 9, 2); //C2 C1 = 0 0
|
||||
STRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
break;
|
||||
case 0xFC:
|
||||
INST_NAME("FRNDINT");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
if(!arm_v8) {
|
||||
// check if finite first
|
||||
VCMP_F64_0(v1);
|
||||
VMRS_APSR();
|
||||
B_NEXT(cVS); // Unordered, skip
|
||||
B_NEXT(cEQ); // Zero, skip
|
||||
// load round mode
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, cw)); // hopefully cw is not too far for an imm8
|
||||
UBFX(x2, x1, 10, 2); // extract round...
|
||||
MOV32(x1, round_map);
|
||||
LDR_REG_LSL_IMM5(x2, x1, x2, 2);
|
||||
VMOV_64(0, v1); // prepare call to fpu_round
|
||||
CALL_1DR(x2, x3, 0);
|
||||
VMOV_64(v1, 0);
|
||||
} else {
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
VRINTR_F64(v1, v1);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xFD:
|
||||
INST_NAME("FSCALE");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
//if(ST0.d!=0.0)
|
||||
// ST0.d *= exp2(trunc(ST1.d));
|
||||
VCMP_F64_0(v1);
|
||||
VMRS_APSR();
|
||||
B_NEXT(cEQ);
|
||||
if(!arm_v8) {
|
||||
VMOV_64(0, v2);
|
||||
CALL_1DD(trunc, exp2, 0);
|
||||
} else {
|
||||
VRINTZ_F64(0, v2);
|
||||
CALL_1D(exp2, 0);
|
||||
}
|
||||
VMUL_F64(v1, v1, 0);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 0xFE:
|
||||
INST_NAME("FSIN");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v1); // prepare call to sin
|
||||
CALL_1D(sin, 0);
|
||||
VMOV_64(v1, 0);
|
||||
//emu->sw.f.F87_C2 = 0; C1 too
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
BFC(x1, 9, 2); //C2 C1 = 0 0
|
||||
STRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
break;
|
||||
case 0xFF:
|
||||
INST_NAME("FCOS");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
VMOV_64(0, v1); // prepare call to cos
|
||||
CALL_1D(cos, 0);
|
||||
VMOV_64(v1, 0);
|
||||
//emu->sw.f.F87_C2 = 0; C1 too
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
BFC(x1, 9, 2); //C2 C1 = 0 0
|
||||
STRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
break;
|
||||
|
||||
|
||||
case 0xD1:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
case 0xEF:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FLD ST0, float[ED]");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0))
|
||||
s0 = v1;
|
||||
else
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress);
|
||||
VMOVtoV(s0, x2);
|
||||
}
|
||||
if(!ST_IS_F(0)) {
|
||||
VCVT_F64_F32(v1, s0);
|
||||
}
|
||||
// should set C1 to 0
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FST float[ED], ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0))
|
||||
s0 = v1;
|
||||
else {
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VCVT_F32_F64(s0, v1);
|
||||
}
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VSTR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095, 0, 0, NULL);
|
||||
VMOVfrV(x2, s0);
|
||||
STR_IMM9(x2, ed, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FSTP float[ED], ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0))
|
||||
s0 = v1;
|
||||
else {
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VCVT_F32_F64(s0, v1);
|
||||
}
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VSTR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095, 0, 0, NULL);
|
||||
VMOVfrV(x2, s0);
|
||||
STR_IMM9(x2, ed, fixedaddress);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FLDENV Ed");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {
|
||||
MOV_REG(x1, ed);
|
||||
}
|
||||
MOVW(x2, 0);
|
||||
CALL(fpu_loadenv, -1, 0);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FLDCW Ew");
|
||||
GETEW(x1);
|
||||
STRH_IMM8(x1, xEmu, offsetof(x86emu_t, cw)); // hopefully cw is not too far for an imm8
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FNSTENV Ed");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {
|
||||
MOV_REG(x1, ed);
|
||||
}
|
||||
MOVW(x2, 0);
|
||||
CALL(fpu_savenv, -1, 0);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FNSTCW Ew");
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 255, 0, 0, NULL);
|
||||
ed = x1;
|
||||
wb1 = 1;
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, cw));
|
||||
EWBACK;
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+237
@@ -0,0 +1,237 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarecDA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
int32_t j32;
|
||||
uint8_t ed;
|
||||
uint8_t wback;
|
||||
int v1, v2;
|
||||
int d0;
|
||||
int s0;
|
||||
int fixedaddress;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(ed);
|
||||
MAYUSE(j32);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FCMOVB ST0, STx");
|
||||
READFLAGS(X_CF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_CF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cNE, v1, v2); // F_CF==1
|
||||
} else {
|
||||
VMOVcond_64(cNE, v1, v2); // F_CF==1
|
||||
}
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FCMOVE ST0, STx");
|
||||
READFLAGS(X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cNE, v1, v2); // F_ZF==1
|
||||
} else {
|
||||
VMOVcond_64(cNE, v1, v2); // F_ZF==1
|
||||
}
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FCMOVBE ST0, STx");
|
||||
READFLAGS(X_CF|X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF));
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cNE, v1, v2); // F_CF==1 | F_ZF==1
|
||||
} else {
|
||||
VMOVcond_64(cNE, v1, v2); // F_CF==1 | F_ZF==1
|
||||
}
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FCMOVU ST0, STx");
|
||||
READFLAGS(X_PF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_PF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cNE, v1, v2); // F_PF==1
|
||||
} else {
|
||||
VMOVcond_64(cNE, v1, v2); // F_PF==1
|
||||
}
|
||||
break;
|
||||
case 0xE9:
|
||||
INST_NAME("FUCOMPP ST0, ST1");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xE4:
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFD:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FIADD ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VADD_F64(v1, v1, d0);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FIMUL ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VMUL_F64(v1, v1, d0);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FICOM ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VCMP_F64(v1, d0);
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FICOMP ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VCMP_F64(v1, d0);
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FISUB ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VSUB_F64(v1, v1, d0);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FISUBR ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VSUB_F64(v1, d0, v1);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FIDIV ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VDIV_F64(v1, v1, d0);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FIDIVR ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
GETED;
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(d0, s0);
|
||||
VDIV_F64(v1, d0, v1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+418
@@ -0,0 +1,418 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t u8;
|
||||
int32_t j32;
|
||||
uint8_t ed;
|
||||
uint8_t wback;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(j32);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FCMOVNB ST0, STx");
|
||||
READFLAGS(X_CF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_CF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cEQ, v1, v2); // F_CF==0
|
||||
} else {
|
||||
VMOVcond_64(cEQ, v1, v2); // F_CF==0
|
||||
}
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FCMOVNE ST0, STx");
|
||||
READFLAGS(X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cEQ, v1, v2); // F_ZF==0
|
||||
} else {
|
||||
VMOVcond_64(cEQ, v1, v2); // F_ZF==0
|
||||
}
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FCMOVNBE ST0, STx");
|
||||
READFLAGS(X_CF|X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF));
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cEQ, v1, v2); // F_CF==0 & F_ZF==0
|
||||
} else {
|
||||
VMOVcond_64(cEQ, v1, v2); // F_CF==0 & F_ZF==0
|
||||
}
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FCMOVNU ST0, STx");
|
||||
READFLAGS(X_PF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
TSTS_IMM8(xFlags, 1<<F_PF);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVcond_32(cEQ, v1, v2); // F_PF==0
|
||||
} else {
|
||||
VMOVcond_64(cEQ, v1, v2); // F_PF==0
|
||||
}
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("FDISI8087_NOP"); // so.. NOP?
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("FNCLEX");
|
||||
LDRH_IMM8(x2, xEmu, offsetof(x86emu_t, sw));
|
||||
BFC(x2, 0, 8); // IE .. PE, SF, ES
|
||||
BFC(x2, 15, 1); // B
|
||||
STRH_IMM8(x2, xEmu, offsetof(x86emu_t, sw));
|
||||
break;
|
||||
case 0xE3:
|
||||
INST_NAME("FNINIT");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
|
||||
CALL(reset_fpu, -1, 0);
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FUCOMI ST0, STx");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOMI(x1, x2);
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
INST_NAME("FCOMI ST0, STx");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOMI(x1, x2);
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FILD ST0, Ed");
|
||||
v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 1023, 0, 0, NULL);
|
||||
VLDR_32(s0, ed, fixedaddress);
|
||||
} else {
|
||||
GETED;
|
||||
VMOVtoV(s0, ed);
|
||||
}
|
||||
VCVT_F64_S32(v1, s0);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FISTTP Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
wback = 0;
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 4095, 0, 0, NULL);
|
||||
ed = x1;
|
||||
}
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VMRS(x14); // Get FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
VCVT_S32_F64(s0, v1);
|
||||
VMRS(x3); // get the FPCSR reg and test FPU exception (IO only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, ed, 0b10, 1); // 0x80000000
|
||||
WBACK;
|
||||
VMSR(x14); // put back values
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FIST Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
u8 = x87_setround_reset(dyn, ninst, x1, x2, x14); // x1 have the modified RPSCR reg
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
wback = 0;
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 4095, 0, 0, NULL);
|
||||
ed = x1; // will not be writen immediatly, so x1 is safe for now
|
||||
}
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, ed, 0b10, 1); // 0x80000000
|
||||
WBACK;
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FISTP Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
u8 = x87_setround_reset(dyn, ninst, x1, x2, x14); // x1 have the modified RPSCR reg
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
wback = 0;
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 4095, 0, 0, NULL);
|
||||
ed = x1;
|
||||
}
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (denormal and overflow only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, ed, 0b10, 1); // 0x80000000
|
||||
WBACK;
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FLD tbyte");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(PK(0)==0xDB && ((PK(1)>>3)&7)==7) {
|
||||
// the FLD is immediatly followed by an FSTP
|
||||
LDR_IMM9(x2, ed, 0);
|
||||
LDR_IMM9(x3, ed, 4);
|
||||
LDRH_IMM8(x14, ed, 8);
|
||||
// no persistant scratch register, so unrool both instruction here...
|
||||
MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n");
|
||||
nextop = F8; //0xDB
|
||||
nextop = F8; //modrm
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
STR_IMM9(x2, ed, 0);
|
||||
STR_IMM9(x3, ed, 4);
|
||||
STRH_IMM8(x14, ed, 8);
|
||||
} else {
|
||||
if(box86_x87_no80bits) {
|
||||
v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if (parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(v1, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress);
|
||||
LDR_IMM9(x3, ed, fixedaddress + 4);
|
||||
VMOVtoV_D(v1, x2, x3);
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
if(ed!=x1) {
|
||||
MOV_REG(x1, ed);
|
||||
}
|
||||
x87_do_push_empty(dyn, ninst, x3);
|
||||
CALL(arm_fld, -1, 0);
|
||||
#else
|
||||
v1 = x87_do_push(dyn, ninst, x2, NEON_CACHE_ST_D);
|
||||
// copy 10bytes of *ED to STld(0)
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, top));
|
||||
int a = -dyn->n.x87stack;
|
||||
if(a) {
|
||||
if(a<0) {
|
||||
SUB_IMM8(x3, x3, -a);
|
||||
} else {
|
||||
ADD_IMM8(x3, x3, a);
|
||||
}
|
||||
AND_IMM8(x3, x3, 7);
|
||||
}
|
||||
ADD_IMM8(x2, xEmu, offsetof(x86emu_t, fpu_ld)+offsetof(fpu_ld_t, ld));
|
||||
MOVW(x14, sizeof(fpu_ld_t));
|
||||
MLA(x2, x3, x14, x2);
|
||||
LDR_IMM9(x14, ed, 0);
|
||||
STR_IMM9(x14, x2, 0);
|
||||
LDR_IMM9(x14, ed, 4);
|
||||
STR_IMM9(x14, x2, 4);
|
||||
LDRH_IMM8(x14, ed, 8);
|
||||
STRH_IMM8(x14, x2, 8);
|
||||
// convert 10bytes -> double
|
||||
CALL_1RD(FromLD, ed, x2, (1<<x3)|(1<<xFlags)|(1<<x2));
|
||||
// store ref to STld(0).uref, but can be unaligned...
|
||||
VMOVfrV_D(x3, x14, 0);
|
||||
// also, store result to ST0
|
||||
VMOVD(v1, 0);
|
||||
STR_IMM9(x3, x2, offsetof(fpu_ld_t, uref)-offsetof(fpu_ld_t, ld));
|
||||
STR_IMM9(x14, x2, offsetof(fpu_ld_t, uref)-offsetof(fpu_ld_t, ld)+4);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FSTP tbyte");
|
||||
if(box86_x87_no80bits) {
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VSTR_64(v1, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
VMOVfrV_D(x2, x3, v1);
|
||||
STR_IMM9(x2, ed, fixedaddress);
|
||||
STR_IMM9(x3, ed, fixedaddress+4);
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x1, x3, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {
|
||||
MOV_REG(x1, ed);
|
||||
}
|
||||
CALL(arm_fstp, -1, 0);
|
||||
#else
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch_double(dyn);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
// get top in x3
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, top));
|
||||
int a = -dyn->n.x87stack;
|
||||
if(a) {
|
||||
if(a<0) {
|
||||
SUB_IMM8(x3, x3, -a);
|
||||
} else {
|
||||
ADD_IMM8(x3, x3, a);
|
||||
}
|
||||
AND_IMM8(x3, x3, 7);
|
||||
}
|
||||
// get STld(0)
|
||||
ADD_IMM8(x2, xEmu, offsetof(x86emu_t, fpu_ld)+offsetof(fpu_ld_t, ld));
|
||||
MOVW(x14, sizeof(fpu_ld_t));
|
||||
MLA(x2, x3, x14, x2);
|
||||
// compare uref with actual value, top is not used anymore, so x3 is free
|
||||
LDR_IMM9(x14, x2, offsetof(fpu_ld_t, uref)-offsetof(fpu_ld_t, ld));
|
||||
LDR_IMM9(x3, x2, offsetof(fpu_ld_t, uref)-offsetof(fpu_ld_t, ld)+4);
|
||||
VMOVtoV_D(v2, x14, x3);
|
||||
VCEQ_32(v2, v2, v1); // same?
|
||||
VMOVfrV_D(x14, x3, v2);
|
||||
TSTS_REG_LSL_IMM5(x14, x3, 0);
|
||||
B_MARK(cEQ); // different, do the conversion
|
||||
// same... copy STld(0).ld
|
||||
LDR_IMM9(x14, x2, 0);
|
||||
LDR_IMM9(x3, x2, 4);
|
||||
STR_IMM9(x14, ed, 0);
|
||||
STR_IMM9(x3, ed, 4);
|
||||
LDRH_IMM8(x14, x2, 8);
|
||||
STRH_IMM8(x14, ed, 8);
|
||||
B_MARK2(c__);
|
||||
MARK;
|
||||
// different, call D2LD
|
||||
SUB_IMM8(xSP, xSP, 8);
|
||||
VSTR_64(v1, xSP, 0);
|
||||
PUSH(xSP, (1<<xEmu)|(1<<xFlags));
|
||||
ADD_IMM8(0, xSP, 8); //1st arg is &d
|
||||
if(ed!=x1) {
|
||||
MOV_REG_LSL_IMM5(x1, ed, 0); //2nd arg is ed
|
||||
}
|
||||
CALL_S(D2LD, -2, 0);
|
||||
POP(xSP, (1<<xEmu)|(1<<xFlags));
|
||||
ADD_IMM8(xSP, xSP, 8);
|
||||
MARK2;
|
||||
#endif
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+316
@@ -0,0 +1,316 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarecDC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t wback;
|
||||
int v1, v2;
|
||||
int d1;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
|
||||
MAYUSE(d1);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FADD STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VADD_F32(v1, v1, v2);
|
||||
} else {
|
||||
VADD_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FMUL STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VMUL_F32(v1, v1, v2);
|
||||
} else {
|
||||
VMUL_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FCOM ST0, STx"); //yep
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FCOMP ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
INST_NAME("FSUBR STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, v2, v1);
|
||||
} else {
|
||||
VSUB_F64(v1, v2, v1);
|
||||
}
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FSUB STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v1, v1, v2);
|
||||
} else {
|
||||
VSUB_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
INST_NAME("FDIVR STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, v2, v1);
|
||||
} else {
|
||||
VDIV_F64(v1, v2, v1);
|
||||
}
|
||||
break;
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
INST_NAME("FDIV STx, ST0");
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v1, v1, v2);
|
||||
} else {
|
||||
VDIV_F64(v1, v1, v2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FADD ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VADD_F64(v1, v1, d1);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FMUL ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VMUL_F64(v1, v1, d1);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FCOM ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VCMP_F64(v1, d1);
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FCOMP ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VCMP_F64(v1, d1);
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FSUB ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VSUB_F64(v1, v1, d1);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FSUBR ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VSUB_F64(v1, d1, v1);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FDIV ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VDIV_F64(v1, v1, d1);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FDIVR ST0, double[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 2);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(d1, wback, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, wback, fixedaddress);
|
||||
LDR_IMM9(x3, wback, fixedaddress+4);
|
||||
VMOVtoV_D(d1, x2, x3);
|
||||
}
|
||||
VDIV_F64(v1, d1, v1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarecDD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
uint8_t ed;
|
||||
int v1, v2;
|
||||
int i1, i2, i3;
|
||||
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FFREE STx");
|
||||
x87_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
MOVW(x1, nextop&7);
|
||||
CALL(fpu_do_free, -1, 0);
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FST ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VMOV_32(v2, v1);
|
||||
} else {
|
||||
VMOV_64(v2, v1);
|
||||
}
|
||||
break;
|
||||
case 0xD8:
|
||||
INST_NAME("FSTP ST0, ST0");
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FSTP ST0, STx");
|
||||
// copy the cache value for st0 to stx
|
||||
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
INST_NAME("FUCOM ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FUCOMP ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FLD double");
|
||||
v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if (parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VLDR_64(v1, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress);
|
||||
LDR_IMM9(x3, ed, fixedaddress + 4);
|
||||
VMOVtoV_D(v1, x2, x3);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FISTTP i64, ST0");
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(arm_fistt64, -1, 0);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FST double");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VSTR_64(v1, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
VMOVfrV_D(x2, x3, v1);
|
||||
STR_IMM9(x2, ed, fixedaddress);
|
||||
STR_IMM9(x3, ed, fixedaddress+4);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FSTP double");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
VSTR_64(v1, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
VMOVfrV_D(x2, x3, v1);
|
||||
STR_IMM9(x2, ed, fixedaddress);
|
||||
STR_IMM9(x3, ed, fixedaddress+4);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FRSTOR m108byte");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(arm_frstor, -1, 0);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FSAVE m108byte");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(arm_fsave, -1, 0);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FNSTSW m2byte");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x14, &fixedaddress, 0, 0, 0, NULL);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
if(dyn->n.x87stack) {
|
||||
// update top
|
||||
if(dyn->n.x87stack>0) {
|
||||
SUB_IMM8(x2, x2, dyn->n.x87stack);
|
||||
} else {
|
||||
ADD_IMM8(x2, x2, -dyn->n.x87stack);
|
||||
}
|
||||
AND_IMM8(x2, x2, 7);
|
||||
}
|
||||
BFI(x1, x2, 11, 3); // inject top
|
||||
STRH_IMM8(x1, ed, 0); // store whole sw flags
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+212
@@ -0,0 +1,212 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
|
||||
uintptr_t dynarecDE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
int v1, v2;
|
||||
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FADDP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VADD_F32(v2, v2, v1);
|
||||
} else {
|
||||
VADD_F64(v2, v2, v1);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
INST_NAME("FMULP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VMUL_F32(v2, v2, v1);
|
||||
} else {
|
||||
VMUL_F64(v2, v2, v1);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
INST_NAME("FCOMP ST0, STx");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xD9:
|
||||
INST_NAME("FCOMPP ST0, ST1");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, 1));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, X87_COMBINE(0, 1));
|
||||
if(ST_IS_F(0)) {
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
INST_NAME("FSUBRP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v2, v1, v2);
|
||||
} else {
|
||||
VSUB_F64(v2, v1, v2);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FSUBP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VSUB_F32(v2, v2, v1);
|
||||
} else {
|
||||
VSUB_F64(v2, v2, v1);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
INST_NAME("FDIVRP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v2, v1, v2);
|
||||
} else {
|
||||
VDIV_F64(v2, v1, v2);
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
INST_NAME("FDIVP STx, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
if(ST_IS_F(0)) {
|
||||
VDIV_F32(v2, v2, v1);
|
||||
} else {
|
||||
VDIV_F64(v2, v2, v1);
|
||||
}
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
if(ST_IS_F(0)) {
|
||||
VNEG_F32_cond(cNE, v2, v2);
|
||||
} else {
|
||||
VNEG_F64_cond(cNE, v2, v2);
|
||||
}
|
||||
VMSR(x14); // restore fpscr
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xD8:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+451
@@ -0,0 +1,451 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
static const void* round_map[4] = {arm_fist64_0, arm_fist64_1, arm_fist64_2, arm_fist64_3};
|
||||
uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t u8;
|
||||
int32_t j32;
|
||||
uint8_t wback;
|
||||
uint8_t ed;
|
||||
int /*v0, */v1, v2;
|
||||
int s0;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
//MAYUSE(v0);
|
||||
MAYUSE(j32);
|
||||
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FFREEP STx");
|
||||
// not handling Tag...
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
INST_NAME("FNSTSW AX");
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, top));
|
||||
LDRH_IMM8(x1, xEmu, offsetof(x86emu_t, sw));
|
||||
if(dyn->n.x87stack) {
|
||||
// update top
|
||||
if(dyn->n.x87stack>0) {
|
||||
SUB_IMM8(x2, x2, dyn->n.x87stack);
|
||||
} else {
|
||||
ADD_IMM8(x2, x2, -dyn->n.x87stack);
|
||||
}
|
||||
AND_IMM8(x2, x2, 7);
|
||||
}
|
||||
BFI(x1, x2, 11, 3); // inject top
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xEA:
|
||||
case 0xEB:
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
INST_NAME("FUCOMIP ST0, STx");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0))
|
||||
{
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOMI(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
INST_NAME("FCOMIP ST0, STx");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
|
||||
if(ST_IS_F(0))
|
||||
{
|
||||
VCMP_F32(v1, v2);
|
||||
} else {
|
||||
VCMP_F64(v1, v2);
|
||||
}
|
||||
FCOMI(x1, x2);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
case 0xCA:
|
||||
case 0xCB:
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD2:
|
||||
case 0xD3:
|
||||
case 0xD4:
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7:
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FILD ST0, Ew");
|
||||
v1 = x87_do_push(dyn, ninst, x1, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 255, 0, 0, NULL);
|
||||
LDRSH_IMM8(x1, wback, fixedaddress);
|
||||
if(ST_IS_F(0)) {
|
||||
VMOVtoV(v1, x1);
|
||||
VCVT_F32_S32(v1, v1);
|
||||
} else {
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, x1);
|
||||
VCVT_F64_S32(v1, s0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FISTTP Ew, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0, 0, NULL);
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VMRS(x14); // get fpscr
|
||||
// x1 already have FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
if(ST_IS_F(0)) {
|
||||
VCVTR_S32_F32(s0, v1);
|
||||
} else {
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
}
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
|
||||
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
|
||||
MOVW_COND(cNE, x3, 0x8000); // saturated
|
||||
STRH_IMM8(x3, wback, fixedaddress);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
VMSR(x14);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FIST Ew, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
u8 = x87_setround_reset(dyn, ninst, x1, x2, x14);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0, 0, NULL);
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
if(ST_IS_F(0)) {
|
||||
VCVTR_S32_F32(s0, v1);
|
||||
} else {
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
}
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
|
||||
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
|
||||
MOVW_COND(cNE, x3, 0x8000); // saturated
|
||||
STRH_IMM8(x3, wback, fixedaddress);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FISTP Ew, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, box86_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
u8 = x87_setround_reset(dyn, ninst, x1, x2, x14);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0, 0, NULL);
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
if(ST_IS_F(0)) {
|
||||
VCVTR_S32_F32(s0, v1);
|
||||
} else {
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
}
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
VMOVfrV(ed, s0);
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
|
||||
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
|
||||
MOVW_COND(cNE, x3, 0x8000); // saturated
|
||||
STRH_IMM8(x3, wback, fixedaddress);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FBLD ST0, tbytes");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_do_push_empty(dyn, ninst, x1);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(fpu_fbld, -1, 0);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FILD ST0, i64");
|
||||
v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(parity) {
|
||||
LDRD_IMM8(x2, wback, 0); // x2/x3 is 64bits
|
||||
} else {
|
||||
LDR_IMM9(x2, wback, 0);
|
||||
LDR_IMM9(x3, wback, 4);
|
||||
}
|
||||
if(ninst<dyn->size
|
||||
&& dyn->insts[ninst+1].x86.addr
|
||||
&& *(uint8_t*)dyn->insts[ninst+1].x86.addr==0xDF
|
||||
&& (((*(uint8_t*)(dyn->insts[ninst+1].x86.addr+1))>>3)&7)==7)
|
||||
{
|
||||
MESSAGE(LOG_DUMP, "Hack for FILD/FISTP i64");
|
||||
} else {
|
||||
// set STll(0).ll=i64 and ref=ST(0).q later (emu->fpu_ll[emu->top].ref == emu->mmx87[emu->top])
|
||||
// get TOP
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, top));
|
||||
int a = 0 - dyn->n.x87stack;
|
||||
if(a<0) {
|
||||
SUB_IMM8(x1, x1, -a);
|
||||
AND_IMM8(x1, x1, 7);
|
||||
} else if(a>0) {
|
||||
ADD_IMM8(x1, x1, a);
|
||||
AND_IMM8(x1, x1, 7);
|
||||
}
|
||||
// ed (and so x1) is not use anymore.
|
||||
ADD_REG_LSL_IMM5(x1, xEmu, x1, 4); // each fpu_ll is 2 int64: ref than ll
|
||||
ADD_IMM8_ROR(x1, x1, offsetof(x86emu_t, fpu_ll)>>2, 15);
|
||||
STRD_IMM8(x2, x1, 8); // save ll
|
||||
// continue with conversion
|
||||
MOVS_REG_LSR_IMM5(x14, x3, 31); // x14 is sign bit
|
||||
B_MARK(cEQ); // no NEG is no sign bit
|
||||
RSBS_IMM8(x2, x2, 0);
|
||||
RSC_IMM8(x3, x3, 0);
|
||||
MARK;
|
||||
VMOVtoV(s0, x3); // last time x3 is used
|
||||
VCVT_F64_U32(v1, s0);
|
||||
VEOR(v2, v2, v2);
|
||||
MOVW(x3, 0x41F0);
|
||||
VMOVtoDx_16(v2, 3, x3);
|
||||
VMUL_F64(v1, v1, v2); // v1 = double high part of i64
|
||||
VMOVtoV(s0, x2);
|
||||
VCVT_F64_U32(v2, s0);
|
||||
VADD_F64(v1, v1, v2);
|
||||
TSTS_IMM8(x14, 1);
|
||||
VNEG_F64_cond(cNE, v1, v1);
|
||||
VST1_64(v1, x1); // Store STll(0).ref
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FBSTP tbytes, ST0");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(fpu_fbst, -1, 0);
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
case 7: // could be inlined for most thing, but is it usefull?
|
||||
INST_NAME("FISTP i64, ST0");
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
if(ninst
|
||||
&& dyn->insts[ninst-1].x86.addr
|
||||
&& *(uint8_t*)dyn->insts[ninst-1].x86.addr==0xDF
|
||||
&& (((*(uint8_t*)(dyn->insts[ninst-1].x86.addr+1))>>3)&7)==5)
|
||||
{
|
||||
if(parity) {
|
||||
STRD_IMM8(x2, ed, 0); // x2/x3 is 64bits
|
||||
} else {
|
||||
STR_IMM9(x2, ed, 0);
|
||||
STR_IMM9(x3, ed, 4);
|
||||
}
|
||||
} else {
|
||||
#if 1
|
||||
v1 = x87_get_st(dyn, ninst, x2, x3, 0, NEON_CACHE_ST_D);
|
||||
//addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
fpu_get_scratch_double(dyn); // to alocate v0
|
||||
v2 = fpu_get_scratch_double(dyn);
|
||||
#if 1
|
||||
// get TOP
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, top));
|
||||
int a = 0 - dyn->n.x87stack;
|
||||
if(a<0) {
|
||||
SUB_IMM8(x14, x14, -a);
|
||||
AND_IMM8(x14, x14, 7); // (emu->top + i)&7
|
||||
} else if(a>0) {
|
||||
ADD_IMM8(x14, x14, a);
|
||||
AND_IMM8(x14, x14, 7); // (emu->top + i)&7
|
||||
}
|
||||
ADD_REG_LSL_IMM5(x14, xEmu, x14, 4); // each fpu_ll is 2 int64: ref than ll
|
||||
MOVW(x2, offsetof(x86emu_t, fpu_ll)); //can be optimized?
|
||||
ADD_REG_LSL_IMM5(x14, x14, x2, offsetof(fpu_ll_t, sref));
|
||||
VLDR_64(v2, x14, 0);
|
||||
VCEQ_32(v2, v2, v1); // compare
|
||||
VMOVfrV_D(x2, x3, v2);
|
||||
ANDS_REG_LSL_IMM5(x2, x2, x3, 0); // if NE then values are the same!
|
||||
B_MARK(cEQ); // do the i64 conversion
|
||||
// memcpy(ed, &STll(0).ll, sizeof(int64_t));
|
||||
LDRD_IMM8(x2, x14, offsetof(fpu_ll_t, sq)); // load ll
|
||||
B_MARK3(c__);
|
||||
MARK;
|
||||
// load round mode
|
||||
LDRH_IMM8(x14, xEmu, offsetof(x86emu_t, cw)); // hopefully cw is not too far for an imm8
|
||||
UBFX(x2, x14, 10, 2); // extract round...
|
||||
MOV32(x14, round_map);
|
||||
LDR_REG_LSL_IMM5(x2, x14, x2, 2);
|
||||
VMOV_64(0, v1); // prepare call to log2
|
||||
CALL_1DR_U64(x2, x2, x3, x14, (1<<x1));
|
||||
MARK3;
|
||||
STR_IMM9(x2, ed, 0);
|
||||
STR_IMM9(x3, ed, 4);
|
||||
#else
|
||||
v0 = fpu_get_scratch_double(dyn);
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
// check STll(0).ref==ST(0).q so emu->fpu_ll[emu->top].ref == emu->mmx87[emu->top]
|
||||
// get TOP
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, top));
|
||||
int a = 0 - dyn->n.x87stack;
|
||||
if(a<0) {
|
||||
SUB_IMM8(x14, x14, -a);
|
||||
AND_IMM8(x14, x14, 7); // (emu->top + i)&7
|
||||
} else if(a>0) {
|
||||
ADD_IMM8(x14, x14, a);
|
||||
AND_IMM8(x14, x14, 7); // (emu->top + i)&7
|
||||
}
|
||||
ADD_REG_LSL_IMM5(x14, xEmu, x14, 4); // each fpu_ll is 2 int64: ref than ll
|
||||
MOVW(x2, offsetof(x86emu_t, fpu_ll)); //can be optimized?
|
||||
ADD_REG_LSL_IMM5(x14, x14, x2, 0);
|
||||
VLDR_64(v2, x14, 0);
|
||||
VCEQ_32(v2, v2, v1); // compare
|
||||
VMOVfrV_D(x2, x3, v2);
|
||||
ANDS_REG_LSL_IMM5(x2, x2, x3, 0); // if NE then values are the same!
|
||||
B_MARK(cEQ); // do the i64 conversion
|
||||
// memcpy(ed, &STll(0).ll, sizeof(int64_t));
|
||||
LDRD_IMM8(x2, x14, 8); // load ll
|
||||
B_MARK3(c__);
|
||||
MARK;
|
||||
VEOR(v0, v0, v0);
|
||||
MOVW(x2, 0x41F0);
|
||||
VMOVtoDx_16(v0, 3, x2); // V0 = (1<<32) as double
|
||||
VMOVfrDx_32(x14, v1, 1); // get high part to extract sign
|
||||
VABS_F64(v1 ,v1); //ST0 will be poped, so lost...
|
||||
VDIV_F64(v2, v1, v0); // v2 = abs(ST0)/(1<<32) : so 32 bits high part
|
||||
MSR_nzcvq_0();
|
||||
VMRS(x2); // get fpscr
|
||||
ORR_IMM8(x3, x2, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
VCVT_U32_F64(s0, v2); // convert high part to U32
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
VMSR(x2); // put back fpscr
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
B_MARK2(cEQ); // not overflow...
|
||||
MARKLOCK;
|
||||
MOV_IMM(x3, 0b10, 1); // 0x80000000
|
||||
MOVW(x2, 0);
|
||||
B_MARK3(c__);
|
||||
MARK2; // continue conversion, it fits an int64!
|
||||
VCVT_F64_U32(v2, s0); // int part now
|
||||
VMLS_F64(v1, v2, v0); // compute low part
|
||||
VMOVfrV(x3, s0); // transfert high path
|
||||
TSTS_IMM8_ROR(x14, 0b10, 1); // test high part with 0x800000000
|
||||
B_MARKLOCK(cNE); // int overflow...
|
||||
VCVT_U32_F64(s0, v1); // convert low part
|
||||
VMOVfrV(x2, s0); // transfert low part
|
||||
TSTS_IMM8_ROR(x14, 0b10, 1); // 0x800000000
|
||||
B_MARK3(cEQ);
|
||||
RSBS_IMM8(x2, x2, 0); // NEG(i64)
|
||||
RSC_IMM8(x3, x3, 0);
|
||||
MARK3;
|
||||
STR_IMM9(x2, x1, 0);
|
||||
STR_IMM9(x3, x1, 4);
|
||||
#endif
|
||||
#else
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
x87_forget(dyn, ninst, x2, x3, 0);
|
||||
if(ed!=x1) {MOV_REG(x1, ed);}
|
||||
CALL(arm_fistp64, -1, 0);
|
||||
#endif
|
||||
}
|
||||
x87_do_pop(dyn, ninst, x3);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Executable
+699
@@ -0,0 +1,699 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
#include "../tools/bridge_private.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
// emit OR32 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch
|
||||
void emit_or32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_or32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit OR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_or32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_or32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
ORRS_IMM8(s1, s1, c, 0);
|
||||
} else {
|
||||
ORR_IMM8(s1, s1, c, 0);
|
||||
}
|
||||
} else {
|
||||
MOV32(s3, c);
|
||||
IFX(X_ALL) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR32 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch
|
||||
void emit_xor32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_xor32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
XORS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
XOR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_xor32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_xor32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
XORS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
XOR_IMM8(s1, s1, c);
|
||||
}
|
||||
} else {
|
||||
MOV32(s3, c);
|
||||
IFX(X_ALL) {
|
||||
XORS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
XOR_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND32 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch
|
||||
void emit_and32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_and32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ANDS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_and32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_and32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
ANDS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
AND_IMM8(s1, s1, c);
|
||||
}
|
||||
} else {
|
||||
if(((~c)>=0 && (~c)<256)) {
|
||||
IFX(X_ALL) {
|
||||
BICS_IMM8_ROR(s1, s1, ~c, 0);
|
||||
} else {
|
||||
BIC_IMM8(s1, s1, ~c, 0);
|
||||
}
|
||||
} else {
|
||||
MOV32(s3, c);
|
||||
IFX(X_ALL) {
|
||||
ANDS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit OR8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_or8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit OR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_or8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ORRS_IMM8(s1, s1, c, 0);
|
||||
} else {
|
||||
ORR_IMM8(s1, s1, c, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_xor8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
XORS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
XOR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_xor8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
XORS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
XOR_IMM8(s1, s1, c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_and8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_and8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ANDS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_and8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ANDS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
AND_IMM8(s1, s1, c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// emit OR16 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_or16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit OR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_or16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_or16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
ORRS_IMM8(s1, s1, c, 0);
|
||||
} else {
|
||||
ORR_IMM8(s1, s1, c, 0);
|
||||
}
|
||||
} else {
|
||||
MOVW(s3, c);
|
||||
IFX(X_ALL) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR16 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_xor16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
XORS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
XOR_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit XOR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_xor16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_xor16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
XORS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
XOR_IMM8(s1, s1, c);
|
||||
}
|
||||
} else {
|
||||
MOVW(s3, c);
|
||||
IFX(X_ALL) {
|
||||
XORS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
XOR_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND16 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
|
||||
void emit_and16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s3, d_and16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
ANDS_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s1, s1, s2, 0);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit AND16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_and16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
SET_DF(s4, d_and16);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c>=0 && c<256) {
|
||||
IFX(X_ALL) {
|
||||
ANDS_IMM8(s1, s1, c);
|
||||
} else {
|
||||
AND_IMM8(s1, s1, c);
|
||||
}
|
||||
} else {
|
||||
MOVW(s3, c);
|
||||
IFX(X_ALL) {
|
||||
ANDS_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s1, s1, s3, 0);
|
||||
}
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 15);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
Executable
+1860
File diff suppressed because it is too large.
Load diff
Executable
+658
@@ -0,0 +1,658 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
#include "../tools/bridge_private.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
// emit SHL32 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch. s3 can be same as s2
|
||||
void emit_shl32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
int32_t j32;
|
||||
MAYUSE(j32);
|
||||
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(F_OF) {
|
||||
CMPS_IMM8(s2, 0);
|
||||
IFX(F_OF) {
|
||||
BIC_IMM8_COND(cEQ, xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9_COND(cEQ, s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
B_NEXT(cEQ);
|
||||
}
|
||||
IFX(X_CF | X_OF) {
|
||||
RSB_IMM8(s4, s2, 32);
|
||||
MOV_REG_LSR_REG(s4, s1, s4);
|
||||
BFI(xFlags, s4, F_CF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVS_REG_LSL_REG(s1, s1, s2);
|
||||
} else {
|
||||
MOV_REG_LSL_REG(s1, s1, s2);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
CMPS_IMM8(s2, 1); // if s3==1
|
||||
IFX(X_SF) {} else {MOV_REG_LSR_IMM5_COND(cEQ, s4, s1, 31);}
|
||||
XOR_REG_LSL_IMM5_COND(cEQ, s4, s4, xFlags, 0); // CF is set if OF is asked
|
||||
BFI_COND(cEQ, xFlags, s4, F_OF, 1);
|
||||
// else
|
||||
BFC_COND(cNE, xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_shl32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c==0) {
|
||||
IFX(F_OF) {
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 32-c);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_ZF|X_OF) {
|
||||
MOVS_REG_LSL_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSL_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
IFX(X_SF) {} else {MOV_REG_LSR_IMM5(s3, s1, 31);}
|
||||
XOR_IMM8_COND(cCS, s3, s3, 1);
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
} else {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHR32 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
|
||||
void emit_shr32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
int32_t j32;
|
||||
MAYUSE(j32);
|
||||
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_ALL) {
|
||||
CMPS_IMM8(s2, 0); //if(!c)
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9_COND(cEQ, s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
B_NEXT(cEQ);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
MOVS_REG_LSR_REG(s1, s1, s2);
|
||||
} else {
|
||||
MOV_REG_LSR_REG(s1, s1, s2);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
CMPS_IMM8(s2, 1);
|
||||
MOV_REG_LSR_IMM5_COND(cEQ, s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8_COND(cEQ, s4, s4, s4, 1);
|
||||
BFI_COND(cEQ, xFlags, s4, F_OF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_shr32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
MOVS_REG_LSR_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSR_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SAR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_sar32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_sar32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
MOVS_REG_ASR_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_ASR_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_rol32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
if(!c)
|
||||
return;
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_rol32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
MOV_REG_ROR_IMM5(s1, s1, 32-c);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
BFI(xFlags, s1, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
ADD_REG_LSR_IMM5(s3, s1, s1, 31);
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit ROR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_ror32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
if(!c)
|
||||
return;
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_ror32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
MOV_REG_ROR_IMM5(s1, s1, c);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_shrd32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4)
|
||||
{
|
||||
c&=0x1f;
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags calc as shr32
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOVS_REG_LSR_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSR_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s2, 32-c);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s2, 32-c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
void emit_shld32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4)
|
||||
{
|
||||
c&=0x1f;
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags computation as with shl32
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c==0) {
|
||||
IFX(F_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 32-c);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOVS_REG_LSL_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSL_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
UBFX(s3, s1, (31-c), 1);
|
||||
XOR_IMM8_COND(cCS, s3, s3, 1);
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
} else {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSR_IMM5(s1, s1, s2, 32-c);
|
||||
} else {
|
||||
ORR_REG_LSR_IMM5(s1, s1, s2, 32-c);
|
||||
}
|
||||
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHRD32 instruction, from s1, fill s2 , shift s3, store result in s1 using s4 and s3 as scratch
|
||||
void emit_shrd32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
int j32;
|
||||
MAYUSE(j32);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags calc as shr32
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
CMPS_IMM8(s3, 0);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9_COND(cEQ, s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
B_NEXT(cEQ);
|
||||
|
||||
IFX(X_CF) {
|
||||
MOVS_REG_LSR_REG(s1, s1, s3);
|
||||
} else {
|
||||
MOV_REG_LSR_REG(s1, s1, s3);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
RSB_IMM8(s3, s3, 32);
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSL_REG(s1, s1, s2, s3);
|
||||
} else {
|
||||
ORR_REG_LSL_REG(s1, s1, s2, s3);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
CMPS_IMM8(s3, 31); // 32-c
|
||||
MOV_REG_LSR_IMM5_COND(cEQ, s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8_COND(cEQ, s4, s4, s4, 1);
|
||||
BFI_COND(cEQ, xFlags, s4, F_OF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHLD32 instruction, from s1, fill s2 , shift s3, store result in s1 using s4 and s3 as scratch
|
||||
void emit_shld32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
int j32;
|
||||
MAYUSE(j32);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags calc as shl32
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
CMPS_IMM8(s3, 0);
|
||||
IFX(F_OF) {
|
||||
BFC_COND(cEQ, xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9_COND(cEQ, s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
B_NEXT(cEQ);
|
||||
|
||||
IFX(X_CF) {
|
||||
RSB_IMM8(s4, s3, 32);
|
||||
MOV_REG_LSR_REG(s4, s1, s4);
|
||||
BFI(xFlags, s4, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOVS_REG_LSL_REG(s1, s1, s3);
|
||||
} else {
|
||||
MOV_REG_LSL_REG(s1, s1, s3);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOVW_COND(cCS, s4, 1);
|
||||
MOVW_COND(cCC, s4, 0);
|
||||
CMPS_IMM8(s3, 1);
|
||||
ORR_REG_LSR_IMM5_COND(cEQ, s4, s4, s1, 30);
|
||||
BFI_COND(cEQ, xFlags, s4, F_OF, 1);
|
||||
//else
|
||||
BFC_COND(cNE, xFlags, F_OF, 1);
|
||||
}
|
||||
RSB_IMM8(s3, s3, 32);
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSR_REG(s1, s1, s2, s3);
|
||||
} else {
|
||||
ORR_REG_LSR_REG(s1, s1, s2, s3);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit ROL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_rol8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(c&7) {
|
||||
BFI(s1, s1, 24, 8); // duplicate the value for rotate left
|
||||
MOV_REG_ROR_IMM5(s1, s1, 32-(c&7));
|
||||
}
|
||||
//AND_IMM8(s1, s1, 0xff);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
BFI(xFlags, s1, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
ADD_REG_LSR_IMM5(s3, s1, s1, 7);
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit ROR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_ror8);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(c&7) {
|
||||
BFI(s1, s1, 8, 8); // duplicate the value for Rotate right
|
||||
MOV_REG_ROR_IMM5(s1, s1, c&7);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
AND_IMM8(s1, s1, 0xff);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 7);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 6);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+411
@@ -0,0 +1,411 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
#include "../tools/bridge_private.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
// emit CMP32 instruction, from cmp s1 , s2, using s3 and s4 as scratch
|
||||
void emit_cmp32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_cmp32);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
SUBS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
ORR_IMM8_COND(cVS, xFlags, xFlags, 0b10, 0x0b);
|
||||
BIC_IMM8_COND(cVC, xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
// reversed carry
|
||||
ORR_IMM8_COND(cCC, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// and now the tricky ones (and mostly unused), PF and AF
|
||||
IFX(X_AF) {
|
||||
// bc = (res & (~d | s)) | (~d & s)
|
||||
MVN_REG_LSL_IMM5(s4, s1, 0); // s4 = ~d
|
||||
ORR_REG_LSL_IMM5(s4, s4, s2, 0); // s4 = ~d | s
|
||||
AND_REG_LSL_IMM5(s4, s4, s3, 0); // s4 = res & (~d | s)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_AF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_CF|X_AF) {
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
}
|
||||
AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit CMP32 instruction, from cmp s1 , 0, using s3 and s4 as scratch
|
||||
void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, op2));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
SET_DF(s4, d_cmp32);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
SUBS_IMM8(s3, s1, 0); // res = s1 - 0
|
||||
// and now the tricky ones (and mostly unused), PF and AF
|
||||
// bc = (res & (~d | s)) | (~d & s) => is 0 here...
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit CMP16 instruction, from cmp s1 , s2, using s3 and s4 as scratch
|
||||
void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s3, d_cmp16);
|
||||
} else {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW(s4, 0xffff);
|
||||
TSTS_REG_LSL_IMM5(s3, s4, 0);
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s)
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
MVN_REG_LSL_IMM5(s4, s1, 0); // s4 = ~d
|
||||
ORR_REG_LSL_IMM5(s4, s4, s2, 0); // s4 = ~d | s
|
||||
AND_REG_LSL_IMM5(s4, s4, s3, 0); // s4 = res & (~d | s)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_CF, 1); // CF : bc & 0x8000
|
||||
}
|
||||
IFX(X_AF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 14);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
}
|
||||
AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit CMP16 instruction, from cmp s1 , #0, using s3 and s4 as scratch
|
||||
void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
MOVW(s3, 0);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
SET_DF(s3, d_cmp16);
|
||||
} else {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s) = 0
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW(s4, 0xffff);
|
||||
TSTS_REG_LSL_IMM5(s1, s4, 0);
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
// emit CMP8 instruction, from cmp s1 , s2, using s3 and s4 as scratch
|
||||
void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_cmp8);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
TSTS_IMM8(s3, 0xff);
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s)
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
MVN_REG_LSL_IMM5(s4, s1, 0); // s4 = ~d
|
||||
ORR_REG_LSL_IMM5(s4, s4, s2, 0); // s4 = ~d | s
|
||||
AND_REG_LSL_IMM5(s4, s4, s3, 0); // s4 = res & (~d | s)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_CF, 1); // CF : bc & 0x80
|
||||
}
|
||||
IFX(X_AF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 6);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
}
|
||||
AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
// emit CMP8 instruction, from cmp s1 , 0, using s3 and s4 as scratch
|
||||
void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, op2));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
SET_DF(s3, d_cmp8);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s) = 0
|
||||
IFX(X_CF | X_AF | X_ZF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
TSTS_IMM8(s1, 0xff);
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
emit_pf(dyn, ninst, s1, s3, s4);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST32 instruction, from test s1 , s2, using s3 and s4 as scratch
|
||||
void emit_test32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
SET_DF(s3, d_tst32);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
if(s1==s2) {
|
||||
AND_IMM8(s3, s1, 31);
|
||||
} else {
|
||||
AND_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
}
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST16 instruction, from test s1 , s2, using s3 and s4 as scratch
|
||||
void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
SET_DF(s3, d_tst16);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST8 instruction, from test s1 , s2, using s3 and s4 as scratch. May destroy s2 also
|
||||
void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX_PENDOR0 {
|
||||
SET_DF(s3, d_tst8);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF|X_CF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX_PENDOR0 {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
AND_IMM8(s2, s3, 0xE0); // lsr 5 masking pre-applied
|
||||
MOV32(s4, GetParityTab());
|
||||
LDR_REG_LSR_IMM5(s4, s4, s2, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
Executable
+1111
File diff suppressed because it is too large.
Load diff
Executable
+485
@@ -0,0 +1,485 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86run.h"
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "arm_printer.h"
|
||||
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
// Get Ex as a double, not a quad (warning, x2 and x3 may get used)
|
||||
#define GETEX(a, w) \
|
||||
if((nextop&0xC0)==0xC0) { \
|
||||
a = sse_get_reg(dyn, ninst, x1, nextop&7,w);\
|
||||
} else { \
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3); \
|
||||
a = fpu_get_scratch_double(dyn); \
|
||||
SMREAD(); \
|
||||
if(parity) { \
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL); \
|
||||
VLDR_64(a, ed, fixedaddress); \
|
||||
} else { \
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);\
|
||||
LDR_IMM9(x2, ed, fixedaddress+0); \
|
||||
LDR_IMM9(x3, ed, fixedaddress+4); \
|
||||
VMOVtoV_D(a, x2, x3); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GETGM(a) \
|
||||
gd = (nextop&0x38)>>3; \
|
||||
a = mmx_get_reg(dyn, ninst, x1, x2, x3, gd)
|
||||
|
||||
uintptr_t dynarecF20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
uint8_t u8;
|
||||
uint32_t u32;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback;
|
||||
int v0, v1;
|
||||
int d0, d1;
|
||||
int s0;
|
||||
int fixedaddress;
|
||||
int parity;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(d0);
|
||||
|
||||
switch(nextop) {
|
||||
|
||||
case 0x10:
|
||||
INST_NAME("MOVSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
d0 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
VMOVD(v0, d0);
|
||||
} else {
|
||||
SMREAD();
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress+0);
|
||||
LDR_IMM9(x3, ed, fixedaddress+4);
|
||||
VMOVtoV_D(v0, x2, x3);
|
||||
VEOR(v0+1, v0+1, v0+1); // upper 64bits set to 0
|
||||
}
|
||||
break;
|
||||
case 0x11:
|
||||
INST_NAME("MOVSD Ex, Gx");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
d0 = sse_get_reg(dyn, ninst, x1, nextop&7, 1);
|
||||
VMOVD(d0, v0);
|
||||
} else {
|
||||
VMOVfrV_D(x2, x3, v0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
STR_IMM9(x2, ed, fixedaddress+0);
|
||||
STR_IMM9(x3, ed, fixedaddress+4);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
INST_NAME("MOVDDUP Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
d0 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
VMOVD(v0, d0);
|
||||
} else {
|
||||
SMREAD();
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress+0);
|
||||
LDR_IMM9(x3, ed, fixedaddress+4);
|
||||
VMOVtoV_D(v0, x2, x3);
|
||||
}
|
||||
VMOVD(v0+1, v0);
|
||||
break;
|
||||
|
||||
case 0x2A:
|
||||
INST_NAME("CVTSI2SD Gx, Ed");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETED;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
VMOVtoV(s0, ed);
|
||||
VCVT_F64_S32(v0, s0);
|
||||
break;
|
||||
|
||||
case 0x2C:
|
||||
INST_NAME("CVTTSD2SI Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
d0 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
VLDR_64(d0, ed, fixedaddress);
|
||||
}
|
||||
if(!box86_dynarec_fastround) {
|
||||
VMRS(x14); // Get FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VCVT_S32_F64(s0, d0);
|
||||
VMOVfrV(gd, s0);
|
||||
if(!box86_dynarec_fastround) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU exception (IO only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, gd, 0b10, 1); // 0x80000000
|
||||
VMSR(x14); // put back values
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("CVTSD2SI Gd, Ex");
|
||||
if(!box86_dynarec_fastround)
|
||||
u8 = sse_setround_reset(dyn, ninst, x1, x2, x14);
|
||||
else
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
d0 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3, 0, NULL);
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
VLDR_64(d0, ed, fixedaddress);
|
||||
}
|
||||
VCVTR_S32_F64(s0, d0);
|
||||
VMOVfrV(gd, s0);
|
||||
if(!box86_dynarec_fastround) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU exception (IO only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, gd, 0b10, 1); // 0x80000000
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
INST_NAME("SQRTSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VSQRT_F64(v0, d0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
VNEG_F64_cond(cNE, v0, v0);
|
||||
VMSR(x14); // restore FPSCR
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
INST_NAME("ADDSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VADD_F64(v0, v0, d0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
VNEG_F64_cond(cNE, v0, v0);
|
||||
VMSR(x14); // restore FPSCR
|
||||
}
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("MULSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VMUL_F64(v0, v0, d0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
VNEG_F64_cond(cNE, v0, v0);
|
||||
VMSR(x14); // restore FPSCR
|
||||
}
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("CVTSD2SS Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(v0<16) {
|
||||
VCVT_F32_F64(v0*2, d0);
|
||||
} else {
|
||||
d1 = fpu_get_scratch_double(dyn);
|
||||
VMOV_64(d1, v0);
|
||||
VCVT_F32_F64(d1*2, d0);
|
||||
VMOV_64(v0, d1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5C:
|
||||
INST_NAME("SUBSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VSUB_F64(v0, v0, d0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
VNEG_F64_cond(cNE, v0, v0);
|
||||
VMSR(x14); // restore FPSCR
|
||||
}
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("MINSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
// MINSD: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
|
||||
VCMP_F64(v0, d0);
|
||||
VMRS_APSR();
|
||||
VMOVcond_64(cCS, v0, d0); // move v0 <- d0 if v0 or d0 unordered or v0 >= d0
|
||||
break;
|
||||
case 0x5E:
|
||||
INST_NAME("DIVSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x14); // get fpscr
|
||||
ORR_IMM8(x3, x14, 0b010, 9); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
}
|
||||
VDIV_F64(v0, v0, d0);
|
||||
if(!box86_dynarec_fastnan) {
|
||||
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
VNEG_F64_cond(cNE, v0, v0);
|
||||
VMSR(x14); // restore FPSCR
|
||||
}
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("MAXSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
// MAXSD: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0]
|
||||
VCMP_F64(d0, v0);
|
||||
VMRS_APSR();
|
||||
VMOVcond_64(cCS, v0, d0); // move v0 <- d0 if v0 or d0 is unordered or d0 >= v0
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
INST_NAME("PSHUFLW Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
v1 = fpu_get_scratch_quad(dyn);
|
||||
VLD1Q_64(v1, ed);
|
||||
}
|
||||
|
||||
u8 = F8;
|
||||
// only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
|
||||
u32 = 0;
|
||||
for (int i=0; i<2; ++i) {
|
||||
u32 |= (((u8>>(i*2))&3)*2+0)<<(i*16+0);
|
||||
u32 |= (((u8>>(i*2))&3)*2+1)<<(i*16+8);
|
||||
}
|
||||
MOV32(x2, u32);
|
||||
u32 = 0;
|
||||
for (int i=2; i<4; ++i) {
|
||||
u32 |= (((u8>>(i*2))&3)*2+0)<<((i-2)*16+0);
|
||||
u32 |= (((u8>>(i*2))&3)*2+1)<<((i-2)*16+8);
|
||||
}
|
||||
MOV32(x3, u32);
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
VMOVtoV_D(d0, x2, x3);
|
||||
VTBL1_8(v0, v1, d0);
|
||||
if(v0!=v1) {
|
||||
VMOVD(v0+1, v1+1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7C:
|
||||
INST_NAME("HADDPS Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
v1 = fpu_get_scratch_quad(dyn);
|
||||
VLD1Q_64(v1, ed);
|
||||
}
|
||||
VPADD_F32(v0, v0, v0+1);
|
||||
if(v0==v1) {
|
||||
VMOVD(v0+1, v0);
|
||||
} else {
|
||||
VPADD_F32(v0+1, v1, v1+1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8A:
|
||||
case 0x8B:
|
||||
case 0x8C:
|
||||
case 0x8D:
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
return dynarec0F(dyn, addr-1, ip, ninst, ok, need_epilog);
|
||||
|
||||
case 0xC2:
|
||||
INST_NAME("CMPSD Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
GETEX(d0, 0);
|
||||
u8 = F8;
|
||||
VCMP_F64(v0, d0);
|
||||
VMRS_APSR();
|
||||
MOVW(x2, 0);
|
||||
switch(u8&7) {
|
||||
case 0: MVN_COND_REG_LSL_IMM5(cEQ, x2, x2, 0); break; // Equal
|
||||
case 1: MVN_COND_REG_LSL_IMM5(cCC, x2, x2, 0); break; // Less than
|
||||
case 2: MVN_COND_REG_LSL_IMM5(cLS, x2, x2, 0); break; // Less or equal
|
||||
case 3: MVN_COND_REG_LSL_IMM5(cVS, x2, x2, 0); break; // NaN
|
||||
case 4: MVN_COND_REG_LSL_IMM5(cNE, x2, x2, 0); break; // Not Equal or unordered
|
||||
case 5: MVN_COND_REG_LSL_IMM5(cCS, x2, x2, 0); break; // Greater or equal or unordered
|
||||
case 6: MVN_COND_REG_LSL_IMM5(cHI, x2, x2, 0); break; // Greater or unordered, test inverted, N!=V so unordereded or less than (inverted)
|
||||
case 7: MVN_COND_REG_LSL_IMM5(cVC, x2, x2, 0); break; // not NaN
|
||||
}
|
||||
VMOVtoV_D(v0, x2, x2);
|
||||
break;
|
||||
|
||||
case 0xD6:
|
||||
INST_NAME("MOVDQ2Q Gm, Ex");
|
||||
nextop = F8;
|
||||
GETGM(v0);
|
||||
GETEX(v1, 0);
|
||||
VMOV_64(v0, v1);
|
||||
break;
|
||||
|
||||
case 0xE6:
|
||||
INST_NAME("CVTPD2DQ Gx, Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, 0, NULL);
|
||||
v1 = fpu_get_scratch_quad(dyn);
|
||||
VLD1Q_8(v1, ed);
|
||||
}
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x14);
|
||||
if(v0<16) {
|
||||
VCVTR_S32_F64(v0*2, v1);
|
||||
VCVTR_S32_F64(v0*2+1, v1+1);
|
||||
} else {
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
VCVTR_S32_F64(d0*2, v1);
|
||||
VCVTR_S32_F64(d0*2+1, v1+1);
|
||||
VMOVD(v0, d0);
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
VEOR(v0+1, v0+1, v0+1);
|
||||
break;
|
||||
|
||||
case 0xF0:
|
||||
INST_NAME("LDDQ Gx,Ex");
|
||||
nextop = F8;
|
||||
gd = (nextop&0x38)>>3;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, nextop&7, 0);
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
VMOVQ(v0, v1);
|
||||
} else {
|
||||
SMREAD();
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-12, 0, 0, NULL);
|
||||
LDR_IMM9(x2, ed, fixedaddress+0);
|
||||
LDR_IMM9(x3, ed, fixedaddress+4);
|
||||
VMOVtoV_D(v0, x2, x3);
|
||||
LDR_IMM9(x2, ed, fixedaddress+8);
|
||||
LDR_IMM9(x3, ed, fixedaddress+12);
|
||||
VMOVtoV_D(v0+1, x2, x3);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
Loaded 100 of 1232 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user