mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-08 10:10:25 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b300bd199 | ||
|
|
9c69ebd717 | ||
|
|
ea01b56422 | ||
|
|
216cf51d4a | ||
|
|
1476b502a2 | ||
|
|
bc53ae8925 | ||
|
|
9cef52a1fc | ||
|
|
5ed60d99a8 | ||
|
|
d7c7a716fe | ||
|
|
41bee35634 | ||
|
|
e764029cae | ||
|
|
b110623103 | ||
|
|
35c1f97115 | ||
|
|
e8a7bef5a0 | ||
|
|
c2f73e6de0 | ||
|
|
0724f52d5f | ||
|
|
61a605a2dc | ||
|
|
7a058c9194 | ||
|
|
99971e94c0 | ||
|
|
445d885090 | ||
|
|
fc02f0d140 | ||
|
|
c2d02977f8 | ||
|
|
946c999e25 | ||
|
|
c8b6f80f99 | ||
|
|
9444ce0b89 | ||
|
|
401d2ae0b9 | ||
|
|
8dde796103 | ||
|
|
7ba0e7a055 | ||
|
|
eb039c0449 | ||
|
|
0c0f5263e1 | ||
|
|
ad70febaac | ||
|
|
39583c6da4 | ||
|
|
1bf4851cf6 | ||
|
|
2129e98b0e | ||
|
|
b015f33376 | ||
|
|
2636e7e8b5 | ||
|
|
b0e726d953 | ||
|
|
eb40c49132 | ||
|
|
5dadc513db | ||
|
|
4120dc10bd | ||
|
|
48f51bd5fe | ||
|
|
940317949a | ||
|
|
f9b6ea48e9 | ||
|
|
3567c6da2b | ||
|
|
f3fe72b541 | ||
|
|
14966e48a6 | ||
|
|
91b282235b | ||
|
|
63c3e4fcf5 | ||
|
|
c740590bcd | ||
|
|
e868c89233 | ||
|
|
c517d7196d | ||
|
|
cb42b3b00f | ||
|
|
61362b06ec | ||
|
|
bb8559933f | ||
|
|
c2cb333261 | ||
|
|
b7e4cc4f50 | ||
|
|
a4908f1407 | ||
|
|
a252e87fa9 | ||
|
|
ee3ee539e0 | ||
|
|
c4b79374fe | ||
|
|
5dfa27ea58 | ||
|
|
49cba432c2 | ||
|
|
39a9cf903f | ||
|
|
611ac3933c | ||
|
|
fdd1509ee5 | ||
|
|
52a9443f53 | ||
|
|
0d1488b016 | ||
|
|
fb4662cb28 | ||
|
|
32a747979a | ||
|
|
362a92c158 | ||
|
|
c27b659bce | ||
|
|
049cbd3783 | ||
|
|
8b5b5aa3a7 | ||
|
|
f85b9ac664 | ||
|
|
ee5a41e21e | ||
|
|
d49fc43791 | ||
|
|
9ec7930eb1 | ||
|
|
26dd597a1b | ||
|
|
040f8d9a9f | ||
|
|
f107321d06 | ||
|
|
64313d5aa6 | ||
|
|
71845a11bb | ||
|
|
e3adda8ff9 | ||
|
|
85e79a8224 | ||
|
|
9ef3e080fa | ||
|
|
4b5f63dc6d | ||
|
|
730e9d215c | ||
|
|
efa1cbd49a | ||
|
|
91798194d5 | ||
|
|
d550f9384c | ||
|
|
d59d531f14 | ||
|
|
c9369c5ea1 | ||
|
|
05fd25d3bb | ||
|
|
2b75a0de55 | ||
|
|
59e1da5f74 | ||
|
|
639466d45a | ||
|
|
95bdaf6eca | ||
|
|
9dc10bdc47 | ||
|
|
bf212a7b52 | ||
|
|
40d83ad882 | ||
|
|
baa9efeaa6 | ||
|
|
0c17b55e28 | ||
|
|
e2f4ab7700 | ||
|
|
84982ff86f | ||
|
|
cfd17e59ac | ||
|
|
af0b0c6c9d | ||
|
|
0e588e444f | ||
|
|
f575a7846e | ||
|
|
c7ff0f658b | ||
|
|
b8cc8594f6 | ||
|
|
6197b70a9a | ||
|
|
60396f58c0 | ||
|
|
ee83ef4c01 | ||
|
|
4b7e116aa7 | ||
|
|
785d3ed5ab | ||
|
|
33d1727925 | ||
|
|
a50d34e4ba | ||
|
|
7e0c4dcee5 | ||
|
|
f5174d12aa | ||
|
|
2cb25c095a | ||
|
|
d0039c65b4 | ||
|
|
099bd148cb | ||
|
|
20885702b9 | ||
|
|
751582df05 | ||
|
|
5212de0d66 | ||
|
|
056bb38607 | ||
|
|
1a01adb2ef | ||
|
|
797731e9e2 | ||
|
|
3e2c698710 | ||
|
|
58b24c85a2 | ||
|
|
28ebc1a0b7 | ||
|
|
65487dac51 | ||
|
|
592af6db3b | ||
|
|
997140f500 | ||
|
|
16f0adec6f | ||
|
|
ba6ff73c69 | ||
|
|
2bf78ea18c | ||
|
|
fc6efb220b | ||
|
|
523bfbdf3b | ||
|
|
46ad2261e7 | ||
|
|
6c60ad4695 | ||
|
|
37697e2ec7 | ||
|
|
f5eb3c1e9b | ||
|
|
5cfd379e97 | ||
|
|
fecaf3111b | ||
|
|
ff6f34aadf | ||
|
|
4c3d55fb5c | ||
|
|
d2a5005dcc | ||
|
|
05e1b422d3 | ||
|
|
69f49f79e4 | ||
|
|
2453eb9b2d | ||
|
|
93b4813ee2 | ||
|
|
7cbe71c218 | ||
|
|
8bb53e1001 | ||
|
|
f79af5afd4 | ||
|
|
7c27085bd3 | ||
|
|
53834f2b29 | ||
|
|
7c09957263 | ||
|
|
242832fa3c | ||
|
|
9beb6b4f63 | ||
|
|
0861a88d6e | ||
|
|
1c0dc8ec7c | ||
|
|
b21776f9b0 | ||
|
|
998f164aa3 | ||
|
|
58d8627cea | ||
|
|
877ca41451 | ||
|
|
94dedd47c6 | ||
|
|
1173c1d23f | ||
|
|
d9c9575e6a | ||
|
|
2239f92816 | ||
|
|
637e177408 | ||
|
|
bb653e6888 | ||
|
|
09e07973dd | ||
|
|
6b7afd7f8e | ||
|
|
eb7858d23a | ||
|
|
1db09fe897 | ||
|
|
22a5b573d5 | ||
|
|
f12f366a3d | ||
|
|
b51ab081ae | ||
|
|
50fcaf04b4 | ||
|
|
96bca6eac3 | ||
|
|
ed7147e598 | ||
|
|
4892c68f17 | ||
|
|
3ab56994da | ||
|
|
a54afc8e04 | ||
|
|
01b5ee9c78 | ||
|
|
a513cd847b | ||
|
|
06b6871c80 | ||
|
|
f5dc038621 | ||
|
|
38dce9138d | ||
|
|
2aa5c5f337 | ||
|
|
e6d2c12792 | ||
|
|
c3dbdf419d | ||
|
|
c566ba970d | ||
|
|
81925643e8 | ||
|
|
285c874e53 | ||
|
|
ba078c63a8 | ||
|
|
a54959a6e3 | ||
|
|
c573742845 | ||
|
|
dab01b8b9f | ||
|
|
9e58047980 | ||
|
|
6f8f37e8ff | ||
|
|
3ec950726b | ||
|
|
cec62dad44 | ||
|
|
89eca28d3a | ||
|
|
313e4854a0 | ||
|
|
8c1ffca530 | ||
|
|
7099774a3c | ||
|
|
925f6a9922 | ||
|
|
356200159a | ||
|
|
f0d8712275 | ||
|
|
fe3b66b018 | ||
|
|
83af8c6cdf | ||
|
|
ad5b5ea617 | ||
|
|
b439817467 | ||
|
|
276191cdcf | ||
|
|
8438b61747 | ||
|
|
f4a9f8dd79 | ||
|
|
f235c7f702 | ||
|
|
8e1e2c7840 | ||
|
|
0b632afbfe | ||
|
|
89dcd2566b | ||
|
|
314edea645 | ||
|
|
fe28bd93bd | ||
|
|
d882a5c8fe | ||
|
|
044dec0bfa | ||
|
|
ed8b6fe9db | ||
|
|
c98b4c8f45 | ||
|
|
b78d81d319 | ||
|
|
9f3be89e12 | ||
|
|
9e0b300354 | ||
|
|
dde6d26236 | ||
|
|
e6eac39759 | ||
|
|
5654e77625 | ||
|
|
c9f01d975d | ||
|
|
1fe213f900 | ||
|
|
802002b7a3 | ||
|
|
69a7c00841 | ||
|
|
c24f040888 | ||
|
|
0f225fc1a0 | ||
|
|
666506e834 | ||
|
|
21c0a2e7d7 | ||
|
|
03204f709e | ||
|
|
6827fc6cc9 | ||
|
|
cff4798249 | ||
|
|
93bf308179 | ||
|
|
166c4858a1 | ||
|
|
4b8fb02198 | ||
|
|
8432f7d8e2 | ||
|
|
ec675564c6 | ||
|
|
8c71178238 | ||
|
|
72df0bd1a0 | ||
|
|
6035cbd5c1 | ||
|
|
d7007dd3cc | ||
|
|
9c5daf5954 | ||
|
|
a57bc9e780 | ||
|
|
2e2bed4374 | ||
|
|
4eeaddf490 | ||
|
|
0cd53ca748 | ||
|
|
fa2bd920bd | ||
|
|
613f2cccf1 | ||
|
|
d91461f468 | ||
|
|
bcc497c865 | ||
|
|
2414f82c38 | ||
|
|
fd7d811b29 | ||
|
|
e533cd0ea1 | ||
|
|
9b7e5d69b2 | ||
|
|
0c5e6d867f | ||
|
|
32c646d0d2 | ||
|
|
35a6828209 | ||
|
|
2b66675a08 | ||
|
|
93638ac95a | ||
|
|
f489761e68 | ||
|
|
56ccde005e | ||
|
|
47e4aa0b84 | ||
|
|
b977d84f11 | ||
|
|
b7f14ff338 | ||
|
|
86211e5970 | ||
|
|
d8669d7c7d | ||
|
|
0d8e02a3fe | ||
|
|
1e681cead0 | ||
|
|
53f2423578 | ||
|
|
6cdfa05604 | ||
|
|
d55e879879 | ||
|
|
d377433997 | ||
|
|
207073bf36 | ||
|
|
316f31a4bb | ||
|
|
ada8efcdef | ||
|
|
99d0889cfd | ||
|
|
653a67c8ad | ||
|
|
b99893d1c3 | ||
|
|
a5c4d01649 | ||
|
|
82105a1543 | ||
|
|
c65910fd25 | ||
|
|
b5de464e85 | ||
|
|
81eb0b45b3 | ||
|
|
c772d1ab49 | ||
|
|
1af7c15801 | ||
|
|
e11901a7a6 | ||
|
|
0b2f84df54 | ||
|
|
a1ff40733b | ||
|
|
a61888e06c | ||
|
|
691259ec0d | ||
|
|
91e678da5b | ||
|
|
8a7c2b5228 | ||
|
|
e7710f59fa | ||
|
|
4039f3c249 | ||
|
|
6f46ccdd5a | ||
|
|
b79ba11d95 | ||
|
|
5a35184ba7 | ||
|
|
db801da658 | ||
|
|
f160fe3300 | ||
|
|
5d5dd3a3bc | ||
|
|
5fa65a4b38 | ||
|
|
cc34c75fc3 | ||
|
|
7fb1a34947 | ||
|
|
d087020139 | ||
|
|
4065e61ec5 | ||
|
|
da6b799a10 | ||
|
|
967c73efd1 | ||
|
|
6a35cd2a56 | ||
|
|
ebf03f8878 | ||
|
|
d7dbee5126 | ||
|
|
08930381e9 | ||
|
|
495c98a488 | ||
|
|
80a4b61e5c | ||
|
|
1d20968f82 | ||
|
|
ca8d569e63 | ||
|
|
670770e24a | ||
|
|
b55b138303 | ||
|
|
d0c7cb46e7 | ||
|
|
6e1e7de52b | ||
|
|
bb0a445a6b | ||
|
|
7157803c03 | ||
|
|
b7c5adae3d | ||
|
|
809b663350 | ||
|
|
1c4f1cb8c2 | ||
|
|
cace5f0ccb | ||
|
|
4aaa0b5d24 | ||
|
|
c0829b807c | ||
|
|
7d3cdb06e3 | ||
|
|
42f3884478 | ||
|
|
fcd46e2cdc | ||
|
|
f36f9d290d | ||
|
|
ae512cc4ed | ||
|
|
4fd59da003 | ||
|
|
e2d7cc5011 | ||
|
|
79413a4147 | ||
|
|
80b357da41 | ||
|
|
a54f516447 | ||
|
|
26ba1148e8 | ||
|
|
8b2b96d5c5 | ||
|
|
e21a506936 | ||
|
|
e86c6359d6 | ||
|
|
acce64b268 | ||
|
|
89713993cb | ||
|
|
cf24eaf9d2 | ||
|
|
cd1ac51b79 | ||
|
|
a7ded59393 | ||
|
|
205ef4ddeb | ||
|
|
145689783f | ||
|
|
21a21b04e6 | ||
|
|
87e19076ad | ||
|
|
9492b6ca66 | ||
|
|
4a45db781f | ||
|
|
0329d5fcc2 | ||
|
|
f39b5514c5 | ||
|
|
4700a6322e | ||
|
|
91a8fef1bb | ||
|
|
a56a66a227 | ||
|
|
1b262dac29 | ||
|
|
3b15ef1cb5 | ||
|
|
9ac695b9be | ||
|
|
05060803b2 | ||
|
|
e84f2e4a8b | ||
|
|
6fac9ee35b | ||
|
|
93cc31bc48 | ||
|
|
13ee4acd59 | ||
|
|
1360e7112c | ||
|
|
12987af561 | ||
|
|
e071a70ec2 | ||
|
|
48db75961e | ||
|
|
da0820ce0a | ||
|
|
ac81132435 | ||
|
|
946da43038 | ||
|
|
cad9450e16 | ||
|
|
0c7cc657cc | ||
|
|
ce4590f5ba | ||
|
|
cd3f5ca97d | ||
|
|
fc2a6d4dd1 | ||
|
|
85fe4c628e | ||
|
|
1bb7d9efd8 | ||
|
|
25b4dd1457 | ||
|
|
ea13414083 | ||
|
|
3e745474d3 | ||
|
|
5ad2f155c1 | ||
|
|
945b4192b1 | ||
|
|
3b71ba6090 | ||
|
|
9fc4697233 | ||
|
|
8a37b12f81 | ||
|
|
6ac7d7a1db | ||
|
|
291db1530c | ||
|
|
e77ea1b45c | ||
|
|
80db0175e0 | ||
|
|
15f90899eb | ||
|
|
e2ce483e0d | ||
|
|
41b31dc58d | ||
|
|
f8b9c7b2b7 | ||
|
|
a8000cb629 | ||
|
|
17f2371804 | ||
|
|
4d377de5ab | ||
|
|
956f6ffc15 | ||
|
|
600ae18d4b | ||
|
|
39aa02c19c | ||
|
|
7dcb86f500 | ||
|
|
f873255a19 | ||
|
|
4662ab1c80 | ||
|
|
b0b34e3a2a | ||
|
|
631da8a532 | ||
|
|
f80886fd68 | ||
|
|
cbe7ced335 | ||
|
|
955f6e74ab | ||
|
|
8a982e8b5e | ||
|
|
47f5fe7caf | ||
|
|
6e0f32f4ca | ||
|
|
62eca11bee | ||
|
|
13f5ec1524 | ||
|
|
e751d41ba7 | ||
|
|
7fd884b9c1 | ||
|
|
a98887589d | ||
|
|
0882f910df | ||
|
|
f65c22d329 | ||
|
|
485959195e | ||
|
|
28fb1bb0c0 | ||
|
|
cc12620868 | ||
|
|
9c89e64691 | ||
|
|
d432b18d23 | ||
|
|
98c0811525 | ||
|
|
77b16ae30d | ||
|
|
f4a4bdd006 | ||
|
|
ed7dddc3d8 | ||
|
|
4c6401c66b | ||
|
|
42441c99cc | ||
|
|
f775474062 | ||
|
|
c30e012e8d | ||
|
|
d90522bc4e | ||
|
|
0f7bec0d38 | ||
|
|
201b971ad7 | ||
|
|
1c72527dc8 | ||
|
|
5ce3e29913 | ||
|
|
1a7cff559a | ||
|
|
c28b0629fa | ||
|
|
6a3c56c131 | ||
|
|
d03c85da90 | ||
|
|
6a5d831331 | ||
|
|
2164c564f2 | ||
|
|
2a33cf4e60 | ||
|
|
6698a844f6 | ||
|
|
1c5ccefdef | ||
|
|
64bfd06be4 | ||
|
|
5bf154195d | ||
|
|
0239305f69 | ||
|
|
3ee5558c70 | ||
|
|
059dc12adc | ||
|
|
610c63cd15 | ||
|
|
fa3db3df11 | ||
|
|
4b4c0143d9 | ||
|
|
fa76ce1f05 | ||
|
|
59bb9c2083 | ||
|
|
689d64b62a | ||
|
|
f6c3386960 | ||
|
|
5055866a5a | ||
|
|
9f7d0c4404 | ||
|
|
7e5aa3e7c6 | ||
|
|
c7afc0b3df | ||
|
|
566ff08109 | ||
|
|
2247b61ed3 | ||
|
|
55d6971a23 | ||
|
|
7168167400 | ||
|
|
7e17c862cf | ||
|
|
bb60cc8568 | ||
|
|
857c4600dc | ||
|
|
88bd65998f | ||
|
|
ecbd382ae4 | ||
|
|
16f63a94c3 | ||
|
|
bd7ff2efd6 | ||
|
|
ed21342995 | ||
|
|
4c238f0e17 | ||
|
|
7c000adb87 | ||
|
|
2d4f073925 | ||
|
|
a25aab1426 | ||
|
|
54f593fa75 | ||
|
|
054de8e83f | ||
|
|
e6d1bf78a6 | ||
|
|
b4b8617a92 | ||
|
|
20bad4e126 | ||
|
|
3650609975 | ||
|
|
fe3b30ccbb | ||
|
|
ccae82e1f5 | ||
|
|
f1addb8b28 | ||
|
|
96f5108a37 | ||
|
|
3eeb10c0a6 | ||
|
|
ce3d2afad2 | ||
|
|
bdee719767 | ||
|
|
42263e0be9 | ||
|
|
ca08012bbf | ||
|
|
ca47ee273e | ||
|
|
eb299f500b | ||
|
|
a25b50d3aa | ||
|
|
b735a8663e | ||
|
|
769c6c8f61 | ||
|
|
b250056a61 | ||
|
|
e305e5f1bb | ||
|
|
18ce48e2c0 | ||
|
|
06c93c93fe | ||
|
|
869ddcfdda | ||
|
|
65e5e86c2b | ||
|
|
122b5e64e8 | ||
|
|
6c66d66b02 | ||
|
|
85d694b36e | ||
|
|
44cff3ae25 | ||
|
|
c2d7dc573a | ||
|
|
a30433ea12 | ||
|
|
6f7b462d53 | ||
|
|
95e5724117 | ||
|
|
1eaef70d2d | ||
|
|
3ed1e565f8 | ||
|
|
8d0c976a18 | ||
|
|
9165ec875a | ||
|
|
6a7997b41e | ||
|
|
2a9d863131 | ||
|
|
e3e9a86088 | ||
|
|
d5c787c213 | ||
|
|
559040e290 | ||
|
|
59ba5b7f0e | ||
|
|
474a43a424 | ||
|
|
fb276bdc6b | ||
|
|
1c1a26626b | ||
|
|
93f29d8cd9 | ||
|
|
0054dde600 | ||
|
|
794f2104bc | ||
|
|
036af9f55f | ||
|
|
5bde45cc86 | ||
|
|
ae1739f330 | ||
|
|
cfc09e0965 | ||
|
|
26c9b3426f | ||
|
|
963da34562 | ||
|
|
4adad381ce | ||
|
|
e561196f44 | ||
|
|
14bd1368cc | ||
|
|
415fc458be | ||
|
|
f2822f1a05 | ||
|
|
646dd718f5 | ||
|
|
83ed8ebb22 | ||
|
|
88aab487f1 | ||
|
|
6d1e30cd3c | ||
|
|
ab73969ea4 | ||
|
|
93b371eb8c | ||
|
|
b7007a1bdd | ||
|
|
a26c108464 | ||
|
|
2971e9729c | ||
|
|
6b2d923041 | ||
|
|
cb30db320e | ||
|
|
e1ae914a1d | ||
|
|
51aa4b0416 | ||
|
|
b0db168fb5 | ||
|
|
3b3338d132 | ||
|
|
cc50331745 | ||
|
|
2777bc142f | ||
|
|
c73545e25b | ||
|
|
b862e74ae4 | ||
|
|
0d662b8543 | ||
|
|
ea0b23b783 | ||
|
|
f15a187087 | ||
|
|
12a82cf91f | ||
|
|
5af2fa49c3 | ||
|
|
843fe30e46 | ||
|
|
0da561cd20 | ||
|
|
fd613de55e | ||
|
|
b2dc460db9 | ||
|
|
e5b7dfb524 | ||
|
|
de0b602748 | ||
|
|
d0d85e684d | ||
|
|
05b322414a | ||
|
|
38ee050a09 | ||
|
|
1ee4959c05 | ||
|
|
bc9086551b | ||
|
|
f9f0c99c1b | ||
|
|
a1b46711c4 | ||
|
|
f6bb071f84 | ||
|
|
746a0031f8 | ||
|
|
f78d0ae471 | ||
|
|
7879a33cdc | ||
|
|
a84a9847be | ||
|
|
0c54e19c5f | ||
|
|
d507f8a6d0 | ||
|
|
b18efe4e40 | ||
|
|
83d69939f3 | ||
|
|
aee5032597 | ||
|
|
c7cc78194f | ||
|
|
089db91b39 | ||
|
|
cb33043dd4 | ||
|
|
b207ecad6a | ||
|
|
48461001d2 | ||
|
|
12649d04c7 | ||
|
|
5033738f73 | ||
|
|
df80b9c5de | ||
|
|
ffa94268d7 | ||
|
|
b7f0996459 | ||
|
|
dcf196c2ae | ||
|
|
a71856801b | ||
|
|
84608fc581 | ||
|
|
c30a392fe8 | ||
|
|
d8c16de2ec | ||
|
|
2d04cbe97c | ||
|
|
ab65422034 | ||
|
|
3bde222242 | ||
|
|
d0af86d5bf | ||
|
|
73b17d4add | ||
|
|
93fa5323c5 | ||
|
|
b0c10c9ae5 | ||
|
|
b8ed1b9646 | ||
|
|
0912e8f16d | ||
|
|
327dc2c835 | ||
|
|
8f937788ce | ||
|
|
52ba725fa5 | ||
|
|
a39249454e | ||
|
|
c1f2304c88 | ||
|
|
85c6e28d47 | ||
|
|
d1a253f469 | ||
|
|
6aa57f5c73 | ||
|
|
023aeae9e6 | ||
|
|
38880ab5a4 | ||
|
|
4e19324177 | ||
|
|
9757d1b67a | ||
|
|
5422b108af | ||
|
|
0d650b183f | ||
|
|
fa432bb9d1 | ||
|
|
81e4e26dc5 | ||
|
|
4f6a66f9c6 | ||
|
|
127d273ada | ||
|
|
469d4f81eb | ||
|
|
8f08a14115 | ||
|
|
4ac43047d0 | ||
|
|
4257fdded3 | ||
|
|
56298870f6 | ||
|
|
48354185dd | ||
|
|
5f0cbcf26d | ||
|
|
ffc875c2d6 | ||
|
|
8a180e3892 | ||
|
|
c4d3d734b1 | ||
|
|
6e8c244b77 | ||
|
|
ac2ed68228 | ||
|
|
fb27c89282 | ||
|
|
74bed6edcb | ||
|
|
49a854fa7e | ||
|
|
5adabbbcaa | ||
|
|
42eae3e1b4 | ||
|
|
518d2b0129 | ||
|
|
bc8c786b80 | ||
|
|
5ab8a6f6f4 | ||
|
|
385a31ec11 | ||
|
|
5c49954f69 | ||
|
|
6ce7a1ba1f | ||
|
|
8c1335626f | ||
|
|
8b0eec097b | ||
|
|
a39c8aa5c5 | ||
|
|
27745ceebb | ||
|
|
64b213fe42 | ||
|
|
eaca84e9ba | ||
|
|
bca0f4d66d | ||
|
|
8c17a37d1a | ||
|
|
979a3232f9 | ||
|
|
47dbbe030c | ||
|
|
d05e719ce3 | ||
|
|
12f4afcba2 | ||
|
|
cd2638d11a | ||
|
|
c87796e51c | ||
|
|
d47b555e12 | ||
|
|
4e568e1fdf | ||
|
|
0688c53675 | ||
|
|
6d523f9c7f | ||
|
|
0f4f274bc7 | ||
|
|
09b8c3b94e | ||
|
|
1dbb676f38 | ||
|
|
331866bd1d | ||
|
|
2515096f56 | ||
|
|
8868023ce9 | ||
|
|
dd9d6f8f83 | ||
|
|
21e403c908 | ||
|
|
f66aa57594 | ||
|
|
506cb980b1 | ||
|
|
937e2cf853 | ||
|
|
82bf71ee19 | ||
|
|
eb9e7b9fee | ||
|
|
b02942c0b0 | ||
|
|
56e813ccb7 | ||
|
|
cf5b94d471 | ||
|
|
5d941f702a | ||
|
|
b46925e7e0 | ||
|
|
e676756cda | ||
|
|
591958c59c | ||
|
|
63a80ff696 | ||
|
|
ee6e3a7a96 | ||
|
|
1d607cb937 | ||
|
|
c5ced39665 | ||
|
|
7b2e77807d | ||
|
|
7a623ef19c | ||
|
|
f292be40b2 | ||
|
|
0166330c73 | ||
|
|
3cc9d47032 | ||
|
|
128708db2d | ||
|
|
3027ee9f3e | ||
|
|
51c673e62d | ||
|
|
56bd83f6fb | ||
|
|
2473bb6902 | ||
|
|
da0e153a05 | ||
|
|
394e81af45 | ||
|
|
6af8d70cc1 | ||
|
|
2dea11a9e3 | ||
|
|
cd55c12e44 | ||
|
|
cb2cf7c9b1 | ||
|
|
494786be26 | ||
|
|
27013d6a03 | ||
|
|
3ba91a6513 | ||
|
|
c547090ee0 | ||
|
|
f87b9c15d3 | ||
|
|
3d76bcde2e | ||
|
|
1a6f49ce45 | ||
|
|
745a7fc034 | ||
|
|
6158a0ad45 | ||
|
|
a51f684c41 | ||
|
|
681e207af5 | ||
|
|
f651b7bfb0 | ||
|
|
6c53e12b49 | ||
|
|
01c9157fce | ||
|
|
3448e94171 | ||
|
|
08085be360 | ||
|
|
3809866d99 | ||
|
|
52a05c9f67 | ||
|
|
ba5aa0c83b | ||
|
|
939486fa05 | ||
|
|
c8d98f6901 | ||
|
|
38cfeeb558 | ||
|
|
cf9f8d0535 | ||
|
|
9e43737e18 | ||
|
|
5d03ad24c3 | ||
|
|
ac6721edac | ||
|
|
126cf27972 | ||
|
|
0a677c7f83 | ||
|
|
63e35941e2 | ||
|
|
3ae6992641 | ||
|
|
a243532730 | ||
|
|
ed99f5e6d2 | ||
|
|
7d1bf95d93 | ||
|
|
93cbf59e9e | ||
|
|
e8f9796752 | ||
|
|
adb423d96b | ||
|
|
74acad3628 | ||
|
|
541adff4d4 | ||
|
|
39189a746b | ||
|
|
f82e938ae8 | ||
|
|
34520c0b4f | ||
|
|
121148da72 | ||
|
|
1e34db98a8 | ||
|
|
9f821d6406 | ||
|
|
70a6d96748 | ||
|
|
4a440b6f0a | ||
|
|
fdfc5c4a41 | ||
|
|
6699c0ee7f | ||
|
|
8807b1aa3c | ||
|
|
2aff4239cc | ||
|
|
d99d18759b | ||
|
|
68c3be3e16 | ||
|
|
f148b106a5 | ||
|
|
9ffabf4c85 | ||
|
|
aebfd61539 | ||
|
|
8dee79d380 | ||
|
|
d3c1ea5b0f | ||
|
|
2835a2f87d | ||
|
|
062a098ac5 | ||
|
|
5563103453 | ||
|
|
a1d62eb92b | ||
|
|
138a021fad | ||
|
|
bdf0e95a12 | ||
|
|
90674b825a | ||
|
|
b3bc09f898 | ||
|
|
320459c2c6 | ||
|
|
8d14c10b8c | ||
|
|
2c2b252dac | ||
|
|
8efd1e3ae0 | ||
|
|
e7adc6b7f9 | ||
|
|
fc7d204d4b | ||
|
|
2153e7098c | ||
|
|
29beabd683 | ||
|
|
80c346060f | ||
|
|
4e10cd654f | ||
|
|
a12653a25d | ||
|
|
f683ae95c3 | ||
|
|
6bdeb18253 | ||
|
|
8f1f23c991 | ||
|
|
42345af443 | ||
|
|
a5797da100 | ||
|
|
0821e6acc2 | ||
|
|
0fb87c7926 | ||
|
|
b578487d01 | ||
|
|
cdf81eb1d7 | ||
|
|
97491658c6 | ||
|
|
b2b3653d67 | ||
|
|
de102bec5e | ||
|
|
3598f2855f | ||
|
|
f36a479d0f | ||
|
|
5363c013e6 | ||
|
|
b609328ac1 | ||
|
|
65c2b103b1 | ||
|
|
22a89ba914 | ||
|
|
fda9b6f75d | ||
|
|
b29e9b706e | ||
|
|
bd145ad6b2 | ||
|
|
fc71ec9785 | ||
|
|
cce43790d2 | ||
|
|
1e31e1fff8 | ||
|
|
af2a0c9747 | ||
|
|
d30488da87 | ||
|
|
59ba2fc7ab | ||
|
|
1936052e79 | ||
|
|
103ec5d72a | ||
|
|
9139ec3e5c | ||
|
|
7430463b33 | ||
|
|
6f2d067f3a | ||
|
|
d31b9c9caa | ||
|
|
2670d37542 | ||
|
|
617fd69bcc | ||
|
|
5fcd9d45a3 | ||
|
|
b6cd19b78b | ||
|
|
6a3a19da68 | ||
|
|
efd103004c | ||
|
|
18e033cdd8 | ||
|
|
2a4ecc1d28 | ||
|
|
c0c91678ba | ||
|
|
7a531ed272 | ||
|
|
93e3fcb386 | ||
|
|
143fc90a4c | ||
|
|
f65feaf9da | ||
|
|
a17b0effa1 | ||
|
|
b0d5c7a1a5 | ||
|
|
9c4a407fdc | ||
|
|
67b2151e3c | ||
|
|
b8024469da | ||
|
|
7f5c826bb1 | ||
|
|
acad3f3963 | ||
|
|
1f6ce24eaa | ||
|
|
4a82f21cc3 | ||
|
|
0cf707599d | ||
|
|
e2e6bdc4cb | ||
|
|
8136186554 | ||
|
|
9b733041af | ||
|
|
9e01876747 | ||
|
|
ee909b8c08 | ||
|
|
fdf1982982 | ||
|
|
88ccd7f537 | ||
|
|
c6cd9ceb75 | ||
|
|
ce735357d6 | ||
|
|
887dee83eb | ||
|
|
fd73a2bc8b | ||
|
|
21b5f90a33 | ||
|
|
d1c5cd7b0a | ||
|
|
656a36061a | ||
|
|
05384f581f | ||
|
|
84f3c104b2 | ||
|
|
761f7e40de | ||
|
|
b760c21414 | ||
|
|
bb651298c4 | ||
|
|
8850a11072 | ||
|
|
499338e80d | ||
|
|
c12f8fa254 | ||
|
|
7ae36b8667 | ||
|
|
591e2db712 | ||
|
|
8414563ad0 | ||
|
|
85fc57faa3 | ||
|
|
c8e10a004b | ||
|
|
e1fac2404c | ||
|
|
65adf2a860 | ||
|
|
dea6906ae9 | ||
|
|
22ccae3301 | ||
|
|
58d58b0af7 | ||
|
|
ce5daaa835 | ||
|
|
8fe0681681 | ||
|
|
3987e644a8 | ||
|
|
f073415510 | ||
|
|
4c69bcd97a | ||
|
|
05aac0879e | ||
|
|
cb5dafe8db | ||
|
|
82c7d45c4b | ||
|
|
f81677278f | ||
|
|
2ef6011c7a | ||
|
|
6e0b5358fb | ||
|
|
e783e3c794 | ||
|
|
8965d9bd70 | ||
|
|
37fe9bad6d | ||
|
|
a4daf4c228 | ||
|
|
ae080c3ad3 | ||
|
|
ad0c08c2de | ||
|
|
7b93791c3f | ||
|
|
172df2cd0c | ||
|
|
b395cd7ccc | ||
|
|
8ec6b15dc2 | ||
|
|
2a2f82a745 | ||
|
|
13a7801421 | ||
|
|
1a5cd1c1ff | ||
|
|
224974f218 | ||
|
|
b96556f80f | ||
|
|
c29be5b945 | ||
|
|
21b60db107 | ||
|
|
baa3f573ae | ||
|
|
0243e93e97 | ||
|
|
778bbc6d08 | ||
|
|
6ae502f181 | ||
|
|
088720db22 | ||
|
|
3d6ecc064f | ||
|
|
333bf19c00 | ||
|
|
25599b91b2 | ||
|
|
18305a1994 | ||
|
|
e6f56bf5fa | ||
|
|
681c6f4e5e | ||
|
|
11f1c3c4ff | ||
|
|
9f4eb36c99 | ||
|
|
cbbafafb46 | ||
|
|
9e853e487d | ||
|
|
0e91ad3ed3 | ||
|
|
c5e894aab2 | ||
|
|
49aaeb3080 | ||
|
|
1c7ac8c761 | ||
|
|
e2492a1426 | ||
|
|
f750391c2e | ||
|
|
95d65a02bc | ||
|
|
2685037c82 | ||
|
|
61c46994cd | ||
|
|
8b8e6501bc | ||
|
|
c4184ef733 | ||
|
|
6a5049b22c | ||
|
|
6cbcfc7ab8 | ||
|
|
564d06e84c | ||
|
|
8398799e1c | ||
|
|
c43d34d0cf | ||
|
|
a188f4ebfe | ||
|
|
e59063a13c | ||
|
|
2f95534bd0 | ||
|
|
2b0c8d45fa | ||
|
|
c88cf6359e | ||
|
|
62405c79c3 | ||
|
|
28dedd66b3 | ||
|
|
f26146bc23 | ||
|
|
2a0489a21c | ||
|
|
0980c4438a | ||
|
|
f7c93b68d8 | ||
|
|
f7e769f8c4 | ||
|
|
7f1ce6ebfd | ||
|
|
4715ef2633 | ||
|
|
703d19b256 | ||
|
|
f7d7fbb9b0 | ||
|
|
a6baf1f370 | ||
|
|
874238f61e | ||
|
|
9968963b97 | ||
|
|
5b68e46bb7 | ||
|
|
9a83521ad6 | ||
|
|
2a7eabfb1c | ||
|
|
b4a0ae20c9 | ||
|
|
87493a9bc9 | ||
|
|
0f9dac511c | ||
|
|
11724fd2ad | ||
|
|
c0955d33de | ||
|
|
bc5e686fde | ||
|
|
541489da4d | ||
|
|
79200d4df6 | ||
|
|
578bae3c37 | ||
|
|
37490d1a44 | ||
|
|
3919bb2e7d | ||
|
|
93e8434a87 | ||
|
|
97a1983c59 | ||
|
|
42e60bc7c5 | ||
|
|
93dc8fce10 | ||
|
|
34d4cde7c4 | ||
|
|
66788af44d | ||
|
|
1a8df98cf2 | ||
|
|
0fb0ac7994 | ||
|
|
24f278c961 | ||
|
|
d45001e4c9 | ||
|
|
95a0e669a2 | ||
|
|
b80e4c552a | ||
|
|
933dc0f5c8 | ||
|
|
6a3904fc48 | ||
|
|
b045dbde0f | ||
|
|
b85ebc73c9 | ||
|
|
7d76fc4945 | ||
|
|
90332ecf6e | ||
|
|
0c4c89f3ca | ||
|
|
62177d2ca3 | ||
|
|
144830bc05 | ||
|
|
24a5917b44 | ||
|
|
b38c5f095c | ||
|
|
d7ad7f0c70 | ||
|
|
dc391439ba | ||
|
|
e44c43deeb | ||
|
|
c795faf167 | ||
|
|
dad0913dcb | ||
|
|
e5db9aa874 | ||
|
|
2d0b60898c | ||
|
|
c25fc8cc24 | ||
|
|
bddeac4b45 | ||
|
|
1aa42a6779 | ||
|
|
73b3aec3ed | ||
|
|
9568cbac0a | ||
|
|
a60c742fa4 | ||
|
|
6313a31668 | ||
|
|
15a4be2db1 | ||
|
|
0c71d8d4e6 | ||
|
|
4409374c47 | ||
|
|
4299e0a3a3 | ||
|
|
c4af15c2e2 | ||
|
|
eacde4008e | ||
|
|
358e24ace5 | ||
|
|
7317472b5f | ||
|
|
9271684e5a | ||
|
|
929d462d05 | ||
|
|
e0ce06483c | ||
|
|
95e78088d6 | ||
|
|
dd72a4542e | ||
|
|
5fe0a68b46 | ||
|
|
61486749f8 | ||
|
|
31f574ed36 | ||
|
|
d9ff07b605 | ||
|
|
dbdb3d6af6 | ||
|
|
4c0a213840 | ||
|
|
aa65bad62b | ||
|
|
60c469ed06 | ||
|
|
cf87ae2e71 | ||
|
|
ea443cfa21 | ||
|
|
5e49e3cfaa | ||
|
|
8574c575f5 | ||
|
|
d2aecc0412 | ||
|
|
710d537f39 | ||
|
|
9e44c65391 | ||
|
|
c36491cfb6 | ||
|
|
c2be0268b1 | ||
|
|
4cda6dbcfb | ||
|
|
e34afea346 | ||
|
|
1ea71c89a8 | ||
|
|
856ffea797 | ||
|
|
9efae57162 | ||
|
|
09d4cb7b38 | ||
|
|
fb4f580922 | ||
|
|
15842f3464 | ||
|
|
e18846fac5 | ||
|
|
4aeb8ea1b0 | ||
|
|
6a415b54d0 | ||
|
|
5abdfd9751 | ||
|
|
ab65619b99 | ||
|
|
88629f7aa6 | ||
|
|
fb11af5859 | ||
|
|
550b72200d | ||
|
|
cd9d19a2bb | ||
|
|
ca9e43d0f0 | ||
|
|
04d2f90ab3 | ||
|
|
906cdb1584 | ||
|
|
1978ec8b71 | ||
|
|
28f32a3ca6 | ||
|
|
3b7a448b07 | ||
|
|
8f0c1efc6f | ||
|
|
c10b673fef | ||
|
|
bfd9f79267 | ||
|
|
f7c596317b | ||
|
|
e4debaf4ba | ||
|
|
4eeba053d5 | ||
|
|
7263a2e7ab | ||
|
|
ef7f25481c | ||
|
|
35d17abeb0 | ||
|
|
33472d3a8e | ||
|
|
e60ddf7ecd | ||
|
|
579332db7d | ||
|
|
b34c031139 | ||
|
|
46bc2e7183 | ||
|
|
26ddbf9466 | ||
|
|
b67dc452b2 | ||
|
|
b37b6addac | ||
|
|
a2dfe70cd8 | ||
|
|
20a2b4e051 | ||
|
|
d7c3c3fcf9 | ||
|
|
7d77a4b31f | ||
|
|
59217ccbbe | ||
|
|
f674953b87 | ||
|
|
b8798c580f | ||
|
|
2b58e8a253 | ||
|
|
f744513941 | ||
|
|
e8ecbbdc6a | ||
|
|
1f7c69e19e | ||
|
|
de4044d5b1 | ||
|
|
1503241c7a | ||
|
|
37a1261693 | ||
|
|
446d57122c | ||
|
|
1e8807ac0a | ||
|
|
40ac1bca84 | ||
|
|
bff3b935fb | ||
|
|
9faa9f41e0 | ||
|
|
9fa43f2386 | ||
|
|
f2397256e2 | ||
|
|
e5ad7c36ec | ||
|
|
3b8ba5dfa6 | ||
|
|
2e1b58a876 | ||
|
|
de7baa0b41 | ||
|
|
b361a0d2ff | ||
|
|
0acd849f18 | ||
|
|
ed4ff15682 | ||
|
|
de276ddfa9 | ||
|
|
192347ea3a | ||
|
|
d618cfdf0e | ||
|
|
0f0762a24c | ||
|
|
89a49db558 | ||
|
|
1ee51a54de | ||
|
|
68f394a38b | ||
|
|
32c94ac31a | ||
|
|
af476e0d10 | ||
|
|
b504d07afe | ||
|
|
9544fbdff9 | ||
|
|
431365d1f8 | ||
|
|
693b4adb4b | ||
|
|
1a637cb1d8 | ||
|
|
0d952641ed | ||
|
|
418e2a00ce | ||
|
|
d1d2de33e6 | ||
|
|
ab84faa3ca | ||
|
|
fc7f83c60b | ||
|
|
af028c9bad | ||
|
|
29daae551c | ||
|
|
e1a91ea420 | ||
|
|
bd60ed8df0 | ||
|
|
6b6d20732e | ||
|
|
4d60b75240 | ||
|
|
fc9900c8f6 | ||
|
|
629346b6a7 | ||
|
|
e95be7cd3f | ||
|
|
1bfb50f29a | ||
|
|
8187c35ea8 | ||
|
|
0d6028d837 | ||
|
|
2127eaea22 | ||
|
|
7794a623aa | ||
|
|
0443edc034 | ||
|
|
a7f8dbac56 | ||
|
|
b0ec124329 | ||
|
|
b40121c9b0 | ||
|
|
cc9984a082 | ||
|
|
c22758d794 | ||
|
|
1b48cd157a | ||
|
|
362402ffbf | ||
|
|
5ce868b100 | ||
|
|
823d1cc004 | ||
|
|
2ce5beae56 | ||
|
|
34fcbbd7b7 | ||
|
|
bdde96be95 | ||
|
|
26b7a49d82 | ||
|
|
fa8a5a2033 | ||
|
|
c87a56ef37 | ||
|
|
2e04ff93ca | ||
|
|
a9f96b9d62 | ||
|
|
8f855f5dde | ||
|
|
6d3fa25d5f | ||
|
|
57b7bcf8f4 | ||
|
|
f30d75ae5d | ||
|
|
e087e7782c | ||
|
|
17fa93035a | ||
|
|
f0d7582845 | ||
|
|
75bdb32828 | ||
|
|
fd633d2cee | ||
|
|
a6d7d83fb3 | ||
|
|
a450b9d12f | ||
|
|
5ac3eeef11 | ||
|
|
9838c2ccff | ||
|
|
16cee6feb2 | ||
|
|
21c86f9ac6 | ||
|
|
6044feb7fd | ||
|
|
7dc59ac342 | ||
|
|
16f156be3f | ||
|
|
64dd09becc | ||
|
|
19dc18f7c5 | ||
|
|
4e63b82f5e | ||
|
|
6bc2abae3b | ||
|
|
6c7f306baa | ||
|
|
c56517b801 | ||
|
|
b5e405b2b4 | ||
|
|
354f46f41b | ||
|
|
b34a50b381 | ||
|
|
a973c53ea2 | ||
|
|
ee7b10f064 | ||
|
|
c1ad6b5829 | ||
|
|
9eaaaaa1e3 | ||
|
|
115707a0f1 | ||
|
|
3179357666 | ||
|
|
cb7433d70a | ||
|
|
62021fc291 | ||
|
|
ab3ff07c93 | ||
|
|
22ab62a729 | ||
|
|
ff7a8bfdae | ||
|
|
27ed109394 | ||
|
|
ea807eda04 | ||
|
|
36321f809d | ||
|
|
254df70148 | ||
|
|
759cef6e01 | ||
|
|
02364151bc | ||
|
|
9178effd9f | ||
|
|
cce9e280ce | ||
|
|
5468d8b08e | ||
|
|
497f629761 | ||
|
|
6f08601479 | ||
|
|
6d6739ccea | ||
|
|
d2511e66fb | ||
|
|
e23eb14809 | ||
|
|
f5dbe2156c | ||
|
|
723b94da05 | ||
|
|
7ecdced486 | ||
|
|
13b72df762 | ||
|
|
95b38b7f79 | ||
|
|
3fb5052223 | ||
|
|
62b93a0785 | ||
|
|
371b45c420 | ||
|
|
4dcf14d026 | ||
|
|
854ee95d69 | ||
|
|
9ac536a1dd | ||
|
|
9820bee5e7 | ||
|
|
b02302a5cf | ||
|
|
9633ad35a8 | ||
|
|
4bd6294862 | ||
|
|
63e525697f | ||
|
|
4cdd46819f | ||
|
|
0450371e28 | ||
|
|
d9e5f8183f | ||
|
|
abbaf9b593 | ||
|
|
126c59b4a4 | ||
|
|
b7be225846 | ||
|
|
041eb4e69d | ||
|
|
04157f2502 | ||
|
|
189222cb66 | ||
|
|
6835c4aaf5 | ||
|
|
875a2ef3a9 | ||
|
|
bfbf18688b | ||
|
|
9de694c46b | ||
|
|
220c5ee47d | ||
|
|
99f2207fd4 | ||
|
|
50623f32f6 | ||
|
|
b5105a1e57 | ||
|
|
9beb745765 | ||
|
|
0b1dd757be | ||
|
|
a7c61d8e20 | ||
|
|
4988fb27dc | ||
|
|
db1f0825ce | ||
|
|
c7b2a5f2df | ||
|
|
b9cbd29bc4 | ||
|
|
84b53ecb42 | ||
|
|
66da28a02f | ||
|
|
15f6bbebe1 | ||
|
|
2daef545dd | ||
|
|
aac6b3d02d | ||
|
|
fda0e9a4cb | ||
|
|
f1da5d433a | ||
|
|
dead2003fa | ||
|
|
44dfa53d45 | ||
|
|
769a9f65a9 | ||
|
|
5b78159cb5 | ||
|
|
c384d53d75 | ||
|
|
683e44baf9 | ||
|
|
c845d0cf81 | ||
|
|
243a4deae7 | ||
|
|
fe80d6305c | ||
|
|
a0e7113397 | ||
|
|
d47b1b0e56 | ||
|
|
fa87b0fcef | ||
|
|
0f1bce0f32 | ||
|
|
bc0b5b1181 | ||
|
|
38833b9cf4 | ||
|
|
dda4f48397 | ||
|
|
bb712b1ad5 | ||
|
|
6ddb5b3477 | ||
|
|
c4253b73fa | ||
|
|
3c1f6c2436 | ||
|
|
83484cfb60 | ||
|
|
a106082397 | ||
|
|
6498248cef | ||
|
|
b2f94b274c | ||
|
|
34b85b3560 | ||
|
|
7bb30efb50 | ||
|
|
7df2b6b252 | ||
|
|
017d13a7b0 | ||
|
|
513647b272 | ||
|
|
280b1576c3 | ||
|
|
2dfd449561 | ||
|
|
65b1b9256a | ||
|
|
7866f116df | ||
|
|
4544e1556a | ||
|
|
8c7d96ad63 | ||
|
|
bd23e1f7fc | ||
|
|
99187a2d22 | ||
|
|
8974caf162 | ||
|
|
f364c03964 | ||
|
|
730eb1f472 | ||
|
|
3760be946f | ||
|
|
7db74b84cf | ||
|
|
4c0a25db2a | ||
|
|
67af8c2bad | ||
|
|
92531929f3 | ||
|
|
0256a6332c | ||
|
|
bd4454d8ad | ||
|
|
4187581be5 | ||
|
|
2a07636623 | ||
|
|
8893344b76 | ||
|
|
f0ea65dc36 | ||
|
|
53756ee966 | ||
|
|
8a2ee1ed59 | ||
|
|
9bc9c10fb3 | ||
|
|
4407a17551 | ||
|
|
c7d6395aa6 | ||
|
|
649a65b8ee | ||
|
|
949b64ca53 | ||
|
|
cef906b24d | ||
|
|
040c2c3d1b | ||
|
|
91ed6a83c1 | ||
|
|
d8ac8a5f1c | ||
|
|
18954abf54 | ||
|
|
ed7ee12e7e | ||
|
|
42d99d2b2a | ||
|
|
d24f13cd73 | ||
|
|
e8fad11128 | ||
|
|
27a8d19f31 | ||
|
|
387a3eeba3 | ||
|
|
3a3578aecc | ||
|
|
a8784eff9f | ||
|
|
b26ae5886d | ||
|
|
e6696f8d23 | ||
|
|
2989afdf84 | ||
|
|
9c1b015689 | ||
|
|
3b1fbef95c | ||
|
|
2e6acc86e1 | ||
|
|
c6e981a363 | ||
|
|
43de5afcf6 | ||
|
|
fb40035957 | ||
|
|
93549259a0 | ||
|
|
f39d3ea43e | ||
|
|
7ad169c7a8 | ||
|
|
052bba4578 | ||
|
|
d1eb01e535 | ||
|
|
3e20a60c37 | ||
|
|
984c136349 | ||
|
|
81f92d8f62 | ||
|
|
427051d04c | ||
|
|
c1a14f93d8 | ||
|
|
f07ee85078 | ||
|
|
51b118d516 | ||
|
|
d5ec4692d3 | ||
|
|
a62336d433 | ||
|
|
abb2cbeeaa | ||
|
|
33381857ff | ||
|
|
f1abd95ed0 | ||
|
|
43b155e8b4 | ||
|
|
6ee5415ea4 | ||
|
|
886ae378c5 | ||
|
|
60d886c052 | ||
|
|
d700cc1f55 | ||
|
|
5c212e92c3 | ||
|
|
1dde4ee959 | ||
|
|
9fe450f2dc | ||
|
|
b84e5f25f2 | ||
|
|
b52ff061b4 | ||
|
|
b7ae79514f | ||
|
|
a90c7af708 | ||
|
|
176e092a6c | ||
|
|
94ccde160a | ||
|
|
d8746c6c70 | ||
|
|
4ff4ca72d3 | ||
|
|
47055f92df | ||
|
|
7a4a44292c | ||
|
|
98270a8601 | ||
|
|
182ca255f7 | ||
|
|
3d33713c2b | ||
|
|
ebf698fdb6 | ||
|
|
9d089f9b18 | ||
|
|
c976833f46 | ||
|
|
1819b7563a | ||
|
|
548a21a5ec | ||
|
|
ad1dce7fb1 | ||
|
|
302a358476 | ||
|
|
74dd9f2778 | ||
|
|
495262f902 | ||
|
|
d10a078473 | ||
|
|
8d9fd7cb0e | ||
|
|
8bd8a923ba | ||
|
|
764a0c31e5 | ||
|
|
1ea0382055 | ||
|
|
bd673dc791 | ||
|
|
4fa00ba283 | ||
|
|
deef011dbf | ||
|
|
afeecf9d9f | ||
|
|
e792f00363 | ||
|
|
f7d9dd4824 | ||
|
|
dfc60e8bf1 | ||
|
|
655e752c07 | ||
|
|
ebdbd1767a | ||
|
|
4eca49697a | ||
|
|
7fa2371bbd | ||
|
|
60c41cadba | ||
|
|
97769b63ad | ||
|
|
bc482e29b0 | ||
|
|
62695ceed4 | ||
|
|
605d5a29c0 | ||
|
|
fdc7e9d1e4 | ||
|
|
dcc7ad45bc | ||
|
|
265f153449 | ||
|
|
ba9aa3657c | ||
|
|
115d666fff | ||
|
|
42ce1a3b61 | ||
|
|
a7b912393c | ||
|
|
e82f17842e | ||
|
|
4838c86ca9 | ||
|
|
d6b9fd2860 | ||
|
|
60dac1aa29 | ||
|
|
8dd071bcfa | ||
|
|
d92d693df3 | ||
|
|
d16bd5104e | ||
|
|
d7e8da6321 | ||
|
|
aec3fd524a | ||
|
|
14b0323bf6 | ||
|
|
b482847779 | ||
|
|
8c5752de23 | ||
|
|
267bffb0ec | ||
|
|
0546216228 | ||
|
|
a46ea2c07f | ||
|
|
ed4e1ee0ba | ||
|
|
6ac3716594 | ||
|
|
42bad3ea6b | ||
|
|
f9c4eda1fc | ||
|
|
688665e730 | ||
|
|
a676255231 | ||
|
|
d227edeefd | ||
|
|
34c3e2dab3 | ||
|
|
2c0bbc06b7 | ||
|
|
299551428f | ||
|
|
d0ac9c2a5a | ||
|
|
a69368e855 | ||
|
|
84b0e2f113 | ||
|
|
eb695d5553 | ||
|
|
b5946f3752 | ||
|
|
371435afd0 | ||
|
|
0ba46403c6 | ||
|
|
cac43a1f5f | ||
|
|
7771a67abe | ||
|
|
9cd8812d8b | ||
|
|
4b0b3fc98a | ||
|
|
c6afd44c1c | ||
|
|
dbb84245a0 | ||
|
|
15a7c4d8dd | ||
|
|
a842938cfe | ||
|
|
3f83038061 | ||
|
|
01568f8fd3 | ||
|
|
1ee4d5aaf4 | ||
|
|
f9b74642a2 | ||
|
|
401e3a7282 | ||
|
|
32b2b388c8 | ||
|
|
013643782f | ||
|
|
cb064f9e5a | ||
|
|
52c97c47ab | ||
|
|
5f06d066e7 | ||
|
|
a7a211fc85 | ||
|
|
5540601918 | ||
|
|
22f99601d9 | ||
|
|
2fe2e52249 | ||
|
|
6caa598dd7 | ||
|
|
aeeb9b719a | ||
|
|
36f1808615 | ||
|
|
0ce5f34f8c | ||
|
|
579ae99d1b | ||
|
|
fa702c0240 | ||
|
|
34bc807bd5 | ||
|
|
71d49badcc | ||
|
|
3dfcc278e0 | ||
|
|
e312fa392d | ||
|
|
bda28e5882 | ||
|
|
68c2abc429 | ||
|
|
b0727d6f2b | ||
|
|
c66be063aa | ||
|
|
1f0165f895 | ||
|
|
b1ae5dc2b6 | ||
|
|
df228f8829 | ||
|
|
dc2d54edf2 | ||
|
|
d39c554541 | ||
|
|
314b2a5583 | ||
|
|
ce30c1179e | ||
|
|
cbb3126b28 | ||
|
|
a3413ba96d | ||
|
|
2b625e4aa5 | ||
|
|
df74626ca2 | ||
|
|
10373ca6fc | ||
|
|
3dcd08bd4a | ||
|
|
a945daf96d | ||
|
|
22116dabc3 | ||
|
|
5494d95b6b | ||
|
|
9ab686b3e0 | ||
|
|
5b24440e8c | ||
|
|
44deff987c | ||
|
|
7273ac0d34 | ||
|
|
ceb9834a27 | ||
|
|
4eebf25f1c | ||
|
|
865ef2ff6e | ||
|
|
8138ba6ecb | ||
|
|
f1c0b52677 | ||
|
|
a4cb62d6d6 | ||
|
|
e4062c6031 | ||
|
|
08844f31c9 | ||
|
|
4dfdba001b | ||
|
|
8dbf982ebe | ||
|
|
031255a946 | ||
|
|
8dfbe80b41 | ||
|
|
2bcc997e4b | ||
|
|
263e79be53 | ||
|
|
d031a8b423 | ||
|
|
7bec96e4b2 | ||
|
|
6bb1bacfba | ||
|
|
95a4aaf8fd | ||
|
|
387c64b74c | ||
|
|
4d068eee26 | ||
|
|
ece732ba41 | ||
|
|
8f40dc1a8c | ||
|
|
c9a6d4c05a | ||
|
|
a66b4e257a | ||
|
|
3796805d98 | ||
|
|
a3d09e95d5 | ||
|
|
626846c37b | ||
|
|
8bf1ac6577 | ||
|
|
58c0bce4cf | ||
|
|
3a82dc6aad | ||
|
|
e42b9e2866 | ||
|
|
8a85acff32 | ||
|
|
b450ea24a2 | ||
|
|
4fa92dc069 | ||
|
|
61a80c9b2d | ||
|
|
bcfd0f7ea3 | ||
|
|
c404b3e0ab | ||
|
|
b246133b3b | ||
|
|
5b28d7bc03 | ||
|
|
8adaefcdb9 | ||
|
|
e64b4d5c04 | ||
|
|
59caccfeae | ||
|
|
bbd3333b5f | ||
|
|
1ce7f32b5d | ||
|
|
95f18dbf15 | ||
|
|
9ed2e3bbf2 | ||
|
|
8b3cd23045 | ||
|
|
072241eb10 | ||
|
|
84a8500323 | ||
|
|
a8911fc979 | ||
|
|
04ba0b2f67 | ||
|
|
d1e5bc5c19 | ||
|
|
38364ef07f | ||
|
|
b25d8db994 | ||
|
|
989ed95891 | ||
|
|
d15ffc48a3 | ||
|
|
06df8c7bed | ||
|
|
950241d52f | ||
|
|
a147c12f72 | ||
|
|
874828c2ac | ||
|
|
3369e5e755 | ||
|
|
9b3930ea62 | ||
|
|
987d0db806 | ||
|
|
97530e4095 | ||
|
|
4c285d4d8a | ||
|
|
cd5fbc1492 | ||
|
|
2e379300a6 | ||
|
|
65c19d073c | ||
|
|
eb013f3492 | ||
|
|
b2fd651abe | ||
|
|
d4b02e6a3f | ||
|
|
537cb65f26 | ||
|
|
f61367fc9a | ||
|
|
46e0505336 | ||
|
|
75004d0b56 | ||
|
|
0dc5761ca6 | ||
|
|
df47fb5be8 | ||
|
|
0cedc70eb3 | ||
|
|
1612687acf | ||
|
|
67d587cd9b | ||
|
|
9e97e96b87 | ||
|
|
79c1ad1431 | ||
|
|
c0ebe09521 | ||
|
|
b568cc529e | ||
|
|
dc8e24c7b7 | ||
|
|
ba411303e9 | ||
|
|
8848bc2e7f | ||
|
|
f7798f361a | ||
|
|
6a25427cb6 | ||
|
|
a6c283f4ce | ||
|
|
48bb907d2d | ||
|
|
c2ce5d5557 | ||
|
|
0d30fe90f8 | ||
|
|
c434cef45e | ||
|
|
d01970f731 | ||
|
|
bb9beb75d1 | ||
|
|
ad3a9e6c55 | ||
|
|
9a30b65180 | ||
|
|
cb548fe1fa | ||
|
|
0a8f049ced | ||
|
|
890809069e | ||
|
|
ca9a6fe019 | ||
|
|
94ccae727b | ||
|
|
001e77952e | ||
|
|
ac6a453833 | ||
|
|
307915130c | ||
|
|
3d225ef908 | ||
|
|
1c9123637a | ||
|
|
f1f690552f | ||
|
|
57dcf3401c | ||
|
|
9e5df7957e | ||
|
|
ca63389ea3 | ||
|
|
7b7ee070b9 | ||
|
|
3aee16e9a0 | ||
|
|
06cb3624e2 | ||
|
|
a1f83418b9 | ||
|
|
e5a32ea129 | ||
|
|
eb209abe62 | ||
|
|
13551fd410 | ||
|
|
2493706315 | ||
|
|
b49273c079 | ||
|
|
7c1b161277 | ||
|
|
d8a1dcc1b4 | ||
|
|
f44d60c58f | ||
|
|
dc71840a5a | ||
|
|
07b17cd0f6 | ||
|
|
cf37e8ea83 | ||
|
|
5384489702 | ||
|
|
1ad69d785f | ||
|
|
ef3acd9f33 | ||
|
|
083b42fead | ||
|
|
c6814a6f97 | ||
|
|
9dbd7fc7e0 | ||
|
|
a79eff3b0d | ||
|
|
a89d7a2e2a | ||
|
|
0336f6a987 | ||
|
|
6d68975ba5 | ||
|
|
2b07fd7c6a | ||
|
|
f8cc423f3d | ||
|
|
f4667fa3cf | ||
|
|
d8f929755a | ||
|
|
031685e0a7 | ||
|
|
9f260eb86c | ||
|
|
75878b24cd | ||
|
|
fe0425eb80 | ||
|
|
453003da23 | ||
|
|
eec08973bf | ||
|
|
c65f8da90f | ||
|
|
2970ed5bfd | ||
|
|
bfebcba431 | ||
|
|
dde85b761b | ||
|
|
34809e48d8 | ||
|
|
6749c2d1a6 | ||
|
|
7eb24ff514 | ||
|
|
e367a2bcc9 | ||
|
|
a02283264a | ||
|
|
7a7e9ee9af | ||
|
|
b7f25a48c2 | ||
|
|
4477aa3159 | ||
|
|
4fd23c752c | ||
|
|
60b625bc0f | ||
|
|
d1703b9bc0 | ||
|
|
eb9da7417f | ||
|
|
782f497b20 | ||
|
|
003a83b40b | ||
|
|
2f8d28e7da | ||
|
|
fa591589c7 | ||
|
|
f0ea459c57 | ||
|
|
f3d733c3ff | ||
|
|
19ca78769f | ||
|
|
3e5784cbc5 | ||
|
|
98d9f36f9c | ||
|
|
22bc6872f4 | ||
|
|
f6fe84afad | ||
|
|
4744534fc9 | ||
|
|
af05d7439f | ||
|
|
6e22f4fd6d | ||
|
|
0e3d92148b | ||
|
|
06cf6d2ecc | ||
|
|
7b5654eea4 | ||
|
|
503eb41939 | ||
|
|
a77db3c6a5 | ||
|
|
4e0889469a | ||
|
|
7c5bf62fc0 | ||
|
|
b79f86b8d1 | ||
|
|
b9f5929439 | ||
|
|
3dc396a647 | ||
|
|
c358bf448f | ||
|
|
abd1d56d7f | ||
|
|
22b9c16351 | ||
|
|
0131958136 | ||
|
|
9f70767acf | ||
|
|
bdeb8d7ee2 | ||
|
|
de831ee5ac | ||
|
|
da1cb42f2a | ||
|
|
2c366ef4bd | ||
|
|
bc0f31407f | ||
|
|
0d755e610b | ||
|
|
55ee7fcc33 | ||
|
|
10200d7b55 | ||
|
|
1eab6a0c8e | ||
|
|
fc2d50c7d3 | ||
|
|
aaed0364bd | ||
|
|
9e0139f3c3 | ||
|
|
ec3c3b7eed | ||
|
|
c67632722b | ||
|
|
580fbf47b2 | ||
|
|
4bffdce8af | ||
|
|
f22e9bf1d2 | ||
|
|
95b516127a | ||
|
|
da7474b1de | ||
|
|
27aa9011ce | ||
|
|
d09a48fd03 | ||
|
|
b5c0a857ca | ||
|
|
ab9f848dcd | ||
|
|
1b3350437c | ||
|
|
03749788e8 | ||
|
|
9a571cfb72 | ||
|
|
39303611ef | ||
|
|
fcf0cf00d0 | ||
|
|
2ee846f48e | ||
|
|
9c846a3e40 | ||
|
|
712e8315f8 | ||
|
|
604ab22526 | ||
|
|
85d09df938 | ||
|
|
5ae93f8431 | ||
|
|
3aab8dd332 | ||
|
|
bf9d297dcd | ||
|
|
080cc77208 | ||
|
|
7ebd92be7d | ||
|
|
22b2f63917 | ||
|
|
5bcfa34bea | ||
|
|
48c47423a4 | ||
|
|
229cae16d1 | ||
|
|
9edb89fc22 | ||
|
|
3faabb478d | ||
|
|
2c127fe69c | ||
|
|
3765d9e6f7 | ||
|
|
8545d0505f | ||
|
|
28b101aaf7 | ||
|
|
24d1250e66 | ||
|
|
706ca3649e | ||
|
|
bb537e4dd5 | ||
|
|
eb59ff2ebd | ||
|
|
7842c9e34d | ||
|
|
3882a98755 | ||
|
|
14c9dc5bdb | ||
|
|
181457b69f | ||
|
|
0b6f543bbd | ||
|
|
01a386445c | ||
|
|
3fce669f6e | ||
|
|
8a701755d8 | ||
|
|
aead503f02 | ||
|
|
7ef2af2549 | ||
|
|
1e44a93c87 | ||
|
|
2e55dec949 | ||
|
|
c80a83485d | ||
|
|
8915484251 | ||
|
|
ed3450388b | ||
|
|
a2d580e926 | ||
|
|
47085bb9c9 | ||
|
|
73619f4d75 | ||
|
|
5228338f97 | ||
|
|
71c0aff78f | ||
|
|
4d7e106088 | ||
|
|
d7127ccc3d | ||
|
|
04e960b0da | ||
|
|
8d199cfc6c | ||
|
|
ffa58e23f1 | ||
|
|
289f94599d | ||
|
|
d0b51ae18f | ||
|
|
cea459d1e3 | ||
|
|
f6cd825ab9 | ||
|
|
f8fa438728 | ||
|
|
07aacc9b08 | ||
|
|
50325785f5 | ||
|
|
ef49b97c75 | ||
|
|
75110ac028 | ||
|
|
57bfa38328 | ||
|
|
2c00386e99 | ||
|
|
3b03b7aee6 | ||
|
|
1491270f1d | ||
|
|
46dfaab639 | ||
|
|
ff755facc0 | ||
|
|
d38f659f42 | ||
|
|
6d95a64412 | ||
|
|
21336c527a | ||
|
|
3db2362c86 | ||
|
|
99b7ef0c92 | ||
|
|
ff030fcbec | ||
|
|
ecf19029f5 | ||
|
|
9494801d0b | ||
|
|
1501592fa8 | ||
|
|
12467916a4 | ||
|
|
6f0eb56621 | ||
|
|
31dabf51ae | ||
|
|
22fd100b04 | ||
|
|
20092ef1ac | ||
|
|
aad6a16984 | ||
|
|
9b00df93c2 | ||
|
|
f1da71a8fe | ||
|
|
efd182971a | ||
|
|
40c5125a92 | ||
|
|
0f6654bf95 | ||
|
|
fa27ddecc5 | ||
|
|
e5be67b005 | ||
|
|
85458d1f20 | ||
|
|
5b5723c5a5 | ||
|
|
e148e89091 | ||
|
|
1d0614f0f3 | ||
|
|
2405e6c8e8 | ||
|
|
817408d247 | ||
|
|
8d77e39f4a | ||
|
|
0fe7e7a88d | ||
|
|
08bc57045a | ||
|
|
ee58b6a734 | ||
|
|
2907e5a0bd | ||
|
|
4f229629c0 | ||
|
|
f0fd2bc30c | ||
|
|
86e9a38384 | ||
|
|
322f97ddbc | ||
|
|
695865f408 | ||
|
|
1f9834dc6b | ||
|
|
d1555a4c78 | ||
|
|
5fc4477a94 | ||
|
|
a5753ec0b5 | ||
|
|
f256c48505 | ||
|
|
71c5447b8a | ||
|
|
a9a338ff42 | ||
|
|
06a21d490b | ||
|
|
ef0c9bd429 | ||
|
|
f619df2773 | ||
|
|
41ae74757e | ||
|
|
2304738336 | ||
|
|
e70a9ba485 | ||
|
|
61a759f802 | ||
|
|
3cb61ff840 | ||
|
|
b7a07c3816 | ||
|
|
ae386b3a7d | ||
|
|
2b8a8314c5 | ||
|
|
eb28edbe58 | ||
|
|
8d683fc19c | ||
|
|
0c50f724e6 | ||
|
|
d406946c2d | ||
|
|
1c7e620a86 | ||
|
|
c40096e128 | ||
|
|
43d2817407 | ||
|
|
ff14ccc0a5 | ||
|
|
1222fee0d0 | ||
|
|
b184a184c4 | ||
|
|
e5dcb3f100 | ||
|
|
411fe19ee5 | ||
|
|
1c040117ec | ||
|
|
856d2653bc | ||
|
|
2a79b60454 | ||
|
|
db32e49879 | ||
|
|
65d83bb6f4 | ||
|
|
17b7ec6358 | ||
|
|
73c3190c86 | ||
|
|
b6f58caf24 | ||
|
|
8c19c3a72c | ||
|
|
c017d3e894 | ||
|
|
35696508fb | ||
|
|
7e3996b0d9 | ||
|
|
a7ec8e7c55 | ||
|
|
dfaa6896c1 | ||
|
|
b64e6bdbba | ||
|
|
e0ef248943 | ||
|
|
cdcb0a46dc | ||
|
|
e82e1f9905 | ||
|
|
cb6616bba1 | ||
|
|
e0f0afdf91 | ||
|
|
5120e74b36 | ||
|
|
8f5fa863bf | ||
|
|
d4e32fdbc0 | ||
|
|
067cf75c65 | ||
|
|
7f16ddacf7 | ||
|
|
d936c072ea | ||
|
|
7dee075c10 | ||
|
|
b9ea2408c2 | ||
|
|
6ce570f4a5 | ||
|
|
b95b99b3c9 | ||
|
|
139197230d | ||
|
|
1d0e0307c4 | ||
|
|
f94ab1be6f | ||
|
|
05c7596acb | ||
|
|
b38d51ce37 | ||
|
|
5c0d765f59 | ||
|
|
db35542706 | ||
|
|
eda857cb10 | ||
|
|
b77c8fe5f1 | ||
|
|
0d864ed848 | ||
|
|
7c613198ce | ||
|
|
1ca68a58fd | ||
|
|
b96139274f | ||
|
|
d84faf57ab | ||
|
|
89f0c494e4 | ||
|
|
24f9263fa4 | ||
|
|
5f4f9337cd | ||
|
|
2a75d28386 | ||
|
|
3e41289167 | ||
|
|
9cf5373724 | ||
|
|
6c5d35df6b | ||
|
|
4d26021705 | ||
|
|
2e9b8eff59 | ||
|
|
a4142f68ce | ||
|
|
4a889e39ad | ||
|
|
d206d69b25 | ||
|
|
83e92d6298 | ||
|
|
e080551d54 | ||
|
|
b40195d26d | ||
|
|
316abec693 | ||
|
|
af685a263b | ||
|
|
31e8afa622 | ||
|
|
1d500ad965 | ||
|
|
a8866c3f41 | ||
|
|
f64eca5d9b | ||
|
|
bdd5e7018a | ||
|
|
3d211143e0 | ||
|
|
c1c11d8daa | ||
|
|
0505b19378 | ||
|
|
e18e532846 | ||
|
|
10cec3de2f | ||
|
|
76c0992d02 | ||
|
|
e32a78a944 | ||
|
|
68d710cd94 | ||
|
|
da64a3eeab | ||
|
|
912622bf1f | ||
|
|
70fec208d8 | ||
|
|
e1f69b9c61 | ||
|
|
81f25b219f | ||
|
|
d191b8c090 | ||
|
|
d53ff127ed | ||
|
|
50caca8fdc | ||
|
|
1dca97b4d3 | ||
|
|
14cf474167 | ||
|
|
47b1203805 | ||
|
|
81ca016581 | ||
|
|
cd8bda7a29 | ||
|
|
8115b47051 | ||
|
|
6384cc6e86 | ||
|
|
2f68df2b5f | ||
|
|
ed2697d6ad | ||
|
|
df928fd2d0 | ||
|
|
52c50a2fd4 | ||
|
|
666d051806 | ||
|
|
1e80316a7d | ||
|
|
65404cba33 | ||
|
|
ac0519a046 | ||
|
|
90a6306bbe | ||
|
|
a5a7d9382e | ||
|
|
bc770d908a | ||
|
|
20724ceb17 | ||
|
|
6ae6ac0272 | ||
|
|
5aa5015348 | ||
|
|
411aecde6f | ||
|
|
e89b93285e | ||
|
|
4e702cfeda | ||
|
|
33846405d8 | ||
|
|
378eb79ad3 | ||
|
|
da71b81d01 | ||
|
|
35d734e6ac | ||
|
|
3937fc4b71 | ||
|
|
5debac4c98 | ||
|
|
3737abe081 | ||
|
|
d0013c0700 | ||
|
|
460277289b | ||
|
|
35ed305718 | ||
|
|
d3c57eecbc | ||
|
|
ad75da8502 | ||
|
|
c7c6880a01 | ||
|
|
5ed3ef918d | ||
|
|
c0f78342e1 | ||
|
|
75494978ad | ||
|
|
602c015321 | ||
|
|
55c2c9ee59 | ||
|
|
8fef5f2c69 | ||
|
|
9a4a62ff2d | ||
|
|
4ebc462e23 | ||
|
|
08e93a0fe9 | ||
|
|
4096869c50 | ||
|
|
3cd87e68c7 | ||
|
|
7165ff7b84 | ||
|
|
81d906fd3b | ||
|
|
b51bdf3d5e | ||
|
|
c8ca7876c3 | ||
|
|
c181a6dcc8 | ||
|
|
b763c22ef4 | ||
|
|
5c83475c95 | ||
|
|
1d1670864b | ||
|
|
5e980767b9 | ||
|
|
2b3c9b95af | ||
|
|
09232ad0b6 | ||
|
|
2533197a3c | ||
|
|
71c43b0de7 | ||
|
|
6606b7b097 | ||
|
|
5c994ff222 | ||
|
|
9372b96e47 | ||
|
|
24e133e006 | ||
|
|
995fa013a6 | ||
|
|
4af1f56713 | ||
|
|
584b258241 | ||
|
|
fb13ce2baf | ||
|
|
f910a70c8a | ||
|
|
fedb8bd816 | ||
|
|
c3f97dd730 | ||
|
|
b1ebf9dc79 | ||
|
|
d07ea96570 | ||
|
|
dc3bdd89c1 | ||
|
|
7e92c912b2 | ||
|
|
5d5c3aec3c | ||
|
|
0ba63ea272 | ||
|
|
a242a8e277 | ||
|
|
cc86e94cd5 | ||
|
|
1c10ae443d | ||
|
|
d44f3d9bae | ||
|
|
d71e5f968a | ||
|
|
4aa9fba4fa | ||
|
|
8aaaddde03 | ||
|
|
d5176ba278 | ||
|
|
13a8108e1e | ||
|
|
82b19f6f69 | ||
|
|
9e37dd008d | ||
|
|
5b1057fe08 | ||
|
|
460fa3f3d7 | ||
|
|
61de3532c2 | ||
|
|
ddfc699809 | ||
|
|
d0edf2e8dd | ||
|
|
a159cb5efe | ||
|
|
26371bb9dd | ||
|
|
de4ffcc8bc | ||
|
|
ebaedca708 | ||
|
|
a86f597239 | ||
|
|
b72d3a77e9 | ||
|
|
64fdf54156 | ||
|
|
463e31251f | ||
|
|
9032f24a56 | ||
|
|
c5828803c6 | ||
|
|
9883c6464e | ||
|
|
67006f2809 | ||
|
|
e49728aa82 | ||
|
|
829c254b1f | ||
|
|
8bf54eda56 | ||
|
|
c58adce8f6 | ||
|
|
92532b0fd1 | ||
|
|
8cba5d55ce | ||
|
|
da1ac7beee | ||
|
|
28b79626d9 | ||
|
|
867059dfae | ||
|
|
50250bd2ca | ||
|
|
0e71c3a2ac | ||
|
|
db01a92edf | ||
|
|
6a9836912d | ||
|
|
bdcfd69795 | ||
|
|
dbe1bb0ec4 | ||
|
|
d76841bdc1 | ||
|
|
0251a29841 | ||
|
|
32b0c173f0 | ||
|
|
90167afc2b | ||
|
|
6a4a58185e | ||
|
|
6cffabacb3 | ||
|
|
d658c47cd0 | ||
|
|
21b06ace43 | ||
|
|
7a27b95df7 | ||
|
|
a730935e6e | ||
|
|
ef705ed494 | ||
|
|
fb6915b059 | ||
|
|
20d675ea48 | ||
|
|
900dbc2a47 | ||
|
|
d8affd8564 | ||
|
|
f3d4a1e1c3 | ||
|
|
d5ebea7928 | ||
|
|
bd95c7a366 | ||
|
|
20fc160230 | ||
|
|
c786e6d576 | ||
|
|
e9ce6a4f80 | ||
|
|
0024e4b970 | ||
|
|
cf8ea5953e | ||
|
|
65ddcdeabb | ||
|
|
6576686b36 | ||
|
|
13404ed090 | ||
|
|
ff6cc84482 | ||
|
|
02caee0c02 | ||
|
|
7260da63af | ||
|
|
ec0d333d81 | ||
|
|
d3eb6b8a11 | ||
|
|
cc0ce73d39 | ||
|
|
2eb92951af | ||
|
|
f8202096f1 | ||
|
|
f470d552cf | ||
|
|
be50bbc149 | ||
|
|
50c49a1692 | ||
|
|
70496c9bde | ||
|
|
f7f7c1c9af | ||
|
|
f02d5fc28f | ||
|
|
422a982917 | ||
|
|
ce60a8cfa2 | ||
|
|
f0026927e3 | ||
|
|
d1388dd7eb | ||
|
|
ffda782c3d | ||
|
|
3a6df996dc | ||
|
|
6141376977 | ||
|
|
3ec2ebabfc | ||
|
|
77dcb025fd | ||
|
|
bbaa01af79 | ||
|
|
d033f34a45 | ||
|
|
f2eb5326af | ||
|
|
f09b541ab7 | ||
|
|
e71df7eb67 | ||
|
|
9d1e6b9b96 | ||
|
|
0d43b16fd5 | ||
|
|
b179bd2415 | ||
|
|
64fbd3db46 | ||
|
|
ea096cd593 | ||
|
|
7934e3ad5c | ||
|
|
52a5335770 | ||
|
|
f3d1ffbe01 | ||
|
|
b40a17fc51 | ||
|
|
02fadef9e7 | ||
|
|
6e4d2470d2 | ||
|
|
8e4faa3de2 | ||
|
|
4f3b9f19a7 | ||
|
|
e562baf30b | ||
|
|
efefd13bf5 | ||
|
|
4314ef1ca8 | ||
|
|
477e531af9 | ||
|
|
47b8e2a983 | ||
|
|
cc01018223 | ||
|
|
7a28084b63 | ||
|
|
ea86b0e32f | ||
|
|
96169af71e | ||
|
|
4633817374 | ||
|
|
a190910cbf | ||
|
|
6170fc8e43 | ||
|
|
aa279c332d | ||
|
|
a79e1be034 | ||
|
|
5924a8eca1 | ||
|
|
fc920b0838 | ||
|
|
e33d51641f | ||
|
|
4b979bf206 | ||
|
|
bc5afbea89 | ||
|
|
65f75b0cc0 | ||
|
|
c50b0ef9e8 | ||
|
|
10c479034f | ||
|
|
3c95826c5c | ||
|
|
fa11368599 | ||
|
|
f4fd01c777 | ||
|
|
96941c9978 | ||
|
|
c5a6875de9 | ||
|
|
549e042e67 | ||
|
|
c70581abc9 | ||
|
|
5e6af37532 | ||
|
|
c0184f926d | ||
|
|
a69e81f034 | ||
|
|
5c01fbabac | ||
|
|
fed47bea4a | ||
|
|
213c063895 | ||
|
|
632af46137 | ||
|
|
b527ebbf5b | ||
|
|
ad55cfde7f | ||
|
|
44e77de620 | ||
|
|
40de8e16ec | ||
|
|
d36f9e4dbb | ||
|
|
a65f448856 | ||
|
|
8cba593882 | ||
|
|
0715dd145f | ||
|
|
5a20322251 | ||
|
|
89b5e1163d | ||
|
|
6a9dbe3d89 | ||
|
|
8e6ae3aa01 | ||
|
|
e46707750b | ||
|
|
b1f6ea8ae6 | ||
|
|
82ae65f477 | ||
|
|
4a3595133a | ||
|
|
4c9a6a5d98 | ||
|
|
a2e01c36ba | ||
|
|
774d872f41 | ||
|
|
fa19435d24 | ||
|
|
902186bdff | ||
|
|
6996c06909 | ||
|
|
315068b111 | ||
|
|
4047d1ba3c | ||
|
|
d74bee3596 | ||
|
|
aea1049223 | ||
|
|
3548195fbe | ||
|
|
8d0cc15eb0 | ||
|
|
ee2580a57f | ||
|
|
255d5c661e | ||
|
|
a60d945968 | ||
|
|
f8fa53aa3b | ||
|
|
1642327015 | ||
|
|
399478d635 | ||
|
|
608c13ebba | ||
|
|
99694d67ca | ||
|
|
bde279f2fa | ||
|
|
e4f56f0b23 | ||
|
|
3e8da0cc1a | ||
|
|
ca0e12d93f | ||
|
|
0c41d9810f | ||
|
|
165961f27e | ||
|
|
81386b7a56 | ||
|
|
5bf2a7d51b | ||
|
|
3fa527b45b | ||
|
|
121d986b11 | ||
|
|
f18f5c9b85 | ||
|
|
d5808f6be3 | ||
|
|
2984d30118 | ||
|
|
efbb5a2ae5 | ||
|
|
31aafe23b7 | ||
|
|
09779e294c | ||
|
|
2fe872de3d | ||
|
|
153d8d2cf0 | ||
|
|
1b07a10b5d | ||
|
|
d743c8235f | ||
|
|
7781bfcbac | ||
|
|
0fd81e067f | ||
|
|
acc2f2e3d5 | ||
|
|
a2be60cce8 | ||
|
|
1344b18379 | ||
|
|
1deec05f3d | ||
|
|
2ee5bcf933 | ||
|
|
5f57de017c | ||
|
|
508a153973 | ||
|
|
5d8b70cc0d | ||
|
|
d60ba04cf4 | ||
|
|
8b3949497a | ||
|
|
754b69f746 | ||
|
|
55c99e9ad7 | ||
|
|
aa2e212480 | ||
|
|
96c6abc889 | ||
|
|
74a73dfc97 | ||
|
|
d3b5553433 | ||
|
|
b8856af18c | ||
|
|
63428d0b2e | ||
|
|
22afd245a8 | ||
|
|
26fdf2275a | ||
|
|
1ad38124df | ||
|
|
aaa4fd1265 | ||
|
|
9793c3b142 | ||
|
|
5a753761dd | ||
|
|
37be26e539 | ||
|
|
96023f2274 | ||
|
|
30b83f4f9c | ||
|
|
265f969a44 | ||
|
|
d5b182cac0 | ||
|
|
ce296f0e32 | ||
|
|
6d5c3489c9 | ||
|
|
d48ab49437 | ||
|
|
8ee250e9ac | ||
|
|
e485fe1d18 | ||
|
|
35a32481c6 | ||
|
|
beaf543012 | ||
|
|
c40e31f374 | ||
|
|
f9c09293bf | ||
|
|
cdffe2388e | ||
|
|
6c0af2dbb9 | ||
|
|
eee428afe5 | ||
|
|
047815c764 | ||
|
|
3b8e0d69a3 | ||
|
|
56f2749da0 | ||
|
|
7d85753350 | ||
|
|
367363a8bd | ||
|
|
30d0836329 | ||
|
|
1680dc63d9 | ||
|
|
806298843f | ||
|
|
7cee4e2453 | ||
|
|
82f21de83e | ||
|
|
65c4f9d9c3 | ||
|
|
8043f53d7d | ||
|
|
124672b811 | ||
|
|
28ef6cdefc | ||
|
|
5e38ea28b6 | ||
|
|
1d0d7e9e09 | ||
|
|
aab6bc0869 | ||
|
|
77213bee1d | ||
|
|
90fc1d93ad | ||
|
|
e51f36c651 | ||
|
|
fc63442ded | ||
|
|
0ee5174e18 | ||
|
|
0004f19325 | ||
|
|
da724e3dd5 | ||
|
|
96ccf0dab9 | ||
|
|
aba3e4a460 | ||
|
|
bc852aebeb | ||
|
|
89da530898 | ||
|
|
2367e7df50 | ||
|
|
2ca85a4976 | ||
|
|
e3860cf09c | ||
|
|
07be405f48 | ||
|
|
92d5210e37 | ||
|
|
01bf7aa774 | ||
|
|
427ca732fe | ||
|
|
ca92a0b90a | ||
|
|
db4547115c | ||
|
|
3ad4a3ae3a | ||
|
|
7bef772488 | ||
|
|
e4c64073c5 | ||
|
|
0ff15e91d9 | ||
|
|
a584aa7df8 | ||
|
|
57ca9dfdbc | ||
|
|
3a2073f785 | ||
|
|
e963d99d5e | ||
|
|
bbe188d4f9 | ||
|
|
9df1ed0b3b | ||
|
|
742998b477 | ||
|
|
a577fac1c5 | ||
|
|
d08abf05ff | ||
|
|
cd6af18183 | ||
|
|
a425275108 | ||
|
|
92f7b6fd9e | ||
|
|
68c7586c4c | ||
|
|
9549a3599c | ||
|
|
b826049893 | ||
|
|
88d950bafb | ||
|
|
50242c6eaa | ||
|
|
e5649d90e7 | ||
|
|
d22e6f28a1 | ||
|
|
307acee9d3 | ||
|
|
184b2cc26b | ||
|
|
613781e6c0 | ||
|
|
92c3c1f829 | ||
|
|
6268367b22 | ||
|
|
4c174a42f8 | ||
|
|
71463476f6 | ||
|
|
20b388c1d2 | ||
|
|
3ab7648384 | ||
|
|
9fb84e3ef2 | ||
|
|
d6bfce9a5d | ||
|
|
328d5c6275 | ||
|
|
19be6b5e17 | ||
|
|
499f9633ba | ||
|
|
774ca6cd80 | ||
|
|
22b5cf3536 | ||
|
|
18fa8af728 | ||
|
|
0f01bdad13 | ||
|
|
d787f67ab8 | ||
|
|
16de80f46a | ||
|
|
294bc51f83 | ||
|
|
70987fc55f | ||
|
|
5b700cb6e6 | ||
|
|
dcb31fa783 | ||
|
|
411a52e16f | ||
|
|
41bfd757ad | ||
|
|
d94c6f2132 | ||
|
|
29052c7a90 | ||
|
|
48de41137d | ||
|
|
203d06831e | ||
|
|
3e9c435ed1 | ||
|
|
e65fda875a | ||
|
|
70c745dd84 | ||
|
|
870b71afec | ||
|
|
18e0af6b38 | ||
|
|
ed87cc1b1e | ||
|
|
5d6ff69e8d | ||
|
|
cbea2b5443 | ||
|
|
a891e1f85d | ||
|
|
ade0aa770a | ||
|
|
a5f2f3b3f1 | ||
|
|
077ba65f7e | ||
|
|
6f6a426424 | ||
|
|
163158cf12 | ||
|
|
e4821aa9e1 | ||
|
|
9b23c3272b | ||
|
|
3454afb3e4 | ||
|
|
ab99ae6951 | ||
|
|
a609452cfd | ||
|
|
ee1256a676 | ||
|
|
a9837a3aaf | ||
|
|
499492e10a | ||
|
|
6e77ce999a | ||
|
|
dd05eeb821 | ||
|
|
919f8faeee | ||
|
|
b0db8e1ae0 | ||
|
|
3e0f2bfc4a | ||
|
|
5e9e1faedc | ||
|
|
dba6a88341 | ||
|
|
ee0b86c0c2 | ||
|
|
7ea2e1bf51 | ||
|
|
c801f2d4a5 | ||
|
|
ae84f02bd0 | ||
|
|
a6c73e2840 | ||
|
|
e6bc1d7c22 | ||
|
|
e2abb6b6db | ||
|
|
cb63cdcd42 | ||
|
|
1f28b9f98d | ||
|
|
7fcc0ba8a4 | ||
|
|
6773ac88af | ||
|
|
46bee1d532 | ||
|
|
10062373d1 | ||
|
|
68e3c2be9b | ||
|
|
099df7a0ee | ||
|
|
21b6537215 | ||
|
|
eb70f6d18e | ||
|
|
4ee6ae5da1 | ||
|
|
2c8d2d8643 | ||
|
|
0582b45389 | ||
|
|
f7cbe71bd9 | ||
|
|
1b87600658 | ||
|
|
446fb9c99f | ||
|
|
c774cb0c27 | ||
|
|
8ff9427a04 | ||
|
|
b427e67619 | ||
|
|
6163f98020 | ||
|
|
316b2fc98a | ||
|
|
9c73204224 | ||
|
|
7da59d5a39 | ||
|
|
a34b63b80d | ||
|
|
5b335f0f26 | ||
|
|
28af18f36e | ||
|
|
10bb9f7079 | ||
|
|
ed7006bbf4 | ||
|
|
b272f6bf15 | ||
|
|
715ce5dbe9 | ||
|
|
7d0f807880 | ||
|
|
b66eccedc0 | ||
|
|
f79e725aa3 | ||
|
|
66c4b6815f | ||
|
|
f073da1d27 | ||
|
|
dad0d648a1 | ||
|
|
f20262c5c8 | ||
|
|
23b6617a3f | ||
|
|
ab5c02c2ae | ||
|
|
1005cee4bc | ||
|
|
95a1b12c07 | ||
|
|
23542bbfee | ||
|
|
ec65c26b3c | ||
|
|
837cc9dd93 | ||
|
|
88a8d1c209 | ||
|
|
f4b780b806 | ||
|
|
3a296d237f | ||
|
|
db64c02bee | ||
|
|
97023ce1dd | ||
|
|
3a87a2665d | ||
|
|
6a2f4fb30d | ||
|
|
49b9b70c29 | ||
|
|
356340ad09 | ||
|
|
986bff1c22 | ||
|
|
e42001b2bc | ||
|
|
9818f5b6a3 | ||
|
|
46e40fbb65 | ||
|
|
c141dbbd82 | ||
|
|
9d5d08fa6c | ||
|
|
7b9aa5b91a | ||
|
|
8c75f7659f | ||
|
|
d8c40c1662 | ||
|
|
7c0180c3b9 | ||
|
|
211fee2e4e | ||
|
|
9b7b91651d | ||
|
|
6ecfe5e141 | ||
|
|
e11291538c | ||
|
|
5b90d59877 | ||
|
|
85df885b90 | ||
|
|
4dd5b67bbf | ||
|
|
88575ebc5d | ||
|
|
d8a19e9832 | ||
|
|
99a938ef37 | ||
|
|
b07ea3460e | ||
|
|
f557a86ecc | ||
|
|
a5f8dd0788 | ||
|
|
effbd82d00 | ||
|
|
9d72c9db1b | ||
|
|
486df332dd | ||
|
|
8806c8ba8b | ||
|
|
0df1e38ded | ||
|
|
7344689ba6 | ||
|
|
0ddbb80ee3 | ||
|
|
48667b7dda | ||
|
|
5708bc6b49 | ||
|
|
9481df50b1 | ||
|
|
840c454c1c | ||
|
|
77143dc8cf | ||
|
|
e3e77a8234 | ||
|
|
c3e84e6daa | ||
|
|
c3f71c43e9 | ||
|
|
df2ad6b1ca | ||
|
|
1d462b7558 | ||
|
|
0a8c3ddd71 | ||
|
|
6ab86657ff | ||
|
|
aed66d81b3 | ||
|
|
e355280232 | ||
|
|
92fff0c903 | ||
|
|
06319911d4 | ||
|
|
98959e902b | ||
|
|
1e996410f8 | ||
|
|
548a8ac87b | ||
|
|
44494df9d3 | ||
|
|
60c698d381 | ||
|
|
df3e1ace61 | ||
|
|
6def5118bb | ||
|
|
7d3224e37f | ||
|
|
28a1581bb6 | ||
|
|
66b8e697ea | ||
|
|
c15f1c917a | ||
|
|
5b72444a6d | ||
|
|
94a37bb60a | ||
|
|
935113a53d | ||
|
|
d39ed15517 | ||
|
|
1dce5ef39f | ||
|
|
2c69b57617 | ||
|
|
06961d3db5 | ||
|
|
bdf2922f5d | ||
|
|
f52d13f86a | ||
|
|
1b7b361b30 | ||
|
|
151c40441f | ||
|
|
e26363dc0f | ||
|
|
5dbc8bf383 | ||
|
|
27e6cf0e31 | ||
|
|
24f241a1cd | ||
|
|
a8febc8638 | ||
|
|
c04dfb82bb | ||
|
|
08d189683d | ||
|
|
b67975a820 | ||
|
|
fa175e7d24 | ||
|
|
c2221e5304 | ||
|
|
104b5ec6d6 | ||
|
|
59b4780afa | ||
|
|
899405456b | ||
|
|
40a81173f3 | ||
|
|
19a6608619 | ||
|
|
558a52909d | ||
|
|
76eb623de6 | ||
|
|
9e45c05383 | ||
|
|
c0a1529468 | ||
|
|
f4a7a88167 | ||
|
|
44ecb62ce7 | ||
|
|
37a976831d | ||
|
|
dd1aeb7265 | ||
|
|
777c62c056 | ||
|
|
717cddcc3d | ||
|
|
d6f7f620fc | ||
|
|
1bd928a766 | ||
|
|
e493b0775d | ||
|
|
a966fa34ae | ||
|
|
8cd27fca4d | ||
|
|
3676ca15c8 | ||
|
|
616f7d3def | ||
|
|
ec4c6ec7a1 | ||
|
|
941fa6d520 | ||
|
|
ce5e561cf3 | ||
|
|
8e5a00db76 | ||
|
|
faaeffbd38 | ||
|
|
a070066b71 | ||
|
|
4e92269ae1 | ||
|
|
994971b08f | ||
|
|
019c0fabe1 | ||
|
|
8e5346be21 | ||
|
|
5f9d1f62cf | ||
|
|
d7bdf862bf | ||
|
|
6470442e08 | ||
|
|
6157f53aae | ||
|
|
3f2d4a5274 | ||
|
|
ae83035380 | ||
|
|
4566ff6d24 | ||
|
|
cbceca3b35 | ||
|
|
436de1c4f5 | ||
|
|
737d4a5506 | ||
|
|
e5b16e9ef1 | ||
|
|
ea64f8453f | ||
|
|
507eb1c786 | ||
|
|
04f8ab3871 | ||
|
|
6b390caef5 | ||
|
|
8cee527ad0 | ||
|
|
bdf7d47742 | ||
|
|
6ad9435b4d | ||
|
|
e853892282 | ||
|
|
4969b8c252 | ||
|
|
239ef8951d | ||
|
|
494510e2a8 | ||
|
|
6dd899df22 | ||
|
|
7c4b97961f | ||
|
|
5c0a82913f | ||
|
|
d7e64d3f11 | ||
|
|
ea8d725546 | ||
|
|
cfffbcc5be | ||
|
|
ba80b40e9e | ||
|
|
b0fe7ecf8c | ||
|
|
84a6cfd558 | ||
|
|
efbf692cca | ||
|
|
f81057416b | ||
|
|
168675d380 | ||
|
|
6327477695 | ||
|
|
4c7ac85ae8 | ||
|
|
afe6fbe3b3 | ||
|
|
39568bff2f | ||
|
|
d3b44f1c84 | ||
|
|
8e74746573 | ||
|
|
bb54f234bd | ||
|
|
572a84c19b | ||
|
|
8fe46092c0 | ||
|
|
02bad8bcd1 | ||
|
|
54be0c0dec | ||
|
|
20df2789b5 | ||
|
|
a8f902885d | ||
|
|
c17e37b6e0 | ||
|
|
df25986597 | ||
|
|
dc06ca51a6 | ||
|
|
d76ea27c54 | ||
|
|
90b606584d | ||
|
|
19a24c2171 | ||
|
|
f7d75ca641 | ||
|
|
5baa083386 | ||
|
|
6f7cb088b0 | ||
|
|
8901d1c37d | ||
|
|
ec9dedd75c | ||
|
|
3edf7ee978 | ||
|
|
9e35b66510 | ||
|
|
713458ac81 | ||
|
|
90e2f04c34 | ||
|
|
9896b02bd6 | ||
|
|
d39dd45ae4 | ||
|
|
d50ae52176 | ||
|
|
784be47702 | ||
|
|
4f1fa811d0 | ||
|
|
201cd065a9 | ||
|
|
d832ec8ab2 | ||
|
|
0c6c01d86a | ||
|
|
13612d4024 | ||
|
|
9daf8d6493 | ||
|
|
e071406829 | ||
|
|
ff85b03e3f | ||
|
|
590429d104 | ||
|
|
eb0b5bd3f8 | ||
|
|
b15a902f6d | ||
|
|
4468d63145 | ||
|
|
aba5c428e9 | ||
|
|
62966c2f64 | ||
|
|
dfd2a4ef0e | ||
|
|
7fcc6e010c | ||
|
|
5d2ae4aa1e | ||
|
|
4318172edd | ||
|
|
9201559b1d | ||
|
|
40f90dd8f3 | ||
|
|
308cc81a27 | ||
|
|
7e8f8cf415 | ||
|
|
62634c6e1e | ||
|
|
70e4bd4174 | ||
|
|
7e0e618222 | ||
|
|
cf6f013909 | ||
|
|
2ed8557ea6 | ||
|
|
da3373ae42 | ||
|
|
cd0173dae4 | ||
|
|
02e7400ef0 | ||
|
|
6d6f29b6e1 | ||
|
|
0260b3177e | ||
|
|
b82d9d15d4 | ||
|
|
3bc0495eb2 | ||
|
|
50c0b60c10 | ||
|
|
c2680fd0a7 | ||
|
|
85c74c6bf8 | ||
|
|
93f665eb9c | ||
|
|
113c879d7a | ||
|
|
f13ee05c6a | ||
|
|
90fd2ff6a3 | ||
|
|
3a40b9f3a3 | ||
|
|
d8805b6af7 | ||
|
|
675336dee5 | ||
|
|
3cd4ed8e63 | ||
|
|
9c7208b1fa | ||
|
|
48af038643 | ||
|
|
ca8ad5e554 | ||
|
|
ab146f5d23 | ||
|
|
13fdd31c67 | ||
|
|
28f69afe96 | ||
|
|
2827e9e253 | ||
|
|
46ba6fc561 | ||
|
|
b3997769c0 | ||
|
|
410f58b7c7 | ||
|
|
fbecdad199 | ||
|
|
9e6e3160ff | ||
|
|
ca8abae240 | ||
|
|
6f0d095364 | ||
|
|
cc661c7549 | ||
|
|
6982846f50 | ||
|
|
eb6ec17504 | ||
|
|
8c68e1108b | ||
|
|
9077fd7b51 | ||
|
|
f8b88418ed | ||
|
|
9c12016859 | ||
|
|
e6943c8a9d | ||
|
|
c6483b5cf8 | ||
|
|
60925658bb | ||
|
|
5ef9ea35d6 | ||
|
|
901bb48877 | ||
|
|
9fc37e6418 | ||
|
|
b34cce3f75 | ||
|
|
787646b3cc | ||
|
|
f0d5e9d01e | ||
|
|
be05309e51 | ||
|
|
52811e2ec2 | ||
|
|
107738f0f2 | ||
|
|
936fa20928 | ||
|
|
362a3fde10 | ||
|
|
5c13f8f10a | ||
|
|
20cf990bf7 | ||
|
|
00744bc0e5 | ||
|
|
cb2a623faa | ||
|
|
7e80e7ba86 | ||
|
|
c50c985c85 | ||
|
|
c3ee794d40 | ||
|
|
c8502fa20c | ||
|
|
a31c037165 | ||
|
|
c71035530a | ||
|
|
acaf23fcb8 | ||
|
|
15860f3245 | ||
|
|
8a1e4cdf30 | ||
|
|
e574dca373 | ||
|
|
32fc932813 | ||
|
|
8a471d4d11 | ||
|
|
81ca3cd06e | ||
|
|
f8d65a831e | ||
|
|
a1ac21af75 | ||
|
|
d3d5e4e7bc | ||
|
|
c11cd7f4af | ||
|
|
840f2dced7 | ||
|
|
f81d6cf262 | ||
|
|
fe378c938a | ||
|
|
d9a4fed2f8 | ||
|
|
2a4fe80399 | ||
|
|
8999713301 | ||
|
|
0900cc2f59 | ||
|
|
87bf751b11 | ||
|
|
12c40a5b80 | ||
|
|
e9a2f9ff62 | ||
|
|
1fc382f74f | ||
|
|
65fc95b614 | ||
|
|
4354e8c861 | ||
|
|
f1014bbbb6 | ||
|
|
72f232e776 | ||
|
|
b7ebc35193 | ||
|
|
671328aaf6 | ||
|
|
c7bd174d7c | ||
|
|
54f8d05105 | ||
|
|
892f102e4a | ||
|
|
f9b54dab31 | ||
|
|
b3daf55ec2 | ||
|
|
391cef8549 | ||
|
|
59b51cccfc | ||
|
|
a83091bc3b | ||
|
|
7372540fce | ||
|
|
ceaa4bcac6 | ||
|
|
862f31ef1c | ||
|
|
6643bf8695 | ||
|
|
3c0297fbdf | ||
|
|
479cdb4218 | ||
|
|
6389ccee8d | ||
|
|
d478f98a4c | ||
|
|
dba0058763 | ||
|
|
10b4782efb | ||
|
|
f82d8d647a | ||
|
|
1698c822a5 | ||
|
|
c9177ec259 | ||
|
|
0481589615 | ||
|
|
6ef2b22a3c | ||
|
|
da19b2008a | ||
|
|
5493ab345a | ||
|
|
2589f7db14 | ||
|
|
2e283b9d6d | ||
|
|
3cf27bb46e | ||
|
|
f67d0709b7 | ||
|
|
2e66d603d3 | ||
|
|
d51560211c | ||
|
|
1b620b31d5 | ||
|
|
b82b730bf9 | ||
|
|
9191c993b1 | ||
|
|
1a2245043d | ||
|
|
2df7b9f302 | ||
|
|
202cbc62db | ||
|
|
9209e57bd9 | ||
|
|
1e1ad7694b | ||
|
|
b920d37f4e | ||
|
|
3cb2bc31a8 | ||
|
|
be24eec9d0 | ||
|
|
60fed04cb7 | ||
|
|
6c956013a6 | ||
|
|
59289ae8f9 | ||
|
|
8310e9762b | ||
|
|
99483d2913 | ||
|
|
b77303931e | ||
|
|
5863dc6c7c | ||
|
|
2a3923a173 | ||
|
|
3e882f3fd9 | ||
|
|
0499c38466 | ||
|
|
3e18d5ea57 | ||
|
|
ae75a502f0 | ||
|
|
6ac200f597 | ||
|
|
d7f635586d | ||
|
|
e27156be58 | ||
|
|
cafe638d5a | ||
|
|
4d996f6273 | ||
|
|
86dfd2840f | ||
|
|
dd9c3a53bf | ||
|
|
57959a1e93 | ||
|
|
6cfd7a988b | ||
|
|
ef95ff3342 | ||
|
|
773c17496e | ||
|
|
6118dafd94 | ||
|
|
8befcbfacf | ||
|
|
b9ea4983f9 | ||
|
|
d8765f86dd | ||
|
|
3d9744362f | ||
|
|
b2162ba263 | ||
|
|
aba40a9360 | ||
|
|
1a9e076685 | ||
|
|
2d9a3c643a | ||
|
|
85d2a06f6f | ||
|
|
8a5719afe1 | ||
|
|
2ec01c9b60 | ||
|
|
5fa02ef1e3 | ||
|
|
cfe8f8f6e1 | ||
|
|
9d63f0ce9a | ||
|
|
afd8d305f3 | ||
|
|
83738a606d | ||
|
|
072311b256 | ||
|
|
c904a9af1c | ||
|
|
7c042a566a | ||
|
|
57b762eb29 | ||
|
|
a4eb0cbd74 | ||
|
|
e558912a36 | ||
|
|
00ea757e77 | ||
|
|
2f04934471 | ||
|
|
1e6f492852 | ||
|
|
582c7c762a | ||
|
|
3ad64aa6a4 | ||
|
|
1c680d3aaa | ||
|
|
eed9ea35f9 | ||
|
|
a724725fdf | ||
|
|
84a5929645 | ||
|
|
cb85a8f5cb | ||
|
|
23dd80ffd8 | ||
|
|
16393c499b | ||
|
|
684160f178 | ||
|
|
e3f193b382 | ||
|
|
37d9c4b480 | ||
|
|
b6633aa306 | ||
|
|
c8651fb1f3 | ||
|
|
83a5b0d223 | ||
|
|
d95ef48d22 | ||
|
|
b59ce0b95b | ||
|
|
c00cd1d627 | ||
|
|
ab65641eae | ||
|
|
6c0781c157 | ||
|
|
bf6c6498aa | ||
|
|
4b6cec8452 | ||
|
|
b77da2635b | ||
|
|
033ddf8cc8 | ||
|
|
5b3c67c692 | ||
|
|
86aa8b8b2e | ||
|
|
0329bbc55e | ||
|
|
c9549e8ab6 | ||
|
|
5903f02086 | ||
|
|
28dcd34624 | ||
|
|
13b7398b3a | ||
|
|
50cf9c0e67 | ||
|
|
71ad38d742 | ||
|
|
c086a1ff24 | ||
|
|
75958f1f31 | ||
|
|
be34e0221d | ||
|
|
0913c94e46 | ||
|
|
910a0ef8e1 | ||
|
|
7b0e8b47a2 | ||
|
|
14e799ebe5 | ||
|
|
5e52c735a6 | ||
|
|
9eb5883f77 | ||
|
|
7a783b867b | ||
|
|
83ec0bd751 | ||
|
|
aacff4a9b6 | ||
|
|
7ab8ad8b10 | ||
|
|
cf7ac30215 | ||
|
|
547944ac88 | ||
|
|
99d7b46e48 | ||
|
|
eca872c04d | ||
|
|
8947b735f9 | ||
|
|
e245dee90b | ||
|
|
edba2a2e96 | ||
|
|
81e8ce4952 | ||
|
|
afd5d3a1e3 | ||
|
|
d1e8bcd7a5 | ||
|
|
79c71bf5c1 | ||
|
|
2c7daa388b | ||
|
|
cc351402a1 | ||
|
|
90a7602e5a | ||
|
|
1e0b8e443b | ||
|
|
96025a1977 | ||
|
|
6e1bcc03a6 | ||
|
|
728ec2e769 | ||
|
|
25a064f3a8 | ||
|
|
8a25b91ad2 | ||
|
|
cacd7dd2eb | ||
|
|
acf6825603 | ||
|
|
1b8c48ee1d | ||
|
|
6a6b75b7b4 | ||
|
|
491cbda0d3 | ||
|
|
aadd5e8786 | ||
|
|
e155d43c4b | ||
|
|
683f5d64b9 | ||
|
|
d26469c6a4 | ||
|
|
57d497c801 | ||
|
|
eac105fe9e | ||
|
|
61c2a3ed7a | ||
|
|
46031c008e | ||
|
|
d2aadd66bf | ||
|
|
646770ff68 | ||
|
|
90ad165359 | ||
|
|
30eae8f513 | ||
|
|
2d37575f3d | ||
|
|
eb1e607b93 | ||
|
|
9d16aec99a | ||
|
|
a95099696f | ||
|
|
be4791f826 | ||
|
|
41d5fa16a7 | ||
|
|
d3635126b7 | ||
|
|
7cba83231a | ||
|
|
7f4145d67f | ||
|
|
103c804c8e | ||
|
|
c7db4470e4 | ||
|
|
2e55fc8c32 | ||
|
|
5d921acd7d | ||
|
|
aa051b662e | ||
|
|
5fabd602ae | ||
|
|
0393e15843 | ||
|
|
539fb8e214 | ||
|
|
7b1fa28b85 | ||
|
|
30475f0eda | ||
|
|
19771b307c | ||
|
|
7a992837a1 | ||
|
|
33d8fa7b23 | ||
|
|
62d55296c0 | ||
|
|
cd0aad731a | ||
|
|
8e7afcc5fb | ||
|
|
a62618ee47 | ||
|
|
4e9b7f27a9 | ||
|
|
7d7ea4405c | ||
|
|
45c4117a40 | ||
|
|
4bd00b0f91 | ||
|
|
9e7225be36 | ||
|
|
154acbef72 | ||
|
|
502611702e | ||
|
|
009b9f7f3d | ||
|
|
77161c8e4d | ||
|
|
b4cd6f27ba | ||
|
|
2bb42ae9a9 | ||
|
|
54ce282b8c | ||
|
|
47057f076a | ||
|
|
7f775b7662 | ||
|
|
48317e0788 | ||
|
|
6c77c8f1aa | ||
|
|
ca759d2c8f | ||
|
|
53a59f593e | ||
|
|
d621670735 | ||
|
|
6653cce464 | ||
|
|
acfbed72de | ||
|
|
c4e322a23a | ||
|
|
6b9d617fa6 | ||
|
|
607ac40ab3 | ||
|
|
69c7ca8bdc | ||
|
|
692eb90dcd | ||
|
|
eee1c62325 | ||
|
|
442c3fdb9b | ||
|
|
e2077c46ce | ||
|
|
e8972efca1 | ||
|
|
f86c856e3b | ||
|
|
6bb674420a | ||
|
|
ee0fdc4332 | ||
|
|
4006992f8d | ||
|
|
8d04940c91 | ||
|
|
4f1d3a75c2 | ||
|
|
24c8af0363 | ||
|
|
4474af2a9a | ||
|
|
a3765ec0f8 | ||
|
|
b04712898c | ||
|
|
adaafc2a6d | ||
|
|
3308cc60e9 | ||
|
|
e4b235378b | ||
|
|
4f5f6b25e8 | ||
|
|
4b40179bc3 | ||
|
|
0f7b23148f | ||
|
|
a46923e494 | ||
|
|
1e7b4b8450 | ||
|
|
0edf24ae97 | ||
|
|
82f60fee35 | ||
|
|
1333e37b71 | ||
|
|
7f3e0b8fe0 | ||
|
|
937863f4aa | ||
|
|
ff3a639c92 | ||
|
|
3eae7156dc | ||
|
|
e12589ea8b | ||
|
|
6b5ee5ecb5 | ||
|
|
f3a9224547 | ||
|
|
8ef326fdc5 | ||
|
|
fb0e8ee9c6 | ||
|
|
6a8cc8ace3 | ||
|
|
f5fadea30e | ||
|
|
bedfb82066 | ||
|
|
8a403d9126 | ||
|
|
aca4e6585c | ||
|
|
0928f50bc6 | ||
|
|
da098cc1f7 | ||
|
|
8da631a14d | ||
|
|
dafa5014a4 | ||
|
|
879c2f365e | ||
|
|
50032affcf | ||
|
|
784cc3ba9c | ||
|
|
1d5a88a319 | ||
|
|
392575ba04 | ||
|
|
83c808c42d | ||
|
|
9a61392cf9 | ||
|
|
b2c2f7bbd2 | ||
|
|
da6ad1a43d | ||
|
|
f9e4253cb7 | ||
|
|
1675ce83b6 | ||
|
|
9b585ef706 | ||
|
|
67c9378fb8 | ||
|
|
7ab299b246 | ||
|
|
0733a87279 | ||
|
|
28dc8e6751 | ||
|
|
51cbb7e1fb | ||
|
|
3a82317dd5 | ||
|
|
1f2ef09d87 | ||
|
|
5bf0f0215d | ||
|
|
8f968e4c9c | ||
|
|
a8ce60ed4a | ||
|
|
27d8911dee | ||
|
|
4bf909393c | ||
|
|
8fc0e1d384 | ||
|
|
60ae205bd4 | ||
|
|
65045c4897 | ||
|
|
e46133c850 | ||
|
|
37ef57f78f | ||
|
|
3c50d99aba | ||
|
|
508efcf51c | ||
|
|
36d11a4443 | ||
|
|
8590b0b4f3 | ||
|
|
7817d629f1 | ||
|
|
7607a87617 | ||
|
|
b2d37d4ddb | ||
|
|
0003c72fc7 | ||
|
|
915f7cbd54 | ||
|
|
0b3097cd0b | ||
|
|
c7e0ba82b4 | ||
|
|
6168fa4275 | ||
|
|
b61a788ce7 | ||
|
|
903ecd207d | ||
|
|
d62e9652fc | ||
|
|
41e3b2b1a1 | ||
|
|
3349757d0f | ||
|
|
066d7458ca | ||
|
|
88a59b4460 | ||
|
|
aaab83356d | ||
|
|
7c1637328a | ||
|
|
0224346ed8 | ||
|
|
35366b25a6 | ||
|
|
b4c951b66b | ||
|
|
b1c09acb0c | ||
|
|
a6b231ce56 | ||
|
|
0862e4995c | ||
|
|
94832fd7d7 | ||
|
|
7cd82d16ce | ||
|
|
dabbca767f | ||
|
|
ca9bc13619 | ||
|
|
3f573711aa | ||
|
|
55306b1d3d | ||
|
|
ab2d68ef45 | ||
|
|
b7a2d59a61 | ||
|
|
25c8453353 | ||
|
|
aa39a923ed | ||
|
|
57b7729ea7 | ||
|
|
0e750a7d0d | ||
|
|
5cd583f944 | ||
|
|
c7a93758cb | ||
|
|
a450806dd2 | ||
|
|
cf6048419b | ||
|
|
cd6487ab94 | ||
|
|
157a9cc651 | ||
|
|
509157a8b0 | ||
|
|
aa8b8184b3 | ||
|
|
1f65d3add7 | ||
|
|
3b97724717 | ||
|
|
144db5f07f | ||
|
|
dc0ab611c4 | ||
|
|
5ddc93cf0d | ||
|
|
ad5328e6c7 | ||
|
|
7e514ce4bd | ||
|
|
42dc36ad5a | ||
|
|
7689d0d568 | ||
|
|
f37265235e | ||
|
|
f83b192d70 | ||
|
|
910420af07 | ||
|
|
8f719b7fed | ||
|
|
0272446f2b | ||
|
|
735d7ab1b4 | ||
|
|
3c9b556ca8 | ||
|
|
4e2ccf13cb | ||
|
|
8d0a7d322e | ||
|
|
3880b7811b | ||
|
|
2604bb078c | ||
|
|
8670d622da | ||
|
|
1ca1c37a9c | ||
|
|
7e7db57369 | ||
|
|
deb6fe8d7a | ||
|
|
1e20ed7099 | ||
|
|
40d94c84e0 | ||
|
|
bfc9af16a1 | ||
|
|
770cba7e2b | ||
|
|
8aa98d3f53 | ||
|
|
4219af78f4 | ||
|
|
0352f2e6f0 | ||
|
|
9ea02922ee | ||
|
|
816cbc74f4 | ||
|
|
e8cd8ca8c0 | ||
|
|
179015a050 | ||
|
|
d34428d249 | ||
|
|
974df6190e | ||
|
|
294a18e680 | ||
|
|
47edda2c1b | ||
|
|
ebe758f741 | ||
|
|
2f42eb02d4 | ||
|
|
08e4823917 | ||
|
|
d67615c976 | ||
|
|
2ca9b70c84 | ||
|
|
bd8e532353 | ||
|
|
4f69f090e6 | ||
|
|
0077fbe916 | ||
|
|
b263d1a049 | ||
|
|
bb3c647f49 | ||
|
|
c9b7180bb3 | ||
|
|
aca28bcb79 | ||
|
|
410447b340 | ||
|
|
6b0a1d286a | ||
|
|
e78cd0d623 | ||
|
|
6eb72b71b1 | ||
|
|
0cef7f27ea | ||
|
|
9698844cc3 | ||
|
|
9ca5e13d7f | ||
|
|
e1825e0ff2 | ||
|
|
a55fc58e24 | ||
|
|
8e2889c2b5 | ||
|
|
95d21e61e4 | ||
|
|
ed09b87953 | ||
|
|
8c3fbe26ad | ||
|
|
af2699ec21 | ||
|
|
17364dc445 | ||
|
|
59dd97cb72 | ||
|
|
a0a98419f0 | ||
|
|
1b47fd952c | ||
|
|
bf9e5b8e6e | ||
|
|
7e282c9027 | ||
|
|
e0dc494e71 | ||
|
|
4110956dda | ||
|
|
d0acd59adc | ||
|
|
8ad6ffc93d | ||
|
|
56d0926bdf | ||
|
|
8d99e12723 | ||
|
|
8ee8301bd0 | ||
|
|
1d584fead4 | ||
|
|
cc56ebbb35 | ||
|
|
56b87146e7 | ||
|
|
a5b9cdf90f | ||
|
|
6cd3d0d977 | ||
|
|
361de53d86 | ||
|
|
4021f6d8c3 | ||
|
|
2949e5cd8d | ||
|
|
c8f3921c3d | ||
|
|
5254834d43 | ||
|
|
2b0ceaf417 | ||
|
|
a688abddc1 | ||
|
|
648678ba7d | ||
|
|
f4c8c29510 | ||
|
|
87be9fd1ad | ||
|
|
7cbb2bf435 | ||
|
|
4f1cefec30 | ||
|
|
5e19c8f142 | ||
|
|
a6737720f4 | ||
|
|
e028a67f4f | ||
|
|
c5e8aaff4a | ||
|
|
2017ef192f | ||
|
|
04d3915171 | ||
|
|
2bdf3088a6 | ||
|
|
9debf2678e | ||
|
|
e03c10142d | ||
|
|
6213e7c390 | ||
|
|
9264aa5e46 | ||
|
|
4c5e1d916a | ||
|
|
d1ac3f3c24 | ||
|
|
ec9447ad5f | ||
|
|
26b01d56f5 | ||
|
|
eb687748c5 | ||
|
|
4b81cfcb47 | ||
|
|
a7074f03f7 | ||
|
|
0b67bba121 | ||
|
|
a791677534 | ||
|
|
be17a6cbf0 | ||
|
|
d2547672f3 | ||
|
|
52d1a09b8a | ||
|
|
1d98aa54d5 | ||
|
|
f56181bdab | ||
|
|
bc40c86f10 | ||
|
|
d61f3e79e2 | ||
|
|
1d58879ae5 | ||
|
|
f115fe331b | ||
|
|
92ac8fed99 | ||
|
|
877d31fefb | ||
|
|
0d77c7f9a7 | ||
|
|
0037f9eccb | ||
|
|
ba51e24fd9 | ||
|
|
7b9e6a57af | ||
|
|
7e9cab2b7d | ||
|
|
dd74ade44d | ||
|
|
9de2aa55cd | ||
|
|
6ac2376aac | ||
|
|
4fadb26cf6 | ||
|
|
61f14ffbbc | ||
|
|
377a55f60f | ||
|
|
e32cb72c62 | ||
|
|
dbd408c6d1 | ||
|
|
6e7bacb3c3 | ||
|
|
91f7078953 | ||
|
|
7787cb59f0 | ||
|
|
dac27435b8 | ||
|
|
50cd5701ce | ||
|
|
adf4fb5ae0 | ||
|
|
1f4cc1cf88 | ||
|
|
92dd53177f | ||
|
|
fe9e5bf21d | ||
|
|
1ca4f6acf5 | ||
|
|
392463b9f0 | ||
|
|
4df1f85492 | ||
|
|
ad79f878eb | ||
|
|
04a7437158 | ||
|
|
1fbeb6bd34 | ||
|
|
54cce67156 | ||
|
|
7db5b33284 | ||
|
|
6607ddb15d | ||
|
|
f18c1b3998 | ||
|
|
bd75b34f5d | ||
|
|
057de8f9be | ||
|
|
404bfdc782 | ||
|
|
b74a1b5a32 | ||
|
|
9f38e81735 | ||
|
|
47ecde75ec | ||
|
|
07948ff6a7 | ||
|
|
381bccfd6a | ||
|
|
3221038bc6 | ||
|
|
0359a65a00 | ||
|
|
eb1b77ad01 | ||
|
|
45c7bab8e4 | ||
|
|
0a558652e3 | ||
|
|
30126c9288 | ||
|
|
39562edc45 | ||
|
|
c19e513efb | ||
|
|
cf22cbcab5 | ||
|
|
e444b277f8 | ||
|
|
49dfbee211 | ||
|
|
3fc3875e82 | ||
|
|
a9099ce2c1 | ||
|
|
ad9fc59d19 | ||
|
|
0e14d42dcf | ||
|
|
987ff861fd | ||
|
|
f3f36e323b | ||
|
|
f7326b0533 | ||
|
|
dbde650339 | ||
|
|
a338e3fae8 | ||
|
|
df59bf8811 | ||
|
|
99e669bb63 | ||
|
|
66b4dcf37a | ||
|
|
1462d5c6bd | ||
|
|
60d2efc74b | ||
|
|
144b44e838 | ||
|
|
3245ff59d3 | ||
|
|
3a4d58f114 | ||
|
|
494f054ef4 | ||
|
|
0079a08cb8 | ||
|
|
d31ff6a83f | ||
|
|
58abb54da5 | ||
|
|
2fb4dccff0 | ||
|
|
45a4fc34d1 | ||
|
|
dc65627453 | ||
|
|
d24cbaf556 | ||
|
|
cbf71f678a | ||
|
|
c983418cb3 | ||
|
|
240c44b338 | ||
|
|
505ac0021d | ||
|
|
c020154a2f | ||
|
|
aac1663d75 | ||
|
|
5b9d963d31 | ||
|
|
31a6f5c4e3 | ||
|
|
98535e572d | ||
|
|
ffcfaba2fa | ||
|
|
464d868af5 | ||
|
|
34a6e81f72 | ||
|
|
57a9b520b0 | ||
|
|
6952970895 | ||
|
|
14e20e6435 | ||
|
|
93abd016b4 | ||
|
|
2ebde976db | ||
|
|
dbaee7c49c | ||
|
|
b6be4f8dde | ||
|
|
68a31c902a | ||
|
|
78e6fbcf07 | ||
|
|
0403b684c4 | ||
|
|
ccf05c6d83 | ||
|
|
a6a62007dc | ||
|
|
549c42ac19 | ||
|
|
6bfeb15655 | ||
|
|
69eb071fab | ||
|
|
277a62a897 | ||
|
|
96da85d2c1 | ||
|
|
b53b71a8ad | ||
|
|
009ffd609d | ||
|
|
50044f2f13 | ||
|
|
0a2f4eb5be | ||
|
|
0ee25621d6 | ||
|
|
e64c542c6a | ||
|
|
97ef3cccef | ||
|
|
766049afbb | ||
|
|
4fff4f679f | ||
|
|
2123f284de | ||
|
|
fb9b8fa625 | ||
|
|
d9e645b63f | ||
|
|
c2545c6762 | ||
|
|
c846d827cc | ||
|
|
f75179134d | ||
|
|
a30b22505c | ||
|
|
bbf4082b1f | ||
|
|
84a9da2f06 | ||
|
|
4f457e945a | ||
|
|
64f081009d | ||
|
|
486bbae323 | ||
|
|
b49a1904df | ||
|
|
1a70b54129 | ||
|
|
70332c4f2b | ||
|
|
8789141d0f | ||
|
|
29e7497adc | ||
|
|
8ecf28de9b | ||
|
|
66abc05259 | ||
|
|
5b04c49e74 | ||
|
|
f26e9758d5 | ||
|
|
531cb89943 | ||
|
|
24ead2f125 | ||
|
|
225e50a32a | ||
|
|
d546877e7d | ||
|
|
9657bd51d0 | ||
|
|
fd47fc3d12 | ||
|
|
c74d8bb602 | ||
|
|
ec7844072f | ||
|
|
128390d52e | ||
|
|
f7d23a4b9f | ||
|
|
2dec48f8af | ||
|
|
3f8ec8d46e | ||
|
|
a607d1178f | ||
|
|
1a3d412669 | ||
|
|
ae08d21bf1 | ||
|
|
5f69e58f37 | ||
|
|
84b0ee2284 | ||
|
|
4e9005be14 | ||
|
|
f280c64980 | ||
|
|
d0ae6a9a7d | ||
|
|
9aca360fe5 | ||
|
|
5d92a3a891 | ||
|
|
70787b0a6d | ||
|
|
206b8bc899 | ||
|
|
a0ea94b531 | ||
|
|
790a7a37d2 | ||
|
|
c0eace067a | ||
|
|
9d6835737b | ||
|
|
1b4625cedd | ||
|
|
fba75e3122 | ||
|
|
91bf99d2a5 | ||
|
|
6f29d2a5d8 | ||
|
|
008ef41261 | ||
|
|
c61d341844 | ||
|
|
49e5a48e42 | ||
|
|
9a97898ea4 | ||
|
|
cce1fa8928 | ||
|
|
cddea1e4c1 | ||
|
|
2cbf5cbf7b | ||
|
|
e360565266 | ||
|
|
dce7be2775 | ||
|
|
922e5beb3f | ||
|
|
6c6b6f7f13 | ||
|
|
798546302d | ||
|
|
65c6945fe3 | ||
|
|
e5820feedd | ||
|
|
df15bf5c59 | ||
|
|
2ccd9da8e8 | ||
|
|
18b5d6f1ed | ||
|
|
a78fe12663 | ||
|
|
87fde19623 | ||
|
|
93a4201c66 | ||
|
|
88369e0366 | ||
|
|
e50094e10a | ||
|
|
4e74819bac | ||
|
|
084b54723a | ||
|
|
60e830b64c | ||
|
|
0d52bb291c | ||
|
|
9e37c04fb2 | ||
|
|
7870940532 | ||
|
|
3adf31c85b | ||
|
|
9b2c6caf22 | ||
|
|
87b48ee3e5 | ||
|
|
9880a488ac | ||
|
|
f59675e9bf | ||
|
|
dd3ea0b5e6 | ||
|
|
4dbb1f6101 | ||
|
|
ced38e86c4 | ||
|
|
927b804684 | ||
|
|
27de834abc | ||
|
|
7de8f63b2b | ||
|
|
f042fe4713 | ||
|
|
27f3ba941f | ||
|
|
9413d5deb4 | ||
|
|
8a903f1e2c | ||
|
|
9246f4925b | ||
|
|
128fb82c1c | ||
|
|
3bf4a93a44 | ||
|
|
6460447ae9 | ||
|
|
344683927f | ||
|
|
828f088b6c | ||
|
|
d9f4730d0b | ||
|
|
aa5d320707 | ||
|
|
69c77c0a24 | ||
|
|
5ceedab213 | ||
|
|
1c4f3cbf19 | ||
|
|
90bf55e645 | ||
|
|
e066e920d0 | ||
|
|
fceaac48a6 | ||
|
|
4330b61217 | ||
|
|
97410042bd | ||
|
|
75592bec01 | ||
|
|
e96b1c8106 | ||
|
|
fdb6908474 | ||
|
|
5d63071849 | ||
|
|
8c98c7b675 | ||
|
|
5eb54321e8 | ||
|
|
9ce44af204 | ||
|
|
51e840a150 | ||
|
|
f6b4ec0fdf | ||
|
|
8439a3add9 | ||
|
|
9b3511cc88 | ||
|
|
48f80ebc93 | ||
|
|
e1108c5e17 | ||
|
|
1d6eee3262 | ||
|
|
14bcdee7e2 | ||
|
|
ec12de89c8 | ||
|
|
57e858ccc4 | ||
|
|
2c44452dc6 | ||
|
|
24f2720df4 | ||
|
|
d9c30c8942 | ||
|
|
6f3d70c69f | ||
|
|
99948b601b | ||
|
|
24a374500c | ||
|
|
b9cd6d3505 | ||
|
|
d9e907535e | ||
|
|
d1426e85b3 | ||
|
|
efdd052674 | ||
|
|
9964a0d9e5 | ||
|
|
d3e1cff733 | ||
|
|
b5096ad65e | ||
|
|
56d0e03991 | ||
|
|
c765943fdf | ||
|
|
91898d1512 | ||
|
|
c4d9262abf | ||
|
|
9b40854d27 | ||
|
|
2092da2907 | ||
|
|
9b9e489b61 | ||
|
|
9f9831ac56 | ||
|
|
afe5148211 | ||
|
|
5ab1606c47 | ||
|
|
b83ab97a8a | ||
|
|
6255932e48 | ||
|
|
9ad09a0166 | ||
|
|
728a656df4 | ||
|
|
4933a70261 | ||
|
|
02c24dffdc | ||
|
|
aa7ee8e65d | ||
|
|
64a6a28c30 | ||
|
|
f8bdb8bd16 | ||
|
|
2417faa39b | ||
|
|
5c2f62657f | ||
|
|
ae34c7e1cc | ||
|
|
07a3a0e1c8 | ||
|
|
c43f4ea080 | ||
|
|
149414f233 | ||
|
|
14695faa43 | ||
|
|
1159c0530b | ||
|
|
053ecec70b | ||
|
|
42601d8451 | ||
|
|
49392992da | ||
|
|
545c303058 | ||
|
|
086daef494 | ||
|
|
6898df1c86 | ||
|
|
307a019cb8 | ||
|
|
4ca16188c2 | ||
|
|
53687387eb | ||
|
|
eff1cea890 | ||
|
|
7867c3d906 | ||
|
|
5b5f421786 | ||
|
|
77cc2a6b8e | ||
|
|
e58ff89044 | ||
|
|
57eae464a3 | ||
|
|
8ec00e90ba | ||
|
|
a0f078718a | ||
|
|
b3a2031484 | ||
|
|
abf6e4856c | ||
|
|
518e6782d8 | ||
|
|
2a346ef0b9 | ||
|
|
83a2b2080b | ||
|
|
f21ecb32bb | ||
|
|
f810fa262d | ||
|
|
a847f46edc | ||
|
|
e710bbcec8 | ||
|
|
52f8fa1d5b | ||
|
|
5661de58a8 | ||
|
|
a1d5cb0e69 | ||
|
|
89ca436e91 | ||
|
|
d5356bee99 | ||
|
|
0384294cbf | ||
|
|
0da1f7be27 | ||
|
|
b24f2f14f0 | ||
|
|
40a1fab5e0 | ||
|
|
9464cbcf87 | ||
|
|
4334a1985b | ||
|
|
ba03124720 | ||
|
|
27b1e28f63 | ||
|
|
4431ef7736 | ||
|
|
4c86c8c264 | ||
|
|
275550a9c3 | ||
|
|
38cf61209e | ||
|
|
8670e9e5aa | ||
|
|
260eeacbeb | ||
|
|
13b2aed936 | ||
|
|
88431b9286 | ||
|
|
a12c6b7bef | ||
|
|
f81d99289f | ||
|
|
97739f8852 | ||
|
|
bdc0309296 | ||
|
|
e1a5edefc1 | ||
|
|
373c400cc3 | ||
|
|
d93e53498d | ||
|
|
e82d526414 | ||
|
|
0f11b55ba3 | ||
|
|
a665d2f62c | ||
|
|
0baa5a82ad | ||
|
|
0ea1775084 | ||
|
|
2fda0bd12b | ||
|
|
3b5c9e7a84 | ||
|
|
c0d8e7e245 | ||
|
|
d73ff21b27 | ||
|
|
4a90199f63 | ||
|
|
0dab0b5969 | ||
|
|
8e9bdf4115 | ||
|
|
613cbb8601 | ||
|
|
8cf02324ce | ||
|
|
9f75f28e7a | ||
|
|
feb4a39457 | ||
|
|
cca1fd6f19 | ||
|
|
4fb126635c | ||
|
|
9f282c2898 | ||
|
|
be3b95db6b | ||
|
|
c02b350b3d | ||
|
|
85f6d8308a | ||
|
|
06f2750eef | ||
|
|
5f078848f1 | ||
|
|
6ff68849f8 | ||
|
|
2ea036e02c | ||
|
|
f58ac3e9bf | ||
|
|
56e161d1ff | ||
|
|
85da2b7e23 | ||
|
|
da7136ab7e | ||
|
|
73264b2e80 | ||
|
|
567d48f813 | ||
|
|
0c3d350865 | ||
|
|
65211c94c3 | ||
|
|
b3b84f8357 | ||
|
|
a49d12b887 | ||
|
|
b5cb7e5649 | ||
|
|
c27c2b3487 | ||
|
|
56e9805562 | ||
|
|
f197e750b6 | ||
|
|
206bc9afb6 | ||
|
|
ffcfa5b2cb | ||
|
|
afae5d80c7 | ||
|
|
5e680e0f66 | ||
|
|
45015d6106 | ||
|
|
c3223245e5 | ||
|
|
fdf43e5874 | ||
|
|
dcc1a5db52 | ||
|
|
46ed52032d | ||
|
|
345a52b153 | ||
|
|
2accb00adc | ||
|
|
65c672fa1c | ||
|
|
f430dafb30 | ||
|
|
44524c057d | ||
|
|
a42322be99 | ||
|
|
6d8de238a0 | ||
|
|
c0d3135e54 | ||
|
|
b8b5203d08 | ||
|
|
f087afd796 | ||
|
|
91a230b38d | ||
|
|
72dc25abd1 | ||
|
|
b85b3d9bbd | ||
|
|
b6188abeeb | ||
|
|
1cd9fac9fb | ||
|
|
f1a2a7cfe9 | ||
|
|
f7fdd0a63a | ||
|
|
79ec2ee8f7 | ||
|
|
5c4f0de1d0 | ||
|
|
b9c1b1a5ea | ||
|
|
75036c43b5 | ||
|
|
3656cd66ea | ||
|
|
da88b87279 | ||
|
|
900f38779d | ||
|
|
d369ac8bf5 | ||
|
|
244eca4b38 | ||
|
|
67690748bd | ||
|
|
218ceb8a2a | ||
|
|
39ec81117d | ||
|
|
70f91204b1 | ||
|
|
f4739ae147 | ||
|
|
518125b836 | ||
|
|
7d4b353780 | ||
|
|
dbede8d6df | ||
|
|
5c48c72b56 | ||
|
|
8f52a3a3cc | ||
|
|
61a6af1de7 | ||
|
|
77f8bea615 | ||
|
|
bb49bc7844 | ||
|
|
c56ad76d18 | ||
|
|
b5dd04aa12 | ||
|
|
788724a1ca | ||
|
|
d577eb338c | ||
|
|
639ce20ecc | ||
|
|
27b6715910 | ||
|
|
b8ef8565e8 | ||
|
|
6d2f855af2 | ||
|
|
ae81bbb441 | ||
|
|
7db570af13 | ||
|
|
6a21831894 | ||
|
|
ee49851de4 | ||
|
|
e1ca614f1c | ||
|
|
01d1ea0b90 | ||
|
|
59ada379e2 | ||
|
|
52715c9220 | ||
|
|
4409fb9b21 | ||
|
|
e845d02242 | ||
|
|
35ed5b3c9b | ||
|
|
2567088192 | ||
|
|
26a083e700 | ||
|
|
8c4c87112c | ||
|
|
d052603335 | ||
|
|
01395fc579 | ||
|
|
bbe15eab7e | ||
|
|
015842ed83 | ||
|
|
d76f346648 | ||
|
|
34a5ab7498 | ||
|
|
72e537e951 | ||
|
|
670c067891 | ||
|
|
5ec4616614 | ||
|
|
bae9ef77e5 | ||
|
|
b2484afe96 | ||
|
|
e2e7479b8e | ||
|
|
cad38fe6da | ||
|
|
f5bfb537da | ||
|
|
e7f8ebaf77 | ||
|
|
29eab14f79 | ||
|
|
febcc8995d | ||
|
|
72cc87b012 | ||
|
|
5705e471b7 | ||
|
|
d8e30eb793 | ||
|
|
2c903dcb67 | ||
|
|
2d3aafefe1 | ||
|
|
5b1f16d7e9 | ||
|
|
4b74a1be58 | ||
|
|
2aeb77736f | ||
|
|
4a9d2d92d3 | ||
|
|
15c051e3ad | ||
|
|
6ee2fbf88c | ||
|
|
5665653b7d | ||
|
|
e7c0480bc3 | ||
|
|
241cec6e43 | ||
|
|
d8328b6f6e | ||
|
|
9e91f6f8d9 | ||
|
|
69b381fb66 | ||
|
|
ffa74500e6 | ||
|
|
356c135cbe | ||
|
|
9e05a02bbf | ||
|
|
b63dcabca4 | ||
|
|
cc9191382f | ||
|
|
0e86633cde | ||
|
|
9212e832e6 | ||
|
|
848763bb5c | ||
|
|
076357a2c4 | ||
|
|
daea5487ba | ||
|
|
dbd1b977fc | ||
|
|
5d14667536 | ||
|
|
ab289f8392 | ||
|
|
fa4584555d | ||
|
|
4b2a340bc7 | ||
|
|
7cb9a5064a | ||
|
|
4b6ec02517 | ||
|
|
9ea3b34e7e | ||
|
|
440c6d2d9a | ||
|
|
e579450af6 | ||
|
|
50e463917c | ||
|
|
a3ad297f92 | ||
|
|
6707640fa3 | ||
|
|
50bc5c8398 | ||
|
|
281065b5d4 | ||
|
|
f64d21e8c2 | ||
|
|
d5284a5704 | ||
|
|
9b2b603c8d | ||
|
|
6f85a204a9 | ||
|
|
b5f3d2565a | ||
|
|
2fdf52afb8 | ||
|
|
a651cf33f4 | ||
|
|
9e15d771c8 | ||
|
|
c48a2252d0 | ||
|
|
978cd2ec51 | ||
|
|
79f3afc2eb | ||
|
|
602142dc45 | ||
|
|
a4b6e99858 | ||
|
|
8730f2b073 | ||
|
|
20a6e66e11 | ||
|
|
94d397b8c5 | ||
|
|
adceb9eabb | ||
|
|
19a06a8755 | ||
|
|
87790a8d7a | ||
|
|
a6d32f4a62 | ||
|
|
a5f9bda131 | ||
|
|
327b2355c1 | ||
|
|
20308faef1 | ||
|
|
170ab57f55 | ||
|
|
874054f3bb | ||
|
|
a08f3c4c9e | ||
|
|
c0f98bb0ec | ||
|
|
42b067dc39 | ||
|
|
089e3816a8 | ||
|
|
ae15532477 | ||
|
|
b8ee806a80 | ||
|
|
9186f5eeeb | ||
|
|
216e70756c | ||
|
|
5a52922cd2 | ||
|
|
55edf30ecf | ||
|
|
d231539504 | ||
|
|
262ec3ed3c | ||
|
|
38a5e55745 | ||
|
|
8a4562c0a9 | ||
|
|
760c313f65 | ||
|
|
706ebc39eb | ||
|
|
46dfbf826d | ||
|
|
60c6858916 | ||
|
|
c5e085bc96 | ||
|
|
8dc669bc33 | ||
|
|
8aed75a338 | ||
|
|
e486e2ce8d | ||
|
|
a1705da6da | ||
|
|
0092a029c4 | ||
|
|
176ef90258 | ||
|
|
f82a6b7b41 | ||
|
|
c79c42b62d | ||
|
|
91dd7adbfa | ||
|
|
de82f07277 | ||
|
|
0c8e0b6708 | ||
|
|
c71a840e74 | ||
|
|
2b5c25ef17 | ||
|
|
da34156267 | ||
|
|
113ef45c6c | ||
|
|
67dd40dc08 | ||
|
|
1e0fee739e | ||
|
|
d59a98ffe6 | ||
|
|
5e9429afe8 | ||
|
|
31fd0451d0 | ||
|
|
b56be08f95 | ||
|
|
b1923cadb5 | ||
|
|
0a955c1020 | ||
|
|
791efc9e79 | ||
|
|
f9bc94bfb8 | ||
|
|
72119ddfa4 | ||
|
|
d4afca9b5a | ||
|
|
219ac40a7d | ||
|
|
b9378fe4c1 | ||
|
|
3c05822011 | ||
|
|
02cad7b5fe | ||
|
|
1a85ec5fdb | ||
|
|
3e19cfe58e | ||
|
|
3d3c7437be | ||
|
|
c4b57774f0 | ||
|
|
f7acded7a1 | ||
|
|
cabcca2e31 | ||
|
|
cc3237a77d | ||
|
|
b65e02420f | ||
|
|
5a7761c294 | ||
|
|
ad332494d0 | ||
|
|
eb212cd27e | ||
|
|
b604dd0bcc | ||
|
|
c0b879c998 | ||
|
|
e473af1635 | ||
|
|
8d9c6b2d01 | ||
|
|
7cdcb6c4ef | ||
|
|
ca44d84e55 | ||
|
|
e73a3c3376 | ||
|
|
1f9973e623 | ||
|
|
9077f3d675 | ||
|
|
ce61d27d8d | ||
|
|
5c1dbc0104 | ||
|
|
aa55f67ee3 | ||
|
|
9516694c35 | ||
|
|
c6a9f239c4 | ||
|
|
a922acc4dd | ||
|
|
bfef8c9bbe | ||
|
|
3fe2843bb3 | ||
|
|
42b8378988 | ||
|
|
c6bd721d2e | ||
|
|
83eedef999 | ||
|
|
1411e7f9f6 | ||
|
|
5d42d9212f | ||
|
|
4a1e05524a | ||
|
|
fb5ac9c4cd | ||
|
|
ed4e33d888 | ||
|
|
c6dd73065d | ||
|
|
9ef48de1a8 | ||
|
|
692ad43285 | ||
|
|
d06ff478d1 | ||
|
|
83db04cdce | ||
|
|
d0a724bb08 | ||
|
|
8e9ac1b9ac | ||
|
|
272d4efd4b | ||
|
|
4610f451e9 | ||
|
|
0810859c21 | ||
|
|
93c447051c | ||
|
|
60b3f042a8 | ||
|
|
c5632360d6 | ||
|
|
a379b4aab8 | ||
|
|
3b8d6ef208 | ||
|
|
9705d5e38b | ||
|
|
2e59b56f16 | ||
|
|
d9f9e8e57a | ||
|
|
33a8befbcf | ||
|
|
4f66a419e3 | ||
|
|
65992746d3 | ||
|
|
cbd4c64084 | ||
|
|
081be61f88 | ||
|
|
b89ca87280 | ||
|
|
ca84f10921 | ||
|
|
2200c4af6b | ||
|
|
838dfa453c | ||
|
|
6f3d636226 | ||
|
|
f03792619a | ||
|
|
21b3292fff | ||
|
|
39ebeb2401 | ||
|
|
8f4e8ed1e7 | ||
|
|
0e10ead81a | ||
|
|
476612d8f8 | ||
|
|
bd769c9261 | ||
|
|
831f78a389 | ||
|
|
920edce73e | ||
|
|
7dc7b002c5 | ||
|
|
c74c9bd693 | ||
|
|
1daf15c525 | ||
|
|
108949345f | ||
|
|
69eb309031 | ||
|
|
e7f0c8cbe1 | ||
|
|
9c8b663d5b | ||
|
|
8309b63fb1 | ||
|
|
6d6de880eb | ||
|
|
a65bf79ad9 | ||
|
|
c192188b42 | ||
|
|
a3516ce655 | ||
|
|
8481db4735 | ||
|
|
b6390c3dbd | ||
|
|
0f914cf747 | ||
|
|
5fab7d2993 | ||
|
|
faee142876 | ||
|
|
215c63233a | ||
|
|
e5afcd14a9 | ||
|
|
96a7d1e7ec | ||
|
|
2d2a65b616 | ||
|
|
b5d32fe271 | ||
|
|
8a5a69818e | ||
|
|
56701220e9 | ||
|
|
6bf434a7ab | ||
|
|
d1e767d30c | ||
|
|
4874df25a2 | ||
|
|
f43868e4dc | ||
|
|
bc8227d2bd | ||
|
|
09e748d6c9 | ||
|
|
4038ad5ce5 | ||
|
|
973864e045 | ||
|
|
af694b57a2 | ||
|
|
07be0c6ef4 | ||
|
|
78a336c092 | ||
|
|
649c0f8055 | ||
|
|
87b66b8db8 | ||
|
|
a4ffa3de7a | ||
|
|
dd111f55f6 | ||
|
|
5db6264d8f | ||
|
|
4ce63c8caf | ||
|
|
727f8b1d9b | ||
|
|
35f2bcf296 | ||
|
|
7ebfe84489 | ||
|
|
4e645debaa | ||
|
|
821ab99bf7 | ||
|
|
282e242f5e | ||
|
|
13deb8d8d7 | ||
|
|
389992c330 | ||
|
|
0753c52bed | ||
|
|
24ce9b0f8d | ||
|
|
6e6f8412a5 | ||
|
|
853cdcdd31 | ||
|
|
f24ec20623 | ||
|
|
cdc7d695e9 | ||
|
|
d1cf754c6e | ||
|
|
d1f63fe260 | ||
|
|
53eee70c03 | ||
|
|
7b73ba551e | ||
|
|
af1176274a | ||
|
|
4c2ef9947a | ||
|
|
db7c9e96ea | ||
|
|
ee5398b3be | ||
|
|
3d3ab0fedc | ||
|
|
d21efb51ce | ||
|
|
bd4c742212 | ||
|
|
c821fd938c | ||
|
|
977caba4ca | ||
|
|
8b167a70b8 | ||
|
|
ecca96c03e | ||
|
|
49231a593a | ||
|
|
0338899804 | ||
|
|
810c2250c4 | ||
|
|
5ed210f0f3 | ||
|
|
7508390747 | ||
|
|
67620b7948 | ||
|
|
6c0500d1b6 | ||
|
|
7144efff4e | ||
|
|
3ae31c34f6 | ||
|
|
bc5072ed54 | ||
|
|
2aa7c45ca2 | ||
|
|
73467dc523 | ||
|
|
4ff744ef89 | ||
|
|
b8722b3537 | ||
|
|
caed2ae757 | ||
|
|
5ffdb8eeb4 | ||
|
|
90445f7f1d | ||
|
|
5a298c165e | ||
|
|
63ba377f6f | ||
|
|
a15cdb4c1d | ||
|
|
dff14a868f | ||
|
|
4304301701 | ||
|
|
2dd31b0a44 | ||
|
|
23e01808a2 | ||
|
|
b8300add62 | ||
|
|
97cb1e2080 | ||
|
|
e9d6735e52 | ||
|
|
9d8381041d | ||
|
|
5cf4226c13 | ||
|
|
5bb3d8a24d | ||
|
|
1de683efa4 | ||
|
|
3e705be6c8 | ||
|
|
6548ec1b43 | ||
|
|
e739a74705 | ||
|
|
c0d401fbfc | ||
|
|
7b813d03b9 | ||
|
|
93d06e8680 | ||
|
|
7f22b33f5a | ||
|
|
ceaacba1c2 | ||
|
|
6bee1dcecd | ||
|
|
3c28048038 | ||
|
|
fb02ae0e9a | ||
|
|
ffb293fe0a | ||
|
|
f46522572e | ||
|
|
2ecb87ddc3 | ||
|
|
a34530ebb7 | ||
|
|
0973e7009e | ||
|
|
d0d18441cf | ||
|
|
3f1c37aa76 | ||
|
|
8165342670 | ||
|
|
686c68a90d | ||
|
|
86dbf089cc | ||
|
|
9f3ea84b57 | ||
|
|
3f007d2dbb | ||
|
|
cde68af79a | ||
|
|
574e70642b | ||
|
|
ae156d9326 | ||
|
|
c08268d0ae | ||
|
|
0e4d031054 | ||
|
|
de15ee057a | ||
|
|
1d873cc701 | ||
|
|
bcde60b9e8 | ||
|
|
d6d2b2e756 | ||
|
|
4276573f67 | ||
|
|
fa3481ea8e | ||
|
|
ac54eceea5 | ||
|
|
e1c29bf2af | ||
|
|
0fe560ed7f | ||
|
|
23269040a6 | ||
|
|
b03649748a | ||
|
|
06851f8b98 | ||
|
|
893fc7c940 | ||
|
|
3819aecf07 | ||
|
|
a186b22d6e | ||
|
|
a43186d137 | ||
|
|
554f4889bc | ||
|
|
b584832e75 | ||
|
|
299c911330 | ||
|
|
6318b592a3 | ||
|
|
2b7e7fe6f6 | ||
|
|
bb8983b48a | ||
|
|
666861419d | ||
|
|
52d6c5ac88 | ||
|
|
5b89a2375a | ||
|
|
c0d19de08d | ||
|
|
27d85a737c | ||
|
|
277f542304 | ||
|
|
517a5b6844 | ||
|
|
d4f98902a0 | ||
|
|
eb289e8542 | ||
|
|
06754daf87 | ||
|
|
ee509f6350 | ||
|
|
6a7c6cba12 | ||
|
|
129f5e93fa | ||
|
|
629312b382 | ||
|
|
d31524691b | ||
|
|
ff6ec86f1c | ||
|
|
0c55facdd9 | ||
|
|
d9e1f91735 | ||
|
|
9f037fef60 | ||
|
|
0bc7100ea8 | ||
|
|
8698a58a60 | ||
|
|
a8151de2cb | ||
|
|
7a9005dae6 | ||
|
|
a77f8bf203 | ||
|
|
efc7877ffd | ||
|
|
3cb7632dc8 | ||
|
|
cde8e54b51 | ||
|
|
8ce1a2d605 | ||
|
|
d09379990b | ||
|
|
136318f98a | ||
|
|
1775844f45 | ||
|
|
987a663094 | ||
|
|
107dbd5645 | ||
|
|
bebd8f3c1a | ||
|
|
3be1e33339 | ||
|
|
91348f22be | ||
|
|
c9279061fa | ||
|
|
5bfe397c63 | ||
|
|
a202640da4 | ||
|
|
08fcdfa0fb | ||
|
|
51fb706781 | ||
|
|
92ed70f029 | ||
|
|
067b28be41 | ||
|
|
81b7fc519c | ||
|
|
24cc0c8422 | ||
|
|
8459ea0d31 | ||
|
|
494c245b59 | ||
|
|
d87f0ea728 | ||
|
|
dbdfc13a23 | ||
|
|
c19730f5e2 | ||
|
|
446e735825 | ||
|
|
0e47d1269c | ||
|
|
7dc5359c2b | ||
|
|
e394903ccf | ||
|
|
98bb78ae3a | ||
|
|
defe5ce594 | ||
|
|
713e3fa89d | ||
|
|
73f813279a | ||
|
|
0063cad60d | ||
|
|
3bb3f618b9 | ||
|
|
53195e3a25 | ||
|
|
09103aa52e | ||
|
|
ee63a9f368 | ||
|
|
9a73c15b84 | ||
|
|
b50dec9d92 | ||
|
|
9f8feb622e | ||
|
|
db156b41fb | ||
|
|
374583bb48 | ||
|
|
5d3c218b1b | ||
|
|
f34427e772 | ||
|
|
a1666986c6 | ||
|
|
b669177c83 | ||
|
|
1678d2b97a | ||
|
|
3564f41c48 | ||
|
|
72314a33ab | ||
|
|
9289b29504 | ||
|
|
de115b87df | ||
|
|
cfeb0626cc | ||
|
|
3f2c4ed794 | ||
|
|
978256179b | ||
|
|
742af765ba | ||
|
|
035d0aebc1 | ||
|
|
a5dbd58200 | ||
|
|
9073e1d47e | ||
|
|
ed1078dadf | ||
|
|
83dbd728ef | ||
|
|
31a6149b0f | ||
|
|
3d274fdfd9 | ||
|
|
8f3ec680c7 | ||
|
|
612e94be9d | ||
|
|
7a95c78ba0 | ||
|
|
5a2a546090 | ||
|
|
baf6fc8987 | ||
|
|
bf75d6496f | ||
|
|
fb7f134c06 | ||
|
|
067dcbc0f7 | ||
|
|
280bc969ce | ||
|
|
010b8a79cb | ||
|
|
4ec39ae323 | ||
|
|
ec7c654451 | ||
|
|
6022a61b3c | ||
|
|
975b489007 | ||
|
|
f8f1859a05 | ||
|
|
92f2a44b28 | ||
|
|
7585a984b2 | ||
|
|
789bf9c220 | ||
|
|
2e9bc93e1f | ||
|
|
e2a993a425 | ||
|
|
d0b5c79b81 | ||
|
|
95622ca964 | ||
|
|
76b63de754 | ||
|
|
58cdb1bda2 | ||
|
|
a530f56511 | ||
|
|
bf6e74ad8e | ||
|
|
c2253dafc0 | ||
|
|
389d159c7a | ||
|
|
21161ae38e | ||
|
|
aa074d7121 | ||
|
|
99d04e93a2 | ||
|
|
d6b9df6ca2 | ||
|
|
4fbeca0aa3 | ||
|
|
f19b89b263 | ||
|
|
0a908d78ca | ||
|
|
f2b8b06280 | ||
|
|
0cc04e5253 | ||
|
|
5e9a9b9867 | ||
|
|
68826baf3b | ||
|
|
cc26096c28 | ||
|
|
1c110080a8 | ||
|
|
7b67bbe698 | ||
|
|
7692371ccb | ||
|
|
534eb4ce88 | ||
|
|
c88b936233 | ||
|
|
32c229215a | ||
|
|
9c5cc38c9a | ||
|
|
12795ea491 | ||
|
|
c0b143043f | ||
|
|
40b849da23 | ||
|
|
4f18bd6293 | ||
|
|
702e92d4f4 | ||
|
|
40fa336829 | ||
|
|
fa93803b45 | ||
|
|
7201dbd477 | ||
|
|
40248c3e13 | ||
|
|
f2a0a1b62d | ||
|
|
dcb4bbb3e6 | ||
|
|
21c56e7898 | ||
|
|
7c74e7be35 | ||
|
|
bf5ec1eb57 | ||
|
|
342241a24d | ||
|
|
d047dcb983 | ||
|
|
0fc310f1c4 | ||
|
|
c6e14a562b | ||
|
|
a3f6a7ddbc | ||
|
|
c8c09d7e09 | ||
|
|
411163c73f | ||
|
|
b25aa07e11 | ||
|
|
bc72a506c1 | ||
|
|
8451c62b44 | ||
|
|
1f3729822a | ||
|
|
a27283aa9b | ||
|
|
1eb1bd6800 | ||
|
|
cda4af3403 | ||
|
|
93ea5bacb7 | ||
|
|
841c5c22e0 | ||
|
|
511446846f | ||
|
|
a79bf97b48 | ||
|
|
a78d5e2636 | ||
|
|
b6d2e3fb55 | ||
|
|
43850ac856 | ||
|
|
532b1697a6 | ||
|
|
a3f63a12f9 | ||
|
|
b2dfe64cea | ||
|
|
ff7dc072d1 | ||
|
|
b185afa29f | ||
|
|
742742fd48 | ||
|
|
5f6104a9d3 | ||
|
|
787198b30e | ||
|
|
3490c63259 | ||
|
|
8077d7bb0b | ||
|
|
b2c8c227ec | ||
|
|
ca8ff5fda9 | ||
|
|
a6f2d96557 | ||
|
|
948205e6f9 | ||
|
|
d90b6b7e51 | ||
|
|
e3e1ee313b | ||
|
|
dc5c049ed9 | ||
|
|
642260bdb6 | ||
|
|
bafa85e772 | ||
|
|
4f102a43fa | ||
|
|
2ac265d529 | ||
|
|
e261270eb8 | ||
|
|
d08bd0c619 | ||
|
|
cc833341e4 | ||
|
|
add0081b50 | ||
|
|
46fb9d6df1 | ||
|
|
e324942a07 | ||
|
|
b853012cb6 | ||
|
|
d64d7db5f5 | ||
|
|
d19a076f1e | ||
|
|
5ad314ba5a | ||
|
|
c7473dd7c9 | ||
|
|
abb9ab1bb6 | ||
|
|
8bc9baefd6 | ||
|
|
0fe835e087 | ||
|
|
e8ed41c763 | ||
|
|
d9cd0604cc | ||
|
|
afb2cc4a99 | ||
|
|
a72751914d | ||
|
|
9e3c5b1bf2 | ||
|
|
bf77789076 | ||
|
|
1b0d063cff | ||
|
|
24f8f47f76 | ||
|
|
7745457f9b | ||
|
|
660bbae9a8 | ||
|
|
c071e9b051 | ||
|
|
1c1bab8d6b | ||
|
|
8beb818100 | ||
|
|
1ff0a7c4e7 | ||
|
|
49991a3341 | ||
|
|
88af5ea07c | ||
|
|
63fbd64eb8 | ||
|
|
8337fd306a | ||
|
|
7df6dbeafb | ||
|
|
bf2d6b8999 | ||
|
|
5528cb9f16 | ||
|
|
d8bc6dcc1b | ||
|
|
c0ebc4cbb0 | ||
|
|
e3b6d6e6b2 | ||
|
|
a50b10b869 | ||
|
|
183704ab95 | ||
|
|
e654ed980a | ||
|
|
a4eb35371f | ||
|
|
0931f95e65 | ||
|
|
83997e1125 | ||
|
|
555a1184e4 | ||
|
|
f6b31f65ac | ||
|
|
fc67b208ad | ||
|
|
b6f83007eb | ||
|
|
6e82268704 | ||
|
|
4142cc296b | ||
|
|
e98b1e6716 | ||
|
|
fda8b96063 | ||
|
|
bb8e11e08d | ||
|
|
aee1fe1004 | ||
|
|
fbcd77a1a7 | ||
|
|
90f58dbcbe | ||
|
|
729d19ab24 | ||
|
|
ca9a1b6666 | ||
|
|
08aa003335 | ||
|
|
b0a56e2790 | ||
|
|
01f589885f | ||
|
|
038c940e8e | ||
|
|
20067c02bc | ||
|
|
efa3fa3aed | ||
|
|
e0908ced14 | ||
|
|
3068ca8908 | ||
|
|
88406332d2 | ||
|
|
6cb9561d96 | ||
|
|
3135ba57cd | ||
|
|
96420b959a | ||
|
|
15bda0af27 | ||
|
|
a076e9b0a8 | ||
|
|
0cb4fa67f1 | ||
|
|
bf79be222c | ||
|
|
1bb27f2b80 | ||
|
|
96dae29f4d | ||
|
|
4e0df627df | ||
|
|
15411c7c9e | ||
|
|
b4c389c374 | ||
|
|
44aeead296 | ||
|
|
5e0d4800d9 | ||
|
|
e1a8e8d82d | ||
|
|
4ae714089d | ||
|
|
3894da6242 | ||
|
|
2f74e6ebf8 | ||
|
|
c1aeb2244c | ||
|
|
d231851734 | ||
|
|
c4a68bcd43 | ||
|
|
1add5dac3e | ||
|
|
ec3786f862 | ||
|
|
0e761801de | ||
|
|
39f70c0956 | ||
|
|
0674636243 | ||
|
|
ea89d85845 | ||
|
|
0f3884afde | ||
|
|
7b3d4c6359 | ||
|
|
f9a8fa3854 | ||
|
|
575c86551e | ||
|
|
57bbac4923 | ||
|
|
7f8167e4e2 | ||
|
|
ebce5998de | ||
|
|
672a41a79c | ||
|
|
48b881f491 | ||
|
|
a6f0525a4c | ||
|
|
d9707926fa | ||
|
|
e38c663dea | ||
|
|
b1873b21b6 | ||
|
|
4c4d3dc9e7 | ||
|
|
c7e6777cc1 | ||
|
|
5336524129 | ||
|
|
de30d37ba9 | ||
|
|
e2b6e32fe9 | ||
|
|
f2573a5c02 | ||
|
|
96f8873f2c | ||
|
|
b3919fe819 | ||
|
|
9eeaaf0a03 | ||
|
|
9328ba79d1 | ||
|
|
0c7168648f | ||
|
|
26f8a756cb | ||
|
|
4174442558 | ||
|
|
452a390325 | ||
|
|
9fcb6e1f38 | ||
|
|
826f9cf2f3 | ||
|
|
c18fbfa106 | ||
|
|
cd695f735b | ||
|
|
0e3cd11a55 | ||
|
|
1236c16c83 | ||
|
|
66a47329db | ||
|
|
322f18926e | ||
|
|
5bbc241168 | ||
|
|
83925633e0 | ||
|
|
42943eab95 | ||
|
|
66bf32bafa | ||
|
|
aa42913ece | ||
|
|
e4e8a46424 | ||
|
|
dfe894a39b | ||
|
|
c80feac629 | ||
|
|
71c1ca3eb6 | ||
|
|
ffc99aa52e | ||
|
|
4b10506691 | ||
|
|
57f1f82d76 | ||
|
|
53f84817ba | ||
|
|
221527e0e1 | ||
|
|
501ab2bbe8 | ||
|
|
f78c5a2b18 | ||
|
|
962c3c25b6 | ||
|
|
ae6d6d753a | ||
|
|
3e764fdc45 | ||
|
|
f52ee794db | ||
|
|
34ece330f3 | ||
|
|
7adaf39f1a | ||
|
|
6392550208 | ||
|
|
98d705ed9b | ||
|
|
a356eb7abf | ||
|
|
e950872ec9 | ||
|
|
ab1fdbfead | ||
|
|
7ac8d7de22 | ||
|
|
f012e02b35 | ||
|
|
1ffbb7bf6b | ||
|
|
72927195fd | ||
|
|
e29326d8d0 | ||
|
|
b7bf1955b7 | ||
|
|
1057b88ba7 | ||
|
|
de21088bc4 | ||
|
|
d8698cdc84 | ||
|
|
1ae1906637 | ||
|
|
5a0fc820d4 | ||
|
|
a1f51ad7dc | ||
|
|
fbb89dcf10 | ||
|
|
736552a559 | ||
|
|
162abb0a32 | ||
|
|
a2cd8b72dc | ||
|
|
11aca3f0aa | ||
|
|
c312ca45bd | ||
|
|
f1dc84afef | ||
|
|
7cafe8311e | ||
|
|
9513053f74 | ||
|
|
bfea73d5d8 | ||
|
|
2ae1713ac1 | ||
|
|
fb2047853c | ||
|
|
3dec81b9eb | ||
|
|
b0fa2f5ec0 | ||
|
|
6c367f4a29 | ||
|
|
c8d4d3b69e | ||
|
|
a0234eed48 | ||
|
|
8cc3b54bcd | ||
|
|
d8630d5bdc | ||
|
|
82118c854c | ||
|
|
b1b558d244 | ||
|
|
6ef734960a | ||
|
|
244e3eafdf | ||
|
|
59e367a88e | ||
|
|
681f0ef111 | ||
|
|
098317ed29 | ||
|
|
30cc36abca | ||
|
|
58090c2c32 | ||
|
|
008f5913e9 | ||
|
|
349736b0a5 | ||
|
|
42e926e27c | ||
|
|
80be548b64 | ||
|
|
bb22be4f4f | ||
|
|
fab4c72285 | ||
|
|
9bb42fc5bf | ||
|
|
5d93fc58b3 | ||
|
|
ab633484cd | ||
|
|
5e69a69b8d | ||
|
|
50a9aef179 | ||
|
|
13bc7d17bf | ||
|
|
d8c328ec09 | ||
|
|
2a4c1d0aac | ||
|
|
6c4b88123a | ||
|
|
b78f3a8216 | ||
|
|
8f93b18469 | ||
|
|
a66725adc4 | ||
|
|
8d9d5f3fc3 | ||
|
|
9699198bcc | ||
|
|
aa163b5010 | ||
|
|
aacc392049 | ||
|
|
74b99b52ee | ||
|
|
c7b573dcff | ||
|
|
5b03a1e218 | ||
|
|
77db70f9b5 | ||
|
|
0379d02d8c | ||
|
|
30302a049c | ||
|
|
bd432a3a15 | ||
|
|
b155850ad1 | ||
|
|
84a7f79315 | ||
|
|
3c84242cf2 | ||
|
|
3faf66a36b | ||
|
|
d94b47d1b0 | ||
|
|
6c07bc386b | ||
|
|
34f7571269 | ||
|
|
dc9144f8f4 | ||
|
|
5538ffde53 | ||
|
|
74cd8cd6fe | ||
|
|
1c83a9f0b7 | ||
|
|
929741e9f8 | ||
|
|
9a20052200 | ||
|
|
ee6c824ccf | ||
|
|
cbe7e1a5e7 | ||
|
|
1b605c4a4e | ||
|
|
9953760fe4 | ||
|
|
968cb3cea4 | ||
|
|
889bbf3e3f | ||
|
|
abb8d29cd4 | ||
|
|
aa4ec7b68c | ||
|
|
2e69f3f480 | ||
|
|
ebcc3b3a72 | ||
|
|
b4adb3f3c8 | ||
|
|
f779d4fadb | ||
|
|
c6b08a936b | ||
|
|
93bb6ebb0f | ||
|
|
780a450da2 | ||
|
|
3f536e4dca | ||
|
|
a4772ff2fa | ||
|
|
23a6d1a752 | ||
|
|
74b1f9ee29 | ||
|
|
e89a203481 | ||
|
|
3f53b616fe | ||
|
|
46e3b7a547 | ||
|
|
395a4901a7 | ||
|
|
6aa5bb3d8c | ||
|
|
f8c7a5f736 | ||
|
|
5ed7db41b3 | ||
|
|
53aff6de4b | ||
|
|
2593f6d267 | ||
|
|
5dd4f20822 | ||
|
|
dc83fd8842 | ||
|
|
8730cd85a2 | ||
|
|
aff3861067 | ||
|
|
4e93c2d327 | ||
|
|
709878793e | ||
|
|
7199742615 | ||
|
|
507ec5abfc | ||
|
|
d164e80f9a | ||
|
|
764b8a0faf | ||
|
|
c18a969ad0 | ||
|
|
4882f8f70e | ||
|
|
f0b9949aaf | ||
|
|
0276267d32 | ||
|
|
f2408e1f62 | ||
|
|
1f869f0e30 | ||
|
|
83f97f9b70 | ||
|
|
ead3217bf4 | ||
|
|
f2012fc636 | ||
|
|
16f82ba6b3 | ||
|
|
5cd8176478 | ||
|
|
ea0ee7c7aa | ||
|
|
18a1cc77d4 | ||
|
|
370286ee25 | ||
|
|
311e8ac3e3 | ||
|
|
716eb97af9 | ||
|
|
3623cb9785 | ||
|
|
3f641c2b67 | ||
|
|
94c3cec69f | ||
|
|
a9a82e581a | ||
|
|
0a8bbe93a5 | ||
|
|
1beba3e27a | ||
|
|
07a65d4827 | ||
|
|
35e35ec5db | ||
|
|
de2b3afa17 | ||
|
|
46ab4b5b71 | ||
|
|
1eaa7159a6 | ||
|
|
4015c26e68 | ||
|
|
b17d802476 | ||
|
|
9ebdf64298 | ||
|
|
fa07a0f331 | ||
|
|
44a20349e3 | ||
|
|
7f7003c484 | ||
|
|
d7ab5e25f0 | ||
|
|
5a563f1cc6 | ||
|
|
7c42cf2d95 | ||
|
|
30e128e41d | ||
|
|
795c405e81 | ||
|
|
515f4e8119 | ||
|
|
4a29c32d0c | ||
|
|
696b88375d | ||
|
|
8a354d4439 | ||
|
|
ace2803928 | ||
|
|
7943858290 | ||
|
|
8073bb279f | ||
|
|
293b07bbb6 | ||
|
|
b57f998c58 | ||
|
|
7fc31d593d | ||
|
|
010f3d9748 | ||
|
|
ff31d0b023 | ||
|
|
652e8318e6 | ||
|
|
e05796674b | ||
|
|
0ce169e7f5 | ||
|
|
726af707eb | ||
|
|
0b37d4aac2 | ||
|
|
749c871124 | ||
|
|
622baec952 | ||
|
|
a326c82158 | ||
|
|
9c47b1fbf9 | ||
|
|
b525b0bdd4 | ||
|
|
0a08b7da1a | ||
|
|
a996f4c091 | ||
|
|
e517e58776 | ||
|
|
d2cb088918 | ||
|
|
6ca94b9f3f | ||
|
|
d8ea2d637b | ||
|
|
a6dd5c9930 | ||
|
|
ec3341e5d6 | ||
|
|
a63e840674 | ||
|
|
0e9b61b3d8 | ||
|
|
4c2008f6cb | ||
|
|
430b7c665e | ||
|
|
90fe73333c | ||
|
|
dd60e17835 | ||
|
|
aad680d61d | ||
|
|
9d65062d35 | ||
|
|
2bd78e25fd | ||
|
|
b1bd9c6810 | ||
|
|
6f4ce37cce | ||
|
|
23bbab10b4 | ||
|
|
8b1f55aff0 | ||
|
|
b00764d658 | ||
|
|
97e9e5d2d2 | ||
|
|
db63885945 | ||
|
|
796d95528b | ||
|
|
c3fd9d03ba | ||
|
|
7a539e4ef7 | ||
|
|
bfd89b404a | ||
|
|
e8337ddd3a | ||
|
|
84e0b2a42d | ||
|
|
4ee2888711 | ||
|
|
24b781a641 | ||
|
|
3ceff2ce2e | ||
|
|
b2309cec52 | ||
|
|
e190bb4b52 | ||
|
|
5d9b14dac7 | ||
|
|
786ceec713 | ||
|
|
3c660f7f16 | ||
|
|
2f1024f167 | ||
|
|
6d41839341 | ||
|
|
ba4bf228cb | ||
|
|
ff909da96a | ||
|
|
0cdb134d45 | ||
|
|
ea6d95986e | ||
|
|
20e8333032 | ||
|
|
fc3b931911 | ||
|
|
a67606db8f | ||
|
|
ab1af8d709 | ||
|
|
ffaae3ef39 | ||
|
|
e3839f6a09 | ||
|
|
9e07083c0f | ||
|
|
77925f264f | ||
|
|
78b51bc367 | ||
|
|
55bc853659 | ||
|
|
97857d55a0 | ||
|
|
4bfacf8a7e | ||
|
|
23709c09c7 | ||
|
|
547b97d4cb | ||
|
|
d7483cb3a4 | ||
|
|
7224281cd6 | ||
|
|
e0dfef8461 | ||
|
|
27a07d23d7 | ||
|
|
30050fd7ec | ||
|
|
a7da857646 | ||
|
|
efd240742f | ||
|
|
d7ca4abf40 | ||
|
|
757b74e1d0 | ||
|
|
552258ed3c | ||
|
|
afc4cbc3b2 | ||
|
|
0a04c9ff39 | ||
|
|
a358167897 | ||
|
|
195f6a33bc | ||
|
|
5aab593a5a | ||
|
|
ca3247d21a | ||
|
|
511a7d2448 | ||
|
|
b6c172865b | ||
|
|
40de393aa5 | ||
|
|
fefda0f6e7 | ||
|
|
4302a311a4 | ||
|
|
ed2a792672 | ||
|
|
e60f8c9a3f | ||
|
|
909ae5ada9 | ||
|
|
4743f8fcc5 | ||
|
|
04e8eb1a45 | ||
|
|
666553c4a0 | ||
|
|
07a6640ff9 | ||
|
|
e005c60d78 | ||
|
|
9bf7185c7c | ||
|
|
97b86e2257 | ||
|
|
10effff239 | ||
|
|
a3f27f9a63 | ||
|
|
1f9db9ef08 | ||
|
|
91e13d3557 | ||
|
|
667dc36962 | ||
|
|
f5d06338c7 | ||
|
|
42ab23a833 | ||
|
|
e249a33d3e | ||
|
|
5f03d1b905 | ||
|
|
c85a2ac9ee | ||
|
|
0c069aaba1 | ||
|
|
1e010f38c9 | ||
|
|
8260931ad7 | ||
|
|
5e01769622 | ||
|
|
97a1da81af | ||
|
|
55e888074d | ||
|
|
255be6e786 | ||
|
|
42b18c57ce | ||
|
|
dd0f7c1d5c | ||
|
|
680a08fb5b | ||
|
|
203c40d27c | ||
|
|
0f3fe62327 | ||
|
|
eea3857065 | ||
|
|
a8fc74a033 | ||
|
|
895c8b7098 | ||
|
|
f3b300e9e0 | ||
|
|
ff82c956f1 | ||
|
|
6e1c0c1353 | ||
|
|
ffe2cd0203 | ||
|
|
ea2b95389b | ||
|
|
2fa366c7a8 | ||
|
|
b75eec2fea | ||
|
|
b932ad8c65 | ||
|
|
cc9f770d90 | ||
|
|
6a9d399648 | ||
|
|
fbb534917a | ||
|
|
41d3fb7432 | ||
|
|
5d1298ebe3 | ||
|
|
37b94ed266 | ||
|
|
40c58241ea | ||
|
|
194c346c18 | ||
|
|
11dae594a3 | ||
|
|
5918fe4b58 | ||
|
|
2cad9392c4 | ||
|
|
3d36eb6345 | ||
|
|
9d7652d3ba | ||
|
|
e905a72e03 | ||
|
|
99e02f978d | ||
|
|
89112197d4 | ||
|
|
96b27013f8 | ||
|
|
262d5670fe | ||
|
|
b7f16075ca | ||
|
|
d093585750 | ||
|
|
3b2797f1e1 | ||
|
|
284345d533 | ||
|
|
07767d42cc | ||
|
|
9d97ce087a | ||
|
|
3fa758e895 | ||
|
|
01fe333167 | ||
|
|
6390b1b9a8 | ||
|
|
f68082edad | ||
|
|
1874c57eae | ||
|
|
8130c110eb | ||
|
|
e6e9fae178 | ||
|
|
7042a1ae30 | ||
|
|
7d277cc1ec | ||
|
|
1ac0465a03 | ||
|
|
3533db97ff | ||
|
|
7888cae6c7 | ||
|
|
b021beba6a | ||
|
|
684d67d12e | ||
|
|
8d7683b851 | ||
|
|
e7290d78d5 | ||
|
|
4f0e98ade5 | ||
|
|
39dbfd9fd8 | ||
|
|
2d18558dc5 | ||
|
|
5fb9397521 | ||
|
|
f85e24dff8 | ||
|
|
2ea272fcd6 | ||
|
|
d3e85b439b | ||
|
|
ea837908b6 | ||
|
|
a1573835dd | ||
|
|
34355d6b0c | ||
|
|
9557e4711f | ||
|
|
6a1b9e050a | ||
|
|
6675b43dd0 | ||
|
|
79d7e9f8eb | ||
|
|
f5c9439f91 | ||
|
|
f73e4193f0 | ||
|
|
841003bc47 | ||
|
|
27cf5c81b2 | ||
|
|
323783bf49 | ||
|
|
fbd9604dc1 | ||
|
|
5494d417c0 | ||
|
|
472037cba2 | ||
|
|
1b19d8b909 | ||
|
|
c2909c32ab | ||
|
|
a7c0c01bf4 | ||
|
|
d80226ec61 | ||
|
|
da81ba5be8 | ||
|
|
f81874277c | ||
|
|
d93b97ee92 | ||
|
|
4812d20da5 | ||
|
|
734e7cd47c | ||
|
|
d052b35c40 | ||
|
|
2bd3a3ccfa | ||
|
|
1886c454ca | ||
|
|
91ee1afe24 | ||
|
|
d867f578df | ||
|
|
b48ba048ed | ||
|
|
35a21d8932 | ||
|
|
81ec174e2a | ||
|
|
400ea800d9 | ||
|
|
0e1215268a | ||
|
|
a72d257443 | ||
|
|
6a99a4b359 | ||
|
|
b6764d1d6f | ||
|
|
d5e105ce62 | ||
|
|
45ee1e3c3c | ||
|
|
b1d0dde0b4 | ||
|
|
cb06d28383 | ||
|
|
36bfcd21d4 | ||
|
|
faa48276e5 | ||
|
|
8e5d32430a | ||
|
|
ac2d5b17dd | ||
|
|
0e2c63d9fb | ||
|
|
71b446774c | ||
|
|
dac71e9f7b | ||
|
|
e1a2230e9c | ||
|
|
82bd4431e6 | ||
|
|
7262288502 | ||
|
|
bcb0bdea77 | ||
|
|
4ca58d1f99 | ||
|
|
0c27b82ff3 | ||
|
|
289deb3655 | ||
|
|
8d69c17839 | ||
|
|
348cb57240 | ||
|
|
46f71f3947 | ||
|
|
0ba4b04078 | ||
|
|
5a5f572162 | ||
|
|
fb5bc122cc | ||
|
|
4c328d0fca | ||
|
|
dbce2758b2 | ||
|
|
837f7edd55 | ||
|
|
f054fb3a5f | ||
|
|
96831b144c | ||
|
|
d75116dab7 | ||
|
|
8da46ee305 | ||
|
|
4cac721e74 | ||
|
|
3fda41cbf6 | ||
|
|
053d5e9b8d | ||
|
|
40cb14bf31 | ||
|
|
27d18e4169 | ||
|
|
5403002a36 | ||
|
|
22f1a6c5ca | ||
|
|
783e9a4b74 | ||
|
|
202a067a61 | ||
|
|
f2d1a8bc70 | ||
|
|
b6bc7922b3 | ||
|
|
7e4af27ba7 | ||
|
|
06bbf93bf8 | ||
|
|
e08bdd644b | ||
|
|
1c5ddfafcd | ||
|
|
0f4db4c230 | ||
|
|
960ce86289 | ||
|
|
b2bd3103d8 | ||
|
|
745fd1b702 | ||
|
|
6df1b65249 | ||
|
|
510f8d45e8 | ||
|
|
c5d328a5da | ||
|
|
1430c811cd | ||
|
|
ec2eadd893 | ||
|
|
56c272c17a | ||
|
|
6f92db542b | ||
|
|
8531750631 | ||
|
|
9414ece323 | ||
|
|
c64cb5b92b | ||
|
|
2b1e12dafd | ||
|
|
b4ca2be9e0 | ||
|
|
203de52d71 | ||
|
|
c48333db44 | ||
|
|
e3552befe9 | ||
|
|
6141421f92 | ||
|
|
911ecc4489 | ||
|
|
63ab450d87 | ||
|
|
bcc29168cd | ||
|
|
4a9b0128d7 | ||
|
|
6cc56ac5f7 | ||
|
|
f53c967e18 | ||
|
|
b309933571 | ||
|
|
c7e8044f92 | ||
|
|
29720048e2 | ||
|
|
716ac9e041 | ||
|
|
fb835fbe66 | ||
|
|
4aac3444bd | ||
|
|
0a343b72f2 | ||
|
|
ab9178f638 | ||
|
|
1b8d952d88 | ||
|
|
e8e966cd80 | ||
|
|
8b80cc328f | ||
|
|
72986e8ba3 | ||
|
|
3df01a153d | ||
|
|
5d5ef75337 | ||
|
|
c3ef6380a7 | ||
|
|
c2782b269f | ||
|
|
1cb55b2633 | ||
|
|
823c6a138a | ||
|
|
e10a78d671 | ||
|
|
04b9195cd2 | ||
|
|
3aa12a52eb | ||
|
|
5f31e0e093 | ||
|
|
39f2b508f8 | ||
|
|
5b5285940f | ||
|
|
c49da85606 | ||
|
|
5cc3512a59 | ||
|
|
cbd1d3781b | ||
|
|
5bca9b52b3 | ||
|
|
fd21d6a8da | ||
|
|
c8ebce5732 | ||
|
|
fce5aa5a6b | ||
|
|
2ac2996abd | ||
|
|
53fb83487a | ||
|
|
3597284e8d | ||
|
|
4e8f387f79 | ||
|
|
305e6326a6 | ||
|
|
e98c7eaa0f | ||
|
|
02462b2c12 | ||
|
|
4d9559f345 | ||
|
|
ed63000e23 | ||
|
|
cc307df592 | ||
|
|
2d321bbd33 | ||
|
|
5b5f7c133e | ||
|
|
69484d7f3c | ||
|
|
43f5438d93 | ||
|
|
2b920d6936 | ||
|
|
01bf3e741e | ||
|
|
f014d4580a | ||
|
|
1f02ab17e3 | ||
|
|
e1d8f1d7e5 | ||
|
|
c8640caba3 | ||
|
|
f4ea86378e | ||
|
|
16011f4b34 | ||
|
|
5a3316b872 | ||
|
|
9f50a19856 | ||
|
|
6207b3fa38 | ||
|
|
35d2103189 | ||
|
|
84626f065c | ||
|
|
eaedda8ceb | ||
|
|
4e9c25893c | ||
|
|
eb5bebb344 | ||
|
|
296ee1baca | ||
|
|
58b5c6ded9 | ||
|
|
ecc07a235c | ||
|
|
fc4f0e3bae | ||
|
|
e00d35f5bf | ||
|
|
790022483b | ||
|
|
100cdd329a | ||
|
|
9c441df959 | ||
|
|
a8ae44a881 | ||
|
|
2f5fe43955 | ||
|
|
86820cf1b1 | ||
|
|
e511e1bf96 | ||
|
|
5fb1c6c497 | ||
|
|
607bb28677 | ||
|
|
36e5fb50ec | ||
|
|
74405a8b00 | ||
|
|
4b1ecc16ff | ||
|
|
139d5128a0 | ||
|
|
7b8bd8a285 | ||
|
|
445d232ee7 | ||
|
|
8ad472c118 | ||
|
|
fd6895782f | ||
|
|
abdd03cdfa | ||
|
|
ba3359353f | ||
|
|
ca473b06dc | ||
|
|
2ee0230793 | ||
|
|
35119f8db2 | ||
|
|
c95af7c81b | ||
|
|
a9aa474884 | ||
|
|
259fe4a238 | ||
|
|
f73bbfc0af | ||
|
|
e7478f3390 | ||
|
|
9be89e8ba2 | ||
|
|
5287e42b02 | ||
|
|
e0a7f775c9 | ||
|
|
f1d238b78d | ||
|
|
41ebdc7604 | ||
|
|
e3fde0807f | ||
|
|
4007ff2610 | ||
|
|
27d79eddec | ||
|
|
0e5bc91a14 | ||
|
|
c715141bf0 | ||
|
|
3d656b5008 | ||
|
|
d84afba7c8 | ||
|
|
7559df965b | ||
|
|
10702c160a | ||
|
|
a66bb7453b | ||
|
|
5406a040fb | ||
|
|
77421d2eed | ||
|
|
78b9b0cec8 | ||
|
|
16a3d46193 | ||
|
|
2976bf5e6a | ||
|
|
b370540447 | ||
|
|
6d7c0f75e7 | ||
|
|
81a7eca5ef | ||
|
|
2711a7e522 | ||
|
|
cc8f926d66 | ||
|
|
486aa58b15 | ||
|
|
8711693698 | ||
|
|
e6f615a1f8 | ||
|
|
813ed6f9a1 | ||
|
|
85dba348a7 | ||
|
|
a7422d11ed | ||
|
|
b39fbc0cfd | ||
|
|
f000951fc9 | ||
|
|
edeac868d0 | ||
|
|
a618dee15c | ||
|
|
8b48773176 | ||
|
|
9a17d9a35e | ||
|
|
a2ca22972c | ||
|
|
b05c449dd0 | ||
|
|
bdb918c9c2 | ||
|
|
7ae9dca562 | ||
|
|
005e3ddf7d | ||
|
|
c5fbc5efd3 | ||
|
|
4b06a0126e | ||
|
|
f8ef852b46 | ||
|
|
741b03761a | ||
|
|
8ccde3ed4a | ||
|
|
b6ce8efa20 | ||
|
|
2bf49e8a11 | ||
|
|
0cfb48f3c7 | ||
|
|
fcd9eba0da | ||
|
|
6d7e729563 | ||
|
|
102744665c | ||
|
|
dd885a694e | ||
|
|
ecf8ffbbdc | ||
|
|
c1e67c31bc | ||
|
|
6eccdc1baf | ||
|
|
7aa7ef6baf | ||
|
|
66ed68ca48 | ||
|
|
d20d007933 | ||
|
|
a91d2d0841 | ||
|
|
649b7772f1 | ||
|
|
fe6304b7cd | ||
|
|
e9b6f3559b | ||
|
|
53b2578b8e | ||
|
|
9507601ee6 | ||
|
|
52e4edd147 | ||
|
|
acc3ed85cb | ||
|
|
dbbda60d9e | ||
|
|
401071c40a | ||
|
|
928eb2a32b | ||
|
|
1c0b1721cd | ||
|
|
15a7d0b9b5 | ||
|
|
6670e924bf | ||
|
|
5b5b974341 | ||
|
|
ad85b7c4c6 | ||
|
|
a5490dc6f2 | ||
|
|
5c52fa6007 | ||
|
|
f8ecf14763 | ||
|
|
d2f7e15fcd | ||
|
|
66ac772585 | ||
|
|
dd365e0b14 | ||
|
|
d612656978 | ||
|
|
91787c4dbf | ||
|
|
c534a9d78c | ||
|
|
06053027a9 | ||
|
|
9291d15215 | ||
|
|
d07036b8ec | ||
|
|
cb73eaf776 | ||
|
|
bb38d8d1ca | ||
|
|
cc269337f2 | ||
|
|
a2aa5fc650 | ||
|
|
26d4f21fa7 | ||
|
|
7f390a5499 | ||
|
|
b9f38bcefd | ||
|
|
81b1f61aec | ||
|
|
ab83d86300 | ||
|
|
450cad7a4d | ||
|
|
c1ee744205 | ||
|
|
f21afb3277 | ||
|
|
7948a25945 | ||
|
|
7711131d5c | ||
|
|
c6119efb04 | ||
|
|
d0dee6cb50 | ||
|
|
e3bbfe3052 | ||
|
|
85a460afb7 | ||
|
|
28a2dba9f7 | ||
|
|
4e7f86979d | ||
|
|
303390bf00 | ||
|
|
623e81a422 | ||
|
|
13e574db3f | ||
|
|
7bd4aae433 | ||
|
|
69382682c4 | ||
|
|
7535b4ac61 | ||
|
|
3bab7d6c53 | ||
|
|
a8a45aede3 | ||
|
|
28c6d72110 | ||
|
|
c3cd14f3c5 | ||
|
|
2010f8dcce | ||
|
|
abcb12f9ed | ||
|
|
283a4dda20 | ||
|
|
3355f39e9f | ||
|
|
a4cd4c0745 | ||
|
|
3834546100 | ||
|
|
a3d7f9cd85 | ||
|
|
10247fcf85 | ||
|
|
b1183e55fd | ||
|
|
b6c9377551 | ||
|
|
c9a4b94efe | ||
|
|
04658cafcc | ||
|
|
27b3a3f33c | ||
|
|
d60a0ef58d | ||
|
|
fff2effd5b | ||
|
|
bb7e473e7b | ||
|
|
908641a414 | ||
|
|
69bd28cc65 | ||
|
|
0126a0d575 | ||
|
|
6cee821138 | ||
|
|
bbed3403e8 | ||
|
|
9a0824af69 | ||
|
|
53375ca728 | ||
|
|
f0503b67eb | ||
|
|
9c0daf0ed5 | ||
|
|
796e6d3a87 | ||
|
|
6112505757 | ||
|
|
9b547c7884 | ||
|
|
1687c48c1b | ||
|
|
f5981c4dca | ||
|
|
6f183aa1cc | ||
|
|
56f6ad84bb | ||
|
|
ed9a29b25f | ||
|
|
20ba6261b6 | ||
|
|
905b27f216 | ||
|
|
c218631c56 | ||
|
|
bd600a6135 | ||
|
|
67c80f683e | ||
|
|
1fb65cbce2 | ||
|
|
7aa5705400 | ||
|
|
bd21214467 | ||
|
|
de8b4da6b5 |
No files matched your search
@@ -0,0 +1,18 @@
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
AlignTrailingComments: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
ColumnLimit: 0
|
||||
IndentWidth: 4
|
||||
SortIncludes: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
IndentCaseLabels: true
|
||||
AlignConsecutiveMacros: true
|
||||
WhitespaceSensitiveMacros: ['QUOTE']
|
||||
IfMacros: ['IFX', 'IFXORNAT', 'IFX2', 'IFXA', 'IFX_PENDOR0', 'IFXX', 'IFX2X', 'IFXN', 'UFLAG_IF', 'PASS2IF', 'IF_UNALIGNED', 'IF_ALIGNED']
|
||||
UseTab: Never
|
||||
IndentPPDirectives: None
|
||||
---
|
||||
@@ -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,99 @@
|
||||
### Manual build Box64 with Github Action
|
||||
name: Custom build Box64
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Target platform name'
|
||||
required: true
|
||||
default: 'GENERIC_ARM'
|
||||
type: choice
|
||||
options:
|
||||
- X64
|
||||
- GENERIC_ARM
|
||||
- PHYTIUM
|
||||
- RK3326
|
||||
- RK3399
|
||||
- RK3588
|
||||
- RPI4ARM64
|
||||
- RPI5ARM64
|
||||
- SD845
|
||||
- SD888
|
||||
- ADLINK
|
||||
- TEGRAX1
|
||||
- ARM64
|
||||
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 Box64 Repository"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Environment preparation"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
if [[ ${{ github.event.inputs.platform }} != 'X64' && ${{ github.event.inputs.platform }} != 'GENERIC_ARM' ]]; then
|
||||
echo "BOX64_PLATFORM_MARCRO=-D${{ github.event.inputs.platform }}=1" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-aarch64-linux-gnu cmake make python3
|
||||
else
|
||||
if [[ ${{ github.event.inputs.platform }} == 'X64' ]]; then
|
||||
echo "BOX64_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git cmake make python3
|
||||
else
|
||||
echo BOX64_PLATFORM_MARCRO="-DARM_DYNAREC=ON" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-aarch64-linux-gnu cmake make python3
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: "Display Build info"
|
||||
run: |
|
||||
echo "CMake Platform Macro: ${{ env.BOX64_PLATFORM_MARCRO }}"
|
||||
echo "CMake C Compiler: ${{ env.BOX64_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 Box64"
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX64_COMPILER }} ${{ env.BOX64_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@v4
|
||||
with:
|
||||
name: box64-${{ github.event.inputs.platform }}-${{ github.event.inputs.build_type }}
|
||||
path: build/box64
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
### Auto build Box64 and release its binary with Github Action
|
||||
name: Build and Release Box64
|
||||
|
||||
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: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, ANDROID_GLIBC]
|
||||
type: [Release, Trace, StaticBuild, Box32]
|
||||
os: [ubuntu-latest, ubuntu-22.04-arm]
|
||||
exclude:
|
||||
- platform: ANDROID
|
||||
type: StaticBuild
|
||||
- platform: TERMUX
|
||||
type: StaticBuild
|
||||
- platform: X64
|
||||
type: StaticBuild
|
||||
- platform: ANDROID
|
||||
type: Box32
|
||||
- platform: TERMUX
|
||||
type: Box32
|
||||
- platform: X64
|
||||
os: ubuntu-22.04-arm
|
||||
- platform: RISCV
|
||||
os: ubuntu-22.04-arm
|
||||
- platform: RK3588
|
||||
os: ubuntu-latest
|
||||
- platform: ARM64
|
||||
os: ubuntu-latest
|
||||
- platform: ANDROID
|
||||
os: ubuntu-22.04-arm
|
||||
- platform: TERMUX
|
||||
os: ubuntu-22.04-arm
|
||||
- platform: LARCH64
|
||||
os: ubuntu-22.04-arm
|
||||
- platform: ANDROID_GLIBC
|
||||
os: ubuntu-latest
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: "Checkout Box64 Repository"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Environment preparation"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' ]]; then
|
||||
sudo apt-get -y install git cmake make python3 patchelf
|
||||
if [[ ${{ matrix.platform }} == 'ANDROID' || ${{ matrix.platform }} == 'TERMUX' ]]; then
|
||||
sudo apt-get -y install p7zip
|
||||
wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
|
||||
unzip android-ndk-r26b-linux.zip
|
||||
echo "BOX64_COMPILER=$PWD/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android31-clang" >> $GITHUB_ENV
|
||||
echo "BOX64_PLATFORM_MARCRO=-DANDROID=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
|
||||
git clone https://github.com/termux/termux-docker.git
|
||||
sudo cp -rf termux-docker/system/arm /system
|
||||
sudo chown -R $(whoami):$(whoami) /system
|
||||
sudo chmod 755 -R /system
|
||||
elif [[ ${{ matrix.platform }} == 'ANDROID_GLIBC' ]]; then
|
||||
sudo apt-get -y install git gcc-aarch64-linux-gnu
|
||||
echo "BOX64_PLATFORM_MARCRO=-DARM64=1 -DWINLATOR_GLIBC=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
else
|
||||
sudo apt-get -y install git gcc-aarch64-linux-gnu
|
||||
echo "BOX64_PLATFORM_MARCRO=-D${{ matrix.platform }}=1" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
fi
|
||||
if [[ ${{ matrix.platform }} == 'TERMUX' ]]; then
|
||||
wget https://mirrors.utermux.dev/termux/termux-main/pool/main/liba/libandroid-sysv-semaphore/libandroid-sysv-semaphore_0.1_aarch64.deb
|
||||
7z x libandroid-sysv-semaphore_0.1_aarch64.deb
|
||||
tar -xf data.tar.xz
|
||||
sudo cp -rf data /
|
||||
sudo chmod 755 -R /data
|
||||
sudo chown -R $(whoami):$(whoami) /data
|
||||
echo "CFLAGS=-L/data/data/com.termux/files/usr/lib" >> $GITHUB_ENV
|
||||
echo "IS_TERMUX=1" >> $GITHUB_ENV
|
||||
echo "QEMU_SET_ENV=LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IS_TERMUX=0" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
if [[ ${{ matrix.platform }} == 'X64' ]]; then
|
||||
echo "BOX64_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git cmake make python3
|
||||
elif [[ ${{ matrix.platform }} == 'RISCV' ]]; then
|
||||
echo BOX64_PLATFORM_MARCRO="-DRV64=ON" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=riscv64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-riscv64-linux-gnu cmake make python3 ninja-build libglib2.0-dev
|
||||
elif [[ ${{ matrix.platform }} == 'LARCH64' ]]; then
|
||||
sudo mkdir /usr/local/larch
|
||||
wget -O- -q https://github.com/loongson/build-tools/releases/download/2023.08.08/CLFS-loongarch64-8.1-x86_64-cross-tools-gcc-glibc.tar.xz | sudo tar -C /usr/local/larch --strip-components=1 --xz -xf -
|
||||
sudo ln -sf /usr/local/larch/target /usr/loongarch64-linux-gnu
|
||||
sudo cp -r /usr/local/larch/loongarch64-unknown-linux-gnu/lib/* /usr/loongarch64-linux-gnu/lib64/
|
||||
for i in objdump objcopy strip; do
|
||||
sudo ln -sf /usr/local/larch/bin/loongarch64-unknown-linux-gnu-$i /usr/bin/loongarch64-linux-gnu-$i
|
||||
done
|
||||
echo '/usr/local/larch/bin/loongarch64-unknown-linux-gnu-gcc -L/usr/local/larch/loongarch64-unknown-linux-gnu "$@"' | sudo tee /usr/bin/loongarch64-linux-gnu-gcc
|
||||
echo '/usr/local/larch/bin/loongarch64-unknown-linux-gnu-g++ -L/usr/local/larch/loongarch64-unknown-linux-gnu "$@"' | sudo tee /usr/bin/loongarch64-linux-gnu-g++
|
||||
sudo chmod 755 /usr/bin/loongarch64-linux-gnu-{gcc,g++}
|
||||
|
||||
echo BOX64_PLATFORM_MARCRO="-DLARCH64=ON" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=loongarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git cmake make python3
|
||||
else
|
||||
echo BOX64_PLATFORM_MARCRO="-DARM_DYNAREC=ON" >> $GITHUB_ENV
|
||||
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
sudo apt-get -y install git gcc-aarch64-linux-gnu cmake make python3
|
||||
fi
|
||||
fi
|
||||
if [[ ${{ matrix.type }} == 'Release' ]]; then
|
||||
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
|
||||
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
|
||||
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
|
||||
echo BOX64_BOX32=0 >> $GITHUB_ENV
|
||||
elif [[ ${{ matrix.type }} == 'StaticBuild' ]]; then
|
||||
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
|
||||
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
|
||||
echo BOX64_STATICBUILD=1 >> $GITHUB_ENV
|
||||
echo BOX64_BOX32=0 >> $GITHUB_ENV
|
||||
elif [[ ${{ matrix.type }} == 'Box32' ]]; then
|
||||
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
|
||||
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
|
||||
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
|
||||
echo BOX64_BOX32=1 >> $GITHUB_ENV
|
||||
else
|
||||
echo BOX64_BUILD_TYPE=RelWithDebInfo >> $GITHUB_ENV
|
||||
echo BOX64_HAVE_TRACE=1 >> $GITHUB_ENV
|
||||
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
|
||||
echo BOX64_BOX32=0 >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: "Get XuanTie QEMU Cache Key"
|
||||
if: matrix.platform == 'RISCV'
|
||||
id: get-xuantie-qemu-cache-key
|
||||
run: |
|
||||
echo "key=f2dfdd13014d51f957c7172acc2e791cb42dc400" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Cache XuanTie QEMU"
|
||||
if: matrix.platform == 'RISCV'
|
||||
id: cache-xuantie-qemu
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ github.workspace }}/xuantie_qemu_install
|
||||
key: ${{ runner.os }}-${{ steps.get-xuantie-qemu-cache-key.outputs.key }}-xuantie-qemu
|
||||
|
||||
- name: "Checkout XuanTie QEMU"
|
||||
if: matrix.platform == 'RISCV' && steps.cache-xuantie-qemu.outputs.cache-hit != 'true'
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: revyos/qemu
|
||||
path: xuantie_qemu
|
||||
ref: f2dfdd13014d51f957c7172acc2e791cb42dc400
|
||||
|
||||
- name: "Build XuanTie QEMU for XTheadVector"
|
||||
if: matrix.platform == 'RISCV' && steps.cache-xuantie-qemu.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd xuantie_qemu
|
||||
./configure --prefix=$GITHUB_WORKSPACE/xuantie_qemu_install --target-list=riscv64-linux-user --disable-system
|
||||
make -j$(nproc)
|
||||
make install
|
||||
|
||||
- name: "Display Build info"
|
||||
run: |
|
||||
echo "CMake Platform Macro: ${{ env.BOX64_PLATFORM_MARCRO }}"
|
||||
echo "CMake C Compiler: ${{ env.BOX64_COMPILER }}"
|
||||
echo "Build type: ${{ env.BOX64_BUILD_TYPE }}"
|
||||
echo "Trace Enabled: ${{ env.BOX64_HAVE_TRACE }}"
|
||||
echo "StaticBuild Enabled: ${{ env.BOX64_STATICBUILD }}"
|
||||
echo "Box32 Enabled: ${{ env.BOX64_BOX32 }}"
|
||||
|
||||
- name: "Build Box64"
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX64_COMPILER }}\
|
||||
-DTERMUX=${{ env.IS_TERMUX }}\
|
||||
${{ env.BOX64_PLATFORM_MARCRO }}\
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BOX64_BUILD_TYPE }}\
|
||||
-DHAVE_TRACE=${{ env.BOX64_HAVE_TRACE }}\
|
||||
-DSTATICBUILD=${{ env.BOX64_STATICBUILD }}\
|
||||
-DBOX32=${{ env.BOX64_BOX32 }}\
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON\
|
||||
-DCI=${{ matrix.platform != 'ANDROID' }}
|
||||
make -j$(nproc) VERBOSE=1
|
||||
|
||||
- name: "Test Box64"
|
||||
run: |
|
||||
if [[ ${{ matrix.platform }} != 'X64' ]]; then
|
||||
mkdir qemu9
|
||||
wget -O- -q https://archive.archlinux.org/packages/q/qemu-user-static/qemu-user-static-9.0.2-1-x86_64.pkg.tar.zst | tar -I zstd -C qemu9 -xf -
|
||||
sudo cp qemu9/usr/bin/* /usr/bin/
|
||||
fi
|
||||
|
||||
cd build
|
||||
export CTEST_OPTIONS="-j$(nproc) --timeout 120 --output-on-failure --repeat until-pass:20"
|
||||
if [[ ${{ matrix.platform }} == 'RISCV' ]]; then
|
||||
export INTERPRETER=qemu-riscv64-static
|
||||
export QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/
|
||||
|
||||
ctest $CTEST_OPTIONS
|
||||
QEMU_CPU=rv64,v=false BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
|
||||
QEMU_CPU=rv64,v=false,zba=true,zbb=true,zbc=true,zbs=true ctest $CTEST_OPTIONS
|
||||
QEMU_CPU=rv64,v=true,vlen=128,vext_spec=v1.0 ctest $CTEST_OPTIONS
|
||||
QEMU_CPU=rv64,v=true,vlen=256,vext_spec=v1.0 ctest $CTEST_OPTIONS
|
||||
QEMU_CPU=thead-c906 ctest $CTEST_OPTIONS
|
||||
|
||||
BOX64_DYNAREC_TEST=1 ctest $CTEST_OPTIONS -E nocosim
|
||||
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=false,zba=true,zbb=true,zbc=true,zbs=true ctest $CTEST_OPTIONS -E nocosim
|
||||
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=true,vlen=128,vext_spec=v1.0 ctest $CTEST_OPTIONS -E nocosim
|
||||
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=true,vlen=256,vext_spec=v1.0 ctest $CTEST_OPTIONS -E nocosim
|
||||
BOX64_DYNAREC_TEST=1 QEMU_CPU=thead-c906 ctest $CTEST_OPTIONS -E nocosim
|
||||
|
||||
export INTERPRETER=$GITHUB_WORKSPACE/xuantie_qemu_install/bin/qemu-riscv64
|
||||
QEMU_CPU=c910v ctest $CTEST_OPTIONS
|
||||
BOX64_DYNAREC_TEST=1 QEMU_CPU=c910v ctest $CTEST_OPTIONS -E nocosim
|
||||
elif [[ ${{ matrix.platform }} == 'LARCH64' ]]; then
|
||||
export INTERPRETER=qemu-loongarch64-static
|
||||
export QEMU_LD_PREFIX=/usr/loongarch64-linux-gnu/
|
||||
|
||||
BOX64_DYNAREC_LA64NOEXT=1 ctest $CTEST_OPTIONS -E nocosim
|
||||
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS -E nocosim
|
||||
|
||||
BOX64_DYNAREC_TEST=1 BOX64_DYNAREC_LA64NOEXT=1 ctest $CTEST_OPTIONS -E nocosim
|
||||
elif [[ ${{ matrix.platform }} == 'ANDROID' ]]; then
|
||||
export INTERPRETER=qemu-aarch64-static
|
||||
export QEMU_LD_PREFIX=/system/lib64
|
||||
|
||||
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
|
||||
ctest $CTEST_OPTIONS
|
||||
elif [[ ${{ matrix.platform }} == 'TERMUX' ]]; then
|
||||
export INTERPRETER=qemu-aarch64-static
|
||||
export QEMU_SET_ENV=LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib
|
||||
export QEMU_LD_PREFIX=/system/lib64:/data/data/com.termux/files/usr/lib
|
||||
|
||||
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
|
||||
ctest $CTEST_OPTIONS
|
||||
else
|
||||
ctest -j$(nproc)
|
||||
fi
|
||||
|
||||
- name: "Get short Git commit"
|
||||
id: git-info
|
||||
run: echo "SHORT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Get Box64 Version"
|
||||
run: echo "BOX64_VERSION=$(cat src/box64version.h | grep BOX64_MAJOR | cut -d " " -f 3).$(cat src/box64version.h | grep BOX64_MINOR | cut -d " " -f 3).$(cat src/box64version.h | grep BOX64_REVISION | cut -d " " -f 3)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Packaging WCP file for Winlator"
|
||||
if: matrix.platform == 'ANDROID_GLIBC' && matrix.type != 'StaticBuild'
|
||||
run: |
|
||||
cd build
|
||||
cat <<EOF > profile.json
|
||||
{
|
||||
"type": "Box64",
|
||||
"versionName": "latest-${SHORT_COMMIT}",
|
||||
"versionCode": 1,
|
||||
"description": "Box64-latest-${SHORT_COMMIT}. Built from [https://github.com/ptitSeb/box64].",
|
||||
"files": [
|
||||
{
|
||||
"source": "box64",
|
||||
"target": "\${localbin}/box64"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
patchelf --set-interpreter /data/data/com.winlator/files/imagefs/usr/lib/ld-linux-aarch64.so.1 ./box64
|
||||
tar --zstd -cf box64-latest.wcp box64 profile.json
|
||||
|
||||
- name: "Package Rat File for MiceWine"
|
||||
if: matrix.platform == 'ANDROID' && matrix.type != 'StaticBuild'
|
||||
run: |
|
||||
cd build
|
||||
|
||||
mkdir -p files/usr/bin
|
||||
|
||||
cp box64 files/usr/bin
|
||||
|
||||
echo "name=Box64 (CI Build)" > pkg-header
|
||||
echo "category=Box64" >> pkg-header
|
||||
echo "version=${BOX64_VERSION}-${SHORT_COMMIT}" >> pkg-header
|
||||
echo "architecture=aarch64" >> pkg-header
|
||||
echo "vkDriverLib=" >> pkg-header
|
||||
|
||||
7z -tzip -mx=5 a box64-latest.rat files pkg-header
|
||||
|
||||
- name: "Upload Artifact"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: box64-${{ matrix.platform }}-${{ matrix.type }}
|
||||
path: build/box64
|
||||
|
||||
- name: "Upload WCP file"
|
||||
if: matrix.platform == 'ANDROID_GLIBC' && matrix.type != 'StaticBuild'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: box64-latest-${{ matrix.type }}-wcp
|
||||
path: build/box64-latest.wcp
|
||||
|
||||
- name: "Upload Rat File"
|
||||
if: matrix.platform == 'ANDROID' && matrix.type != 'StaticBuild'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: box64-MiceWine-${{ matrix.type }}
|
||||
path: build/box64-latest.rat
|
||||
+28
@@ -55,7 +55,35 @@ dkms.conf
|
||||
build/
|
||||
build*/
|
||||
.vscode
|
||||
.cache
|
||||
.gdb_history
|
||||
src/git_head.h
|
||||
backup/
|
||||
|
||||
# Wrapper helper
|
||||
/wrapperhelper/bin
|
||||
/wrapperhelper/makedir
|
||||
/wrapperhelper/obj
|
||||
/wrapperhelper/sanaddress
|
||||
/wrapperhelper/sanleak
|
||||
/wrapperhelper/sanundefined
|
||||
/wrapperhelper/src/machine.gen
|
||||
/wrapperhelper/*.h
|
||||
!/wrapperhelper/example-libc.h
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Archives
|
||||
*.7z
|
||||
*.deb
|
||||
*.eopkg
|
||||
*.gz
|
||||
*.rar
|
||||
*.rpm
|
||||
*.tar*
|
||||
*.xbps
|
||||
*.xz
|
||||
*.zip
|
||||
*.zst
|
||||
*.zstd
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
language: c
|
||||
arch:
|
||||
- amd64
|
||||
- arm64-graviton2
|
||||
os: linux
|
||||
dist: focal
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- python3
|
||||
|
||||
#Build steps
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [ "$TRAVIS_CPU_ARCH" = "arm64" ]; then cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; else cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; fi
|
||||
|
||||
script:
|
||||
- make
|
||||
- ctest --output-on-failure
|
||||
@@ -1,52 +0,0 @@
|
||||
v0.1.2
|
||||
======
|
||||
* OpenSource!
|
||||
* A few more opcode added to the Interpretor and the Dynarec
|
||||
* Improved Native Function calling
|
||||
* Added some function to limit allocated memory to 47bits space (for Wine)
|
||||
* Improved and Fixed the functions to limit allocated memory to 32bits space
|
||||
* Wine is starting now, but not everything and every version works
|
||||
|
||||
v0.1.0
|
||||
======
|
||||
* Improvement to ElfLoader
|
||||
* More opcode added to the Dynarec
|
||||
* More lib wrapping
|
||||
* Some fixes to a few function signature
|
||||
* Improvement to Signal handling, and internal mutex handling
|
||||
* A few fixes to some dynarec opcodes
|
||||
* A few fixes to some interpretor opcodes
|
||||
|
||||
v0.0.8
|
||||
======
|
||||
* Improvement to SSE/x87 handling
|
||||
* More opcode added to the Dynarec
|
||||
* More lib wrapping
|
||||
|
||||
v0.0.6
|
||||
======
|
||||
* Added Dynarec for ARM64
|
||||
* Many general CPU opcode added to the Dynarec
|
||||
* Many SSEx opcodes added to the Dynarec
|
||||
* Added a few more symbols in libc
|
||||
* A few changes to the "thread once" handling
|
||||
* New Logo and Icon from @grayduck
|
||||
|
||||
v0.0.4
|
||||
======
|
||||
* Added a lot of opcodes
|
||||
* Added SDL1 and SDL2 wrapping
|
||||
* OpenGL/GLU wrapping done
|
||||
* libasound / libpulse wrapping done
|
||||
* libopenal / libalure / libalut wrapping done
|
||||
* Many X11 libs wrapped
|
||||
* Added "install" with binfmt integration
|
||||
* A few games are actualy starting now (old WorldOfGoo, Into The Breach, VVVVVV and Thimbeweed Park)
|
||||
|
||||
v0.0.2
|
||||
======
|
||||
* Using box86 as a base, implemented most planned box64 part except dynarec
|
||||
* Wrapped a few libs
|
||||
* ELF loader a bit crude, but seems working
|
||||
* Signal handling implemented
|
||||
* MMX and x87 are sharing their registers
|
||||
Executable → Regular
+1453
-156
File diff suppressed because it is too large.
Load diff
-76
@@ -1,76 +0,0 @@
|
||||
Compiling
|
||||
----
|
||||
#### for RK3399
|
||||
|
||||
Using a 64bits OS:
|
||||
```
|
||||
git clone https://github.com/ptitSeb/box64
|
||||
cd box64
|
||||
mkdir build; cd build; cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
make -j4
|
||||
sudo make install
|
||||
```
|
||||
If it's the first install, you also need:
|
||||
```
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
|
||||
#### for PI4
|
||||
|
||||
Warning, you need a 64bits OS:
|
||||
|
||||
```
|
||||
git clone https://github.com/ptitSeb/box64
|
||||
cd box64
|
||||
mkdir build; cd build; cmake .. -DRPI4ARM64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
make -j4
|
||||
sudo make install
|
||||
```
|
||||
If it's the first install, you also need:
|
||||
```
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
|
||||
#### for Other ARM64 Linux platforms
|
||||
|
||||
`mkdir build; cd build; cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j$(nproc)`
|
||||
|
||||
#### for x86_64 Linux
|
||||
|
||||
`mkdir build; cd build; cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j$(nproc)`
|
||||
|
||||
If you encounter some linking errors, try activating `NOLOADADDR` (`cmake -DNOLOADADDR=ON; make -j$(nproc)`).
|
||||
|
||||
### 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 ( ***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 library folders.
|
||||
|
||||
*To have ARM Dynarec*
|
||||
|
||||
The Dynarec is only available on the ARM architecture(Right now, anyways.). Notes also that VFPv3 and NEON are required for the Dynarec. Activate it by using `-DARM_DYNAREC=1`. Also, be sure to use `-marm` in compilation flags (because many compileur use Thumb as default, and the dynarec will not work in this mode).
|
||||
|
||||
*Not building from a git clone*
|
||||
|
||||
If you are not building from a git clone (for example, downloading a release source zipped from github), you need to activate `-DNOGIT=1` from cmake to be able to build (normal process include git sha1 of HEAD in the version that box64 print).
|
||||
|
||||
----
|
||||
|
||||
Testing
|
||||
----
|
||||
A few tests are included.
|
||||
They can be launched with `ctest`
|
||||
They are very basic and don't test much for now.
|
||||
@@ -1,51 +1,109 @@
|
||||
# box64
|
||||

|
||||
|
||||

|
||||
Linux Userspace x86_64 Emulator with a twist
|
||||
# Box64: Linux Userspace x86-64 Emulator with a Twist
|
||||
|
||||
[Changelog](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Report an Error](https://github.com/ptitSeb/box64/issues/new)
|
||||
|
||||
     
|
||||
|
||||
---
|
||||
|
||||
Box64 enables running x86_64 Linux programs, including games, on non-x86_64 Linux systems such as Arm (64-bit little-endian host system required).
|
||||
|
||||
Check out Box64 in action on YouTube:
|
||||
- [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)
|
||||
- [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)
|
||||
- [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
|
||||
|
||||
Box64 leverages native system libraries (libc, libm, SDL, OpenGL), offering ease of integration and surprising performance in many applications. For performance benchmarks, check [this analysis](https://box86.org/index.php/2021/06/game-performances/).
|
||||
|
||||
With DynaRec for ARM64, RV64 and LA64 platforms, Box64 achieves a speed boost 5-10x faster than the interpreter alone. For a deeper look at DynaRec, see [Inner workings](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/).
|
||||
|
||||
<img src="docs/img/Box64Icon.png" width="96" height="96" alt="Box64 Icon">
|
||||
|
||||
_Logo and icon by @grayduck - Thank you!_
|
||||
|
||||
---
|
||||
|
||||
## 📖 Usage
|
||||
|
||||
Box64 offers environment variables to control its behavior. For details, see [Usage Documentation](docs/USAGE.md).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Compiling and Installation
|
||||
|
||||
- [Compilation Instructions](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md)
|
||||
- [Bundle x86 Libraries](https://github.com/ptitSeb/box64/blob/main/docs/BUNDLE-X86-LIBS.md)
|
||||
- [Wine Installation for Box64](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Version History
|
||||
|
||||
See the [Changelog](docs/CHANGELOG.md) for version updates.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Platform Compatibility Notes
|
||||
|
||||
Box64 requires 64-bit libraries on the host system, as it directly translates x86_64 function calls. For 32-bit binaries, use Box86.
|
||||
|
||||
**Notes**
|
||||
|
||||
1. Box32 mode is in the making, which aims to support 32-bit binaries on Box64, you can enable it at build time, but do not expect everything to work. There is actually a few things that work, many that don't. It's a known issue, no need to create tickets about it for now.
|
||||
2. Some installers may default to x86 on 64-bit host OSes, causing compatibility issues. Workaround: Use a fake `uname` that returns "x86_64" for `-m`.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
Box64 has configuration files located in `/etc/box64.box64rc` and `~/.box64rc`, both formatted as `.ini` files. If you don’t want to use the default `/etc/box64.box64rc` file, copy it to `~/.box64rc` to ensure compatibility.
|
||||
|
||||
Settings priority: `~/.box64rc` > `/etc/box64.box64rc` > Command line.
|
||||
|
||||
---
|
||||
|
||||
## 📄 Additional Platform-Specific Notes
|
||||
|
||||
### Unity Game Emulation
|
||||
|
||||
- Many Unity games require OpenGL 3+, which may be challenging on ARM/RISC-V SBCs.
|
||||
- **Tip for Pi4 and Pi5 Users**: Set `MESA_GL_VERSION_OVERRIDE=3.2` with `BOX64_DYNAREC_STRONGMEM=1` to prevent freezes and enable strong memory mode.
|
||||
- **Using Panfrost**: For better compatibility on ARM, enable `PAN_MESA_DEBUG=gl3` to force higher OpenGL profiles. This can help if a game starts but quits unexpectedly before showing any content.
|
||||
|
||||
### GTK Programs
|
||||
|
||||
Box64 wraps GTK libraries, supporting both gtk2 and gtk3.
|
||||
|
||||
### Steam
|
||||
|
||||
Steam requires Box86 due to its 32-bit client app, but uses 64-bit local server binaries. Systems with less than 6GB RAM may need a swap file for optimal performance.
|
||||
|
||||
### Wine
|
||||
|
||||
Box64 supports Wine64 and Proton. For 32-bit components, Box86 is required. Systems with both Box64 and Box86 can run 32- and 64-bit Windows programs.
|
||||
|
||||
**Note**: You can use Wine WOW64 build to run x86 Windows programs in Box64-only environments, this is still experimental, but it works in most cases.
|
||||
|
||||
### Vulkan
|
||||
|
||||
Box64 wraps Vulkan libraries.
|
||||
|
||||
----
|
||||
|
||||
Box64 lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux systems, like ARM (host system needs to be 64bit little-endian).
|
||||
|
||||
You can find many more Box64 video on Youtube in 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) Channels
|
||||
|
||||
Because Box64 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 thoses bench analysis for an example [here](https://box86.org/index.php/2021/06/game-performances/).
|
||||
|
||||
Box64 integrates a DynaRec (dynamic recompiler) for the ARM64 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/).
|
||||
|
||||
Some x86 internal opcodes use parts of "Realmode X86 Emulator Library", see [x86primop.c](src/emu/x86primop.c) for copyright details
|
||||
|
||||
<img src="Box64Icon.png" width="96" height="96">
|
||||
|
||||
Logo and Icon made by @grayduck, thanks!
|
||||
|
||||
Final word
|
||||
----
|
||||
|
||||
Usage
|
||||
----
|
||||
I want to thank everyone who has contributed to box64 development.
|
||||
There are many ways to contribute: code contribution, financial, hardware and advertisement!
|
||||
So, in no particular order, I want to thank:
|
||||
* For their major code contribution: rajdakin, mogery, ksco, xctan
|
||||
* For their major financial contribution: [Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
|
||||
* For hardware contribution and LoongArch migration: [xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
|
||||
* For their hardware contribution: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
|
||||
* For their continuous advertisements for the box64 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
|
||||
|
||||
There are a few environment variables to control the behaviour of Box64.
|
||||
And I also thank the many other people who participated even once in this project.
|
||||
|
||||
See [here](USAGE.md) for all environment variables and what they do.
|
||||
(If you use Box64 in your project, please don't forget to mention it!)
|
||||
|
||||
Note: Box64'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_memprotectionhandler` in `signals.c` if you want to trap SegFaults.
|
||||
|
||||
----
|
||||
|
||||
Compiling/Installation
|
||||
----
|
||||
> Compilation instructions can be found [here](COMPILE.md)
|
||||
|
||||
----
|
||||
|
||||
Version history
|
||||
----
|
||||
|
||||
The change log is available [here](CHANGELOG.md)
|
||||
|
||||
----
|
||||
|
||||
Final words
|
||||
----
|
||||
|
||||
(If you use Box64 in your project, please don't forget to mention Box64!)
|
||||
+108
@@ -0,0 +1,108 @@
|
||||

|
||||
|
||||
# Box64:Linux 用户空间 x86-64 模拟器(支持原生库)
|
||||
|
||||
[更新日志](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [English](https://github.com/ptitSeb/box64/blob/main/README.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Report an Error](https://github.com/ptitSeb/box64/issues/new)
|
||||
|
||||
     
|
||||
|
||||
---
|
||||
|
||||
Box64 可以在非 x86_64 Linux 主机系统(比如 Arm)上运行 x86_64 Linux 程序(比如游戏),目前仅支持 64 位小端主机系统。
|
||||
|
||||
在 YouTube 上查看 Box64 的运行效果:
|
||||
- [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)
|
||||
- [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)
|
||||
- [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
|
||||
|
||||
Box64 可以使用本机原生的系统库(libc、libm、SDL、OpenGL),有着易于集成的特性和令人惊讶的性能。如需性能基准测试,请查看[此分析](https://box86.org/index.php/2021/06/game-performances/)。
|
||||
|
||||
借助适用于 ARM64,RV64 以及 LA64 平台的 DynaRec,Box64 的速度比单独使用解释器快 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/)。
|
||||
|
||||
<img src="docs/img/Box64Icon.png" width="96" height="96" alt="Box64 Icon">
|
||||
|
||||
_Logo 由 @grayduck 制作,感谢!_
|
||||
|
||||
---
|
||||
|
||||
## 📖 使用方法
|
||||
|
||||
Box64 提供了环境变量来控制其行为。有关详细信息请参阅[使用文档](docs/USAGE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 🚀 编译和安装
|
||||
|
||||
- [编译说明](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md)
|
||||
- [安装 Wine](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 版本历史
|
||||
|
||||
请参阅[变更日志](docs/CHANGELOG.md)了解版本更新说明。
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ 平台兼容性说明
|
||||
|
||||
Box64 直接转换 x86_64 函数调用到本机原生库,因此需要主机系统上的 64 位库。对于 32 位二进制文件,请使用 Box86。
|
||||
|
||||
**注意事项**
|
||||
|
||||
1. Box32 模式正在制作中,旨在支持 Box64 上运行 32 位二进制文件,敬请期待!
|
||||
2. 某些安装程序可能会将 64 位的主机操作系统判定为 x86 导致兼容性问题。解决方法:使用假的 `uname` ,并使它在运行参数为 `-m` 时返回 `x86_64`。
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ 配置
|
||||
|
||||
Box64 的配置文件位于 `/etc/box64.box64rc` 和 `~/.box64rc`,均为 `.ini` 格式的文件。如果您不想使用默认的 `/etc/box64.box64rc` 文件,请将其复制到 `~/.box64rc` 以确保兼容性。
|
||||
|
||||
配置项的优先级:`~/.box64rc` > `/etc/box64.box64rc` > 命令行。
|
||||
|
||||
---
|
||||
|
||||
## 📄 特定平台的其他说明
|
||||
|
||||
### Unity 游戏
|
||||
- 许多 Unity 游戏需要 OpenGL 3+,这对 ARM/RISC-V SBC 来说可能具有挑战性。
|
||||
- **对 Pi4 和 Pi5 用户的提示**:设置 `MESA_GL_VERSION_OVERRIDE=3.2` 和 `BOX64_DYNAREC_STRONGMEM=1` 以防止卡死并启用强内存模式。
|
||||
- **Panfrost**:为了在 ARM 上实现更好的兼容性,启用 `PAN_MESA_DEBUG=gl3` 以强制更高的 OpenGL Profile。如果游戏可以启动但在显示任何内容之前意外退出,这个设置可能会有所帮助。
|
||||
|
||||
### GTK 程序
|
||||
|
||||
Box64 包装了 GTK 库,支持 gtk2 和 gtk3。
|
||||
|
||||
### Steam
|
||||
|
||||
由于 Steam 客户端应用是 32 位的,需要使用 Box86,但其本地服务器是 64 位的二进制文件。对于内存少于 6GB 的系统,可能需要使用交换文件以获得最佳性能。
|
||||
|
||||
### Wine
|
||||
|
||||
Box64 支持 Wine64 和 Proton。对于 32 位组件,需要 Box86。配备 Box64 和 Box86 的系统可以运行 32 位和 64 位的 Windows 程序。
|
||||
|
||||
**提示**:您可以使用 Wine WOW64 版本在仅限 Box64 的环境中运行 x86 Windows 程序,这项支持仍处于实验阶段,但在大多数情况下都可以工作。
|
||||
|
||||
### Vulkan
|
||||
|
||||
Box64 包装了 Vulkan 库。
|
||||
|
||||
----
|
||||
|
||||
结语
|
||||
----
|
||||
|
||||
我要感谢所有为 box64 开发做出贡献的人。
|
||||
贡献方式有很多种:代码贡献、财务帮助、捐赠捐赠和广告合作!
|
||||
以下感谢不分先后:
|
||||
|
||||
* 代码贡献:rajdakin, mogery, ksco, xctan
|
||||
* 财务支持:[Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
|
||||
* 硬件捐赠和 LoongArch 迁移:[xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
|
||||
* 硬件捐赠:[ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
|
||||
* 为本项目持续的宣传:salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
|
||||
|
||||
我还要感谢很多人,即使他们只参与了一次本项目。
|
||||
|
||||
(如果你的项目中使用了Box64,请不要忘记提及!)
|
||||
+117
@@ -0,0 +1,117 @@
|
||||

|
||||
|
||||
Емулятор простіра користувача x86_64 із родзинкою
|
||||
|
||||
[Дивитись журнал змін](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [English](https://github.com/ptitSeb/box64/blob/main/README.md) | [Повідомити про помилку](https://github.com/ptitSeb/box64/issues/new)
|
||||
|
||||
     
|
||||
|
||||
----
|
||||
|
||||
Box64 дозволяє запускати x86_64 Linux програми (наприклад, ігри) на системах Linux відмінних від x86_64, наприклад ARM (хост-система має мати 64-розрядний порядок редагування).
|
||||
|
||||
Ви можете знайти багато відео про Box64 в YouTube каналах [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) або [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
|
||||
|
||||
Оскільки Box64 використовує рідні версії деяких «системних» бібліотек, таких як libc, libm, SDL і OpenGL, його легко інтегрувати та використовувати з більшістю програм, а продуктивність у багатьох випадках може бути напрочуд високою. Подивіться на цей стендовий аналіз для прикладу [тут](https://box86.org/index.php/2021/06/game-performances/).
|
||||
|
||||
Box64 інтегрується з 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/).
|
||||
|
||||
Деякі внутрішні коди операцій x64 використовують частини «Бібліотеки емулятора Realmode X86», дивіться [x64primop.c](src/emu/x64primop.c) для детальної інформації про авторські права.
|
||||
|
||||
<img src="docs/img/Box64Icon.png" width="96" height="96">
|
||||
|
||||
Логотип і піктограма зроблені @grayduck, дякую!
|
||||
|
||||
----
|
||||
|
||||
Використання
|
||||
----
|
||||
|
||||
Є кілька змінних середовища для керування поведінкою Box64.
|
||||
|
||||
Дивіться [тут](docs/USAGE.md) для перегляду всіх змінних середовища та того, що вони роблять.
|
||||
|
||||
Примітка: Dynarec від Box64 використовує механізм із захистом пам’яті та обробником сигналу помилки сегментів для обробки JIT коду. Простіше кажучи, якщо ви хочете використовувати GDB для налагодження запущеної програми, яка використовує JIT-код (наприклад, mono/Unity3D), ви все одно матимете багато «звичайних» помилок сегментів. Пропонується використовувати щось на зразок `handle SIGSEGV nostop` в GDB, щоб не зупинятися на кожній помилці сегмента, і, можливо, поставити точку зупину всередині `my_memprotectionhandler` в `signals.c`, якщо ви хочете перехопити помилки сегментів.
|
||||
|
||||
----
|
||||
Компіляція/Встановлення
|
||||
----
|
||||
> Інструкцію зі складання Box64 можна знайти [тут](docs/COMPILE.md).\
|
||||
> Інструкцію з встановлення Wine для Box64 можна знайти [тут](docs/X64WINE.md).
|
||||
|
||||
----
|
||||
Історія версій/Журнал змін
|
||||
----
|
||||
|
||||
Історія версій доступна [тут](docs/CHANGELOG.md).
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо 32 бітних платформ
|
||||
----
|
||||
Оскільки Box64 працює шляхом прямого перекладу викликів функцій з x86_64 на хост-систему, хост-система (та, на якій працює Box64) повинна мати 64-розрядні бібліотеки. Box64 не містить 64-біт <-> 32-біт перекладу.
|
||||
|
||||
Також розумійте що Box64 запускатиме лише 64-розрядні двійкові Linux файли. Для 32-розрядних двійкових файлів вам потрібен Box86 (з усіма хитрощами з мультиархітектурною системою або корінними правами). Зауважте, що багато інсталяторів (на основі mojo) повертаються до "x86" при виявленні ОС ARM64, і тому намагатимуться використовувати Box86 для налаштування, навіть якщо існує версія x86_64. Ви можете зламати свій шлях за допомогою фальшивого "uname", який повертає "x86_64", коли аргумент "-m"
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо конфігурації Box64
|
||||
----
|
||||
|
||||
Обидва файли мають однаковий синтаксис і в основному є файлами ini. Розділ у квадратних дужках визначає назву процесу, а решта — встановлють змінну середовища. Подивіться [використання](USAGE.md), щоб дізнатися, які параметри можна завдати. Box64 поставляється з файлом за замовчуванням, який слід встановити для кращої стабільності. Файл знаходиться в `system/box64.box64rc` і має бути встановлен в `/etc/box64.box64rc`. Якщо з певних причин ви не хочете встановлювати цей файл у `/etc`, принаймні скопіюйте його в `~/.box64rc` або гра може не працювати належним чином. Зауважте, що пріоритетом є: `~/.bashrc` > `/etc/box64.box64rc` > командний рядок
|
||||
Таким чином, ваші налаштування в `~/.bashrc` можуть замінити налаштування з вашого командного рядка...
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо емуляції ігор Unity
|
||||
----
|
||||
|
||||
Запуск ігор Unity має працювати, але ви також повинні зауважити, що для багатьох ігор Unity3D потрібен OpenGL 3+, який може бути складно забезпечити на ARM SBC (одноплатних комп’ютерах). Крім того, багато нових ігор Unity3D (наприклад, KSP) використовують стиснуті текстури BC7, які не підтримуються багатьма інтегрованими GPU ARM.
|
||||
Підказка: на Pi4 і Pi5 використовуйте `MESA_GL_VERSION_OVERRIDE=3.2` з `BOX64_DYNAREC_STRONGMEM=1`, щоб запобігти зависанням і ввімкнути режим сильної пам’яті, і використовуйте Panfrost `PAN_MESA_DEBUG=gl3`, щоб використовувати вищий профіль, якщо гра починається, а потім завершується, перш ніж щось показати.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо програм GTK
|
||||
----
|
||||
|
||||
Бібліотеки GTK2 і GTK3 тепер використовуються в Box64.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Steam
|
||||
----
|
||||
|
||||
Зауважте, що Steam є гібридом 32-біт / 64-біт. Вам ПОТРІБЕН box86, щоб запустити Steam, оскільки клієнта є 32-розрядною двійковою програмою. Він також використовує 64-розрядні двійкові файли локального сервера, і цей процес steamwebhelper тепер є обов’язковим навіть у «малому режимі». І цей процес з’їсть багато оперативної пам’яті, таким чином машині з 6 Гб оперативної пам’яті знадобиться файл підкачки для використання Steam.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Wine
|
||||
----
|
||||
|
||||
Wine64 підтримується Box64, Proton теж. Майте на увазі, що 64-розрядний Wine також містить 32-розрядні компоненти щоб мати можливість запускати 32-розрядні програми Windows. Для 32-розрядних програм потрібен Box86, і вони не працюватимуть без нього. У системі, де присутні і працюють Box64, і Box86, 64-розрядне встановлення Wine може запускати як 32-розрядні, так і 64-розрядні програми Windows (просто використовуйте `wine` і `wine64` відповідно).
|
||||
Зауважте, що новий 32-бітний PE в 64-бітному процесі, який Wine зараз реалізує у Wine 7+ тепер підтримується, але підтримка є досить молодою тому можуть виникнути деякі проблеми.
|
||||
|
||||
----
|
||||
|
||||
Примітки щодо Vulkan
|
||||
----
|
||||
|
||||
Box64 використовує бібліотеки Vulkan, але зауважте що він тестувався з картою AMD Radeon RX550 і драйвером Freedreno, тому деякі розширення можуть бути відсутні залежно від вашої відеокарти.
|
||||
|
||||
----
|
||||
|
||||
Останнє слово
|
||||
----
|
||||
|
||||
Я хочу подякувати всім, хто зробив внесок у розвиток box64.
|
||||
Є багато способів зробити внесок: внесок коду, фінансовий внесок, апаратне забезпечення та реклама!
|
||||
Отже, без особливого порядку, я хочу подякувати:
|
||||
* За основний внесок у код: rajdakin, mogery, ksco, xctan
|
||||
* За великий фінансовий внесок: [Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
|
||||
* За апаратне забезпечення та міграцію LoongArch: [xiaoji](https://www.linuxgame.cn/), команда розробників Deepin Beijing
|
||||
* За внесок у апаратне забезпечення: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
|
||||
* За безперервну рекламу Box64: 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), ekianjo ([Boilingsteam](https://boilingsteam.com/))
|
||||
|
||||
І я також дякую багатьом іншим людям, які хоч раз брали участь у цьому проекті.
|
||||
|
||||
(Якщо ви використовуєте Box64 у своєму проекті, будь ласка, не забудьте згадати про це!)
|
||||
@@ -1,147 +0,0 @@
|
||||
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variables to control Box64 behaviour.
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_NOBANNER
|
||||
Disables Box64 printing its version and build
|
||||
* 0 : Enable printing its banner. (Default.)
|
||||
* 1 : Disable printing its banner.
|
||||
|
||||
#### BOX64_LD_LIBRARY_PATH
|
||||
Path to look for x86_64 libraries. Default is current folder and `lib` in current folder.
|
||||
Also, `/usr/lib/x86_64-linux-gnu` and `/lib/x86_64-linux-gnu` are added if they exist.
|
||||
|
||||
#### BOX64_PATH
|
||||
Path to look for x86_64 executable. Default is current folder and `bin` in current folder.
|
||||
|
||||
#### BOX64_DLSYM_ERROR
|
||||
Enables/Disables the logging of `dlsym` errors.
|
||||
* 0 : Don't log `dlsym` errors. (Default.)
|
||||
* 1 : Log dlsym errors.
|
||||
|
||||
#### BOX64_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 box64 instance
|
||||
Use `stderr` to use this instead of default `stdout`
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_TRACE_INIT
|
||||
Use BOX64_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.
|
||||
|
||||
#### BOX64_TRACE_START
|
||||
Only on builds with trace enabled.
|
||||
* NNNNNNN : Start trace only after NNNNNNNN opcode execute (number is an `uint64_t`).
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_TRACE_EMM
|
||||
Only on builds with trace enabled.
|
||||
* 0 : The EMM (i.e. XMM/x87) register will not be logged with the general and x86 registers. (Default.)
|
||||
* 1 : Dump the EMM registers.
|
||||
|
||||
#### BOX64_TRACE_COLOR
|
||||
Only on builds with trace enabled.
|
||||
* 0 : The general registers will always be the default white color. (Default.)
|
||||
* 1 : The general registers will change color in the dumps when they changed value.
|
||||
|
||||
#### BOX64_LOAD_ADDR
|
||||
Try to load at 0xXXXXXX main binary (if binary is a PIE)
|
||||
* 0xXXXXXXXX : The load address . (Only active on PIE programs.)
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_NOSIGILL
|
||||
Disable handling of SigILL (to ease debugging mainly).
|
||||
* 0 : Let x86 program set sighandler for Illegal Instruction
|
||||
* 1 : Disables the handling of SigILL
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_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.)
|
||||
|
||||
#### BOX64_DYNAREC_DUMP
|
||||
Enables/disables Box64'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.
|
||||
|
||||
#### BOX64_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.
|
||||
|
||||
#### BOX64_DYNAREC
|
||||
Enables/Disables Box64's Dynarec.
|
||||
* 0 : Disables Dynarec.
|
||||
* 1 : Enable Dynarec. (Default.)
|
||||
|
||||
#### BOX64_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).
|
||||
|
||||
#### BOX64_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)
|
||||
|
||||
#### BOX64_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
|
||||
|
||||
#### BOX64_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
|
||||
|
||||
#### BOX64_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
|
||||
|
||||
#### BOX64_ALLOWMISSINGLIBS
|
||||
Allow Box64 to continue even if a library is missing.
|
||||
* 0 : Box64 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.
|
||||
|
||||
#### BOX64_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_box64signalhandler` in is stack)
|
||||
then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`,
|
||||
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/box64` 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 ` BOX64_JITGDB=1`.
|
||||
This mode can be usefullwhen programs redirect all console output to a file (like Unity3D Games)
|
||||
@@ -0,0 +1,38 @@
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.i686.rpm,af1aba8e6fa5ccf33032d58a3acc59368c07d532293396db205fb9a4bc1241ae
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.x86_64.rpm,49c273813b4616240acdae8dae893192658c7541482f9bbb2c46dfe19b61877d
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.i686.rpm,75f808f0f5f93aceb4e477aa5f302edbed07a605a0644f0ea929d4ea609e36a0
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.x86_64.rpm,b4763ca410f8479b2775efb55ba09e6722948af7526180a56309e3e090c27010
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.i686.rpm,fe352f7d197ebdf2c92bbd6e548f9f6b7ac9e69e7a9d6c9861a6274482e79d73
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.x86_64.rpm,babe0b1385e723476a216d5f4b72453e031c3d683b19344786c2bddf7203cb04
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.i686.rpm,64cf0b0136d3f9b80b07ce2d4b8ce6a4ab86617e8ef9baf560bdfa5edef825ea
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.x86_64.rpm,16c48c504fe62f8e19cac7c6442d3e08bba487f610c2f533116dac32357cda86
|
||||
https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb,d5ae55e3a9838d12358530cd03218cc0d18127a84e9cfc73bdf79dacd40b25e4
|
||||
https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb,625e5189304d4d3bfb27cb821e257816c5ce761b1696b5da5ca4fa1035c48463
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.i686.rpm,686ac26afe2073a3607f26fd1592a8ccd9b78f6eec6e872528634b43c4e04dd7
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.x86_64.rpm,9a2bdc6807b22ffb6294b30dcc13e20198abe5facaeefcf1bfacec3e1013e3c2
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.i686.rpm,d9c44bb34c990fdcc6987feefacfc9e1e7997ca25f1e0a59c9adc9c16f2266d1
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.x86_64.rpm,d0b867203384942985c3c4ad6fc9ec0000fcc9965408451a6cdef8df06a3833c
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.i686.rpm,4458e2d416b5e6714ec664c4f88791eee7d1e707026a5854d948a6159911465b
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.x86_64.rpm,c3ff43237c05258ee0dd77c28540fc8d0d824f1567b115ddfd555b78d2ee0e7a
|
||||
https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-32bit-3.0.3-21-1-x86_64.eopkg,5624990281f6520026aa2252c711f02d4916099aeac63accc83bd2135b9d3220
|
||||
https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-3.0.3-21-1-x86_64.eopkg,c92f19d446b4c2450306f13b1a908f2552400da09301996fe349fee243d964d2
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.i686.rpm,9e4ff6fa0251c5357ae8f648b3e396d0043d5b3f2fb28d23325f5bd592c67aee
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.x86_64.rpm,83b4b333e335654674032d1cda4d7deb328b5a409f95e3952c3dc482b684fd8f
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.i686.rpm,66bf967e84f0d8e7a0059f2b7dda33482ff5e4fe088d0e3bc86dc54e6c7c97be
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.x86_64.rpm,ebb3e927dfafa0b199e00e2bef4c10c85fc82a70c359faf9aeb599eda70bfa5e
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.i686.rpm,ec68b3def828ba442248f3cff495f42c4af3dd58f38c8daad07dfddc109d999a
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.x86_64.rpm,d00318843a50138829b470a97b8db1a00723b10bca23c16a8386d9ab670e4c64
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.i686.rpm,9cbd11277e89bd0d4a80900bee01ca71b0c582c9cb5744f5035135b2ed907c85
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.x86_64.rpm,2dd3a1ad2785df642cb03dfed6dfbeec929ff8b14e52e61272ca7e89f86ba3cd
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.i686.rpm,2155c688b516ab359d0c47be6d73e51d3c65f199ed5591f7bb7ce6d5d9799977
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.x86_64.rpm,25ab4a8ad997b450b4a34a777f5a0678eea72ca1665944a7a461ac63de4b25bf
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.i686.rpm,792600a879fbd94ce4bf249713b0cb3a166c147cfad397e8a15e6b4f01c75997
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.x86_64.rpm,d2f86fbee729a4900a433a6c52a3cb95d9b52b1d79c9e719ee3ef509813eb6d9
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.i686.rpm,e38c5185fea611330ea253db020315dd564507bf95c48a81dbe7db186ce4214b
|
||||
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.x86_64.rpm,3c340337a073975636d198a282503f32a54bf85fb5345522a2c22e530b8d6c9e
|
||||
https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.i686.rpm,13bc8758355c3ec885f414e0e86efad29a7fe82c0999cdb3754d666949c06cc5
|
||||
https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.x86_64.rpm,fb4aaa22b2e2f2fc0c451b87ac464e8746d240397d64e79f6bfd38f4e9128a5a
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.i686.rpm,e5610fe3b25cfca1616440e1a8a7489fd37b0852f182fdda87ab8e196d981970
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.x86_64.rpm,9786b6610d17aa495fb640ba6d046bf73704915b82d12e6d8339090ff4891de5
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.i686.rpm,abe4ab924b405c236eaf3fa067fed50ac66d15d0ef42c782a745788c1a9c5b91
|
||||
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.x86_64.rpm,0e1bd97e697a9fa3b4e508b945cf352b73b06e4e8218c14ac5fb912b0022c646
|
||||
|
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
extract_pkg_auto() {
|
||||
# Example x86_64 package name: libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb
|
||||
# Example x86 package name: libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb
|
||||
if echo "${1}" | grep -q -P ".deb$"; then
|
||||
echo "DEB (Debian) package detected."
|
||||
ar x "$(basename "${1}")"
|
||||
tar --extract --file data.tar*
|
||||
# Example x86_64 package name: curl-gnutls-8.1.2-44-1-x86_64.eopkg
|
||||
# Example x86 package name: curl-gnutls-32bit-8.1.2-44-1-x86_64.eopkg
|
||||
elif echo "${1}" | grep -q -P ".eopkg$"; then
|
||||
echo "EOPKG (Solus Linux) package detected."
|
||||
unzip -o "$(basename "${1}")"
|
||||
tar --extract --file install.tar.xz
|
||||
# Example x86_64 package name: bluez-libs-5.63-1.el8.x86_64.rpm
|
||||
# Example x86 package name: bluez-libs-5.63-1.el8.i686.rpm
|
||||
elif echo "${1}" | grep -q -P ".rpm$"; then
|
||||
echo "RPM (Fedora) detected."
|
||||
rpm2cpio "$(basename "${1}")" | cpio -idmv
|
||||
# Example x86_64 package name: libjpeg-turbo-3.0.1_1.x86_64.xbps
|
||||
# Example x86 package name: libjpeg-turbo-32bit-3.0.1_1.x86_64.xbps
|
||||
elif echo "${1}" | grep -q -P ".xbps$"; then
|
||||
echo "XBPS (Void Linux) package detected."
|
||||
tar --extract --file "$(basename "${1}")"
|
||||
else
|
||||
echo "Unknown package."
|
||||
echo "Unsupported package type."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
box64_dir=$(pwd)
|
||||
dir_tmp_local="$(mktemp --directory)"
|
||||
cd "${dir_tmp_local}"
|
||||
|
||||
for line in $(cat "${box64_dir}/box64-bundle-x86-libs.csv");
|
||||
do pkg_url="$(echo "${line}" | cut -d, -f1)"
|
||||
pkg_checksum_expected="$(echo "${line}" | cut -d, -f2)"
|
||||
pkg_name="$(basename "${pkg_url}")"
|
||||
curl --silent --location --remote-name "${pkg_url}"
|
||||
pkg_checksum_actual="$(sha256sum ${pkg_name} | awk '{print $1}')"
|
||||
if [[ "${pkg_checksum_expected}" -ne "${pkg_checksum_actual}" ]];
|
||||
then echo "Invalid checksum for ${pkg_name}"
|
||||
echo "Expected: ${pkg_checksum_expected}"
|
||||
echo "Actual: ${pkg_checksum_actual}"
|
||||
exit 1
|
||||
fi
|
||||
extract_pkg_auto "${pkg_name}"
|
||||
done
|
||||
|
||||
# Start preperation of bundles.
|
||||
mkdir -p \
|
||||
"${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu" \
|
||||
"${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu" \
|
||||
"${dir_tmp_local}/bundle-pkgs" \
|
||||
|
||||
# Copy Debian family libraries.
|
||||
cp --archive "${dir_tmp_local}"/usr/lib/i386-linux-gnu/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
|
||||
cp --archive "${dir_tmp_local}"/usr/lib/x86_64-linux-gnu/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
|
||||
# Copy Fedora family libraries.
|
||||
cp --archive "${dir_tmp_local}"/usr/lib/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
|
||||
cp --archive "${dir_tmp_local}"/usr/lib64/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
|
||||
# Copy Solus and Void Linux family libraries.
|
||||
cp --archive "${dir_tmp_local}"/usr/lib32/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
|
||||
|
||||
# Create "<LIBRARY_FILE>.so" symlinks.
|
||||
for dir_lib in \
|
||||
"${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu" \
|
||||
"${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
|
||||
# If two or more libraries of the same name exist, this will symlink the oldest version.
|
||||
# Pipe this into a reverse sort `| sort -r` to symlink the newest version.
|
||||
do for lib in $(ls -1 "${dir_lib}")
|
||||
# Example output: libbluetooth.so
|
||||
do lib_base="$(echo "${lib}" | cut -d. -f1,2)"
|
||||
if ! ls "${dir_lib}/${lib_base}" 2> /dev/null
|
||||
then ln -s "${lib}" "${dir_lib}/${lib_base}"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
mv "${dir_tmp_local}"/*.deb "${dir_tmp_local}/bundle-pkgs/"
|
||||
mv "${dir_tmp_local}"/*.eopkg "${dir_tmp_local}/bundle-pkgs/"
|
||||
mv "${dir_tmp_local}"/*.rpm "${dir_tmp_local}/bundle-pkgs/"
|
||||
|
||||
tar --directory "${dir_tmp_local}/bundle-libs" --create --file "${box64_dir}/box64-bundle-x86-libs.tar.gz" .
|
||||
tar --directory "${dir_tmp_local}/bundle-pkgs" --create --file "${box64_dir}/box64-bundle-x86-pkgs.tar.gz" .
|
||||
|
||||
# Clean up.
|
||||
cd -
|
||||
rm -r -f "${dir_tmp_local}"
|
||||
Vendored
+248
@@ -0,0 +1,248 @@
|
||||
box64 (0.3.4) unstable; urgency=low
|
||||
|
||||
* This version is Faster and more compatible
|
||||
* => The RV64 backend got faster and more stable, with lots of RVV 1.0 / xThreadVector support to emulate SSE/SSE2+ opcode (no AVX yet)
|
||||
* => On ARM64, Box64 now support more DRM types than before.
|
||||
* => BOX32 can run steam now. At least on ARM64 backend, it's still not working on RV64 and LA64 for now.
|
||||
* Please check CHAGELOG.md for more details
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 10 Mar 2025 10:30:33 -0100
|
||||
|
||||
box64 (0.3.2) unstable; urgency=low
|
||||
|
||||
* Introduced Box32 to run 32bits apps on 64bits OS
|
||||
* => Box32 is a build option for Box64, and is disabled by default
|
||||
* => Optionnal binfmt integration available for Box32
|
||||
* => Wrapped some basics libs, including graphics and sounds so a few games already works
|
||||
* => Work In Progress, many issues remain to be fixed, but some Linux games are playable
|
||||
* Introduced Native Flags. Can be controled with BOX64_DYNAREC_NATIVEFLAGS, but enabled by default
|
||||
* => Available on the 3 Dynarec backend, with different implementations
|
||||
* => ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
|
||||
* +> Can lead to large speedup on certain cases
|
||||
* Improved Strong Memory Model emulation, with better default options and a more efficiant emulation
|
||||
* Dynarec: RV64: using RVV (and XThreadVector) to implement SSEx opcodes, with some massive speedup when used!
|
||||
* Some bugfix and improvment in the Signal handler and internal memory tracking
|
||||
* Improvment to TRAP signal generation and Handling
|
||||
* Improved CPUID opcodes again, and the various virtual file in /proc that represent those data
|
||||
* Improved some x87 operations, like long double handling and infinity comparisons...
|
||||
* Dynarec: ARM64 fixes to a few opcodes
|
||||
* Dynarec: RV64 fixes to many opcodes
|
||||
* Dynarec: LA64 fixes to a few opcodes
|
||||
* Dynarec: RV64 fixes and improvments on LOCK prefixes opcodes
|
||||
* Dynarec: Many optimisation on some individual opcodes, an all 3 backends
|
||||
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too
|
||||
* WREPPING: New wrapperhelper to help coding new wrapping & fixing/enhancing existing one
|
||||
* ElfLoader: Improved object fetching
|
||||
* New build profile for SD865 and ORYON
|
||||
* Changed the installation folder of x86 libs to avoid conflict with linux distro
|
||||
* Added a few syscalls
|
||||
* Some more Vulkan extensions wrapped
|
||||
* More work on build system, and github CI (generating WCP archive), with some fixes on the Android version (still not 100% operational)
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 6 Dec 2024 10:30:33 -0100
|
||||
|
||||
box64 (0.3.0) unstable; urgency=low
|
||||
|
||||
* AVX and AVX2 implemented, along with BMI1, BMI2, ADX, FMA, F16C and RDANDR extension!
|
||||
* Introduced BOX64_AVX env. var. to enable/disable AVX extension:
|
||||
* => BOX64_AVX=1 enable AVX, BMI1, F16C and VAES extension
|
||||
* => BOX64_AVX=2 also enable AVX2, BMI2, FMA, ADX,VPCLMULQDQ and RDRAND
|
||||
* Dynarec: Implemented most AVX/AVX2 and friends in ARM64 Dynarec (using only NEON, so available on all ARM64 CPU)
|
||||
* => ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
|
||||
* Improved CPUID opcodes, adding a few leaf, fixing same. Returnning an Haswell type of CPU now (was Pentium IV before)
|
||||
* Dynarec: Small optim in the emit_pf helper, on all 3 backends
|
||||
* Dynarec: ARM64 some fixes to a few opcodes
|
||||
* Dynarec: LA64 many new opcodes added, and fixes.
|
||||
* Dynarec: RV64 some new opcodes added, many fixes.
|
||||
* Dynarec: RV64 Adding some infrastructure to use RVV (if available) for SIMD emulation.
|
||||
* Dynarec: Many small changes and fixes around handling of x87, registers and internal jump.
|
||||
* WRAPPING: Added a workaround on SDL_GetThreadID to fix a race condition that was happening mostly on LA64 and broke many SDL games
|
||||
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too (including a nasty error on some rare libGL functions)
|
||||
* WRAPPING: Wayland is now supported. Wine-wayland at least works now
|
||||
* Dynarec: LA64 improved LOCK CMPXCHG handling, and better 16Byte LOCK handling too (fixes many Unity3D games)
|
||||
* Dynarec: RV64 improved LOCK CMPXCHG handling
|
||||
* COSIM: Many fixes and improvment, to make BOX64_DYNAREC_TEST more usable
|
||||
* Detect when a Wine program use UnityPlayer.dll to atumaticaly use BOX64_DYNAREC_STRONGMEM=1 (unless it's already set), so more games just work
|
||||
* ElfLoader: Added a new type of relocation
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 9 Jul 2024 10:30:33 -0100
|
||||
|
||||
box64 (0.2.8) unstable; urgency=low
|
||||
|
||||
* Wrapping: More libs and function wrapping (gtk3, vulkan...)
|
||||
* Reworked X11 Callback handling, for better stability
|
||||
* Reworked exit and the load/unload of libs and symbol resolution
|
||||
* Some more profiles in box64rc
|
||||
* Better way to rename executable (including wine ones) so driver like mesa can apply the correct profile
|
||||
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
|
||||
* Improved memory tracking and managment. Also introduce BOX64_MMAP32 to force 32bits compatible mmap for external libs (like mesa)
|
||||
* => Allow Vulkan drvier on Wine/WOW64 games to allocate 32bits compatible memory, allowing dxvk on 32bits.
|
||||
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
|
||||
* Lots of improvments in x87 handling (virtual stack, rounding, ffree, etc.)
|
||||
* => should improve games stability
|
||||
* Dynarec: ARM64 some opcodes optimisation, especialy shift and rotation ones
|
||||
* Dynarec: RV64 lots of opcoded added.
|
||||
* => Some games on linux now have a good speed. Game on Wine are still a bit slow, and dxvk still have issues
|
||||
* Dynarec: Added Loogarch backend! Note that Loongarch are 16K pagesize platform by default.
|
||||
* => Linux games are running, and with good speed, especialy on 3A6000 platforms. Games on Wine are not working yet due to 16k pagesize limitation
|
||||
* Dynarec: Better handling of large block in the dynarec
|
||||
* Dynarec: Lots of improvments and fixes to BOX86_DYNAREC_CALLRET optimisation.
|
||||
* => It can be used on more software now, and combine with BOX64_DYNAREC_BOGBLOCKS 2 or 3 can gives some good speed boosts.
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 31 May 2024 17:30:33 -0100
|
||||
|
||||
box64 (0.2.6) unstable; urgency=low
|
||||
|
||||
* X64Libs: Updated libstdc++ & libgcc_s
|
||||
* X64Libs: Use x86_64 vrsion of libunwind (it's needed by wine)
|
||||
* Dynarec: More opcodes on ARM64 & RV64
|
||||
* Dynarec: Fixed some flags propagation issues inside blocks
|
||||
* Dynarec: Improved Strong Memory Model emulation, introducing a 3rd level
|
||||
* Dynarec: ARM64: reworked shift and bit opcodes flags handling
|
||||
* Dynarec: RV64: Many fixes, making Wow64 apps running
|
||||
* Dynarec: ARM64: Added support for SSE4.2 (with CRC32 if supported by CPU)
|
||||
* Dynarec: ARM64: Added support for SHA (with hardware support if CPU allows it)
|
||||
* Dynarec: ARM64: The CALLRET optimisation has been improved and is now default
|
||||
* CPU: Remoworked how INT, priviliged opcodes and teh Trace flags works
|
||||
* CPU: Added full support for SSE4.2
|
||||
* CPU: Added full support for SHA extension
|
||||
* ElfLoader: rework how elf memory is handled
|
||||
* Emulation: Added some more syscalls
|
||||
* Emulation: Better handling of Signal (also handling SIGMAX correctly)
|
||||
* Emulation: Better support for POKEUSER/PEEKUSER (helps Windows Unity games)
|
||||
* Wrapping: More libs and some fixes in function wrapping (gtk3, vulkan...)
|
||||
* Wrapping: Removed faked libunwind wrapping
|
||||
* Hardware: Added more profile, with support ADLink Ampere Altra, Qualcomm 8Gen3, and Pi5 machines
|
||||
* OS: Added profile to build for Android and Termux.
|
||||
* OS: New option to use mold for a high speed link
|
||||
* => More hadware support, more functions wrapped for an improve compatibity
|
||||
* => More CPU extension, with ARM64 hardware support when possible, and improved CALLRET optimisation for an improved speed of emulation
|
||||
* => Some work also to reduce the memory footprint
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 15 Dec 2023 17:30:33 -0100
|
||||
|
||||
box64 (0.2.4) unstable; urgency=low
|
||||
|
||||
* Added Dynarec for RISC-V
|
||||
* Added partial 32 bits support (WoW64 works)
|
||||
* Changed cpuid to display box64
|
||||
* Fixed steam, again
|
||||
* Improved hacked version for overridden malloc/free functions
|
||||
* More wrapped libs
|
||||
* More wrapped functions and syscalls
|
||||
* Reduced memory footprint
|
||||
* Added support for the BIND_NOW flags in ELF files
|
||||
* Added RTLD_NOLOAD support
|
||||
* Fixed some typos and general cleanup, again
|
||||
* Added a cosimulation mode (to compare the behaviour of the dynarec with the interpreter)
|
||||
* Added FASTNAN/FASTROUND handling for more opcodes
|
||||
* Better float/double/long double handling
|
||||
* Better dlopen/dlclose handling
|
||||
* More games in the rc file
|
||||
* Added BOX64_DYNAREC_MISSING to show only missing opcode, independantly of the log level
|
||||
* Added BOX64_RESERVE_HIGH to reserve addresses above 47bits
|
||||
* Improved multitreading support
|
||||
* Ukrainian translation of the README
|
||||
* => Dynarec now support RISC-V, large speedup on RISC-V 64, were games are now playable (like Stardew Valley on a Vision Five 2)
|
||||
* => Improved compatibility with more fixes in elf handling, more wrapped libs and functiond, more fixed opcodes and refined profile
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 10 Mar 2023 10:20:33 -0500
|
||||
|
||||
box64 (0.2.2) unstable; urgency=low
|
||||
|
||||
* Added a hacked version for overridden malloc/free functions, enabling libcef (and derivative) to work.
|
||||
* Added rcfile handling: box64 now read "/etc/box64.box64rc" and "~/.box64rc" and apply per process parameters
|
||||
* Added BOX64_DYNAREC_CALLRET to optimized CALL/RET opcode using semi-direct native CALL/RET (get more than 10% speedup)
|
||||
* Added BOX64_DYNAREC_FORWARD to allow bigger Dynarec block to be build (can get more then 30% of Speedup!)
|
||||
* Improved memory protection tracking and signal handling, again
|
||||
* Simplified mutex handling (faster, cleaner)
|
||||
* Reduce memory used by the memory tracking (memory almost divide by 4 is some critical use case)
|
||||
* Added d3dadaptor9 wrapping
|
||||
* More wrapped libs (especially on the gtk familly)
|
||||
* Improved/fixed some Syscall handling
|
||||
* Refactored Strong Memory Model emulation (faster and more accurate)
|
||||
* Added some more opcode to ARM64 Dynarec, and fixed some other
|
||||
* Some fixes to flags handling in the Dynarec on some special cases
|
||||
* Refactor library loading/unloading, with refcount.
|
||||
* Some special cases fixes for dlopen (fixes deadcells, maybe others too)
|
||||
* Improved mmap mapping, espcially with MAP_32BITS flag
|
||||
* More wrapped functions and syscalls
|
||||
* Lots of improvment in the Rounding of float & double (Dynarec and Interpreter), 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)
|
||||
* More support on the RV64 port
|
||||
* More support to build under musl environment
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 10 Mar 2023 10:20:33 -0500
|
||||
|
||||
box64 (0.2.0) unstable; urgency=low
|
||||
|
||||
* Wrapped more vulkan function, dxvk 2.0 now works
|
||||
* Added support for overridden malloc/free functions
|
||||
* Refactor Dynarec memory management, reducing memory footprint (from 20% to 40% of Dynarec size)
|
||||
* Improved elf loader
|
||||
* Improved dlsym handling with RTLD_NEXT
|
||||
* Added BOX64_DYNAREC_SAFEFLAGS to allow finetuning Dynarec generated code handling of flags accross function calls and returns.
|
||||
* Added BOX64_BASH to setup x86_64 bash binary, so shell script can be run in x86_64 world
|
||||
* Added BOX64_ROLLING_LOG to have details log only on crash
|
||||
* Work on alignment for some of pthread structures
|
||||
* More wrapped libraries in the gtk family
|
||||
* Some fixes on the Dynarec x87 code (fixing a bunch of games like ut2004 or Piczle Puzzle)
|
||||
* Improved TLS Size handling (Unity3D games now works)
|
||||
* More PageSize Compile options
|
||||
* Improved execv family of function to have better box64 integration
|
||||
* Added support for wrapped libfuse so AppImage works
|
||||
* Adjusted the binfmt integration so AppImage are automaticaly picked
|
||||
* Improved FAudio, SDL2, GL (and more) wrapping
|
||||
* More wrapped libs, like libEGL.so, to helps emulated Qt4/5 libs to load
|
||||
* Improved Signal Handling and memory protection traking
|
||||
* Some signature fixes to some wrapped functions (in libc)
|
||||
* Added more syscalls
|
||||
* Added a lot of new opcodes to the ARM64 Dynarec
|
||||
* docs: add instructions for Debian-based Linux by @ryanfortner in #306
|
||||
* Fix typos and arch type string by @archanox in #321
|
||||
* Fix grammar by @Jai-JAP in #326
|
||||
* Enable 64k page size by @martinmanyhats in #334
|
||||
* Align address when call mprotect by @wannacu in #336
|
||||
* Add wrapped functions needed for 'ls -l'. by @stiltr in #294
|
||||
* add 18.04 tegra X1 github actions by @theofficialgman in #345
|
||||
* change order of matrix (to preview better under checkmark dropdown by @theofficialgman in #346
|
||||
* Backport SDL_DYNAPI_entry wrapper from box86. by @JohnnyonFlame in #374
|
||||
* Add SW64 base support by @wannacu in #382
|
||||
* fix overzealous replace in wrappers pathnames by @NobodyNada in #415
|
||||
* Create X64WINE.md by @WheezyE in #423
|
||||
* src: asm: Rename lr & fp registers to their x-equivalents by @fredldotme in #426
|
||||
* Malloc override by @ptitSeb in #437
|
||||
* Remove dynablocklist by @ptitSeb in #438
|
||||
* Fix Pkgbuilds by @Jai-JAP in #452
|
||||
|
||||
-- Sebastien Chevalier <[email protected]> Thu, 17 Nov 2022 11:20:33 -0500
|
||||
|
||||
box64 (0.1.8) unstable; urgency=low
|
||||
|
||||
* Added an option to get generated -NAN on SSE2 operation
|
||||
* Many small fixes and improvement to get SteamPlay (i.e. proton) working (along with box86)
|
||||
* Added some workaround for program calling uname to mimic x86_64 system
|
||||
* Added some granularity to mmap, 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
|
||||
* - make adding new architecture easier, by sharing as much infrastructure as possible
|
||||
* Improved elfloader
|
||||
* Improved some tests
|
||||
* Improved a bit the "Hotpage" handling and messages
|
||||
* Added more dynarec opcodes
|
||||
* A few fixes in some Dynarec opcodes
|
||||
* A bit more optimisation in some Dynarec opcodes
|
||||
* Don't quit on unsupported syscall, return -1 / ENOSYS error
|
||||
* Added some more Syscall
|
||||
* Wrapped Vulkan library. Vulkan and dxvk now supported!
|
||||
* Support building on PPC64LE (interpreter only)
|
||||
* Added support for Risc-V (interpreter only)
|
||||
|
||||
-- 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: box64
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Ryan Fortner <[email protected]>
|
||||
Build-Depends: cmake, debhelper (>=11~), python3
|
||||
Standards-Version: 4.1.4
|
||||
Homepage: https://github.com/ptitSeb/box64
|
||||
|
||||
Package: box64
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: Linux Userspace x86_64 Emulator with a twist, targeted at ARM Linux devices
|
||||
Box86 lets you run x86_64 Linux programs (such as games) on non-x86 Linux systems, like ARM (host system needs to be 64bit 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 @@
|
||||
box64: no-manual-page
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
#!/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 \
|
||||
--exclude=libmbedcrypto.so.7 \
|
||||
--exclude=libssl.so.1.1 \
|
||||
--exclude=libunwind.so.8 \
|
||||
--exclude=libmbedtls.so.14 \
|
||||
--exclude=libcrypto.so.1.1 \
|
||||
--exclude=libmbedx509.so.1 \
|
||||
--exclude=libcrypto.so.1.0.0 \
|
||||
--exclude=libssl.so.1.0.0 \
|
||||
--exclude=box64-bash
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
Bug-Database: https://github.com/ptitSeb/box64/issues
|
||||
Bug-Submit: https://github.com/ptitSeb/box64/issues/new
|
||||
Repository: https://github.com/ptitSeb/box64.git
|
||||
Repository-Browse: https://github.com/ptitSeb/box64
|
||||
Security-Contact: [email protected]
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
version=3
|
||||
@@ -0,0 +1,66 @@
|
||||
# Bundling x86 Libraries
|
||||
|
||||
The script `box64-bundle-x86-libs.sh` is provided to download, extract, and re-bundle x86_64 and x86 libraries for use with Box64/Box32 and Box86. These libraries improve Box emulation. This bundle provides a much smaller size compared to using a full root file system of an operating system.
|
||||
|
||||
## Usage
|
||||
|
||||
### Administrator
|
||||
|
||||
Install required dependencies for the bundle script.
|
||||
|
||||
- Debian
|
||||
```
|
||||
sudo apt-get update
|
||||
sudo apt-get install coreutils curl binutils rpm2cpio tar zstd
|
||||
```
|
||||
|
||||
Run `box64-bundle-x86-libs.sh`. This will create two archives:
|
||||
- `box64-bundle-x86-libs.tar.gz` = All of the extracted library files in the directory structure of `usr/lib/box64-i386-linux-gnu` and `usr/lib/box64-x86_64-linux-gnu`.
|
||||
- `box64-bundle-x86-pkgs.tar.gz` = All of the Linux distribution packages used to extract the library files. This is only created for preservation purposes and is otherwise unused.
|
||||
|
||||
Extract the library archive. Box will automatically search these paths for library files to emulate.
|
||||
|
||||
```
|
||||
sudo tar --extract --file box64-bundle-x86-libs.tar.gz --directory /
|
||||
```
|
||||
|
||||
### Developer
|
||||
|
||||
Add new packages to the `box64-bundle-x86-libs.csv` file in the format of `<PACKAGE_URL>,<SHA256_CHECKSUM>`.
|
||||
|
||||
Supported packages:
|
||||
- DEB (Debian)
|
||||
- EOPKG (Solus)
|
||||
- RPM (Fedora)
|
||||
- XBPS (Void Linux)
|
||||
|
||||
Preference of operating system packages that provide a library:
|
||||
1. RPMs from AlmaLinux 9 provide 10 years of updates.
|
||||
2. DEBs from Debian 11 provide 5 years of updates.
|
||||
3. EOPKG from Solus provide old variants of obscure 32-bit libraries.
|
||||
4. XBPS from Void Linux provide updated variants of obscure 32-bit libraries.
|
||||
5. Other (whereever a library is packaged)
|
||||
|
||||
For finding package names that contian a specific library file, use the [pkgs.org](https://pkgs.org/) website. Otherwise, use one of these package manager commands on a x86_64 Linux distribution:
|
||||
- DEB
|
||||
- `apt-file <LIBRARY_FILE>`
|
||||
- EOPKG
|
||||
- Does not support file search. Use pkgs.org instead.
|
||||
- RPM
|
||||
- `dnf provides <LIBRARY_FILE>`
|
||||
- XBPS
|
||||
- `xbps-query --repository --ownedby <LIBRARY_FILE>`
|
||||
|
||||
Once the package name is found, find the exact URL for downloading it.
|
||||
- DEB = Explore "main" and "contrib". Search for packages with the name "deb11" in it. Use the "amd64.deb" and "i386.deb" packages.
|
||||
- https://archive.debian.org/debian/pool/
|
||||
- EOPKG = Use the "`<VERSION>-<RELEASE>-x86_64.eopkg`" and "`32bit-<VERSION>-<RELEASE>-x86_64.eopkg`" packages.
|
||||
- https://cdn.getsol.us/repo/shannon/
|
||||
- RPM = Navigate to the "`<MAJOR>.<MINOR>`" version directory first. Then explore "AppStream" and "BaseOS". Use the "x86_64.rpm" and "i686.rpm" packages.
|
||||
- https://repo.almalinux.org/almalinux/
|
||||
- XBPS = There are too many files in the repository to display on a web browser. Use pkgs.org instead to find the exact URL for downloading it.
|
||||
- https://repo-default.voidlinux.org/current/
|
||||
|
||||
Download the package and then find the checksum with the `sha256sum` command.
|
||||
|
||||
Major Linux distributions such as AlmaLinux and Debian provide archives of packages. Rolling distributions such as Arch Linux, Solus, and Void Linux do not. In those cases, use the [Internet Archive](https://web.archive.org/) to archive any rolling release package used by Box by using the "Save Page Now" feature. If the error "Save Page Now browser crashed" appears, it can be safely ignored. The archive will still have been saved.
|
||||
@@ -0,0 +1,337 @@
|
||||
v0.3.4
|
||||
======
|
||||
* This version is Faster and more compatible:
|
||||
=> The RV64 backend got faster and more stable, with lots of RVV 1.0 / xThreadVector support to emulate SSE/SSE2+ opcode (no AVX yet)
|
||||
=> On ARM64, Box64 now support more DRM types than before.
|
||||
=> BOX32 can run steam now. At least on ARM64 backend, it's still not working on RV64 and LA64 for now.
|
||||
* Added support to emulate Windows Syscall (needs Proton and a 48bits address space for now)
|
||||
* Added BOX64_DYNAREC_DIRTY to have a faster (but less safe) way to handle code that write in it's current page
|
||||
* Added a few rarely used opcodes
|
||||
* Added experimental support for GDBJIT, that allow an x86/x86_64 program to be debugged on ARM/RV64/LA64 platform with x86 regs and opcode view (might generate a lot of file tho)
|
||||
* Added support for Perf tools in a similar way if GDBJIT, to have an x86 fine view of the performances
|
||||
* Reworked undefined flags for common operations, to be similar to real CPU
|
||||
* Reworked cpuid handling, adding BOX64_CPUTYPE support to select Intel/AMD emulation (no 3DNow! support on AMD for now)
|
||||
* Reworked ucontext link to be closer to the real thing (and make it more simple)
|
||||
* Improved memory traking, file descriptor backed memory map, and detect wine loaded dll
|
||||
* Introduced settings per library and dll (mostly for Dynarec)
|
||||
* Wrapper: More functions addes, and some fixes too
|
||||
* BOX32: Many fixes around pthreads wrapping
|
||||
* BOX32: More functions wrapped.
|
||||
* BOX32: More libraies wrapped.
|
||||
* BOX32: Some reworks on how high memory (higher than 32bits) is masked, and can be used for Dynarec blocks.
|
||||
* Dynarec: The usual batch of fixes, improvments and opcodes additions on all 3 supported backend
|
||||
* Dynarec: Some fixes to NativeFlags handling, both on ARM64 and RV64
|
||||
* Dynarec: Added optimized REP MOVSB (expected for default CPUTYPE=0, according to new cpuid return)
|
||||
* Dynarec: LA64: more opcoded addes, using hardware extensions like AES
|
||||
* Dynarec: RV64: More work on using RVV 1.0 and xTheadVector extension to emulate SSE/SSE2+ opcodes
|
||||
* Dynarec: RV64: Added informations on flags when building blocks, to be used when a signal happens to rebuild a x86 context more accurate
|
||||
* Dynarec: ARM64: Reworked undefined flags for common operations, to be similar to real CPU
|
||||
* Dynarec: ARM64: Added informations on flags and xmm/ymm/x87 register when building blocks, to be used when a signal happens to rebuild a x86 context 100% accurate
|
||||
* TRACE: Reworked how trace for wrapped function call is printed.
|
||||
* TRACE: Reworked logs to prefix each line with a (optionaly colored) BOX32 or BOX64
|
||||
* COSIM: Some rework on cosim to limit false negative, especialy when handling x87 operations
|
||||
* LA64: Added limited support for ABI 1.0
|
||||
* CI: github CI now also generate MiceWine .rat archive, along with Winlator .wcp archive and regular linux builds.
|
||||
* RCFile: Added many new games profiles (both for speed improvment or for compatibilty)
|
||||
|
||||
v0.3.2
|
||||
======
|
||||
* Introduced Box32 to run 32bits apps on 64bits OS
|
||||
=> Box32 is a build option for Box64, and is disabled by default
|
||||
=> Optionnal binfmt integration available for Box32
|
||||
=> Wrapped some basics libs, including graphics and sounds so a few games already works
|
||||
=> Work In Progress, many issues remain to be fixed, but some Linux games are playable
|
||||
* Introduced Native Flags. Can be controled with BOX64_DYNAREC_NATIVEFLAGS, but enabled by default
|
||||
=> Available on the 3 Dynarec backend, with different implementations
|
||||
=> ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
|
||||
+> Can lead to large speedup on certain cases
|
||||
* Improved Strong Memory Model emulation, with better default options and a more efficiant emulation
|
||||
* Dynarec: RV64: using RVV (and XThreadVector) to implement SSEx opcodes, with some massive speedup when used!
|
||||
* Some bugfix and improvment in the Signal handler and internal memory tracking
|
||||
* Improvment to TRAP signal generation and Handling
|
||||
* Improved CPUID opcodes again, and the various virtual file in /proc that represent those data
|
||||
* Improved some x87 operations, like long double handling and infinity comparisons...
|
||||
* Dynarec: ARM64 fixes to a few opcodes
|
||||
* Dynarec: RV64 fixes to many opcodes
|
||||
* Dynarec: LA64 fixes to a few opcodes
|
||||
* Dynarec: RV64 fixes and improvments on LOCK prefixes opcodes
|
||||
* Dynarec: Many optimisation on some individual opcodes, an all 3 backends
|
||||
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too
|
||||
* WREPPING: New wrapperhelper to help coding new wrapping & fixing/enhancing existing one
|
||||
* ElfLoader: Improved object fetching
|
||||
* New build profile for SD865 and ORYON
|
||||
* Changed the installation folder of x86 libs to avoid conflict with linux distro
|
||||
* Added a few syscalls
|
||||
* Some more Vulkan extensions wrapped
|
||||
* More work on build system, and github CI (generating WCP archive), with some fixes on the Android version (still not 100% operational)
|
||||
|
||||
v0.3.0
|
||||
======
|
||||
* AVX and AVX2 implemented, along with BMI1, BMI2, ADX, FMA, F16C and RDANDR extension!
|
||||
* Introduced BOX64_AVX env. var. to enable/disable AVX extension:
|
||||
=> BOX64_AVX=1 enable AVX, BMI1, F16C and VAES extension
|
||||
=> BOX64_AVX=2 also enable AVX2, BMI2, FMA, ADX,VPCLMULQDQ and RDRAND
|
||||
* Dynarec: Implemented most AVX/AVX2 and friends in ARM64 Dynarec (using only NEON, so available on all ARM64 CPU)
|
||||
=> ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
|
||||
* Improved CPUID opcodes, adding a few leaf, fixing same. Returnning an Haswell type of CPU now (was Pentium IV before)
|
||||
* Dynarec: Small optim in the emit_pf helper, on all 3 backends
|
||||
* Dynarec: ARM64 some fixes to a few opcodes
|
||||
* Dynarec: LA64 many new opcodes added, and fixes.
|
||||
* Dynarec: RV64 some new opcodes added, many fixes.
|
||||
* Dynarec: RV64 Adding some infrastructure to use RVV (if available) for SIMD emulation.
|
||||
* Dynarec: Many small changes and fixes around handling of x87, registers and internal jump.
|
||||
* WRAPPING: Added a workaround on SDL_GetThreadID to fix a race condition that was happening mostly on LA64 and broke many SDL games
|
||||
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too (including a nasty error on some rare libGL functions)
|
||||
* WRAPPING: Wayland is now supported. Wine-wayland at least works now
|
||||
* Dynarec: LA64 improved LOCK CMPXCHG handling, and better 16Byte LOCK handling too (fixes many Unity3D games)
|
||||
* Dynarec: RV64 improved LOCK CMPXCHG handling
|
||||
* COSIM: Many fixes and improvment, to make BOX64_DYNAREC_TEST more usable
|
||||
* Detect when a Wine program use UnityPlayer.dll to atumaticaly use BOX64_DYNAREC_STRONGMEM=1 (unless it's already set), so more games just work
|
||||
* ElfLoader: Added a new type of relocation
|
||||
|
||||
v0.2.8
|
||||
======
|
||||
* Wrapping: More libs and function wrapping (gtk3, vulkan...)
|
||||
* Reworked X11 Callback handling, for better stability
|
||||
* Reworked exit and the load/unload of libs and symbol resolution
|
||||
* Some more profiles in box64rc
|
||||
* Better way to rename executable (including wine ones) so driver like mesa can apply the correct profile
|
||||
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
|
||||
* Improved memory tracking and managment. Also introduce BOX64_MMAP32 to force 32bits compatible mmap for external libs (like mesa)
|
||||
=> Allow Vulkan drvier on Wine/WOW64 games to allocate 32bits compatible memory, allowing dxvk on 32bits.
|
||||
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
|
||||
* Lots of improvments in x87 handling (virtual stack, rounding, ffree, etc.)
|
||||
=> should improve games stability
|
||||
* Dynarec: ARM64 some opcodes optimisation, especialy shift and rotation ones
|
||||
* Dynarec: RV64 lots of opcoded added.
|
||||
=> Some games on linux now have a good speed. Game on Wine are still a bit slow, and dxvk still have issues
|
||||
* Dynarec: Added Loogarch backend! Note that Loongarch are 16K pagesize platform by default.
|
||||
=> Linux games are running, and with good speed, especialy on 3A6000 platforms. Games on Wine are not working yet due to 16k pagesize limitation
|
||||
* Dynarec: Better handling of large block in the dynarec
|
||||
* Dynarec: Lots of improvments and fixes to BOX86_DYNAREC_CALLRET optimisation.
|
||||
=> It can be used on more software now, and combine with BOX64_DYNAREC_BOGBLOCKS 2 or 3 can gives some good speed boosts.
|
||||
|
||||
v0.2.6
|
||||
======
|
||||
* X64Libs: Updated libstdc++ & libgcc_s
|
||||
* X64Libs: Use x86_64 vrsion of libunwind (it's needed by wine)
|
||||
* Dynarec: More opcodes on ARM64 & RV64
|
||||
* Dynarec: Fixed some flags propagation issues inside blocks
|
||||
* Dynarec: Improved Strong Memory Model emulation, introducing a 3rd level
|
||||
* Dynarec: ARM64: reworked shift and bit opcodes flags handling
|
||||
* Dynarec: RV64: Many fixes, making Wow64 apps running
|
||||
* Dynarec: ARM64: Added support for SSE4.2 (with CRC32 if supported by CPU)
|
||||
* Dynarec: ARM64: Added support for SHA (with hardware support if CPU allows it)
|
||||
* Dynarec: ARM64: The CALLRET optimisation has been improved and is now default
|
||||
* CPU: Remoworked how INT, priviliged opcodes and teh Trace flags works
|
||||
* CPU: Added full support for SSE4.2
|
||||
* CPU: Added full support for SHA extension
|
||||
* ElfLoader: rework how elf memory is handled
|
||||
* Emulation: Added some more syscalls
|
||||
* Emulation: Better handling of Signal (also handling SIGMAX correctly)
|
||||
* Emulation: Better support for POKEUSER/PEEKUSER (helps Windows Unity games)
|
||||
* Wrapping: More libs and some fixes in function wrapping (gtk3, vulkan...)
|
||||
* Wrapping: Removed faked libunwind wrapping
|
||||
* Hardware: Added more profile, with support ADLink Ampere Altra, Qualcomm 8Gen3, and Pi5 machines
|
||||
* OS: Added profile to build for Android and Termux.
|
||||
* OS: New option to use mold for a high speed link
|
||||
=> More hadware support, more functions wrapped for an improve compatibity
|
||||
=> More CPU extension, with ARM64 hardware support when possible, and improved CALLRET optimisation for an improved speed of emulation
|
||||
=> Some work also to reduce the memory footprint
|
||||
|
||||
v0.2.4
|
||||
======
|
||||
* Added Dynarec for RISC-V
|
||||
* Added partial 32 bits support (WoW64 works)
|
||||
* Changed cpuid to display box64
|
||||
* Fixed steam, again
|
||||
* Improved hacked version for overridden malloc/free functions
|
||||
* More wrapped libs
|
||||
* More wrapped functions and syscalls
|
||||
* Reduced memory footprint
|
||||
* Added support for the BIND_NOW flags in ELF files
|
||||
* Added RTLD_NOLOAD support
|
||||
* Fixed some typos and general cleanup, again
|
||||
* Added a cosimulation mode (to compare the behaviour of the dynarec with the interpreter)
|
||||
* Added FASTNAN/FASTROUND handling for more opcodes
|
||||
* Better float/double/long double handling
|
||||
* Better dlopen/dlclose handling
|
||||
* More games in the rc file
|
||||
* Added BOX64_DYNAREC_MISSING to show only missing opcode, independantly of the log level
|
||||
* Added BOX64_RESERVE_HIGH to reserve addresses above 47bits
|
||||
* Improved multitreading support
|
||||
* Ukrainian translation of the README
|
||||
=> Dynarec now support RISC-V, large speedup on RISC-V 64, were games are now playable (like Stardew Valley on a Vision Five 2)
|
||||
=> Improved compatibility with more fixes in elf handling, more wrapped libs and functiond, more fixed opcodes and refined profile
|
||||
|
||||
v0.2.2
|
||||
======
|
||||
* Added a hacked version for overridden malloc/free functions, enabling libcef (and derivative) to work.
|
||||
=> Steam Large mode and new BigPicture are working
|
||||
=> Heroic Launcher is working
|
||||
* Added rcfile handling: box64 now read `/etc/box64.box64rc` and `~/.box64rc` and apply per process parameters
|
||||
=> Every program can be finetuned, for speed or just to make them work
|
||||
* Added BOX64_DYNAREC_CALLRET to optimized CALL/RET opcode using semi-direct native CALL/RET (get more than 10% speedup)
|
||||
* Added BOX64_DYNAREC_FORWARD to allow bigger Dynarec block to be build (can get more then 30% of Speedup!)
|
||||
* Improved memory protection tracking and signal handling, again
|
||||
* Box64 now return a custom name for the CPU instal of P4, build with Box64 and the cpu name it's running on
|
||||
* Simplified mutex handling (faster, cleaner)
|
||||
* Reduce memory used by the memory tracking (memory almost divide by 4 is some critical use case)
|
||||
* Added d3dadapter9 wrapping
|
||||
=> gallium nine is now supported on box64 too
|
||||
* More wrapped libs (especially on the gtk familly)
|
||||
* Improved/fixed some Syscall handling
|
||||
* Refactored Strong Memory Model emulation (faster and more accurate)
|
||||
* Added some more opcode to ARM64 Dynarec, and fixed some other
|
||||
* Some fixes to flags handling in the Dynarec on some special cases
|
||||
* Refactor library loading/unloading, with refcount.
|
||||
* Some special cases fixes for dlopen (fixes deadcells, maybe others too)
|
||||
* Improved mmap mapping, espcially with MAP_32BITS flag
|
||||
* More wrapped functions and syscalls
|
||||
* Lots of improvment in the Rounding of float & double (Dynarec and Interpreter), 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)
|
||||
* More support on the RV64 port
|
||||
* More support to build under musl environment
|
||||
|
||||
v0.2.0
|
||||
======
|
||||
* Wrapped more vulkan function, dxvk 2.0 now works
|
||||
* Added support for overridden malloc/free functions
|
||||
* Refactor Dynarec memory management, reducing memory footprint (from 20% to 40% of Dynarec size)
|
||||
* Improved elf loader
|
||||
* Improved dlsym handling with RTLD_NEXT
|
||||
* Added BOX64_DYNAREC_SAFEFLAGS to allow finetuning Dynarec generated code handling of flags accross function calls and returns.
|
||||
* Added BOX64_BASH to setup x86_64 bash binary, so shell script can be run in x86_64 world
|
||||
* Added BOX64_ROLLING_LOG to have details log only on crash
|
||||
* Work on alignment for some of pthread structures
|
||||
* More wrapped libraries in the gtk family
|
||||
* Some fixes on the Dynarec x87 code (fixing a bunch of games like ut2004 or Piczle Puzzle)
|
||||
* Improved TLS Size handling (Unity3D games now works)
|
||||
* More PageSize Compile options
|
||||
* Improved `execv` family of function to have better box64 integration
|
||||
* Added support for wrapped libfuse so AppImage works
|
||||
* Adjusted the binfmt integration so AppImage are automaticaly picked
|
||||
* Improved FAudio, SDL2, GL (and more) wrapping
|
||||
* More wrapped libs, like libEGL.so, to helps emulated Qt4/5 libs to load
|
||||
* Improved Signal Handling and memory protection traking
|
||||
* Some signature fixes to some wrapped functions (in libc)
|
||||
* Added more syscalls
|
||||
* Added a lot of new opcodes to the ARM64 Dynarec
|
||||
=> Lot's of new games stat working, to name a few: Surviving Mars, Piczle Cross Adventure (using Proton experimental), UT2004, Obduction, Machinarium, Silicon Zero, Hacknet, Absolute Drift, Art of Rally, Dota2
|
||||
=> Some apps also runs now, like TeamSpeak 3 Client and Server or Discord
|
||||
=> The bash integration is usefull for device with no binfmt integration or for script that check the machine it's running on
|
||||
|
||||
v0.1.8
|
||||
======
|
||||
* Added an option to get generated -NAN on SSE2 operation
|
||||
* Many small fixes and improvement to get SteamPlay (i.e. proton) working (along with box86)
|
||||
* Added some workaround for program calling uname to mimic x86_64 system
|
||||
* Added some granularity to mmap, 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
|
||||
* make adding new architecture easier, by sharing as much infrastructure as possible
|
||||
* Improved elfloader
|
||||
* Improved some tests
|
||||
* Improved a bit the "Hotpage" handling and messages
|
||||
* Added more dynarec opcodes
|
||||
* A few fixes in some Dynarec opcodes
|
||||
* A bit more optimisation in some Dynarec opcodes
|
||||
* Don't quit on unsupported syscall, return -1 / ENOSYS error
|
||||
* Added some more Syscall
|
||||
* Wrapped Vulkan library. Vulkan and dxvk now supported!
|
||||
* Support building on PPC64LE (interpreter only)
|
||||
* Added support for Risc-V (interpreter only)
|
||||
|
||||
v0.1.6
|
||||
======
|
||||
* Introduce "HotPage", to temporarily disable Dynarec on a page were writing is also occuring (can help speed up C# code)
|
||||
* Some work on Dynarec to limit the number of mutex use, and also allow smaller block to be built (for JIT'd programs)
|
||||
* Introduce BOX64_DYNAREC_STRONGMEM for the (Arm) dynarec to emulate StrngMemory Model (needed by some games, like RimWorld)
|
||||
* More functions wrapped
|
||||
* Improve speed of the custom allocator used by dynarec and Hash (speedup loading)
|
||||
* Added a workaround for streamwebhelper to not load it
|
||||
* More opcodes added
|
||||
* More wrapped libraries, including gtk2
|
||||
* Added a fix for linking box64 on system using glibc 2.34+
|
||||
* Some residual fixes on thread attribute handling
|
||||
* Better handling of app that want 32bits jumps, like unity3d/mono (thanks mogery)
|
||||
* More ARM hardware option in CMake (Phytium, NX...)
|
||||
* Added loongarch64 support (interpreter only)
|
||||
* Some fixes to elfloader
|
||||
* Added a mecanism to cancel a Dynarec block construction if it triggers a segfault (instead of a crash)
|
||||
|
||||
v0.1.4
|
||||
======
|
||||
* Reworked README a bit
|
||||
* Added some more wrapped libs
|
||||
* Added some SSE4x opcodes
|
||||
* Preliminary support for VSyscall (still missing VDSO)
|
||||
* Added support for AES-NI cpu extension, also in Dynarec (and using ARM extension if present)
|
||||
* Added some syscall
|
||||
* Added some more wrapped functions
|
||||
* Improvment to the handling of longjmp inside signal handlers
|
||||
* Improved wrapper helpers (from rajdakin)
|
||||
* Some fixes to opcodes (especially C2 flags for some x87 opcodes)
|
||||
* Handling of some specific opcode as privileged instruction (instead of NOP)
|
||||
* Fixed ELF signature detection
|
||||
* Some fixes to a few env. var. handling
|
||||
|
||||
v0.1.2
|
||||
======
|
||||
* OpenSource!
|
||||
* A few more opcode added to the Interpreter and the Dynarec
|
||||
* Improved Native Function calling
|
||||
* Added some function to limit allocated memory to 47bits space (for Wine)
|
||||
* Improved and Fixed the functions to limit allocated memory to 32bits space
|
||||
* Wine is starting now, but not everything and every version works
|
||||
|
||||
v0.1.0
|
||||
======
|
||||
* Improvement to ElfLoader
|
||||
* More opcode added to the Dynarec
|
||||
* More lib wrapping
|
||||
* Some fixes to a few function signature
|
||||
* Improvement to Signal handling, and internal mutex handling
|
||||
* A few fixes to some dynarec opcodes
|
||||
* A few fixes to some interpreter opcodes
|
||||
|
||||
v0.0.8
|
||||
======
|
||||
* Improvement to SSE/x87 handling
|
||||
* More opcode added to the Dynarec
|
||||
* More lib wrapping
|
||||
|
||||
v0.0.6
|
||||
======
|
||||
* Added Dynarec for ARM64
|
||||
* Many general CPU opcode added to the Dynarec
|
||||
* Many SSEx opcodes added to the Dynarec
|
||||
* Added a few more symbols in libc
|
||||
* A few changes to the "thread once" handling
|
||||
* New Logo and Icon from @grayduck
|
||||
|
||||
v0.0.4
|
||||
======
|
||||
* Added a lot of opcodes
|
||||
* Added SDL1 and SDL2 wrapping
|
||||
* OpenGL/GLU wrapping done
|
||||
* libasound / libpulse wrapping done
|
||||
* libopenal / libalure / libalut wrapping done
|
||||
* Many X11 libs wrapped
|
||||
* Added "install" with binfmt integration
|
||||
* A few games are actualy starting now (old WorldOfGoo, Into The Breach, VVVVVV and Thimbeweed Park)
|
||||
|
||||
v0.0.2
|
||||
======
|
||||
* Using box86 as a base, implemented most planned box64 part except dynarec
|
||||
* Wrapped a few libs
|
||||
* ELF loader a bit crude, but seems working
|
||||
* Signal handling implemented
|
||||
* MMX and x87 are sharing their registers
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
Compiling/Installing
|
||||
----
|
||||
|
||||
If you don't want to compile box64 yourself and prefer to use third-party pre-build version, go to the [end of the document](#pre-build-packages) for alternatives.
|
||||
|
||||
You can also generate your own package using the [instructions below](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md#debian-packaging).
|
||||
|
||||
Additional installation steps may be necessary when copying only the box64 executable file without running make install in cross-build environments. See [Cross-compiling](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md#Cross-compiling)
|
||||
|
||||
## Per-platform compiling instructions
|
||||
|
||||
### The general approach
|
||||
|
||||
```
|
||||
git clone https://github.com/ptitSeb/box64
|
||||
cd box64
|
||||
mkdir build; cd build; cmake .. ${OPTIONS}
|
||||
make -j4
|
||||
sudo make install
|
||||
```
|
||||
If it's the first install, you also need:
|
||||
```
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
- You can use `make -j1`, `make -j2` with less jobs to prevent running out of memory
|
||||
- You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on a Linux Kernel mixed with Android, like on RK3588.
|
||||
|
||||
#### Example of generic ARM64 build for linux platforms
|
||||
|
||||
```
|
||||
git clone https://github.com/ptitSeb/box64
|
||||
cd box64
|
||||
mkdir build; cd build; cmake .. -D ARM_DYNAREC=ON -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
make -j4
|
||||
sudo make install
|
||||
sudo systemctl restart systemd-binfmt
|
||||
```
|
||||
----
|
||||
|
||||
#### for RK3399
|
||||
|
||||
On a 64bit OS:
|
||||
```
|
||||
-D RK3399=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for RK3588 / RK3588S
|
||||
|
||||
On a 64bit OS:
|
||||
```
|
||||
-D RK3588=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Raspberry Pi 3
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
If building on the Pi, you will also need a large swap (3 GB+)
|
||||
[optionally reduce GPU memory to a minimum (e.g. 16 MB) using `raspi-config`
|
||||
(and reboot) before starting the build]:
|
||||
|
||||
You can use e.g. '`make -j4`' to speed up the build, but on a Pi 3 with 1GB memory you will likely
|
||||
run out of memory at some point and need to run the build again.
|
||||
Still, this can be faster if your build is attended.
|
||||
|
||||
```
|
||||
-D RPI3ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Raspberry Pi 4
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D RPI4ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Raspberry Pi 5
|
||||
|
||||
```
|
||||
-D RPI5ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for TEGRA X1
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D TEGRAX1=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Jetson Xavier/T194
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D TEGRA_T194=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Jetson Orin/T234
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
Note: use gcc-11 or higher, older gcc doesn't know cortex-a78ae
|
||||
```
|
||||
-D TEGRA_T234=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for ODROID N2/N2+
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D ODROIDN2=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Snapdragon
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D SD845=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
-D SD888=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
Depending on how recent your Snapdragon is
|
||||
|
||||
#### for Phytium
|
||||
|
||||
On a 64bit OS:
|
||||
```
|
||||
-D PHYTIUM=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for ADLink machines
|
||||
|
||||
On a 64bit OS:
|
||||
```
|
||||
-D ADLINK=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for M1
|
||||
|
||||
Only test on Asahi with Fedora, using the default "16K page" kernel
|
||||
|
||||
```
|
||||
-D M1=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for LoongArch
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D LARCH64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for RISC-V
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D RV64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for PowerPC 64 LE
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D PPC64LE=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for LX2160A
|
||||
|
||||
On a 64bit OS:
|
||||
|
||||
```
|
||||
-D LX2160A=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for Termux
|
||||
|
||||
You must have ARM64 machine to build box64.
|
||||
|
||||
##### in CHRoot/PRoot
|
||||
|
||||
```
|
||||
-D ARM64=1 -DCMAKE_C_COMPILER=gcc -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
##### in Termux (Native)
|
||||
|
||||
Note: Box64 in native termux is experimental and won't run linux binaries!
|
||||
|
||||
You also need `libandroid-sysv-semaphore` and `libandroid-spawn` libraries.
|
||||
|
||||
```
|
||||
-D TERMUX=1 -DCMAKE_C_COMPILER=clang -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
#### for x86_64 Linux
|
||||
|
||||
```
|
||||
-D LD80BITS=1 -D NOALIGN=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
If you encounter some linking errors, try using `NOLOADADDR=ON` (`cmake -D NOLOADADDR=ON; make -j$(nproc)`).
|
||||
|
||||
----
|
||||
|
||||
### Use ccmake
|
||||
|
||||
Alternatively, you can **use the curses-based ccmake (or any other gui frontend for cmake)** to select which platform to use interactively.
|
||||
|
||||
### Customize your build
|
||||
|
||||
#### Use ccache when present
|
||||
|
||||
Add `-DUSE_CCACHE=1` option if you have ccache and plan to touch the sources.
|
||||
|
||||
#### Include debug information
|
||||
|
||||
Add `-DCMAKE_BUILD_TYPE=RelWithDebInfo` option for an optimized build with debug information embedded. That way, if you want to debug a crash or analyze performance, you have symbols.
|
||||
|
||||
#### Build with trace
|
||||
|
||||
To have a trace enabled build (***the interpreter will be slightly slower***), add `-DHAVE_TRACE=1`. 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 get x86 trace. Use version v3.2.1, as later versions have changed the API and no longer work with box64.
|
||||
|
||||
#### Build ARM DynaRec
|
||||
|
||||
Add `-DARM_DYNAREC=1` option to enable DynaRec on ARM machines.
|
||||
|
||||
#### Save memory at run time
|
||||
|
||||
You can use `-DSAVE_MEM` to have a build that will try to save some memory. For now, it only increases the jumptable from 4 levels to 5. The added granularity avoids wasting space, but adds one more read from memory when jumping between blocks.
|
||||
|
||||
#### Build outside of a git repo
|
||||
|
||||
Box64 uses git SHA1 to show last commit in version number, use `-DNOGIT=1` option when building outside of a git repo (for example, downloading a release source code zip from github).
|
||||
|
||||
#### Use faster linker
|
||||
|
||||
Add `-DWITH_MOLD=1` option when GNU ld is extremely slow. Then run `mold -run make -j4` to build (make sure [Mold](https://github.com/rui314/mold) is installed).
|
||||
|
||||
#### Build a statically linked box64
|
||||
|
||||
You can now build box64 statically linked, with `-DSTATICBUILD` to use inside of a x86_64 chroot. Note that this version of box64 will only have the minimal wrapped libs, such as libc, libm and libpthread. Other libs (like libGL or libvulkan, SDL2, etc...) will use x86_64 versions. A static build is intended to be used in a docker image, or in a headless server. It is highly experimental, but feedback is always welcome.
|
||||
|
||||
----
|
||||
|
||||
## Testing
|
||||
|
||||
A few tests are included with box64.
|
||||
|
||||
They can be launched using the `ctest` command.
|
||||
|
||||
The tests are very basic and only test some functionality for now.
|
||||
|
||||
----
|
||||
|
||||
## Debian Packaging
|
||||
|
||||
Box64 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 want in `debian/rules`.
|
||||
|
||||
## Pre-built packages
|
||||
|
||||
### Debian-based Linux
|
||||
|
||||
You can use the [Pi-Apps-Coders apt repository](https://github.com/Pi-Apps-Coders/box64-debs) to install precompiled box64 debs, updated every 24 hours.
|
||||
|
||||
```
|
||||
# check if .list file already exists
|
||||
if [ -f /etc/apt/sources.list.d/box64.list ]; then
|
||||
sudo rm -f /etc/apt/sources.list.d/box64.list || exit 1
|
||||
fi
|
||||
|
||||
# check if .sources file already exists
|
||||
if [ -f /etc/apt/sources.list.d/box64.sources ]; then
|
||||
sudo rm -f /etc/apt/sources.list.d/box64.sources || exit 1
|
||||
fi
|
||||
|
||||
# download gpg key from specified url
|
||||
if [ -f /usr/share/keyrings/box64-archive-keyring.gpg ]; then
|
||||
sudo rm -f /usr/share/keyrings/box64-archive-keyring.gpg
|
||||
fi
|
||||
sudo mkdir -p /usr/share/keyrings
|
||||
wget -qO- "https://pi-apps-coders.github.io/box64-debs/KEY.gpg" | sudo gpg --dearmor -o /usr/share/keyrings/box64-archive-keyring.gpg
|
||||
|
||||
# create .sources file
|
||||
echo "Types: deb
|
||||
URIs: https://Pi-Apps-Coders.github.io/box64-debs/debian
|
||||
Suites: ./
|
||||
Signed-By: /usr/share/keyrings/box64-archive-keyring.gpg" | sudo tee /etc/apt/sources.list.d/box64.sources >/dev/null
|
||||
|
||||
sudo apt update
|
||||
sudo apt install box64-generic-arm -y
|
||||
```
|
||||
|
||||
## Cross-compiling
|
||||
----
|
||||
### Set Up the Cross-Compiler
|
||||
For example, to compile Box64 for RISC-V on an x86 machine, you can get prebuilt GNU toolchain from the [riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain/releases)
|
||||
|
||||
### Run CMake with Cross-Compilation Options
|
||||
Follow the per-platform compilation instructions to configure the CMake options for your target architecture.
|
||||
In particular, you must specify the cross-compiler. For example:
|
||||
```
|
||||
-DCMAKE_C_COMPILER=riscv64-unknown-linux-gnu-gcc # Or whichever cross-compiler you use
|
||||
```
|
||||
|
||||
### Running tests with QEMU (optional)
|
||||
To do a quick check, run:
|
||||
```
|
||||
qemu-riscv64 -L path/to/your/riscv64/sysroot box64 --help
|
||||
```
|
||||
You can run `dirname $(find -name libc.so.6)` to determine whether sysroot is provided by the prebuilt GNU toolchain or not.
|
||||
|
||||
To run CTest-based tests under QEMU:
|
||||
```
|
||||
ctest -j$(nproc)
|
||||
```
|
||||
|
||||
### Installing on the Target Machine
|
||||
After successfully cross-compiling, copy the box64 executable to your RISC-V device. Note that simply copying the binary does not automatically install Box64’s shared libraries. Because `make install` does not run on the target during cross-compilation, libraries required for emulation may be missing.
|
||||
|
||||
To fix this, copy the shared libraries folder from the Box64 repository (`x64lib` or `x86lib`) to your target. Place them into the proper library search paths, for example:
|
||||
- `/usr/lib/box64-x86_64-linux-gnu/` (for x86_64)
|
||||
- `/usr/lib/box64-i386-linux-gnu/` (for i386)
|
||||
+695
@@ -0,0 +1,695 @@
|
||||
<!--- This file is generated by gen.py, do not edit it directly. -->
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variables to control Box64's behaviour, which will be listed below by category.
|
||||
|
||||
### Configuration files
|
||||
|
||||
In addition to environment variables, by default, Box64 also looks for 2 places for rcfile: the system-wide `/etc/box64.box64rc` and user-specific `~/.box64rc`.
|
||||
Settings priority follows this order (from highest to lowest): `~/.box64rc` > `/etc/box64.box64rc` > environment variables.
|
||||
|
||||
Example configuration:
|
||||
|
||||
```
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
```
|
||||
|
||||
This configuration will apply the specified settings application-wide to any executable named `factorio`.
|
||||
|
||||
### Advanced usage
|
||||
|
||||
1. **Wildcard Matching**
|
||||
|
||||
Asterisks (`*`) can be used for basic pattern matching in application names. For instance, `[*setup*]` will match any program containing "setup" in its name. Note this implements simple wildcard matching rather than full regex support.
|
||||
2. **Custom Configuration File**
|
||||
|
||||
The `BOX64_RCFILE` environment variable can specify an alternative configuration file instead of the default `/etc/box64.box64rc`.
|
||||
3. **Per-File Settings**
|
||||
|
||||
Sections starting with `/` apply to specific files. For example:
|
||||
```
|
||||
[/d3d9.dll]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
```
|
||||
These settings will only affect the `d3d9.dll` file. This syntax also works for **emulated** Linux libraries, e.g., `[/libstdc++.so.6]`.
|
||||
|
||||
----
|
||||
|
||||
## Libraries
|
||||
|
||||
### BOX64_ADDLIBS
|
||||
|
||||
Add extras to the needed libraries list, rarely needed.
|
||||
|
||||
* XXXX: Add library XXXX to the needed libraries list.
|
||||
* XXXX:YYYY:ZZZZ: Add library XXXX, YYYY and ZZZZ to the needed libraries list.
|
||||
|
||||
### BOX64_ALLOWMISSINGLIBS
|
||||
|
||||
Allow missing libraries to be ignored.
|
||||
|
||||
* 0: Do not allow missing libraries. [Default]
|
||||
* 1: Allow missing libraries.
|
||||
|
||||
### BOX64_EMULATED_LIBS
|
||||
|
||||
Force the use of emulated libraries.
|
||||
|
||||
* XXXX: Force the use of emulated library XXXX.
|
||||
* XXXX:YYYY:ZZZZ: Force the use of emulated libraries XXXX, YYYY and ZZZZ.
|
||||
|
||||
### BOX64_LD_LIBRARY_PATH
|
||||
|
||||
Path to look for x86_64 libraries.
|
||||
|
||||
* XXXX: Add path XXXX to the library path.
|
||||
|
||||
### BOX64_LD_PRELOAD
|
||||
|
||||
Force loading libraries with the binary.
|
||||
|
||||
* XXXX: Force the loading of library XXXX.
|
||||
* XXXX:YYYY: Force the loading of libraries XXXX and YYYY.
|
||||
|
||||
### BOX64_LIBGL
|
||||
|
||||
Set the name for libGL.
|
||||
|
||||
* libXXXX: Set the name for libGL to libXXXX.
|
||||
* /path/to/libXXXX: Set the name and path for libGL to /path/to/libXXXX, you can also use SDL_VIDEO_GL_DRIVER.
|
||||
|
||||
### BOX64_NOGTK
|
||||
|
||||
Do not load wrapped GTK libraries.
|
||||
|
||||
* 0: Load wrapped GTK libraries. [Default]
|
||||
* 1: Do not load wrapped GTK libraries.
|
||||
|
||||
### BOX64_NOPULSE
|
||||
|
||||
Do not load PulseAudio libraries (both native and x86_64).
|
||||
|
||||
* 0: Load PulseAudio libraries. [Default]
|
||||
* 1: Do not load PulseAudio libraries.
|
||||
|
||||
### BOX64_NOVULKAN
|
||||
|
||||
Do not load Vulkan libraries.
|
||||
|
||||
* 0: Load Vulkan libraries. [Default]
|
||||
* 1: Do not load Vulkan libraries, both native and x86_64.
|
||||
|
||||
### BOX64_PREFER_EMULATED
|
||||
|
||||
Prefer emulated libraries over native ones.
|
||||
|
||||
* 0: Prefer native libraries over emulated ones. [Default]
|
||||
* 1: Prefer emulated libraries over native ones.
|
||||
|
||||
### BOX64_PREFER_WRAPPED
|
||||
|
||||
Prefer wrapped libs first even if the lib is specified with absolute path.
|
||||
|
||||
* 0: Prefer libs with absolute path over wrapped ones. [Default]
|
||||
* 1: Prefer wrapped libs first even if the lib is specified with absolute path.
|
||||
|
||||
### BOX64_WRAP_EGL
|
||||
|
||||
Prefer wrapped libs for EGL and GLESv2.
|
||||
|
||||
* 0: Prefer emulated libs for EGL and GLESv2. [Default]
|
||||
* 1: Prefer wrapped libs for EGL and GLESv2.
|
||||
|
||||
## Arguments
|
||||
|
||||
### BOX64_ARGS
|
||||
|
||||
Arguments to pass to the guest program, only valid if there is no existing arguments.
|
||||
|
||||
* XXXX: Pass argument XXXX to the program.
|
||||
* XXXX YYYY ZZZZ: Pass arguments XXXX, YYYY and ZZZZ to the guest program.
|
||||
|
||||
### BOX64_CEFDISABLEGPU
|
||||
|
||||
Add -cef-disable-gpu argument to the guest program.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Add -cef-disable-gpu argument to the guest program.
|
||||
|
||||
### BOX64_CEFDISABLEGPUCOMPOSITOR
|
||||
|
||||
Add -cef-disable-gpu-compositor argument to the guest program.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Add -cef-disable-gpu-compositor argument to the guest program.
|
||||
|
||||
### BOX64_INSERT_ARGS
|
||||
|
||||
Prepend arguments to the command line.
|
||||
|
||||
* XXXX: Prepend argument XXXX to the program.
|
||||
* XXXX YYYY ZZZZ: Prepend arguments XXXX, YYYY and ZZZZ to the guest program.
|
||||
|
||||
### BOX64_INPROCESSGPU
|
||||
|
||||
Add --in-process-gpu argument to the guest program.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Add --in-process-gpu argument to the guest program.
|
||||
|
||||
### BOX64_NOSANDBOX
|
||||
|
||||
Add --no-sandbox argument to the guest program.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Add --no-sandbox argument to the guest program.
|
||||
|
||||
## Compatibility
|
||||
|
||||
### BOX64_BASH
|
||||
|
||||
Path to the bash executable.
|
||||
|
||||
* XXXX: Use bash executable at path XXXX.
|
||||
|
||||
### BOX64_CPUTYPE
|
||||
|
||||
Specify the CPU type to emulate.
|
||||
|
||||
* 0: Emulate a Intel CPU Model. [Default]
|
||||
* 1: Emulate a AMD CPU Model.
|
||||
|
||||
### BOX64_CRASHHANDLER
|
||||
|
||||
Use a dummy crash handler or not.
|
||||
|
||||
* 0: Use emulated crashhandler.so library if nedded.
|
||||
* 1: Use an internal dummy (empty) crashhandler.so library. [Default]
|
||||
|
||||
### BOX64_DYNAREC_BLEEDING_EDGE
|
||||
|
||||
Detect MonoBleedingEdge and apply conservative settings.
|
||||
|
||||
* 0: Do not detect MonoBleedingEdge.
|
||||
* 1: Detect MonoBleedingEdge and apply BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_STRONGMEM=1 when detected. [Default]
|
||||
|
||||
### BOX64_DYNAREC_DIV0
|
||||
|
||||
Enable or disable the generation of division-by-zero exception.
|
||||
|
||||
* 0: Do not generate thr division-by-zero exception. [Default]
|
||||
* 1: Generate the division-by-zero exception.
|
||||
|
||||
### BOX64_DYNAREC_TBB
|
||||
|
||||
Enable or disable libtbb detection.
|
||||
|
||||
* 0: Do not detect libtbb.
|
||||
* 1: Detect libtbb and apply conservative settings. [Default]
|
||||
|
||||
### BOX64_DYNAREC_X87DOUBLE
|
||||
|
||||
Force the use of float/double for x87 emulation.
|
||||
|
||||
* 0: Try to use float when possible for x87 emulation. [Default]
|
||||
* 1: Only use Double for x87 emulation.
|
||||
|
||||
### BOX64_EXIT
|
||||
|
||||
Just exit, do not try to run the program.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Just exit.
|
||||
|
||||
### BOX64_FIX_64BIT_INODES
|
||||
|
||||
Fix 64bit inodes.
|
||||
|
||||
* 0: Do not fix 64bit inodes. [Default]
|
||||
* 1: Fix 64bit inodes.
|
||||
|
||||
### BOX64_IGNOREINT3
|
||||
|
||||
Ignore INT3 instructions.
|
||||
|
||||
* 0: Trigger a TRAP signal if a handler is present. [Default]
|
||||
* 1: Skip the opcode silently.
|
||||
|
||||
### BOX64_JVM
|
||||
|
||||
Detect libjvm and apply conservative settings.
|
||||
|
||||
* 0: Does nothing.
|
||||
* 1: Detect libjvm, and apply BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_STRONGMEM=1 BOX64_SSE42=0 when detected. [Default]
|
||||
|
||||
### BOX64_LIBCEF
|
||||
|
||||
Detect libcef and apply BOX64_MALLOC_HACK settings.
|
||||
|
||||
* 0: Does nothing.
|
||||
* 1: Detect libcef, and apply BOX64_MALLOC_HACK=2 if detected. [Default]
|
||||
|
||||
### BOX64_MALLOC_HACK
|
||||
|
||||
Behaviour when hooking malloc operators.
|
||||
|
||||
* 0: Don't allow malloc operator to be redirected, rewriting code to use regular function. [Default]
|
||||
* 1: Allow malloc operator to be redirected.
|
||||
* 2: Like 0, but track special mmap/free (some redirected functions are inlined and cannot be redirected).
|
||||
|
||||
### BOX64_MAXCPU
|
||||
|
||||
Maximum CPU cores exposed.
|
||||
|
||||
* 0: Use the actual number of CPU cores. [Default]
|
||||
* XXXX: Use XXXX CPU cores.
|
||||
|
||||
### BOX64_NORCFILES
|
||||
|
||||
Do not load any rc files.
|
||||
|
||||
* 0: Load rc files. [Default]
|
||||
* 1: Do not load any rc files.
|
||||
|
||||
### BOX64_PATH
|
||||
|
||||
Path to look for x86_64 binaries.
|
||||
|
||||
* XXXX: Add path XXXX to the binary path.
|
||||
|
||||
### BOX64_RCFILE
|
||||
|
||||
Path to the rc file to load.
|
||||
|
||||
* XXXX: Load the rc file XXXX, default rc files will not be loaded.
|
||||
|
||||
### BOX64_RESERVE_HIGH
|
||||
|
||||
Reserve high memory area for the program, always enabled on Box32.
|
||||
|
||||
* 0: Do not reserve high memory area for the program. [Default]
|
||||
* 1: Reserve high memory area for the program.
|
||||
|
||||
### BOX64_SDL2_JGUID
|
||||
|
||||
Use a workaround for SDL_GetJoystickGUIDInfo function for wrapped SDL2.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Use a workaround for SDL_GetJoystickGUIDInfo function for wrapped SDL2.
|
||||
|
||||
### BOX64_SHAEXT
|
||||
|
||||
Expose SHAEXT (a.k.a. SHA_NI) capabilities.
|
||||
|
||||
* 0: Do not expose SHAEXT capabilities.
|
||||
* 1: Expose SHAEXT capabilities. [Default]
|
||||
|
||||
### BOX64_SSE_FLUSHTO0
|
||||
|
||||
Behaviour of SSE Flush to 0 flags.
|
||||
|
||||
* 0: Just track the flag. [Default]
|
||||
* 1: Apply SSE Flush to 0 flag directly.
|
||||
|
||||
### BOX64_SSE42
|
||||
|
||||
Expose SSE4.2 capabilities.
|
||||
|
||||
* 0: Do not expose SSE4.2 capabilities.
|
||||
* 1: Expose SSE4.2 capabilities. [Default]
|
||||
|
||||
### BOX64_SYNC_ROUNDING
|
||||
|
||||
Synchronize rounding mode between x86 and native.
|
||||
|
||||
* 0: Do not synchronize rounding mode. [Default]
|
||||
* 1: Synchronize rounding mode between x86 and native.
|
||||
|
||||
### BOX64_UNITYPLAYER
|
||||
|
||||
Detect UnityPlayer and apply conservative settings.
|
||||
|
||||
* 0: Does nothing.
|
||||
* 1: Detect UnityPlayer, and apply BOX64_DYNAREC_STRONGMEM=1 when detected. [Default]
|
||||
|
||||
### BOX64_X11GLX
|
||||
|
||||
Force Xorg GLX extension to be present.
|
||||
|
||||
* 0: Do not force Xorg GLX extension to be present. [Default]
|
||||
* 1: Require Xorg GLX extension when using XQueryExtension.
|
||||
|
||||
### BOX64_X11SYNC
|
||||
|
||||
Force synchronized operation on X11 display.
|
||||
|
||||
* 0: Do not force synchronized operation on X11 display. [Default]
|
||||
* 1: Force synchronized operation on X11 display.
|
||||
|
||||
### BOX64_X11THREADS
|
||||
|
||||
Call XInitThreads when loading X11. This is mostly for old Loki games with the Loki_Compat library.
|
||||
|
||||
* 0: Do not call XInitThreads. [Default]
|
||||
* 1: Call XInitThreads as soon as libX11 is loaded.
|
||||
|
||||
### BOX64_X87_NO80BITS
|
||||
|
||||
Behavoiur of x87 80bits long double.
|
||||
|
||||
* 0: Try to handle 80bits long double as precise as possible. [Default]
|
||||
* 1: Use 64bits double for x87.
|
||||
|
||||
## Debugging
|
||||
|
||||
### BOX64_DLSYM_ERROR
|
||||
|
||||
Enable or disable the logging of dlsym errors.
|
||||
|
||||
* 0: Disable the logging of dlsym errors. [Default]
|
||||
* 1: Enable the logging of dlsym errors.
|
||||
|
||||
### BOX64_DUMP
|
||||
|
||||
Dump elfloader debug information.
|
||||
|
||||
* 0: Do not dump elfloader debug information. [Default]
|
||||
* 1: Dump elfloader debug information.
|
||||
|
||||
### BOX64_DYNAREC_DUMP
|
||||
|
||||
Enable DynaRec dump.
|
||||
|
||||
* 0: Do not dump DynaRec blocks. [Default]
|
||||
* 1: Dump DynaRec blocks.
|
||||
* 2: Dump DynaRec blocks with some colors.
|
||||
|
||||
### BOX64_DYNAREC_GDBJIT
|
||||
|
||||
The GDBJIT debugging support, only available on build with `-DGDBJIT=ON`, enable it with gdb command: jit-reader-load /usr/local/lib/libbox64gdbjitreader.so.
|
||||
|
||||
* 0: Dynarec will not generate GDBJIT debuginfo. [Default]
|
||||
* 1: Dynarec will generate GDBJIT debuginfo.
|
||||
* 2: Dynarec will generate detailed GDBJIT debuginfo with internal state.
|
||||
|
||||
### BOX64_DYNAREC_LOG
|
||||
|
||||
Disable or enable DynaRec logs.
|
||||
|
||||
* 0: Disable DynaRec logs. [Default]
|
||||
* 1: Enable minimal DynaRec logs.
|
||||
* 2: Enable debug level DynaRec logs.
|
||||
* 3: Enable verbose level DynaRec logs.
|
||||
|
||||
### BOX64_DYNAREC_MISSING
|
||||
|
||||
Print missing opcodes.
|
||||
|
||||
* 0: Do not print the missing opcode. [Default]
|
||||
* 1: Print missing opcodes.
|
||||
* 2: Print the fallback to scalar opcodes, only valid on RISC-V.
|
||||
|
||||
### BOX64_DYNAREC_PERFMAP
|
||||
|
||||
Generate map file for Linux perf tool.
|
||||
|
||||
* 0: Dynarec will not generate perf map. [Default]
|
||||
* 1: Dynarec will generate perf map.
|
||||
|
||||
### BOX64_DYNAREC_TEST
|
||||
|
||||
Enable DynaRec execution comparison with the interpreter, very slow, only for testing.
|
||||
|
||||
* 0: No comparison. [Default]
|
||||
* 1: Each opcode runs on interpreter and on Dynarec, regs and memory are compared and printed when they differ.
|
||||
* 0xXXXXXXXX-0xYYYYYYYY: Define the range where dynarec is tested (inclusive-exclusive).
|
||||
|
||||
### BOX64_DYNAREC_TRACE
|
||||
|
||||
Enable or disable DynaRec trace.
|
||||
|
||||
* 0: Do not trace DynaRec blocks. [Default]
|
||||
* 1: Trace DynaRec blocks, will slow down the program a lot and generates huge logs.
|
||||
|
||||
### BOX64_JITGDB
|
||||
|
||||
Launch gdb or not for SIGSEGV, SIGILL, and SIGBUS.
|
||||
|
||||
* 0: Just print the message when the signal is caught. [Default]
|
||||
* 1: Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in is stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.
|
||||
* 2: Launch gdbserver when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process, and go in an endless loop, waiting. Use `gdb /PATH/TO/box64` 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 `BOX64_JITGDB=1`.
|
||||
* 3: Launch lldb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting.
|
||||
|
||||
### BOX64_LOAD_ADDR
|
||||
|
||||
Set the address where the program is loaded, only active for PIE guest programs.
|
||||
|
||||
* 0xXXXXXXXX: Set the address where the program is loaded.
|
||||
|
||||
### BOX64_LOG
|
||||
|
||||
Enable or disable Box64 logs.
|
||||
|
||||
* 0: Disable Box64 logs. [Default]
|
||||
* 1: Enable minimal Box64 logs.
|
||||
* 2: Enable debug level Box64 logs.
|
||||
* 3: Enable verbose level Box64 logs.
|
||||
|
||||
### BOX64_NOBANNER
|
||||
|
||||
Disable the Box64 banner.
|
||||
|
||||
* 0: Show the Box64 banner. [Default]
|
||||
* 1: Do not show the Box64 banner.
|
||||
|
||||
### BOX64_NOSIGSEGV
|
||||
|
||||
Disable the handling of SIGSEGV.
|
||||
|
||||
* 0: Let the x86 program set sighandler for SIGSEGV. [Default]
|
||||
* 1: Disable the handling of SIGSEGV.
|
||||
|
||||
### BOX64_NOSIGILL
|
||||
|
||||
Disable the handling of SIGILL.
|
||||
|
||||
* 0: Let the x86 program set sighandler for SIGILL. [Default]
|
||||
* 1: Disable the handling of SIGILL.
|
||||
|
||||
### BOX64_ROLLING_LOG
|
||||
|
||||
Show last few wrapped function call when a signal is caught.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Show last 16 wrapped function call when a signal is caught.
|
||||
* XXX: Show last XXX wrapped function call when a signal is caught.
|
||||
|
||||
### BOX64_SHOWBT
|
||||
|
||||
Show native and emulated backtrace when a signal is caught.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Show native and emulated backtrace when a signal is caught.
|
||||
|
||||
### BOX64_SHOWSEGV
|
||||
|
||||
Always show SIGSEGV signal detailes.
|
||||
|
||||
* 0: Does nothing. [Default]
|
||||
* 1: Always show SIGSEGV signal detailes.
|
||||
|
||||
### BOX64_TRACE_COLOR
|
||||
|
||||
Enable or disable colored trace output.
|
||||
|
||||
* 0: Disable colored trace output. [Default]
|
||||
* 1: Enable colored trace output.
|
||||
|
||||
### BOX64_TRACE_EMM
|
||||
|
||||
Enable or disable EMM (i.e. MMX) trace output.
|
||||
|
||||
* 0: Disable EMM trace output. [Default]
|
||||
* 1: Enable EMM trace output.
|
||||
|
||||
### BOX64_TRACE_FILE
|
||||
|
||||
Send all log and trace to a file instead of `stdout`.
|
||||
|
||||
* XXXX: Send all log and trace to file XXXX.
|
||||
* XXXX%pid: Send all log and trace to file XXXX with pid appended.
|
||||
* stderr: Send all log and trace to `stderr`.
|
||||
|
||||
### BOX64_TRACE_INIT
|
||||
|
||||
Same as BOX64_TRACE but starts the trace immediately.
|
||||
|
||||
* 0: Disable trace output. [Default]
|
||||
* 1: Enable trace output. Trace starts before the initialization of dependencies.
|
||||
|
||||
### BOX64_TRACE_START
|
||||
|
||||
Start trace after N opcodes executed.
|
||||
|
||||
* 0: Start trace immediately. [Default]
|
||||
* 1: Start trace after 1 opcode executed.
|
||||
* XXXX: Start trace after XXXX opcodes executed.
|
||||
|
||||
### BOX64_TRACE_XMM
|
||||
|
||||
Enable or disable XMM (i.e. SSE) trace output.
|
||||
|
||||
* 0: Disable XMM trace output. [Default]
|
||||
* 1: Enable XMM trace output.
|
||||
|
||||
### BOX64_TRACE
|
||||
|
||||
Only available on box64 build with trace. Adds trace of all instructions executed, along with a register dump.
|
||||
|
||||
* 0: Disable trace output. [Default]
|
||||
* 1: Enable trace output.
|
||||
* symbolname: Enable trace output for `symbolname` only.
|
||||
* 0xXXXXXXX-0xYYYYYYY: Enable trace output for the range of address (inclusive-exclusive).
|
||||
|
||||
## Performance
|
||||
|
||||
### BOX64_DYNAREC_ALIGNED_ATOMICS
|
||||
|
||||
Generate aligned atomics only (only available on Arm64 for now).
|
||||
|
||||
* 0: Generate unaligned atomics handling code. [Default]
|
||||
* 1: Generate aligned atomics only, which is faster and smaller code size, but will cause SIGBUS for LOCK prefixed opcodes operating on aligned data addresses.
|
||||
|
||||
### BOX64_DYNAREC_BIGBLOCK
|
||||
|
||||
Enable building bigger DynaRec code blocks for better performance.
|
||||
|
||||
* 0: Do not try to build block as big as possible, suitable for programs using lots of threads and JIT, like Unity.
|
||||
* 1: Build Dynarec block as big as possible.
|
||||
* 2: Build Dynarec block bigger, do not stop when block overlaps, but only for blocks in elf memory. [Default]
|
||||
* 3: Build Dynarec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.
|
||||
|
||||
### BOX64_DYNAREC_CALLRET
|
||||
|
||||
Optimize CALL/RET opcodes.
|
||||
|
||||
* 0: Do not optimize CALL/RET, use jump table. [Default]
|
||||
* 1: Try to optimize CALL/RET, skipping the jump table when possible.
|
||||
|
||||
### BOX64_DYNAREC_DF
|
||||
|
||||
Enable or disable the use of deferred flags.
|
||||
|
||||
* 0: Disable the use of deferred flags.
|
||||
* 1: Enable the use of deferred flags. [Default]
|
||||
|
||||
### BOX64_DYNAREC_DIRTY
|
||||
|
||||
Allow continue running a block that is unprotected and potentially dirty.
|
||||
|
||||
* 0: Do not allow continue running a block that is unprotected and potentially dirty. [Default]
|
||||
* 1: Allow continue to run a dynablock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.
|
||||
|
||||
### BOX64_DYNAREC_FASTNAN
|
||||
|
||||
Enable or disable fast NaN handling.
|
||||
|
||||
* 0: Precisely emulate the -NaN generation like on x86.
|
||||
* 1: Do not do anything special with -NAN generation, faster. [Default]
|
||||
|
||||
### BOX64_DYNAREC_FASTROUND
|
||||
|
||||
Enable or disable fast rounding.
|
||||
|
||||
* 0: Generate float/double -> int rounding and use current rounding mode for float/double computation like on x86.
|
||||
* 1: Do not do anything special with edge case rounding, faster. [Default]
|
||||
* 2: Generate float/double -> int rounding using current rounding mode for float/double computation like on x86, but use fast int -> float/double conversion.
|
||||
|
||||
### BOX64_DYNAREC_FORWARD
|
||||
|
||||
Define max allowed forward value when building block.
|
||||
|
||||
* 0: No forward value. When current block ends, do not try to go further even if there are previous forward jumps.
|
||||
* 128: Allow up to 128 bytes of gap between end of the block and the next forward jump. [Default]
|
||||
* XXXX: Allow up to XXXX bytes of gap between end of the block and the next forward jump.
|
||||
|
||||
### BOX64_DYNAREC_NATIVEFLAGS
|
||||
|
||||
Enable or disable the use of native flags.
|
||||
|
||||
* 0: Do not use native flags.
|
||||
* 1: Use native flags when possible. [Default]
|
||||
|
||||
### BOX64_DYNAREC_PAUSE
|
||||
|
||||
Enable x86 PAUSE emulation, may help the performance of spinlocks.
|
||||
|
||||
* 0: Ignore x86 PAUSE instruction. [Default]
|
||||
* 1: Use YIELD to emulate x86 PAUSE instruction.
|
||||
* 2: Use WFI to emulate x86 PAUSE instruction.
|
||||
* 3: Use SEVL+WFE to emulate x86 PAUSE instruction.
|
||||
|
||||
### BOX64_DYNAREC_SAFEFLAGS
|
||||
|
||||
Behaviour of flags emulation on CALL/RET opcodes.
|
||||
|
||||
* 0: Treat CALL/RET as if it never needs any flags.
|
||||
* 1: Most of RETs will need flags, most of CALLs will not. [Default]
|
||||
* 2: All CALL/RET will need flags.
|
||||
|
||||
### BOX64_DYNAREC_STRONGMEM
|
||||
|
||||
Enable the emulation of x86 strong memory model.
|
||||
|
||||
* 0: Do not try anything special. [Default]
|
||||
* 1: Enable some memory barriers when writing to memory to emulate the x86 strong memory model in a limited way.
|
||||
* 2: All in 1, plus memory barriers on SIMD instructions.
|
||||
* 3: All in 2, plus more memory barriers on a regular basis.
|
||||
|
||||
### BOX64_DYNAREC_WAIT
|
||||
|
||||
Wait or not for the building of a DynaRec code block to be ready.
|
||||
|
||||
* 0: Do not wait and use interpreter instead, might speedup a bit on massive multithread or JIT programs.
|
||||
* 1: Wait for a DynaRec code block to be ready. [Default]
|
||||
|
||||
### BOX64_DYNAREC_WEAKBARRIER
|
||||
|
||||
Tweak the memory barriers to reduce the performance impact by strong memory emualtion.
|
||||
|
||||
* 0: Use regular safe barrier.
|
||||
* 1: Use weak barriers to have more performance boost. [Default]
|
||||
* 2: All in 1, plus disabled the last write barriers.
|
||||
|
||||
### BOX64_NODYNAREC
|
||||
|
||||
Forbid dynablock creation in the address range specified, helpful for debugging behaviour difference between Dynarec and Interpreter.
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY: Define the range where dynablock creation is forbidden (inclusive-exclusive).
|
||||
|
||||
### BOX64_RDTSC_1GHZ
|
||||
|
||||
Use hardware counter for rdtsc if available.
|
||||
|
||||
* 0: Use hardware counter for rdtsc opcode if available. [Default]
|
||||
* 1: Use hardware counter for rdtsc if and only if precision is at least 1GHz.
|
||||
|
||||
## Environment
|
||||
|
||||
### BOX64_ENV
|
||||
|
||||
Add an environment variable.
|
||||
|
||||
* XXXX=yyyy: Add environment variable XXXX with value yyyy.
|
||||
|
||||
### BOX64_ENV[1-5]
|
||||
|
||||
Add an environment variable.
|
||||
|
||||
* XXXX=yyyy: Add environment variable XXXX with value yyyy.
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
# Installing Wine64
|
||||
Running Wine64/Wine with Box64/Box86 allows x64/x86 Windows programs to run on 64-bit ARM Linux devices.
|
||||
- Box64 needs `wine-amd64` to be installed **manually** on ARM64 (aarch64) devices. This will run 64-bit Windows programs (aka x86_64).
|
||||
- Box86 needs `wine-i386` to be installed **manually** on ARM32 (armhf) devices (or on ARM64 with multiarch or chroot). This will run 32-bit Windows programs (aka x86).
|
||||
- _Note that `wine:arm64` and `wine:armhf` will not work with Box64/Box86. Your device's package manager might try to install those if you ask it to install wine._
|
||||
|
||||
See installation steps below (in the [Examples](#examples) section).
|
||||
|
||||
## Overview
|
||||
The general procedure for installing Wine64 & Wine for Box64 & Box86 is to...
|
||||
- Download all the install 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 (often `~/wine/` by default)
|
||||
- Go to `/usr/local/bin` and make symlinks or scripts that will point to your main wine binaries.
|
||||
- Boot wine to create a new wineprefix.
|
||||
- Download winetricks (which is just a complicated bash script), make it executable, then copy it to `/usr/local/bin`.
|
||||
|
||||
## Examples
|
||||
### Installing Wine64 & Wine for Box64 & Box86 on Raspberry Pi OS from WineHQ .deb files
|
||||
_Links from the [WineHQ repo](https://dl.winehq.org/wine-builds/debian/dists/)_
|
||||
|
||||
This install method allows you to install different versions of Wine64/Wine. You may install any version/branch of Wine that you wish.
|
||||
```
|
||||
# NOTE: Can only run on aarch64 (since box64 can only run on aarch64)
|
||||
# box64 runs wine-amd64, box86 runs wine-i386.
|
||||
|
||||
### User-defined Wine version variables ################
|
||||
# - Replace the variables below with your system's info.
|
||||
# - Note that we need the amd64 version for Box64 even though we're installing it on our ARM processor.
|
||||
# - 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/
|
||||
|
||||
local branch="devel" #example: devel, staging, or stable (wine-staging 4.5+ requires libfaudio0:i386)
|
||||
local version="7.1" #example: "7.1"
|
||||
local id="debian" #example: debian, ubuntu
|
||||
local dist="bullseye" #example (for debian): bullseye, buster, jessie, wheezy, ${VERSION_CODENAME}, etc
|
||||
local tag="-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 any old wine-mono/wine-gecko install files
|
||||
rm -rf ~/.local/share/applications/wine # remove any old program shortcuts
|
||||
|
||||
# Backup any old wine installs
|
||||
rm -rf ~/wine-old 2>/dev/null; mv ~/wine ~/wine-old 2>/dev/null
|
||||
rm -rf ~/.wine-old 2>/dev/null; mv ~/.wine ~/.wine-old 2>/dev/null
|
||||
sudo mv /usr/local/bin/wine /usr/local/bin/wine-old 2>/dev/null
|
||||
sudo mv /usr/local/bin/wine64 /usr/local/bin/wine-old 2>/dev/null
|
||||
sudo mv /usr/local/bin/wineboot /usr/local/bin/wineboot-old 2>/dev/null
|
||||
sudo mv /usr/local/bin/winecfg /usr/local/bin/winecfg-old 2>/dev/null
|
||||
sudo mv /usr/local/bin/wineserver /usr/local/bin/wineserver-old 2>/dev/null
|
||||
|
||||
# Wine download links from WineHQ: https://dl.winehq.org/wine-builds/
|
||||
LNKA="https://dl.winehq.org/wine-builds/${id}/dists/${dist}/main/binary-amd64/" #amd64-wine links
|
||||
DEB_A1="wine-${branch}-amd64_${version}~${dist}${tag}_amd64.deb" #wine64 main bin
|
||||
DEB_A2="wine-${branch}_${version}~${dist}${tag}_amd64.deb" #wine64 support files (required for wine64 / can work alongside wine_i386 main bin)
|
||||
#DEB_A3="winehq-${branch}_${version}~${dist}${tag}_amd64.deb" #shortcuts & docs
|
||||
LNKB="https://dl.winehq.org/wine-builds/${id}/dists/${dist}/main/binary-i386/" #i386-wine links
|
||||
DEB_B1="wine-${branch}-i386_${version}~${dist}${tag}_i386.deb" #wine_i386 main bin
|
||||
DEB_B2="wine-${branch}_${version}~${dist}${tag}_i386.deb" #wine_i386 support files (required for wine_i386 if no wine64 / CONFLICTS WITH wine64 support files)
|
||||
#DEB_B3="winehq-${branch}_${version}~${dist}${tag}_i386.deb" #shortcuts & docs
|
||||
|
||||
# Install amd64-wine (64-bit) alongside i386-wine (32-bit)
|
||||
echo -e "Downloading wine . . ."
|
||||
wget -q ${LNKA}${DEB_A1}
|
||||
wget -q ${LNKA}${DEB_A2}
|
||||
wget -q ${LNKB}${DEB_B1}
|
||||
echo -e "Extracting wine . . ."
|
||||
dpkg-deb -x ${DEB_A1} wine-installer
|
||||
dpkg-deb -x ${DEB_A2} wine-installer
|
||||
dpkg-deb -x ${DEB_B1} wine-installer
|
||||
echo -e "Installing wine . . ."
|
||||
mv wine-installer/opt/wine* ~/wine
|
||||
|
||||
# Download wine dependencies
|
||||
# - these packages are needed for running box86/wine-i386 on a 64-bit RPiOS via multiarch
|
||||
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.
|
||||
|
||||
# - these packages are needed for running box64/wine-amd64 on RPiOS (box64 only runs on 64-bit OS's)
|
||||
sudo apt-get install -y libasound2:arm64 libc6:arm64 libglib2.0-0:arm64 libgphoto2-6:arm64 libgphoto2-port12:arm64 \
|
||||
libgstreamer-plugins-base1.0-0:arm64 libgstreamer1.0-0:arm64 libldap-2.4-2:arm64 libopenal1:arm64 libpcap0.8:arm64 \
|
||||
libpulse0:arm64 libsane1:arm64 libudev1:arm64 libunwind8:arm64 libusb-1.0-0:arm64 libvkd3d1:arm64 libx11-6:arm64 libxext6:arm64 \
|
||||
ocl-icd-libopencl1:arm64 libasound2-plugins:arm64 libncurses6:arm64 libncurses5:arm64 libcups2:arm64 \
|
||||
libdbus-1-3:arm64 libfontconfig1:arm64 libfreetype6:arm64 libglu1-mesa:arm64 libgnutls30:arm64 \
|
||||
libgssapi-krb5-2:arm64 libjpeg62-turbo:arm64 libkrb5-3:arm64 libodbc1:arm64 libosmesa6:arm64 libsdl2-2.0-0:arm64 libv4l-0:arm64 \
|
||||
libxcomposite1:arm64 libxcursor1:arm64 libxfixes3:arm64 libxi6:arm64 libxinerama1:arm64 libxrandr2:arm64 \
|
||||
libxrender1:arm64 libxxf86vm1:arm64 libc6:arm64 libcap2-bin:arm64
|
||||
# This list found by downloading...
|
||||
# wget https://dl.winehq.org/wine-builds/debian/dists/bullseye/main/binary-amd64/wine-devel_7.1~bullseye-1_amd64.deb
|
||||
# wget https://dl.winehq.org/wine-builds/debian/dists/bullseye/main/binary-amd64/wine-devel-amd64_7.1~bullseye-1_amd64.deb
|
||||
# then `dpkg-deb -I package.deb`. Read output, add `:arm64` to packages in dep list, then try installing them on Pi aarch64.
|
||||
|
||||
# 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
|
||||
|
||||
# Install symlinks
|
||||
sudo ln -s ~/wine/bin/wine /usr/local/bin/wine
|
||||
sudo ln -s ~/wine/bin/wine64 /usr/local/bin/wine64
|
||||
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/wine64 /usr/local/bin/wineboot /usr/local/bin/winecfg /usr/local/bin/wineserver
|
||||
```
|
||||
|
||||
## 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
|
||||
Creating a 64-bit wineprefix:
|
||||
`wine64 wineboot` or `wine wineboot` (wineprefix is created in `~/.wine/`)
|
||||
`WINEPREFIX="$HOME/prefix64" wine wineboot` (wineprefix is created in `~/prefix64/`) _Note: You will need to invoke `WINEPREFIX="$HOME/prefix64"` before every command to use this wineprefix._
|
||||
|
||||
Creating a 32-bit wineprefix:
|
||||
`WINEARCH=win32 wine wineboot` (wineprefix is created in `~/.wine/`)
|
||||
|
||||
Fore-quitting wine:
|
||||
`wineserver -k`
|
||||
|
||||
Running Wine Configuration:
|
||||
`winecfg`
|
||||
|
||||
Using winetricks:
|
||||
`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._
|
||||
|
||||
Invoking Box86's logging features (with `BOX86_LOG=1` or similar) will cause winetricks to crash.
|
||||
|
||||
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
|
||||
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.
|
||||
+784
@@ -0,0 +1,784 @@
|
||||
=head1 NAME
|
||||
|
||||
box64 - Linux Userspace x86_64 Emulator with a twist
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<box64> [B<--help>] [B<--version>] I<executable>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<Box64> lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux
|
||||
systems, like ARM (host system needs to be 64-bit little-endian). Since B<Box64>
|
||||
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. B<Box64> integrates with DynaRec (dynamic
|
||||
recompiler) for the ARM64 platform, providing a speed boost between 5 to 10
|
||||
times faster than using only the interpreter.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-h,--help>
|
||||
|
||||
Print box64 help and quit.
|
||||
|
||||
=item B<-v,--version>
|
||||
|
||||
Print box64 version and quit.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BRIEF USAGE
|
||||
|
||||
There are many environment variables to control B<Box64>'s behaviour. In
|
||||
addition to environment variables, B<Box64> also looks for 2 places for rcfile:
|
||||
F</etc/box64.box64rc> and F<~/.box64rc>, in the format of .ini files.
|
||||
Settings priority: F<~/.box64rc> > F</etc/box64.box64rc> > environment variables.
|
||||
Example:
|
||||
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
=over 8
|
||||
|
||||
|
||||
=item B<BOX64_ADDLIBS> =I<XXXX|XXXX:YYYY:ZZZZ>
|
||||
|
||||
Add extras to the needed libraries list, rarely needed.
|
||||
|
||||
* XXXX : Add library XXXX to the needed libraries list.
|
||||
* XXXX:YYYY:ZZZZ : Add library XXXX, YYYY and ZZZZ to the needed libraries list.
|
||||
|
||||
|
||||
=item B<BOX64_ALLOWMISSINGLIBS> =I<0|1>
|
||||
|
||||
Allow missing libraries to be ignored.
|
||||
|
||||
* 0 : Do not allow missing libraries. [Default]
|
||||
* 1 : Allow missing libraries.
|
||||
|
||||
|
||||
=item B<BOX64_ARGS> =I<XXXX|XXXX YYYY ZZZZ>
|
||||
|
||||
Arguments to pass to the guest program, only valid if there is no existing arguments.
|
||||
|
||||
* XXXX : Pass argument XXXX to the program.
|
||||
* XXXX YYYY ZZZZ : Pass arguments XXXX, YYYY and ZZZZ to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_BASH> =I<XXXX>
|
||||
|
||||
Path to the bash executable.
|
||||
|
||||
* XXXX : Use bash executable at path XXXX.
|
||||
|
||||
|
||||
=item B<BOX64_CEFDISABLEGPU> =I<0|1>
|
||||
|
||||
Add -cef-disable-gpu argument to the guest program.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Add -cef-disable-gpu argument to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_CEFDISABLEGPUCOMPOSITOR> =I<0|1>
|
||||
|
||||
Add -cef-disable-gpu-compositor argument to the guest program.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Add -cef-disable-gpu-compositor argument to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_CPUTYPE> =I<0|1>
|
||||
|
||||
Specify the CPU type to emulate.
|
||||
|
||||
* 0 : Emulate a Intel CPU Model. [Default]
|
||||
* 1 : Emulate a AMD CPU Model.
|
||||
|
||||
|
||||
=item B<BOX64_CRASHHANDLER> =I<0|1>
|
||||
|
||||
Use a dummy crash handler or not.
|
||||
|
||||
* 0 : Use emulated crashhandler.so library if nedded.
|
||||
* 1 : Use an internal dummy (empty) crashhandler.so library. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DLSYM_ERROR> =I<0|1>
|
||||
|
||||
Enable or disable the logging of dlsym errors.
|
||||
|
||||
* 0 : Disable the logging of dlsym errors. [Default]
|
||||
* 1 : Enable the logging of dlsym errors.
|
||||
|
||||
|
||||
=item B<BOX64_DUMP> =I<0|1>
|
||||
|
||||
Dump elfloader debug information.
|
||||
|
||||
* 0 : Do not dump elfloader debug information. [Default]
|
||||
* 1 : Dump elfloader debug information.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_ALIGNED_ATOMICS> =I<0|1>
|
||||
|
||||
Generate aligned atomics only (only available on Arm64 for now).
|
||||
|
||||
* 0 : Generate unaligned atomics handling code. [Default]
|
||||
* 1 : Generate aligned atomics only, which is faster and smaller code size, but will cause SIGBUS for LOCK prefixed opcodes operating on aligned data addresses.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_BIGBLOCK> =I<0|1|2|3>
|
||||
|
||||
Enable building bigger DynaRec code blocks for better performance.
|
||||
|
||||
* 0 : Do not try to build block as big as possible, suitable for programs using lots of threads and JIT, like Unity.
|
||||
* 1 : Build Dynarec block as big as possible.
|
||||
* 2 : Build Dynarec block bigger, do not stop when block overlaps, but only for blocks in elf memory. [Default]
|
||||
* 3 : Build Dynarec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_BLEEDING_EDGE> =I<0|1>
|
||||
|
||||
Detect MonoBleedingEdge and apply conservative settings.
|
||||
|
||||
* 0 : Do not detect MonoBleedingEdge.
|
||||
* 1 : Detect MonoBleedingEdge and apply BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_STRONGMEM=1 when detected. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_CALLRET> =I<0|1>
|
||||
|
||||
Optimize CALL/RET opcodes.
|
||||
|
||||
* 0 : Do not optimize CALL/RET, use jump table. [Default]
|
||||
* 1 : Try to optimize CALL/RET, skipping the jump table when possible.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_DF> =I<0|1>
|
||||
|
||||
Enable or disable the use of deferred flags.
|
||||
|
||||
* 0 : Disable the use of deferred flags.
|
||||
* 1 : Enable the use of deferred flags. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_DIRTY> =I<0|1>
|
||||
|
||||
Allow continue running a block that is unprotected and potentially dirty.
|
||||
|
||||
* 0 : Do not allow continue running a block that is unprotected and potentially dirty. [Default]
|
||||
* 1 : Allow continue to run a dynablock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_DIV0> =I<0|1>
|
||||
|
||||
Enable or disable the generation of division-by-zero exception.
|
||||
|
||||
* 0 : Do not generate thr division-by-zero exception. [Default]
|
||||
* 1 : Generate the division-by-zero exception.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_DUMP> =I<0|1|2>
|
||||
|
||||
Enable DynaRec dump.
|
||||
|
||||
* 0 : Do not dump DynaRec blocks. [Default]
|
||||
* 1 : Dump DynaRec blocks.
|
||||
* 2 : Dump DynaRec blocks with some colors.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_FASTNAN> =I<0|1>
|
||||
|
||||
Enable or disable fast NaN handling.
|
||||
|
||||
* 0 : Precisely emulate the -NaN generation like on x86.
|
||||
* 1 : Do not do anything special with -NAN generation, faster. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_FASTROUND> =I<0|1|2>
|
||||
|
||||
Enable or disable fast rounding.
|
||||
|
||||
* 0 : Generate float/double -> int rounding and use current rounding mode for float/double computation like on x86.
|
||||
* 1 : Do not do anything special with edge case rounding, faster. [Default]
|
||||
* 2 : Generate float/double -> int rounding using current rounding mode for float/double computation like on x86, but use fast int -> float/double conversion.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_FORWARD> =I<0|128|XXXX>
|
||||
|
||||
Define max allowed forward value when building block.
|
||||
|
||||
* 0 : No forward value. When current block ends, do not try to go further even if there are previous forward jumps.
|
||||
* 128 : Allow up to 128 bytes of gap between end of the block and the next forward jump. [Default]
|
||||
* XXXX : Allow up to XXXX bytes of gap between end of the block and the next forward jump.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_GDBJIT> =I<0|1|2>
|
||||
|
||||
The GDBJIT debugging support, only available on build with `-DGDBJIT=ON`, enable it with gdb command: jit-reader-load /usr/local/lib/libbox64gdbjitreader.so.
|
||||
|
||||
* 0 : Dynarec will not generate GDBJIT debuginfo. [Default]
|
||||
* 1 : Dynarec will generate GDBJIT debuginfo.
|
||||
* 2 : Dynarec will generate detailed GDBJIT debuginfo with internal state.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_LOG> =I<0|1|2|3>
|
||||
|
||||
Disable or enable DynaRec logs.
|
||||
|
||||
* 0 : Disable DynaRec logs. [Default]
|
||||
* 1 : Enable minimal DynaRec logs.
|
||||
* 2 : Enable debug level DynaRec logs.
|
||||
* 3 : Enable verbose level DynaRec logs.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_MISSING> =I<0|1|2>
|
||||
|
||||
Print missing opcodes.
|
||||
|
||||
* 0 : Do not print the missing opcode. [Default]
|
||||
* 1 : Print missing opcodes.
|
||||
* 2 : Print the fallback to scalar opcodes, only valid on RISC-V.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_NATIVEFLAGS> =I<0|1>
|
||||
|
||||
Enable or disable the use of native flags.
|
||||
|
||||
* 0 : Do not use native flags.
|
||||
* 1 : Use native flags when possible. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_PAUSE> =I<0|1|2|3>
|
||||
|
||||
Enable x86 PAUSE emulation, may help the performance of spinlocks.
|
||||
|
||||
* 0 : Ignore x86 PAUSE instruction. [Default]
|
||||
* 1 : Use YIELD to emulate x86 PAUSE instruction.
|
||||
* 2 : Use WFI to emulate x86 PAUSE instruction.
|
||||
* 3 : Use SEVL+WFE to emulate x86 PAUSE instruction.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_PERFMAP> =I<0|1>
|
||||
|
||||
Generate map file for Linux perf tool.
|
||||
|
||||
* 0 : Dynarec will not generate perf map. [Default]
|
||||
* 1 : Dynarec will generate perf map.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_SAFEFLAGS> =I<0|1|2>
|
||||
|
||||
Behaviour of flags emulation on CALL/RET opcodes.
|
||||
|
||||
* 0 : Treat CALL/RET as if it never needs any flags.
|
||||
* 1 : Most of RETs will need flags, most of CALLs will not. [Default]
|
||||
* 2 : All CALL/RET will need flags.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_STRONGMEM> =I<0|1|2|3>
|
||||
|
||||
Enable the emulation of x86 strong memory model.
|
||||
|
||||
* 0 : Do not try anything special. [Default]
|
||||
* 1 : Enable some memory barriers when writing to memory to emulate the x86 strong memory model in a limited way.
|
||||
* 2 : All in 1, plus memory barriers on SIMD instructions.
|
||||
* 3 : All in 2, plus more memory barriers on a regular basis.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_TBB> =I<0|1>
|
||||
|
||||
Enable or disable libtbb detection.
|
||||
|
||||
* 0 : Do not detect libtbb.
|
||||
* 1 : Detect libtbb and apply conservative settings. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_TEST> =I<0|1|0xXXXXXXXX-0xYYYYYYYY>
|
||||
|
||||
Enable DynaRec execution comparison with the interpreter, very slow, only for testing.
|
||||
|
||||
* 0 : No comparison. [Default]
|
||||
* 1 : Each opcode runs on interpreter and on Dynarec, regs and memory are compared and printed when they differ.
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where dynarec is tested (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_TRACE> =I<0|1>
|
||||
|
||||
Enable or disable DynaRec trace.
|
||||
|
||||
* 0 : Do not trace DynaRec blocks. [Default]
|
||||
* 1 : Trace DynaRec blocks, will slow down the program a lot and generates huge logs.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_WAIT> =I<0|1>
|
||||
|
||||
Wait or not for the building of a DynaRec code block to be ready.
|
||||
|
||||
* 0 : Do not wait and use interpreter instead, might speedup a bit on massive multithread or JIT programs.
|
||||
* 1 : Wait for a DynaRec code block to be ready. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_WEAKBARRIER> =I<0|1|2>
|
||||
|
||||
Tweak the memory barriers to reduce the performance impact by strong memory emualtion.
|
||||
|
||||
* 0 : Use regular safe barrier.
|
||||
* 1 : Use weak barriers to have more performance boost. [Default]
|
||||
* 2 : All in 1, plus disabled the last write barriers.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_X87DOUBLE> =I<0|1>
|
||||
|
||||
Force the use of float/double for x87 emulation.
|
||||
|
||||
* 0 : Try to use float when possible for x87 emulation. [Default]
|
||||
* 1 : Only use Double for x87 emulation.
|
||||
|
||||
|
||||
=item B<BOX64_EMULATED_LIBS> =I<XXXX|XXXX:YYYY:ZZZZ>
|
||||
|
||||
Force the use of emulated libraries.
|
||||
|
||||
* XXXX : Force the use of emulated library XXXX.
|
||||
* XXXX:YYYY:ZZZZ : Force the use of emulated libraries XXXX, YYYY and ZZZZ.
|
||||
|
||||
|
||||
=item B<BOX64_ENV> =I<XXXX=yyyy>
|
||||
|
||||
Add an environment variable.
|
||||
|
||||
* XXXX=yyyy : Add environment variable XXXX with value yyyy.
|
||||
|
||||
|
||||
=item B<BOX64_ENV[1-5]> =I<XXXX=yyyy>
|
||||
|
||||
Add an environment variable.
|
||||
|
||||
* XXXX=yyyy : Add environment variable XXXX with value yyyy.
|
||||
|
||||
|
||||
=item B<BOX64_EXIT> =I<0|1>
|
||||
|
||||
Just exit, do not try to run the program.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Just exit.
|
||||
|
||||
|
||||
=item B<BOX64_FIX_64BIT_INODES> =I<0|1>
|
||||
|
||||
Fix 64bit inodes.
|
||||
|
||||
* 0 : Do not fix 64bit inodes. [Default]
|
||||
* 1 : Fix 64bit inodes.
|
||||
|
||||
|
||||
=item B<BOX64_IGNOREINT3> =I<0|1>
|
||||
|
||||
Ignore INT3 instructions.
|
||||
|
||||
* 0 : Trigger a TRAP signal if a handler is present. [Default]
|
||||
* 1 : Skip the opcode silently.
|
||||
|
||||
|
||||
=item B<BOX64_INSERT_ARGS> =I<XXXX|XXXX YYYY ZZZZ>
|
||||
|
||||
Prepend arguments to the command line.
|
||||
|
||||
* XXXX : Prepend argument XXXX to the program.
|
||||
* XXXX YYYY ZZZZ : Prepend arguments XXXX, YYYY and ZZZZ to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_INPROCESSGPU> =I<0|1>
|
||||
|
||||
Add --in-process-gpu argument to the guest program.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Add --in-process-gpu argument to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_JITGDB> =I<0|1|2|3>
|
||||
|
||||
Launch gdb or not for SIGSEGV, SIGILL, and SIGBUS.
|
||||
|
||||
* 0 : Just print the message when the signal is caught. [Default]
|
||||
* 1 : Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in is stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.
|
||||
* 2 : Launch gdbserver when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process, and go in an endless loop, waiting. Use `gdb /PATH/TO/box64` 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 `BOX64_JITGDB=1`.
|
||||
* 3 : Launch lldb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting.
|
||||
|
||||
|
||||
=item B<BOX64_JVM> =I<0|1>
|
||||
|
||||
Detect libjvm and apply conservative settings.
|
||||
|
||||
* 0 : Does nothing.
|
||||
* 1 : Detect libjvm, and apply BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_STRONGMEM=1 BOX64_SSE42=0 when detected. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_LD_LIBRARY_PATH> =I<XXXX>
|
||||
|
||||
Path to look for x86_64 libraries.
|
||||
|
||||
* XXXX : Add path XXXX to the library path.
|
||||
|
||||
|
||||
=item B<BOX64_LD_PRELOAD> =I<XXXX|XXXX:YYYY>
|
||||
|
||||
Force loading libraries with the binary.
|
||||
|
||||
* XXXX : Force the loading of library XXXX.
|
||||
* XXXX:YYYY : Force the loading of libraries XXXX and YYYY.
|
||||
|
||||
|
||||
=item B<BOX64_LIBCEF> =I<0|1>
|
||||
|
||||
Detect libcef and apply BOX64_MALLOC_HACK settings.
|
||||
|
||||
* 0 : Does nothing.
|
||||
* 1 : Detect libcef, and apply BOX64_MALLOC_HACK=2 if detected. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_LIBGL> =I<libXXXX|/path/to/libXXXX>
|
||||
|
||||
Set the name for libGL.
|
||||
|
||||
* libXXXX : Set the name for libGL to libXXXX.
|
||||
* /path/to/libXXXX : Set the name and path for libGL to /path/to/libXXXX, you can also use SDL_VIDEO_GL_DRIVER.
|
||||
|
||||
|
||||
=item B<BOX64_LOAD_ADDR> =I<0xXXXXXXXX>
|
||||
|
||||
Set the address where the program is loaded, only active for PIE guest programs.
|
||||
|
||||
* 0xXXXXXXXX : Set the address where the program is loaded.
|
||||
|
||||
|
||||
=item B<BOX64_LOG> =I<0|1|2|3>
|
||||
|
||||
Enable or disable Box64 logs.
|
||||
|
||||
* 0 : Disable Box64 logs. [Default]
|
||||
* 1 : Enable minimal Box64 logs.
|
||||
* 2 : Enable debug level Box64 logs.
|
||||
* 3 : Enable verbose level Box64 logs.
|
||||
|
||||
|
||||
=item B<BOX64_MALLOC_HACK> =I<0|1|2>
|
||||
|
||||
Behaviour when hooking malloc operators.
|
||||
|
||||
* 0 : Don't allow malloc operator to be redirected, rewriting code to use regular function. [Default]
|
||||
* 1 : Allow malloc operator to be redirected.
|
||||
* 2 : Like 0, but track special mmap/free (some redirected functions are inlined and cannot be redirected).
|
||||
|
||||
|
||||
=item B<BOX64_MAXCPU> =I<0|XXXX>
|
||||
|
||||
Maximum CPU cores exposed.
|
||||
|
||||
* 0 : Use the actual number of CPU cores. [Default]
|
||||
* XXXX : Use XXXX CPU cores.
|
||||
|
||||
|
||||
=item B<BOX64_NOBANNER> =I<0|1>
|
||||
|
||||
Disable the Box64 banner.
|
||||
|
||||
* 0 : Show the Box64 banner. [Default]
|
||||
* 1 : Do not show the Box64 banner.
|
||||
|
||||
|
||||
=item B<BOX64_NODYNAREC> =I<0xXXXXXXXX-0xYYYYYYYY>
|
||||
|
||||
Forbid dynablock creation in the address range specified, helpful for debugging behaviour difference between Dynarec and Interpreter.
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where dynablock creation is forbidden (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_NOGTK> =I<0|1>
|
||||
|
||||
Do not load wrapped GTK libraries.
|
||||
|
||||
* 0 : Load wrapped GTK libraries. [Default]
|
||||
* 1 : Do not load wrapped GTK libraries.
|
||||
|
||||
|
||||
=item B<BOX64_NOPULSE> =I<0|1>
|
||||
|
||||
Do not load PulseAudio libraries (both native and x86_64).
|
||||
|
||||
* 0 : Load PulseAudio libraries. [Default]
|
||||
* 1 : Do not load PulseAudio libraries.
|
||||
|
||||
|
||||
=item B<BOX64_NORCFILES> =I<0|1>
|
||||
|
||||
Do not load any rc files.
|
||||
|
||||
* 0 : Load rc files. [Default]
|
||||
* 1 : Do not load any rc files.
|
||||
|
||||
|
||||
=item B<BOX64_NOSANDBOX> =I<0|1>
|
||||
|
||||
Add --no-sandbox argument to the guest program.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Add --no-sandbox argument to the guest program.
|
||||
|
||||
|
||||
=item B<BOX64_NOSIGSEGV> =I<0|1>
|
||||
|
||||
Disable the handling of SIGSEGV.
|
||||
|
||||
* 0 : Let the x86 program set sighandler for SIGSEGV. [Default]
|
||||
* 1 : Disable the handling of SIGSEGV.
|
||||
|
||||
|
||||
=item B<BOX64_NOSIGILL> =I<0|1>
|
||||
|
||||
Disable the handling of SIGILL.
|
||||
|
||||
* 0 : Let the x86 program set sighandler for SIGILL. [Default]
|
||||
* 1 : Disable the handling of SIGILL.
|
||||
|
||||
|
||||
=item B<BOX64_NOVULKAN> =I<0|1>
|
||||
|
||||
Do not load Vulkan libraries.
|
||||
|
||||
* 0 : Load Vulkan libraries. [Default]
|
||||
* 1 : Do not load Vulkan libraries, both native and x86_64.
|
||||
|
||||
|
||||
=item B<BOX64_PATH> =I<XXXX>
|
||||
|
||||
Path to look for x86_64 binaries.
|
||||
|
||||
* XXXX : Add path XXXX to the binary path.
|
||||
|
||||
|
||||
=item B<BOX64_PREFER_EMULATED> =I<0|1>
|
||||
|
||||
Prefer emulated libraries over native ones.
|
||||
|
||||
* 0 : Prefer native libraries over emulated ones. [Default]
|
||||
* 1 : Prefer emulated libraries over native ones.
|
||||
|
||||
|
||||
=item B<BOX64_PREFER_WRAPPED> =I<0|1>
|
||||
|
||||
Prefer wrapped libs first even if the lib is specified with absolute path.
|
||||
|
||||
* 0 : Prefer libs with absolute path over wrapped ones. [Default]
|
||||
* 1 : Prefer wrapped libs first even if the lib is specified with absolute path.
|
||||
|
||||
|
||||
=item B<BOX64_RCFILE> =I<XXXX>
|
||||
|
||||
Path to the rc file to load.
|
||||
|
||||
* XXXX : Load the rc file XXXX, default rc files will not be loaded.
|
||||
|
||||
|
||||
=item B<BOX64_RDTSC_1GHZ> =I<0|1>
|
||||
|
||||
Use hardware counter for rdtsc if available.
|
||||
|
||||
* 0 : Use hardware counter for rdtsc opcode if available. [Default]
|
||||
* 1 : Use hardware counter for rdtsc if and only if precision is at least 1GHz.
|
||||
|
||||
|
||||
=item B<BOX64_RESERVE_HIGH> =I<0|1>
|
||||
|
||||
Reserve high memory area for the program, always enabled on Box32.
|
||||
|
||||
* 0 : Do not reserve high memory area for the program. [Default]
|
||||
* 1 : Reserve high memory area for the program.
|
||||
|
||||
|
||||
=item B<BOX64_ROLLING_LOG> =I<0|1|XXX>
|
||||
|
||||
Show last few wrapped function call when a signal is caught.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Show last 16 wrapped function call when a signal is caught.
|
||||
* XXX : Show last XXX wrapped function call when a signal is caught.
|
||||
|
||||
|
||||
=item B<BOX64_SDL2_JGUID> =I<0|1>
|
||||
|
||||
Use a workaround for SDL_GetJoystickGUIDInfo function for wrapped SDL2.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Use a workaround for SDL_GetJoystickGUIDInfo function for wrapped SDL2.
|
||||
|
||||
|
||||
=item B<BOX64_SHAEXT> =I<0|1>
|
||||
|
||||
Expose SHAEXT (a.k.a. SHA_NI) capabilities.
|
||||
|
||||
* 0 : Do not expose SHAEXT capabilities.
|
||||
* 1 : Expose SHAEXT capabilities. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_SHOWBT> =I<0|1>
|
||||
|
||||
Show native and emulated backtrace when a signal is caught.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Show native and emulated backtrace when a signal is caught.
|
||||
|
||||
|
||||
=item B<BOX64_SHOWSEGV> =I<0|1>
|
||||
|
||||
Always show SIGSEGV signal detailes.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Always show SIGSEGV signal detailes.
|
||||
|
||||
|
||||
=item B<BOX64_SSE_FLUSHTO0> =I<0|1>
|
||||
|
||||
Behaviour of SSE Flush to 0 flags.
|
||||
|
||||
* 0 : Just track the flag. [Default]
|
||||
* 1 : Apply SSE Flush to 0 flag directly.
|
||||
|
||||
|
||||
=item B<BOX64_SSE42> =I<0|1>
|
||||
|
||||
Expose SSE4.2 capabilities.
|
||||
|
||||
* 0 : Do not expose SSE4.2 capabilities.
|
||||
* 1 : Expose SSE4.2 capabilities. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_SYNC_ROUNDING> =I<0|1>
|
||||
|
||||
Synchronize rounding mode between x86 and native.
|
||||
|
||||
* 0 : Do not synchronize rounding mode. [Default]
|
||||
* 1 : Synchronize rounding mode between x86 and native.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_COLOR> =I<0|1>
|
||||
|
||||
Enable or disable colored trace output.
|
||||
|
||||
* 0 : Disable colored trace output. [Default]
|
||||
* 1 : Enable colored trace output.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_EMM> =I<0|1>
|
||||
|
||||
Enable or disable EMM (i.e. MMX) trace output.
|
||||
|
||||
* 0 : Disable EMM trace output. [Default]
|
||||
* 1 : Enable EMM trace output.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_FILE> =I<XXXX|XXXX%pid|stderr>
|
||||
|
||||
Send all log and trace to a file instead of `stdout`.
|
||||
|
||||
* XXXX : Send all log and trace to file XXXX.
|
||||
* XXXX%pid : Send all log and trace to file XXXX with pid appended.
|
||||
* stderr : Send all log and trace to `stderr`.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_INIT> =I<0|1>
|
||||
|
||||
Same as BOX64_TRACE but starts the trace immediately.
|
||||
|
||||
* 0 : Disable trace output. [Default]
|
||||
* 1 : Enable trace output. Trace starts before the initialization of dependencies.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_START> =I<0|1|XXXX>
|
||||
|
||||
Start trace after N opcodes executed.
|
||||
|
||||
* 0 : Start trace immediately. [Default]
|
||||
* 1 : Start trace after 1 opcode executed.
|
||||
* XXXX : Start trace after XXXX opcodes executed.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE_XMM> =I<0|1>
|
||||
|
||||
Enable or disable XMM (i.e. SSE) trace output.
|
||||
|
||||
* 0 : Disable XMM trace output. [Default]
|
||||
* 1 : Enable XMM trace output.
|
||||
|
||||
|
||||
=item B<BOX64_TRACE> =I<0|1|symbolname|0xXXXXXXX-0xYYYYYYY>
|
||||
|
||||
Only available on box64 build with trace. Adds trace of all instructions executed, along with a register dump.
|
||||
|
||||
* 0 : Disable trace output. [Default]
|
||||
* 1 : Enable trace output.
|
||||
* symbolname : Enable trace output for `symbolname` only.
|
||||
* 0xXXXXXXX-0xYYYYYYY : Enable trace output for the range of address (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_UNITYPLAYER> =I<0|1>
|
||||
|
||||
Detect UnityPlayer and apply conservative settings.
|
||||
|
||||
* 0 : Does nothing.
|
||||
* 1 : Detect UnityPlayer, and apply BOX64_DYNAREC_STRONGMEM=1 when detected. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_WRAP_EGL> =I<0|1>
|
||||
|
||||
Prefer wrapped libs for EGL and GLESv2.
|
||||
|
||||
* 0 : Prefer emulated libs for EGL and GLESv2. [Default]
|
||||
* 1 : Prefer wrapped libs for EGL and GLESv2.
|
||||
|
||||
|
||||
=item B<BOX64_X11GLX> =I<0|1>
|
||||
|
||||
Force Xorg GLX extension to be present.
|
||||
|
||||
* 0 : Do not force Xorg GLX extension to be present. [Default]
|
||||
* 1 : Require Xorg GLX extension when using XQueryExtension.
|
||||
|
||||
|
||||
=item B<BOX64_X11SYNC> =I<0|1>
|
||||
|
||||
Force synchronized operation on X11 display.
|
||||
|
||||
* 0 : Do not force synchronized operation on X11 display. [Default]
|
||||
* 1 : Force synchronized operation on X11 display.
|
||||
|
||||
|
||||
=item B<BOX64_X11THREADS> =I<0|1>
|
||||
|
||||
Call XInitThreads when loading X11. This is mostly for old Loki games with the Loki_Compat library.
|
||||
|
||||
* 0 : Do not call XInitThreads. [Default]
|
||||
* 1 : Call XInitThreads as soon as libX11 is loaded.
|
||||
|
||||
|
||||
=item B<BOX64_X87_NO80BITS> =I<0|1>
|
||||
|
||||
Behavoiur of x87 80bits long double.
|
||||
|
||||
* 0 : Try to handle 80bits long double as precise as possible. [Default]
|
||||
* 1 : Use 64bits double for x87.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
# Usage: python gen.py
|
||||
|
||||
import json
|
||||
import os
|
||||
from collections import defaultdict
|
||||
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
usage_file = os.path.join(script_dir, 'usage.json')
|
||||
|
||||
with open(usage_file, 'r') as file:
|
||||
data = json.load(file)
|
||||
|
||||
with open(os.path.join(script_dir, '../USAGE.md'), 'w') as md_file:
|
||||
md_file.write("""<!--- This file is generated by gen.py, do not edit it directly. -->
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variables to control Box64's behaviour, which will be listed below by category.
|
||||
|
||||
### Configuration files
|
||||
|
||||
In addition to environment variables, by default, Box64 also looks for 2 places for rcfile: the system-wide `/etc/box64.box64rc` and user-specific `~/.box64rc`.
|
||||
Settings priority follows this order (from highest to lowest): `~/.box64rc` > `/etc/box64.box64rc` > environment variables.
|
||||
|
||||
Example configuration:
|
||||
|
||||
```
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
```
|
||||
|
||||
This configuration will apply the specified settings application-wide to any executable named `factorio`.
|
||||
|
||||
### Advanced usage
|
||||
|
||||
1. **Wildcard Matching**
|
||||
|
||||
Asterisks (`*`) can be used for basic pattern matching in application names. For instance, `[*setup*]` will match any program containing "setup" in its name. Note this implements simple wildcard matching rather than full regex support.
|
||||
2. **Custom Configuration File**
|
||||
|
||||
The `BOX64_RCFILE` environment variable can specify an alternative configuration file instead of the default `/etc/box64.box64rc`.
|
||||
3. **Per-File Settings**
|
||||
|
||||
Sections starting with `/` apply to specific files. For example:
|
||||
```
|
||||
[/d3d9.dll]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
```
|
||||
These settings will only affect the `d3d9.dll` file. This syntax also works for **emulated** Linux libraries, e.g., `[/libstdc++.so.6]`.
|
||||
|
||||
----
|
||||
|
||||
""")
|
||||
|
||||
categories = defaultdict(list)
|
||||
for entry in data:
|
||||
categories[entry["category"]].append(entry)
|
||||
|
||||
for category, entries in categories.items():
|
||||
md_file.write(f"## {category}\n\n")
|
||||
for entry in entries:
|
||||
md_file.write(f"### {entry['name']}\n\n{entry['description']}\n\n")
|
||||
for option in entry['options']:
|
||||
md_file.write(f" * {option['key']}: {option['description']} {"[Default]" if option['default'] else ""}\n")
|
||||
md_file.write("\n")
|
||||
|
||||
|
||||
with open(os.path.join(script_dir, '../box64.pod'), 'w') as pod_file:
|
||||
pod_file.write("""=head1 NAME
|
||||
|
||||
box64 - Linux Userspace x86_64 Emulator with a twist
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<box64> [B<--help>] [B<--version>] I<executable>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<Box64> lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux
|
||||
systems, like ARM (host system needs to be 64-bit little-endian). Since B<Box64>
|
||||
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. B<Box64> integrates with DynaRec (dynamic
|
||||
recompiler) for the ARM64 platform, providing a speed boost between 5 to 10
|
||||
times faster than using only the interpreter.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-h,--help>
|
||||
|
||||
Print box64 help and quit.
|
||||
|
||||
=item B<-v,--version>
|
||||
|
||||
Print box64 version and quit.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BRIEF USAGE
|
||||
|
||||
There are many environment variables to control B<Box64>'s behaviour. In
|
||||
addition to environment variables, B<Box64> also looks for 2 places for rcfile:
|
||||
F</etc/box64.box64rc> and F<~/.box64rc>, in the format of .ini files.
|
||||
Settings priority: F<~/.box64rc> > F</etc/box64.box64rc> > environment variables.
|
||||
Example:
|
||||
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
=over 8
|
||||
|
||||
""")
|
||||
|
||||
for entry in data:
|
||||
pod_file.write(f"\n=item B<{entry['name']}> =I<{ '|'.join(option['key'] for option in entry['options']) }>\n\n{entry['description']}\n\n")
|
||||
for option in entry['options']:
|
||||
pod_file.write(f" * {option['key']} : {option['description']} {"[Default]" if option['default'] else ""}\n")
|
||||
pod_file.write("\n")
|
||||
|
||||
pod_file.write("""
|
||||
=back
|
||||
|
||||
=cut
|
||||
""")
|
||||
+1605
File diff suppressed because it is too large.
Load diff
Executable → Regular
File renamed without changes.
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Executable → Regular
File renamed without changes.
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
@@ -0,0 +1,45 @@
|
||||
#include "gdbjit.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static char block_name_buffer[16];
|
||||
|
||||
static enum gdb_status read_debug_info(struct gdb_reader_funcs* self, struct gdb_symbol_callbacks* cbs, void* memory, long memory_sz)
|
||||
{
|
||||
gdbjit_block_t* block = (gdbjit_block_t*)memory;
|
||||
|
||||
struct gdb_object* object = cbs->object_open(cbs);
|
||||
struct gdb_symtab* symtab = cbs->symtab_open(cbs, object, block->filename);
|
||||
sprintf(block_name_buffer, "%x", block->x64start);
|
||||
cbs->block_open(cbs, symtab, NULL, block->start, block->end, block_name_buffer);
|
||||
|
||||
cbs->line_mapping_add(cbs, symtab, block->nlines, block->lines);
|
||||
|
||||
cbs->symtab_close(cbs, symtab);
|
||||
cbs->object_close(cbs, object);
|
||||
|
||||
return GDB_SUCCESS;
|
||||
}
|
||||
|
||||
enum gdb_status unwind_frame(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
|
||||
{
|
||||
return GDB_SUCCESS;
|
||||
}
|
||||
|
||||
struct gdb_frame_id get_frame_id(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
|
||||
{
|
||||
struct gdb_frame_id frame = {0xdeadbeef, 0};
|
||||
return frame;
|
||||
}
|
||||
|
||||
void destroy_reader(struct gdb_reader_funcs* self) {}
|
||||
|
||||
__attribute__((visibility("default"))) struct gdb_reader_funcs* gdb_init_reader(void)
|
||||
{
|
||||
static struct gdb_reader_funcs funcs = {GDB_READER_INTERFACE_VERSION, NULL, read_debug_info, unwind_frame, get_frame_id, destroy_reader};
|
||||
return &funcs;
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) int plugin_is_GPL_compatible (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/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
|
||||
|
||||
# make script executable and move
|
||||
chmod +x steam
|
||||
sudo mv steam /usr/local/bin/
|
||||
|
||||
echo "Script complete."
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-arm64-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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 -DARM_DYNAREC=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]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-asahi-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-asahi-git}-git" "${pkgname%-asahi-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-asahi-git}-git" "${pkgname%-asahi-git}")
|
||||
source=('git+https://github.com/ptitSeb/box64')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-asahi-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-asahi-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DM1=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-asahi-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-asahi-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-lx2160a-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-lx2160a-git}-git" "${pkgname%-lx2160a-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-lx2160a-git}-git" "${pkgname%-lx2160a-git}")
|
||||
source=('git+https://github.com/ptitSeb/box64')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-lx2160a-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-lx2160a-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DLX2160A=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-lx2160a-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-lx2160a-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-odroid-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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 -DODROIDN2=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]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-phytium-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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,49 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-rpi-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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
|
||||
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}ARM64=1 -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,51 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-rk3xxx-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
md5sums=('SKIP')
|
||||
_rkmodel=`tr -d '\0' < /proc/device-tree/compatible`
|
||||
|
||||
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} =~ "rk3326" ]]; then
|
||||
_rksuffix=3326
|
||||
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 3326/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}=1 -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]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-rv64-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('riscv64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-rv64-git}-git" "${pkgname%-rv64-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-rv64-git}-git" "${pkgname%-rv64-git}")
|
||||
source=('git+https://github.com/ptitSeb/box64')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-rv64-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-rv64-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DRV64=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-rv64-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-rv64-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Maintainer: Jai-JAP <[email protected]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-sd845-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-tegra-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('aarch64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
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/box64')
|
||||
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 -DTEGRAX1=1 -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]>
|
||||
# Author: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box64-x64-git
|
||||
pkgver=r2431.60c6858
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
|
||||
arch=('x86_64')
|
||||
url="https://github.com/ptitSeb/box64"
|
||||
license=('MIT')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-x64-git}-git" "${pkgname%-x64-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-x64-git}-git" "${pkgname%-x64-git}")
|
||||
source=('git+https://github.com/ptitSeb/box64')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${pkgname%-x64-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-x64-git}"
|
||||
[[ ! -d ./build ]] && mkdir build
|
||||
cmake -B build -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname%-x64-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname%-x64-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# The directory containing all PKGBUILDs for BOX64
|
||||
## 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
|
||||
# use the below line if you need a DEBUG build
|
||||
# sed -i 's/RelWithDebInfo/Debug/g' ./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 64-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.
|
||||
All specified in [COMPILE.md](../docs/COMPILE.md) except for LARCH64, PPC64LE and SW64.
|
||||
|
||||
### 3. Any advantages with this solution?
|
||||
This might give you some advantages like:
|
||||
- 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 `box64` 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 box64 to .deb or .rpm installer files.
|
||||
+1317
-454
File diff suppressed because it is too large.
Load diff
Executable
+1655
File diff suppressed because it is too large.
Load diff
Executable → Regular
+17
-3
@@ -11,20 +11,23 @@ endif( NOT TEST_OUTPUT )
|
||||
if( NOT TEST_REFERENCE )
|
||||
message( FATAL_ERROR "Require TEST_REFERENCE to be defined" )
|
||||
endif( NOT TEST_REFERENCE )
|
||||
if(NOT DEFINED ENV{INTERPRETER})
|
||||
set(ENV{INTERPRETER} "")
|
||||
endif()
|
||||
|
||||
set(ENV{BOX64_LOG} 0)
|
||||
set(ENV{BOX64_NOBANNER} 1)
|
||||
if( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
|
||||
# we are inside box64 folder
|
||||
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x64lib)
|
||||
set(ENV{BOX64_LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x64lib)
|
||||
else()
|
||||
# we are inside build folder
|
||||
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/../x64lib)
|
||||
set(ENV{BOX64_LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/../x64lib)
|
||||
endif( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
|
||||
|
||||
# run the test program, capture the stdout/stderr and the result var
|
||||
execute_process(
|
||||
COMMAND ${TEST_PROGRAM} ${TEST_ARGS} ${TEST_ARGS2}
|
||||
COMMAND $ENV{INTERPRETER} ${TEST_PROGRAM} ${TEST_ARGS} ${TEST_ARGS2}
|
||||
OUTPUT_FILE ${TEST_OUTPUT}
|
||||
ERROR_VARIABLE TEST_ERROR
|
||||
RESULT_VARIABLE TEST_RESULT
|
||||
@@ -32,6 +35,9 @@ 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 )
|
||||
|
||||
@@ -43,8 +49,16 @@ execute_process(
|
||||
|
||||
# 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}" )
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box32.h"
|
||||
#include "custommem.h"
|
||||
#include "converter32.h"
|
||||
|
||||
#include "khash.h"
|
||||
|
||||
KHASH_MAP_INIT_INT64(to, ulong_t);
|
||||
KHASH_MAP_INIT_INT(from, uintptr_t);
|
||||
KHASH_MAP_INIT_STR(strings, ptr_t);
|
||||
|
||||
static kh_from_t* hash_from = NULL;
|
||||
static kh_to_t* hash_to = NULL;
|
||||
#define HASH_MSK 0xf000000f
|
||||
#define HASH_VAL 0x00ffffff
|
||||
#define HASH_SHIFT 4
|
||||
static uint32_t hash_cnt = 1;
|
||||
static pthread_rwlock_t hash_lock = {0};
|
||||
static int hash_running = 0;
|
||||
// locale
|
||||
static kh_from_t* locale_from = NULL;
|
||||
static kh_to_t* locale_to = NULL;
|
||||
static kh_strings_t* const_strings = NULL;
|
||||
|
||||
|
||||
void init_hash_helper() {
|
||||
hash_from = kh_init(from);
|
||||
hash_to = kh_init(to);
|
||||
locale_from = kh_init(from);
|
||||
locale_to = kh_init(to);
|
||||
const_strings = kh_init(strings);
|
||||
pthread_rwlock_init(&hash_lock, NULL);
|
||||
hash_running = 1;
|
||||
}
|
||||
void fini_hash_helper() {
|
||||
if(!hash_running)
|
||||
return;
|
||||
hash_running = 0;
|
||||
kh_destroy(from, hash_from);
|
||||
hash_from = NULL;
|
||||
kh_destroy(to, hash_to);
|
||||
hash_to = NULL;
|
||||
hash_cnt = 1;
|
||||
kh_destroy(from, locale_from);
|
||||
locale_from = NULL;
|
||||
kh_destroy(to, locale_to);
|
||||
locale_to = NULL;
|
||||
kh_destroy(strings, const_strings); //TODO: does not free memory correctly
|
||||
const_strings = NULL;
|
||||
pthread_rwlock_destroy(&hash_lock);
|
||||
}
|
||||
|
||||
// Convert from hash key to original 64bits value
|
||||
uintptr_t from_hash(ulong_t l) {
|
||||
// easy case first
|
||||
if((l&HASH_MSK)!=HASH_MSK) {
|
||||
return (uintptr_t)l;
|
||||
}
|
||||
if(l==0xffffffff) {
|
||||
return 0xffffffffffffffffll;
|
||||
}
|
||||
// get value from hash table second
|
||||
uintptr_t ret = 0;
|
||||
if(!hash_running) {
|
||||
//printf_log(LOG_INFO, "Warning, from_hash used but hash not running\n");
|
||||
return ret;
|
||||
}
|
||||
pthread_rwlock_rdlock(&hash_lock);
|
||||
khint_t k = kh_get(from, hash_from, l);
|
||||
if (k==kh_end(hash_from)) {
|
||||
ret = (uintptr_t)l;
|
||||
} else {
|
||||
ret = kh_value(hash_from, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
// same as from_hash
|
||||
uintptr_t from_hash_d(ulong_t l) {
|
||||
return from_hash(l);
|
||||
}
|
||||
|
||||
// Convert from 64bits to hash key, creating it if needed
|
||||
ulong_t to_hash(uintptr_t p) {
|
||||
if((p<0x100000000LL) && ((p&HASH_MSK)!=HASH_MSK))
|
||||
return (ulong_t)p;
|
||||
if(p==0xffffffffffffffffll) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
ulong_t ret = 0;
|
||||
if(!hash_running) {
|
||||
//printf_log(LOG_INFO, "Warning, to_hash used but hash not running\n");
|
||||
return ret;
|
||||
}
|
||||
khint_t k;
|
||||
pthread_rwlock_rdlock(&hash_lock);
|
||||
k = kh_get(to, hash_to, p);
|
||||
if(k==kh_end(hash_to)) {
|
||||
// create a new key, but need write lock!
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
ret = HASH_MSK | (((hash_cnt++)&HASH_VAL)<<HASH_SHIFT);
|
||||
int r;
|
||||
k = kh_put(to, hash_to, p, &r);
|
||||
kh_value(hash_to, k) = ret;
|
||||
k = kh_put(from, hash_from, ret, &r);
|
||||
kh_value(hash_from, k) = p;
|
||||
} else {
|
||||
ret = kh_value(hash_to, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Convert from 64bits to hash key and delete the entry from both hash table
|
||||
ulong_t to_hash_d(uintptr_t p) {
|
||||
if((p<0x100000000LL) && ((p&HASH_MSK)!=HASH_MSK))
|
||||
return (ulong_t)p;
|
||||
if(p==0xffffffffffffffffll)
|
||||
return 0xffffffff;
|
||||
ulong_t ret = 0;
|
||||
if(!hash_running) {
|
||||
//printf_log(LOG_INFO, "Warning, to_hash_d used but hash not running\n");
|
||||
return ret;
|
||||
}
|
||||
khint_t k;
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
k = kh_get(to, hash_to, p);
|
||||
if(k==kh_end(hash_to)) {
|
||||
/// should this be an assert?
|
||||
} else {
|
||||
ret = kh_value(hash_to, k);
|
||||
// delete both entries
|
||||
//k = kh_get(to, hash_to, p);
|
||||
kh_del(to, hash_to, k);
|
||||
k = kh_get(from, hash_from, ret);
|
||||
kh_del(from, hash_from, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct struct_locale_s {
|
||||
void* p0[13]; // struct __locale_data *
|
||||
void* p1; //const unsigned short int *__ctype_b;
|
||||
void* p2; //const int *__ctype_tolower;
|
||||
void* p3; //const int *__ctype_toupper;
|
||||
void* p4[13]; //const char*
|
||||
} struct_locale_t;
|
||||
// not a real structure
|
||||
#define LOCALE_SIGN 0x54abcd845412LL
|
||||
typedef struct struct_locale_32_s {
|
||||
ptr_t p0[13];
|
||||
ptr_t p1;
|
||||
ptr_t p2;
|
||||
ptr_t p3;
|
||||
ptr_t p4[13];
|
||||
uint64_t sign;
|
||||
struct_locale_t* org; // save the orginal locale
|
||||
// copy of the array, in case some apps use them
|
||||
unsigned short int type_b[384];
|
||||
int tolower[384];
|
||||
int tohigher[384];
|
||||
} struct_locale_32_t;
|
||||
|
||||
void to_struct_locale(ptr_t d, const struct_locale_t *src) {
|
||||
if (!src) return;
|
||||
struct_locale_32_t* dest = from_ptrv(d);
|
||||
// save the original locale
|
||||
dest->sign = LOCALE_SIGN;
|
||||
dest->org = (void*)src;
|
||||
//copy the 2 arrays
|
||||
for(int i=0; i<13; ++i) {
|
||||
dest->p0[i] = to_hashv(src->p0[i]);
|
||||
}
|
||||
for(int i=0; i<13; ++i) {
|
||||
dest->p4[i] = to_cstring(src->p4[i]);
|
||||
}
|
||||
// copy the 3 ctype int (1st is short int, but int will do)
|
||||
memcpy(dest->type_b, src->p1-128*sizeof(short), 384*sizeof(short));
|
||||
memcpy(dest->tolower, src->p2-128*sizeof(int), 384*sizeof(int));
|
||||
memcpy(dest->tohigher, src->p3-128*sizeof(int), 384*sizeof(int));
|
||||
dest->p1 = to_ptrv(dest->type_b)+128*sizeof(short);
|
||||
dest->p2 = to_ptrv(dest->tolower)+128*sizeof(int);
|
||||
dest->p3 = to_ptrv(dest->tohigher)+128*sizeof(int);
|
||||
}
|
||||
void free_struct_locale(const struct_locale_t *src) {
|
||||
for(int i=0; i<13; ++i) {
|
||||
to_hash_d((uintptr_t)src->p0[i]);
|
||||
}
|
||||
/*for(int i=0; i<13; ++i) {
|
||||
to_hash_d((uintptr_t)src->p4[i]);
|
||||
}*/
|
||||
}
|
||||
|
||||
// Convert from locale key to original 64bits value
|
||||
void* from_locale(ptr_t l) {
|
||||
// easy case first
|
||||
if(l < 0x100) {
|
||||
return from_ptrv(l);
|
||||
}
|
||||
if(l == 0xffffffff) {
|
||||
return (void*)-1;
|
||||
}
|
||||
// get value from hash table second
|
||||
void* ret = 0;
|
||||
if(!hash_running) {
|
||||
//printf_log(LOG_INFO, "Warning, from_locale used but hash not running\n");
|
||||
return ret;
|
||||
}
|
||||
struct_locale_32_t* loc = from_ptrv(l);
|
||||
if(loc->sign==LOCALE_SIGN)
|
||||
return loc->org;
|
||||
pthread_rwlock_rdlock(&hash_lock);
|
||||
khint_t k = kh_get(from, locale_from, l);
|
||||
if (k==kh_end(locale_from)) {
|
||||
ret = from_ptrv(l);
|
||||
} else {
|
||||
ret = (void*)kh_value(locale_from, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
//from_struct_locale((struct_locale_t*)ret, l);
|
||||
return ret;
|
||||
}
|
||||
// same as from_locale
|
||||
void* from_locale_d(ptr_t l) {
|
||||
return from_locale(l);
|
||||
}
|
||||
|
||||
// Convert from 64bits to locale key, creating it if needed
|
||||
ptr_t to_locale(void* p) {
|
||||
if((uintptr_t)p < 0x100) {
|
||||
return to_ptrv(p);
|
||||
}
|
||||
if(p == (void*)-1) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
ptr_t ret = 0;
|
||||
if(!hash_running) {
|
||||
//printf_log(LOG_INFO, "Warning, to_locale used but hash not running\n");
|
||||
return ret;
|
||||
}
|
||||
khint_t k;
|
||||
pthread_rwlock_rdlock(&hash_lock);
|
||||
k = kh_get(to, locale_to, (uintptr_t)p);
|
||||
int conv = 0;
|
||||
if(k==kh_end(locale_to)) {
|
||||
// create a new key, but need write lock!
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
// a locale_t is 5 pointer!
|
||||
void* m = calloc(1, sizeof(struct_locale_32_t)); // the 3 ctype value are also inside the locale struct
|
||||
ret = to_ptrv(m);
|
||||
// add to hash maps
|
||||
int r;
|
||||
k = kh_put(to, locale_to, (uintptr_t)p, &r);
|
||||
kh_value(locale_to, k) = ret;
|
||||
k = kh_put(from, locale_from, ret, &r);
|
||||
kh_value(locale_from, k) = (uintptr_t)p;
|
||||
conv = 1;
|
||||
} else {
|
||||
ret = kh_value(locale_to, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
if(conv)
|
||||
to_struct_locale(ret, (struct_locale_t*)p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Convert from 64bits to hash key and delete the entry from both hash table
|
||||
ptr_t to_locale_d(void* p) {
|
||||
if((uintptr_t)p < 0x100)
|
||||
return to_ptrv(p);
|
||||
ptr_t ret = 0;
|
||||
if(!hash_running)
|
||||
return ret;
|
||||
khint_t k;
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
k = kh_get(to, locale_to, (uintptr_t)p);
|
||||
if(k==kh_end(locale_to)) {
|
||||
/// should this be an assert?
|
||||
} else {
|
||||
ret = kh_value(locale_to, k);
|
||||
// free the memory
|
||||
free_struct_locale(p);
|
||||
free(from_ptrv(ret));
|
||||
// delete both entries
|
||||
k = kh_get(to, locale_to, (uintptr_t)p);
|
||||
kh_del(to, locale_to, k);
|
||||
k = kh_get(from, locale_from, ret);
|
||||
kh_del(from, locale_from, k);
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* from_cstring(ptr_t p) {
|
||||
return (char*)from_ptrv(p);
|
||||
}
|
||||
|
||||
ptr_t to_cstring(char* p) {
|
||||
if((uintptr_t)p<0x100000000LL)
|
||||
return to_ptrv(p);
|
||||
ptr_t ret = 0;
|
||||
pthread_rwlock_rdlock(&hash_lock);
|
||||
khint_t k = kh_get(strings, const_strings, p);
|
||||
if(k==kh_end(const_strings)) {
|
||||
// create a new key, but need write lock!
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
ret = to_ptrv(box32_strdup(p));
|
||||
int r;
|
||||
k = kh_put(strings, const_strings, (char*)from_ptrv(ret), &r);
|
||||
kh_value(const_strings, k) = ret;
|
||||
} else
|
||||
ret = kh_value(const_strings, k);
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptr_t to_cstring_d(char* p) {
|
||||
if((uintptr_t)p<0x100000000LL)
|
||||
return to_ptrv(p);
|
||||
ptr_t ret = 0;
|
||||
pthread_rwlock_wrlock(&hash_lock);
|
||||
khint_t k = kh_get(strings, const_strings, p);
|
||||
if(k==kh_end(const_strings)) {
|
||||
// assert?
|
||||
} else {
|
||||
ret = kh_value(const_strings, k);
|
||||
kh_del(strings, const_strings, k);
|
||||
box32_free(from_ptrv(ret));
|
||||
}
|
||||
pthread_rwlock_unlock(&hash_lock);
|
||||
return ret;
|
||||
}
|
||||
Executable → Regular
+209
-104
@@ -5,6 +5,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "box64context.h"
|
||||
#include "debug.h"
|
||||
@@ -18,6 +19,12 @@
|
||||
#include "wrapper.h"
|
||||
#include "x64emu.h"
|
||||
#include "signals.h"
|
||||
#include "gltools.h"
|
||||
#include "rbtree.h"
|
||||
#include "dynarec.h"
|
||||
#ifdef BOX32
|
||||
#include "box32.h"
|
||||
#endif
|
||||
|
||||
EXPORTDYN
|
||||
void initAllHelpers(box64context_t* context)
|
||||
@@ -26,6 +33,9 @@ void initAllHelpers(box64context_t* context)
|
||||
if(inited)
|
||||
return;
|
||||
my_context = context;
|
||||
#ifdef BOX32
|
||||
init_hash_helper();
|
||||
#endif
|
||||
init_pthread_helper();
|
||||
init_bridge_helper();
|
||||
init_signal_helper(context);
|
||||
@@ -41,6 +51,9 @@ void finiAllHelpers(box64context_t* context)
|
||||
fini_pthread_helper(context);
|
||||
fini_signal_helper();
|
||||
fini_bridge_helper();
|
||||
#ifdef BOX32
|
||||
fini_hash_helper();
|
||||
#endif
|
||||
fini_custommem_helper(context);
|
||||
finied = 1;
|
||||
}
|
||||
@@ -62,24 +75,34 @@ void free_tlsdatasize(void* p)
|
||||
if(!p)
|
||||
return;
|
||||
tlsdatasize_t *data = (tlsdatasize_t*)p;
|
||||
free(data->tlsdata);
|
||||
free(p);
|
||||
actual_free(data->ptr);
|
||||
actual_free(p);
|
||||
if(my_context)
|
||||
pthread_setspecific(my_context->tlskey, NULL);
|
||||
}
|
||||
|
||||
void x64Syscall(x64emu_t *emu);
|
||||
void x86Syscall(x64emu_t *emu);
|
||||
|
||||
int unlockMutex()
|
||||
{
|
||||
int ret = unlockCustommemMutex();
|
||||
int i;
|
||||
#ifdef USE_CUSTOM_MUTEX
|
||||
uint32_t tid = (uint32_t)GetTID();
|
||||
#define GO(A, B) \
|
||||
i = (native_lock_storeifref2_d(&A, 0, 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)
|
||||
@@ -88,6 +111,7 @@ int unlockMutex()
|
||||
#endif
|
||||
GO(my_context->mutex_tls, 9)
|
||||
GO(my_context->mutex_thread, 10)
|
||||
GO(my_context->mutex_bridge, 11)
|
||||
#undef GO
|
||||
|
||||
return ret;
|
||||
@@ -98,10 +122,8 @@ void relockMutex(int locks)
|
||||
relockCustommemMutex(locks);
|
||||
#define GO(A, B) \
|
||||
if(locks&(1<<B)) \
|
||||
pthread_mutex_lock(&A); \
|
||||
mutex_trylock(&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)
|
||||
@@ -110,26 +132,43 @@ void relockMutex(int locks)
|
||||
#endif
|
||||
GO(my_context->mutex_tls, 9)
|
||||
GO(my_context->mutex_thread, 10)
|
||||
GO(my_context->mutex_bridge, 11)
|
||||
#undef GO
|
||||
}
|
||||
|
||||
static void init_mutexes(box64context_t* context)
|
||||
void init_mutexes(box64context_t* context)
|
||||
{
|
||||
#ifndef DYNAREC
|
||||
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);
|
||||
#ifndef DYNAREC
|
||||
pthread_mutex_init(&context->mutex_lock, &attr);
|
||||
#else
|
||||
pthread_mutex_init(&context->mutex_dyndump, &attr);
|
||||
#endif
|
||||
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_mutexattr_destroy(&attr);
|
||||
#else
|
||||
#ifdef USE_CUSTOM_MUTEX
|
||||
native_lock_store(&context->mutex_trace, 0);
|
||||
native_lock_store(&context->mutex_tls, 0);
|
||||
native_lock_store(&context->mutex_thread, 0);
|
||||
native_lock_store(&context->mutex_bridge, 0);
|
||||
native_lock_store(&context->mutex_dyndump, 0);
|
||||
#else
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
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_dyndump, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
#endif
|
||||
pthread_mutex_init(&context->mutex_lock, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void atfork_child_box64context(void)
|
||||
@@ -138,6 +177,31 @@ static void atfork_child_box64context(void)
|
||||
init_mutexes(my_context);
|
||||
}
|
||||
|
||||
void freeCycleLog(box64context_t* ctx)
|
||||
{
|
||||
if(BOX64ENV(rolling_log)) {
|
||||
for(int i=0; i<BOX64ENV(rolling_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(box64context_t* context)
|
||||
{
|
||||
if(BOX64ENV(rolling_log)) {
|
||||
context->log_call = (char**)box_calloc(BOX64ENV(rolling_log), sizeof(char*));
|
||||
context->log_ret = (char**)box_calloc(BOX64ENV(rolling_log), sizeof(char*));
|
||||
for(int i=0; i<BOX64ENV(rolling_log); ++i) {
|
||||
context->log_call[i] = (char*)box_calloc(256, 1);
|
||||
context->log_ret[i] = (char*)box_calloc(128, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPORTDYN
|
||||
box64context_t *NewBox64Context(int argc)
|
||||
{
|
||||
@@ -148,24 +212,46 @@ box64context_t *NewBox64Context(int argc)
|
||||
}
|
||||
#endif
|
||||
// init and put default values
|
||||
box64context_t *context = my_context = (box64context_t*)calloc(1, sizeof(box64context_t));
|
||||
box64context_t *context = my_context = (box64context_t*)box_calloc(1, sizeof(box64context_t));
|
||||
|
||||
context->deferedInit = 1;
|
||||
initCycleLog(context);
|
||||
|
||||
context->deferredInit = 1;
|
||||
context->sel_serial = 1;
|
||||
|
||||
init_custommem_helper(context);
|
||||
|
||||
context->maplib = NewLibrarian(context, 1);
|
||||
context->local_maplib = NewLibrarian(context, 1);
|
||||
context->maplib = NewLibrarian(context);
|
||||
context->local_maplib = NewLibrarian(context);
|
||||
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, x64Syscall, 0, NULL);
|
||||
context->vsyscall = AddBridge(context->system, vFEv, box64_is32bits?x86Syscall:x64Syscall, 0, NULL);
|
||||
// create the vsyscalls
|
||||
if(box64_is32bits) {
|
||||
#ifdef BOX32
|
||||
addAlternate((void*)0xffffe400, from_ptrv(context->vsyscall));
|
||||
#endif
|
||||
} else {
|
||||
context->vsyscalls[0] = AddVSyscall(context->system, 96);
|
||||
context->vsyscalls[1] = AddVSyscall(context->system, 201);
|
||||
context->vsyscalls[2] = AddVSyscall(context->system, 309);
|
||||
// create the alternate to map at address
|
||||
addAlternate((void*)0xffffffffff600000, (void*)context->vsyscalls[0]);
|
||||
addAlternate((void*)0xffffffffff600400, (void*)context->vsyscalls[1]);
|
||||
addAlternate((void*)0xffffffffff600800, (void*)context->vsyscalls[2]);
|
||||
}
|
||||
// create exit bridge
|
||||
context->exit_bridge = AddBridge(context->system, NULL, NULL, 0, NULL);
|
||||
// get handle to box64 itself
|
||||
#ifndef STATICBUILD
|
||||
context->box64lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
|
||||
#endif
|
||||
context->dlprivate = NewDLPrivate();
|
||||
|
||||
context->argc = argc;
|
||||
context->argv = (char**)calloc(context->argc+1, sizeof(char*));
|
||||
context->argv = (char**)box_calloc(context->argc+1, sizeof(char*));
|
||||
|
||||
init_mutexes(context);
|
||||
pthread_atfork(NULL, NULL, atfork_child_box64context);
|
||||
@@ -177,11 +263,35 @@ box64context_t *NewBox64Context(int argc)
|
||||
context->canary[getrand(4)] = 0;
|
||||
printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at FS:0x28, value:%08X\n", *(uint32_t*)context->canary);
|
||||
|
||||
// init segments
|
||||
for(int i=0; i<16; i++) {
|
||||
context->segtls[i].limit = (uintptr_t)-1LL;
|
||||
}
|
||||
context->segtls[10].key_init = 0; // 0x53 selector
|
||||
context->segtls[10].present = 1;
|
||||
context->segtls[8].key_init = 0; // 0x43 selector
|
||||
context->segtls[8].present = 1;
|
||||
context->segtls[6].key_init = 0; // 0x33 selector
|
||||
context->segtls[6].present = 1;
|
||||
context->segtls[5].key_init = 0; // 0x2b selector
|
||||
context->segtls[5].present = 1;
|
||||
context->segtls[4].key_init = 0; // 0x23 selector
|
||||
context->segtls[4].present = 1;
|
||||
context->segtls[4].is32bits = 1;
|
||||
|
||||
context->globdata = NewMapSymbols();
|
||||
context->uniques = NewMapSymbols();
|
||||
|
||||
initAllHelpers(context);
|
||||
|
||||
#ifdef DYNAREC
|
||||
context->db_sizes = rbtree_init("db_sizes");
|
||||
#endif
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void freeALProcWrapper(box64context_t* context);
|
||||
EXPORTDYN
|
||||
void FreeBox64Context(box64context_t** context)
|
||||
{
|
||||
@@ -191,8 +301,9 @@ void FreeBox64Context(box64context_t** context)
|
||||
if(--(*context)->forked >= 0)
|
||||
return;
|
||||
|
||||
box64context_t* ctx = *context; // local copy to do the cleanning
|
||||
box64context_t* ctx = *context; // local copy to do the cleaning
|
||||
|
||||
//clean_current_emuthread(); // cleaning main thread seems a bad idea
|
||||
if(ctx->local_maplib)
|
||||
FreeLibrarian(&ctx->local_maplib, NULL);
|
||||
if(ctx->maplib)
|
||||
@@ -202,7 +313,7 @@ void FreeBox64Context(box64context_t** context)
|
||||
for(int i=0; i<ctx->elfsize; ++i) {
|
||||
FreeElfHeader(&ctx->elfs[i]);
|
||||
}
|
||||
free(ctx->elfs);
|
||||
box_free(ctx->elfs);
|
||||
|
||||
FreeCollection(&ctx->box64_path);
|
||||
FreeCollection(&ctx->box64_ld_lib);
|
||||
@@ -210,20 +321,22 @@ void FreeBox64Context(box64context_t** context)
|
||||
// stop trace now
|
||||
if(ctx->dec)
|
||||
DeleteX64TraceDecoder(&ctx->dec);
|
||||
if(ctx->dec32)
|
||||
DeleteX86TraceDecoder(&ctx->dec32);
|
||||
if(ctx->zydis)
|
||||
DeleteX64Trace(ctx);
|
||||
|
||||
if(ctx->deferedInitList)
|
||||
free(ctx->deferedInitList);
|
||||
if(ctx->deferredInitList)
|
||||
box_free(ctx->deferredInitList);
|
||||
|
||||
free(ctx->argv);
|
||||
/*box_free(ctx->argv);*/
|
||||
|
||||
for (int i=0; i<ctx->envc; ++i)
|
||||
free(ctx->envv[i]);
|
||||
free(ctx->envv);
|
||||
/*for (int i=0; i<ctx->envc; ++i)
|
||||
box_free(ctx->envv[i]);
|
||||
box_free(ctx->envv);*/
|
||||
|
||||
if(ctx->atfork_sz) {
|
||||
free(ctx->atforks);
|
||||
box_free(ctx->atforks);
|
||||
ctx->atforks = NULL;
|
||||
ctx->atfork_sz = ctx->atfork_cap = 0;
|
||||
}
|
||||
@@ -239,63 +352,104 @@ void FreeBox64Context(box64context_t** context)
|
||||
|
||||
FreeDLPrivate(&ctx->dlprivate);
|
||||
|
||||
free(ctx->fullpath);
|
||||
free(ctx->box64path);
|
||||
box_free(ctx->fullpath);
|
||||
box_free(ctx->box64path);
|
||||
box_free(ctx->bashpath);
|
||||
|
||||
FreeBridge(&ctx->system);
|
||||
|
||||
#ifndef STATICBUILD
|
||||
freeGLProcWrapper(ctx);
|
||||
freeALProcWrapper(ctx);
|
||||
#ifdef BOX32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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)
|
||||
free(ctx->tlsdata);
|
||||
box_free(ctx->tlsdata);
|
||||
|
||||
pthread_mutex_destroy(&ctx->mutex_once);
|
||||
pthread_mutex_destroy(&ctx->mutex_once2);
|
||||
pthread_mutex_destroy(&ctx->mutex_trace);
|
||||
#ifndef DYNAREC
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
#else
|
||||
pthread_mutex_destroy(&ctx->mutex_dyndump);
|
||||
#endif
|
||||
pthread_mutex_destroy(&ctx->mutex_tls);
|
||||
pthread_mutex_destroy(&ctx->mutex_thread);
|
||||
|
||||
free_neededlib(&ctx->neededlibs);
|
||||
free_neededlib(ctx->neededlibs);
|
||||
ctx->neededlibs = NULL;
|
||||
|
||||
if(ctx->emu_sig)
|
||||
FreeX64Emu(&ctx->emu_sig);
|
||||
|
||||
FreeMapSymbols(&ctx->globdata);
|
||||
FreeMapSymbols(&ctx->uniques);
|
||||
|
||||
#ifdef DYNAREC
|
||||
//dynarec_log(LOG_INFO, "BOX64 Dynarec at exit: Max DB=%d, righter=%d\n", ctx->max_db_size, rb_get_righter(ctx->db_sizes));
|
||||
rbtree_delete(ctx->db_sizes);
|
||||
#endif
|
||||
|
||||
finiAllHelpers(ctx);
|
||||
|
||||
free(ctx);
|
||||
#ifdef DYNAREC
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
#else
|
||||
pthread_mutex_destroy(&ctx->mutex_trace);
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
pthread_mutex_destroy(&ctx->mutex_tls);
|
||||
pthread_mutex_destroy(&ctx->mutex_thread);
|
||||
pthread_mutex_destroy(&ctx->mutex_bridge);
|
||||
#endif
|
||||
|
||||
freeCycleLog(ctx);
|
||||
|
||||
box_free(ctx);
|
||||
}
|
||||
|
||||
int AddElfHeader(box64context_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(box64context_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(box64context_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 = realloc(context->tlsdata, context->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
|
||||
@@ -308,52 +462,3 @@ int AddTLSPartition(box64context_t* context, int tlssize) {
|
||||
return -context->tlssize; // negative offset
|
||||
}
|
||||
|
||||
void add_neededlib(needed_libs_t* needed, library_t* lib)
|
||||
{
|
||||
if(!needed)
|
||||
return;
|
||||
for(int i=0; i<needed->size; ++i)
|
||||
if(needed->libs[i] == lib)
|
||||
return;
|
||||
if(needed->size == needed->cap) {
|
||||
needed->cap += 8;
|
||||
needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*));
|
||||
}
|
||||
needed->libs[needed->size++] = lib;
|
||||
}
|
||||
|
||||
void free_neededlib(needed_libs_t* needed)
|
||||
{
|
||||
if(!needed)
|
||||
return;
|
||||
needed->cap = 0;
|
||||
needed->size = 0;
|
||||
if(needed->libs)
|
||||
free(needed->libs);
|
||||
needed->libs = NULL;
|
||||
}
|
||||
|
||||
void add_dependedlib(needed_libs_t* depended, library_t* lib)
|
||||
{
|
||||
if(!depended)
|
||||
return;
|
||||
for(int i=0; i<depended->size; ++i)
|
||||
if(depended->libs[i] == lib)
|
||||
return;
|
||||
if(depended->size == depended->cap) {
|
||||
depended->cap += 8;
|
||||
depended->libs = (library_t**)realloc(depended->libs, depended->cap*sizeof(library_t*));
|
||||
}
|
||||
depended->libs[depended->size++] = lib;
|
||||
}
|
||||
|
||||
void free_dependedlib(needed_libs_t* depended)
|
||||
{
|
||||
if(!depended)
|
||||
return;
|
||||
depended->cap = 0;
|
||||
depended->size = 0;
|
||||
if(depended->libs)
|
||||
free(depended->libs);
|
||||
depended->libs = NULL;
|
||||
}
|
||||
Executable → Regular
+2
-2
@@ -2,7 +2,7 @@
|
||||
#define __BOX64_VERSION_H_
|
||||
|
||||
#define BOX64_MAJOR 0
|
||||
#define BOX64_MINOR 1
|
||||
#define BOX64_REVISION 2
|
||||
#define BOX64_MINOR 3
|
||||
#define BOX64_REVISION 4
|
||||
|
||||
#endif //__BOX64_VERSION_H_
|
||||
Executable → Regular
+1
-1
@@ -9,7 +9,7 @@
|
||||
|
||||
void PrintBox64Version()
|
||||
{
|
||||
printf("Box64%s%s v%d.%d.%d %s built on %s %s\n",
|
||||
printf_ftrace(1, "Box64%s%s v%d.%d.%d %s built on %s %s\n",
|
||||
#ifdef HAVE_TRACE
|
||||
" with trace",
|
||||
#else
|
||||
|
||||
Executable → Regular
+16
-1
@@ -1,6 +1,21 @@
|
||||
#include "box64version.h"
|
||||
#ifdef NOGIT
|
||||
#define GITREV "nogit"
|
||||
#else
|
||||
#include "git_head.h"
|
||||
#endif
|
||||
|
||||
#ifndef __BUILD_INFO_H__
|
||||
#define __BUILD_INFO_H__
|
||||
|
||||
void PrintBox64Version();
|
||||
void PrintBox64Version(void);
|
||||
|
||||
#define BOX64_BUILD_INFO_STR_HELPER(x) #x
|
||||
#define BOX64_BUILD_INFO_STR(x) BOX64_BUILD_INFO_STR_HELPER(x)
|
||||
|
||||
#define BOX64_BUILD_INFO_STRING \
|
||||
"Box64" \
|
||||
" v" BOX64_BUILD_INFO_STR(BOX64_MAJOR) "." BOX64_BUILD_INFO_STR(BOX64_MINOR) "." BOX64_BUILD_INFO_STR(BOX64_REVISION) \
|
||||
" " GITREV
|
||||
|
||||
#endif //__BUILD_INFO_H__
|
||||
+1577
File diff suppressed because it is too large.
Load diff
+1890
-828
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,56 @@
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#ifdef BUILD_DYNAMIC
|
||||
#define EXPORTDYN __attribute__((visibility("default")))
|
||||
#else
|
||||
#define EXPORTDYN
|
||||
#endif
|
||||
|
||||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0x40
|
||||
#endif
|
||||
|
||||
typedef void x64emu_t;
|
||||
extern void* mapallmem;
|
||||
extern int box64_is32bits;
|
||||
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
|
||||
void freeProtection(uintptr_t addr, size_t size);
|
||||
void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
|
||||
int internal_munmap(void* addr, unsigned long length);
|
||||
void* box_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
|
||||
|
||||
void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
|
||||
|
||||
extern int running32bits;
|
||||
extern box64env_t box64env;
|
||||
|
||||
EXPORT void* mmap64(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset)
|
||||
{
|
||||
void* ret;
|
||||
if(!addr && ((running32bits && BOX64ENV(mmap32)) || (flags&MAP_32BIT) || box64_is32bits))
|
||||
ret = box_mmap(addr, length, prot, flags | MAP_32BIT, fd, offset);
|
||||
else
|
||||
ret = internal_mmap(addr, length, prot, flags, fd, offset);
|
||||
if(ret!=MAP_FAILED && mapallmem)
|
||||
setProtection((uintptr_t)ret, length, prot);
|
||||
return ret;
|
||||
}
|
||||
EXPORT void* mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) __attribute__((alias("mmap64")));
|
||||
|
||||
EXPORT int munmap(void* addr, unsigned long length)
|
||||
{
|
||||
int ret = internal_munmap(addr, length);
|
||||
if(!ret && mapallmem) {
|
||||
freeProtection((uintptr_t)addr, length);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
Executable → Regular
+913
-144
File diff suppressed because it is too large.
Load diff
Executable → Regular
+3
-21
@@ -19,36 +19,18 @@ arm64_epilog:
|
||||
stp x24, x25, [x0, (8 * 14)]
|
||||
stp x26, x27, [x0, (8 * 16)] // put back reg value in emu, including EIP (so x27 must be EIP now)
|
||||
//restore all used register
|
||||
add sp, x28, 0
|
||||
//vpop {d8-d15}
|
||||
ldp x19, x20, [sp, (8 * 0)]
|
||||
ldp x21, x22, [sp, (8 * 2)]
|
||||
ldp x23, x24, [sp, (8 * 4)]
|
||||
ldp x25, x26, [sp, (8 * 6)]
|
||||
ldr x27, [sp, (8 * 8)]
|
||||
ldp x27, x28, [sp, (8 * 8)]
|
||||
ldp d8, d9, [sp, (8 *10)]
|
||||
ldp d10, d11, [sp, (8 *12)]
|
||||
ldp d12, d13, [sp, (8 *14)]
|
||||
ldp d14, d15, [sp, (8 *16)]
|
||||
add sp, sp, (8 * 18)
|
||||
ldp lr, fp, [sp], 16 // saved lr
|
||||
//end, return...
|
||||
ret
|
||||
|
||||
|
||||
.global arm64_epilog_fast
|
||||
arm64_epilog_fast:
|
||||
//restore all used register
|
||||
//vpop {d8-d15}
|
||||
ldp x19, x20, [sp, (8 * 0)]
|
||||
ldp x21, x22, [sp, (8 * 2)]
|
||||
ldp x23, x24, [sp, (8 * 4)]
|
||||
ldp x25, x26, [sp, (8 * 6)]
|
||||
ldr x27, [sp, (8 * 8)]
|
||||
ldp d8, d9, [sp, (8 *10)]
|
||||
ldp d10, d11, [sp, (8 *12)]
|
||||
ldp d12, d13, [sp, (8 *14)]
|
||||
ldp d14, d15, [sp, (8 *16)]
|
||||
add sp, sp, (8 * 18)
|
||||
ldp lr, fp, [sp], 16 // saved lr
|
||||
ldp x30, x29, [sp], 16 // saved lr
|
||||
//end, return...
|
||||
ret
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <stdint.h>
|
||||
#include "arm64_immenc.h"
|
||||
|
||||
#define one (uint64_t)1
|
||||
|
||||
// Returns the packed valid-N-imms-immr (1-1-6-6 bits); returns 0 if bitmask is not encodable
|
||||
int convert_bitmask(uint64_t bitmask) {
|
||||
if (bitmask == 0 || bitmask == ~0ULL) return 0;
|
||||
|
||||
uint64_t size, mask, pat;
|
||||
|
||||
for (size = 6; size > 1; --size) {
|
||||
mask = (one << (1 << (size - 1))) - 1;
|
||||
pat = bitmask & mask;
|
||||
|
||||
if (pat != ((bitmask >> (1 << (size - 1))) & mask)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mask = (size >= 6) ? ~0ULL : ((one << (1 << size)) - 1);
|
||||
pat = bitmask & mask;
|
||||
|
||||
for (uint64_t i = 1; i < 7 - size; ++i) {
|
||||
uint64_t boff = i * (1 << size);
|
||||
if (((bitmask >> boff) & mask) != pat) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int immr = 0;
|
||||
uint64_t last_bit = one << ((1 << size) - 1);
|
||||
|
||||
if (pat & 1) {
|
||||
while (pat & last_bit) {
|
||||
pat = ((pat - last_bit) << 1) | 1;
|
||||
++immr;
|
||||
}
|
||||
} else {
|
||||
immr = 1 << size;
|
||||
while (!(pat & 1)) {
|
||||
pat >>= 1;
|
||||
--immr;
|
||||
}
|
||||
}
|
||||
|
||||
if (pat & (pat + 1)) return 0;
|
||||
|
||||
int to = 1;
|
||||
while (pat & (one << to)) ++to;
|
||||
|
||||
return 0x2000 + ((size == 6) << 12) + ((((0x1E << size) & 0x3F) + (to - 1)) << 6) + immr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <unordered_set>
|
||||
int main() {
|
||||
std::unordered_set<uint64_t> okvals;
|
||||
uint64_t val;
|
||||
|
||||
for (int n = 1; n < 7; ++n) {
|
||||
int imms0 = ((n == 6) ? 0xC0 : 0x80) + ((0x1E << n) & 0x3F);
|
||||
for (int nones = 0; nones < (1 << n) - 1; ++nones) {
|
||||
val = (one << (nones + 1)) - 1;
|
||||
for (int j = 0; j < 6 - n; ++j) {
|
||||
val += val << (1 << (n + j));
|
||||
}
|
||||
for (int immr = 0; immr < (1 << n); ++immr) {
|
||||
int exp = ((imms0 + nones) << 6) + immr;
|
||||
int got = convert_bitmask(val);
|
||||
if (exp != got) {
|
||||
printf("0x%016lX: expected %04X, got %04X\n", val, exp, got);
|
||||
}
|
||||
okvals.emplace(val);
|
||||
val = (val >> 1) | ((val & 1) << 63);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for (uint64_t i = 1; i < 0xFFFFFFFFFFFFFFFFu; ++i) {
|
||||
int got = convert_bitmask(i);
|
||||
if (!!got != (okvals.find(i) != okvals.cend())) {
|
||||
printf("0x%016lX: expected %s, got %04X\n", i, (!!got ? "non0" : "0000"), got);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef __ARM64_IMMENC_H__
|
||||
#define __ARM64_IMMENC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int convert_bitmask(uint64_t bitmask);
|
||||
|
||||
#endif // __ARM64_IMMENC_H__
|
||||
@@ -0,0 +1,277 @@
|
||||
//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 arm64_lock_read_b
|
||||
.global arm64_lock_write_b
|
||||
.global arm64_lock_read_h
|
||||
.global arm64_lock_write_h
|
||||
.global arm64_lock_read_d
|
||||
.global arm64_lock_write_d
|
||||
.global arm64_lock_read_dd
|
||||
.global arm64_lock_write_dd
|
||||
.global arm64_lock_read_dq
|
||||
.global arm64_lock_write_dq
|
||||
.global arm64_lock_xchg_dd
|
||||
.global arm64_lock_xchg_d
|
||||
.global arm64_lock_xchg_h
|
||||
.global arm64_lock_xchg_b
|
||||
.global arm64_lock_storeifnull
|
||||
.global arm64_lock_storeifnull_d
|
||||
.global arm64_lock_storeifref
|
||||
.global arm64_lock_storeifref_d
|
||||
.global arm64_lock_storeifref2_d
|
||||
.global arm64_lock_decifnot0b
|
||||
.global arm64_lock_storeb
|
||||
.global arm64_lock_incif0
|
||||
.global arm64_lock_decifnot0
|
||||
.global arm64_lock_store
|
||||
.global arm64_lock_store_dd
|
||||
.global arm64_lock_get_b
|
||||
.global arm64_lock_get_d
|
||||
.global arm64_lock_get_dd
|
||||
|
||||
arm64_lock_read_b:
|
||||
dmb ish
|
||||
// address is x0, return is x0
|
||||
ldaxrb w0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_write_b:
|
||||
// address is x0, value is x1, return is x0
|
||||
mov x2, x0
|
||||
stlxrb w0, w1, [x2]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_read_h:
|
||||
dmb ish
|
||||
// address is x0, return is x0
|
||||
ldaxrh w0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_write_h:
|
||||
// address is x0, value is x1, return is x0
|
||||
mov x2, x0
|
||||
stlxrh w0, w1, [x2]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_read_d:
|
||||
dmb ish
|
||||
// address is x0, return is x0
|
||||
ldaxr w0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_write_d:
|
||||
// address is x0, value is w1, return is x0
|
||||
mov x2, x0
|
||||
stlxr w0, w1, [x2]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_read_dd:
|
||||
dmb ish
|
||||
// address is x0, return is x0
|
||||
ldaxr x0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_write_dd:
|
||||
// address is x0, value is x1, return is x0
|
||||
mov x2, x0
|
||||
stlxr w0, x1, [x2]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_read_dq:
|
||||
dmb ish
|
||||
// address is r2, return is r0, r1
|
||||
ldaxp x4, x3, [x2]
|
||||
str x4, [x0]
|
||||
str x3, [x1]
|
||||
ret
|
||||
|
||||
arm64_lock_write_dq:
|
||||
// address is r2, value is r0, r1, return is r0
|
||||
// r0 needs to be aligned
|
||||
stlxp w3, x0, x1, [x2]
|
||||
mov w0, w3
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
|
||||
arm64_lock_xchg_dd:
|
||||
dmb ish
|
||||
arm64_lock_xchg_dd_0:
|
||||
// address is x0, value is x1, return old value in x0
|
||||
ldaxr x2, [x0]
|
||||
stlxr w3, x1, [x0]
|
||||
cbnz w3, arm64_lock_xchg_dd_0
|
||||
mov x0, x2
|
||||
ret
|
||||
|
||||
arm64_lock_xchg_d:
|
||||
dmb ish
|
||||
arm64_lock_xchg_d_0:
|
||||
// address is x0, value is x1, return old value in x0
|
||||
ldaxr w2, [x0]
|
||||
stlxr w3, w1, [x0]
|
||||
cbnz w3, arm64_lock_xchg_d_0
|
||||
mov w0, w2
|
||||
ret
|
||||
|
||||
arm64_lock_xchg_h:
|
||||
dmb ish
|
||||
arm64_lock_xchg_h_0:
|
||||
// address is x0, value is x1, return old value in x0
|
||||
ldaxrh w2, [x0]
|
||||
stlxrh w3, w1, [x0]
|
||||
cbnz w3, arm64_lock_xchg_h_0
|
||||
mov w0, w2
|
||||
ret
|
||||
|
||||
arm64_lock_xchg_b:
|
||||
dmb ish
|
||||
arm64_lock_xchg_b_0:
|
||||
// address is x0, value is x1, return old value in x0
|
||||
ldaxrb w2, [x0]
|
||||
stlxrb w3, w1, [x0]
|
||||
cbnz w3, arm64_lock_xchg_b_0
|
||||
mov w0, w2
|
||||
ret
|
||||
|
||||
arm64_lock_storeifnull:
|
||||
dmb ish
|
||||
1:
|
||||
// address is x0, value is x1, x1 store to x0 only if [x0] is 0. return old [x0] value
|
||||
ldaxr x2, [x0]
|
||||
cbnz x2, 2f
|
||||
stlxr w3, x1, [x0]
|
||||
cbnz w3, 1b
|
||||
2:
|
||||
mov x0, x2
|
||||
ret
|
||||
|
||||
arm64_lock_storeifnull_d:
|
||||
dmb ish
|
||||
1:
|
||||
// address is x0, value is w1, w1 store to x0 only if [x0] is 0. return old [x0] value
|
||||
ldaxr w2, [x0]
|
||||
cbnz w2, 2f
|
||||
stlxr w3, w1, [x0]
|
||||
cbnz w3, 1b
|
||||
2:
|
||||
dmb ish
|
||||
mov w0, w2
|
||||
ret
|
||||
|
||||
arm64_lock_storeifref:
|
||||
dmb ish
|
||||
1:
|
||||
// address is x0, value is x1, x1 store to x0 only if [x0] is x2. return new [x0] value (so x1 or old value)
|
||||
ldaxr x3, [x0]
|
||||
cmp x2, x3
|
||||
bne 2f
|
||||
stlxr w4, x1, [x0]
|
||||
cbnz w4, 1b
|
||||
mov x0, x1
|
||||
ret
|
||||
2:
|
||||
mov x0, x3
|
||||
ret
|
||||
|
||||
arm64_lock_storeifref_d:
|
||||
dmb ish
|
||||
1:
|
||||
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return new [x0] value (so x1 or old value)
|
||||
ldaxr w3, [x0]
|
||||
cmp w2, w3
|
||||
bne 2f
|
||||
stlxr w4, w1, [x0]
|
||||
cbnz w4, 1b
|
||||
mov w0, w1
|
||||
ret
|
||||
2:
|
||||
mov w0, w3
|
||||
ret
|
||||
|
||||
arm64_lock_storeifref2_d:
|
||||
dmb ish
|
||||
1:
|
||||
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return old [x0] value
|
||||
ldaxr w3, [x0]
|
||||
cmp w2, w3
|
||||
bne 2f
|
||||
stlxr w4, w1, [x0]
|
||||
cbnz w4, 1b
|
||||
2:
|
||||
mov w0, w3
|
||||
ret
|
||||
|
||||
arm64_lock_decifnot0b:
|
||||
dmb ish
|
||||
1:
|
||||
ldaxrb w1, [x0]
|
||||
cmp w1, #0
|
||||
beq 2f
|
||||
sub w1, w1, #1
|
||||
stlxrb w2, w1, [x0]
|
||||
cbnz w2, 1b
|
||||
2:
|
||||
ret
|
||||
|
||||
arm64_lock_storeb:
|
||||
strb w1, [x0]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_decifnot0:
|
||||
dmb ish
|
||||
1:
|
||||
ldaxr w1, [x0]
|
||||
cmp w1, #0
|
||||
beq 2f
|
||||
sub w3, w1, #1
|
||||
stlxr w2, w3, [x0]
|
||||
cbnz w2, 1b
|
||||
2:
|
||||
mov w0, w1
|
||||
ret
|
||||
|
||||
arm64_lock_incif0:
|
||||
dmb ish
|
||||
1:
|
||||
ldaxr w1, [x0]
|
||||
cmp w1, #0
|
||||
bne 2f
|
||||
add w3, w1, #1
|
||||
stlxr w2, w3, [x0]
|
||||
cbnz w2, 1b
|
||||
2:
|
||||
mov w0, w1
|
||||
ret
|
||||
|
||||
arm64_lock_store:
|
||||
str w1, [x0]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_store_dd:
|
||||
str x1, [x0]
|
||||
dmb ish
|
||||
ret
|
||||
|
||||
arm64_lock_get_b:
|
||||
ldaxrb w0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_get_d:
|
||||
ldaxr w0, [x0]
|
||||
ret
|
||||
|
||||
arm64_lock_get_dd:
|
||||
ldaxr x0, [x0]
|
||||
ret
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef __ARM64_LOCK__H__
|
||||
#define __ARM64_LOCK__H__
|
||||
#include <stdint.h>
|
||||
|
||||
// LDAXRB of ADDR
|
||||
extern uint8_t arm64_lock_read_b(void* addr);
|
||||
// STLXRB of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm64_lock_write_b(void* addr, uint8_t val);
|
||||
|
||||
// LDAXRH of ADDR
|
||||
extern uint16_t arm64_lock_read_h(void* addr);
|
||||
// STLXRH of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm64_lock_write_h(void* addr, uint16_t val);
|
||||
|
||||
// LDAXR of ADDR
|
||||
extern uint32_t arm64_lock_read_d(void* addr);
|
||||
// STLXR of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm64_lock_write_d(void* addr, uint32_t val);
|
||||
|
||||
// LDAXR of ADDR
|
||||
extern uint64_t arm64_lock_read_dd(void* addr);
|
||||
// STLXR of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm64_lock_write_dd(void* addr, uint64_t val);
|
||||
|
||||
// LDAXRD of ADDR
|
||||
extern void arm64_lock_read_dq(uint64_t * a, uint64_t* b, void* addr);
|
||||
// STLXRD of ADDR, return 0 if ok, 1 if not
|
||||
extern int arm64_lock_write_dq(uint64_t a, uint64_t b, void* addr);
|
||||
|
||||
// Atomically exchange value at [p] with val, return old p
|
||||
extern uintptr_t arm64_lock_xchg_dd(void* p, uintptr_t val);
|
||||
|
||||
// Atomically exchange value at [p] with val, return old p
|
||||
extern uint32_t arm64_lock_xchg_d(void* p, uint32_t val);
|
||||
|
||||
// Atomically exchange value at [p] with val, return old p
|
||||
extern uint32_t arm64_lock_xchg_h(void* p, uint32_t val);
|
||||
|
||||
// Atomically exchange value at [p] with val, return old p
|
||||
extern uint32_t arm64_lock_xchg_b(void* p, uint32_t val);
|
||||
|
||||
// Atomically store value to [p] only if [p] is NULL. Return old [p] value
|
||||
extern uint32_t arm64_lock_storeifnull_d(void*p, uint32_t val);
|
||||
|
||||
// Atomically store value to [p] only if [p] is NULL. Return old [p] value
|
||||
extern void* arm64_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* arm64_lock_storeifref(void*p, void* val, void* ref);
|
||||
|
||||
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
|
||||
extern uint32_t arm64_lock_storeifref_d(void*p, uint32_t val, uint32_t ref);
|
||||
|
||||
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
|
||||
extern uint32_t arm64_lock_storeifref2_d(void*p, uint32_t val, uint32_t ref);
|
||||
|
||||
// decrement atomically the byte at [p] (but only if p not 0)
|
||||
extern void arm64_lock_decifnot0b(void*p);
|
||||
|
||||
// atomic store (with memory barrier)
|
||||
extern void arm64_lock_storeb(void*p, uint8_t b);
|
||||
|
||||
// increment atomically the int at [p] only if it was 0. Return the old value of [p]
|
||||
extern int arm64_lock_incif0(void*p);
|
||||
|
||||
// decrement atomically the int at [p] (but only if p not 0)
|
||||
extern int arm64_lock_decifnot0(void*p);
|
||||
|
||||
// atomic store (with memory barrier)
|
||||
extern void arm64_lock_store(void*p, uint32_t v);
|
||||
|
||||
// atomic store (with memory barrier)
|
||||
extern void arm64_lock_store_dd(void*p, uint64_t v);
|
||||
|
||||
// atomic get (with memory barrier)
|
||||
extern uint8_t arm64_lock_get_b(void*p);
|
||||
|
||||
// atomic get (with memory barrier)
|
||||
extern uint32_t arm64_lock_get_d(void*p);
|
||||
|
||||
// atomic get (with memory barrier)
|
||||
extern void* arm64_lock_get_dd(void*p);
|
||||
|
||||
#endif //__ARM64_LOCK__H__
|
||||
Executable → Regular
+6
-3
@@ -9,6 +9,8 @@
|
||||
.extern LinkNext
|
||||
|
||||
.global arm64_next
|
||||
|
||||
.8byte 0 // NULL pointer before arm64_next, for getDB
|
||||
arm64_next:
|
||||
// emu is r0
|
||||
// IP address is r1
|
||||
@@ -18,9 +20,10 @@ arm64_next:
|
||||
stp x12, x13, [sp, (8 * 4)]
|
||||
stp x14, x15, [sp, (8 * 6)]
|
||||
stp x16, x17, [sp, (8 * 8)]
|
||||
str x18, [sp, (8 * 10)]
|
||||
stp x18, x27, [sp, (8 * 10)] // also save x27(rip) to allow change in LinkNext
|
||||
|
||||
mov x2, lr // "from" is in lr, so put in x2
|
||||
mov x2, x30 // "from" is in lr, so put in x2
|
||||
add x3, sp, 8*11 // x3 is address to change rip
|
||||
// call the function
|
||||
bl LinkNext
|
||||
// preserve return value
|
||||
@@ -31,7 +34,7 @@ arm64_next:
|
||||
ldp x12, x13, [sp, (8 * 4)]
|
||||
ldp x14, x15, [sp, (8 * 6)]
|
||||
ldp x16, x17, [sp, (8 * 8)]
|
||||
ldr x18, [sp, (8 * 10)]
|
||||
ldp x18, x27, [sp, (8 * 10)]
|
||||
add sp, sp, (8 * 12)
|
||||
// return offset is jump address
|
||||
br x3
|
||||
Executable → Regular
+630
-43
@@ -16,7 +16,7 @@ static const char* conds[] = {"cEQ", "cNE", "cCS", "cCC", "cMI", "cPL", "cVS", "
|
||||
#define abs(A) (((A)<0)?(-(A)):(A))
|
||||
|
||||
typedef struct arm64_print_s {
|
||||
int N, S, U, L, Q;
|
||||
int N, S, U, L, Q, A, R;
|
||||
int t, n, m, d, t2, a;
|
||||
int f, c, o, h, p;
|
||||
int i, r, s;
|
||||
@@ -25,7 +25,7 @@ typedef struct arm64_print_s {
|
||||
|
||||
uint64_t DecodeBitMasks(int N, int imms, int immr)
|
||||
{
|
||||
int len = 31-__builtin_clz(N<<6 | ((~imms)&0b111111));
|
||||
int len = 31-__builtin_clz((N<<6) | ((~imms)&0b111111));
|
||||
if(len<1) return 0;
|
||||
int levels = (1<<len) - 1;
|
||||
int s = imms & levels;
|
||||
@@ -34,10 +34,12 @@ uint64_t DecodeBitMasks(int N, int imms, int immr)
|
||||
if(s==levels) return 0;
|
||||
uint64_t mask = (1LL<<(s+1))-1;
|
||||
if(r) { // rotate
|
||||
mask=(mask>>r)|(mask<<(e-r));
|
||||
mask&=((1LL<<e)-1);
|
||||
mask=(mask>>r)|(mask<<(e-r));
|
||||
if(e<64) {
|
||||
mask&=((1LL<<e)-1);
|
||||
}
|
||||
}
|
||||
while (e<64) { // replicate
|
||||
while(e<64) { // replicate
|
||||
mask|=(mask<<e);
|
||||
e<<=1;
|
||||
}
|
||||
@@ -60,6 +62,8 @@ int isMask(uint32_t opcode, const char* mask, arm64_print_t *a)
|
||||
case 'N': a->N = (a->N<<1) | v; break;
|
||||
case 'S': a->S = (a->S<<1) | v; break;
|
||||
case 'U': a->U = (a->U<<1) | v; break;
|
||||
case 'A': a->A = (a->A<<1) | v; break;
|
||||
case 'R': a->R = (a->R<<1) | v; break;
|
||||
case 'L': a->L = (a->L<<1) | v; break;
|
||||
case 'Q': a->Q = (a->Q<<1) | v; break;
|
||||
case 't': a->t = (a->t<<1) | v; break;
|
||||
@@ -120,6 +124,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "NOP");
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "11010101000000110010000001011111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "WFE");
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "11010101000000110010000001111111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "WFI");
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "11010101000000110010000000111111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "YIELD");
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "11010101000000110010000010111111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SEVL");
|
||||
return buff;
|
||||
}
|
||||
// --- LDR / STR
|
||||
if(isMask(opcode, "f010100011iiiiiii22222nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 7)<<(2+sf);
|
||||
@@ -160,13 +180,60 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
if(isMask(opcode, "1x111000010iiiiiiiii01nnnnnttttt", &a)) {
|
||||
int size = (opcode>>30)&3;
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
snprintf(buff, sizeof(buff), "LDUR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "1x111000010iiiiiiiii11nnnnnttttt", &a)) {
|
||||
int size = (opcode>>30)&3;
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
snprintf(buff, sizeof(buff), "LDUR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "1x111000010iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int size = (opcode>>30)&3;
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDUR %s, [%s, %s0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "00111000010iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDURB %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01111000010iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDURH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "001110001x0iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDURSB %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "011110001x0iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDURSH %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "10111000100iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "LDURSW %s, [%s, %s0x%x]", Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "1x111000000iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int size = (opcode>>30)&3;
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "STUR %s, [%s, %s0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "00111000000iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "STURB %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01111000000iiiiiiiii00nnnnnttttt", &a)) {
|
||||
int offset = signExtend(imm, 9);
|
||||
snprintf(buff, sizeof(buff), "STURH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "1x11100101iiiiiiiiiiiinnnnnttttt", &a)) {
|
||||
@@ -236,6 +303,15 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "STR %s, [%s, %s, %s %d]", (size==2)?Wt[Rt]:Xt[Rt], XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm], extend[option], amount);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "00111000001mmmmmoooS10nnnnnttttt", &a)) {
|
||||
const char* extend[] = {"?0", "?1", "UXTW", "LSL", "?4", "?5", "SXTW", "SXTX"};
|
||||
int amount = a.S;
|
||||
if(option==3 && !amount)
|
||||
snprintf(buff, sizeof(buff), "STRB %s, [%s, %s]", Wt[Rt], XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "STRB %s, [%s, %s, %s %d]", Wt[Rt], XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm], extend[option], amount);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0x111000010iiiiiiiii01nnnnnttttt", &a)) {
|
||||
int size = a.x;
|
||||
int offset = signExtend(imm, 9);
|
||||
@@ -329,13 +405,13 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
}
|
||||
if(isMask(opcode, "f00100101wwiiiiiiiiiiiiiiiiddddd", &a)) {
|
||||
if(sf) {
|
||||
uint64_t noti=~(uint64_t)imm;
|
||||
uint64_t noti=~(((uint64_t)imm)<<(hw*16));
|
||||
if(!hw)
|
||||
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x\t; 0x%lx", Xt[Rd], imm, noti);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x LSL %d\t; 0x%lx", Xt[Rd], imm, 16*hw, noti);
|
||||
} else {
|
||||
uint32_t noti=~(uint32_t)imm;
|
||||
uint32_t noti=~(((uint32_t)imm)<<(hw*16));
|
||||
if(!hw)
|
||||
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x\t; 0x%x", Wt[Rd], imm, noti);
|
||||
else
|
||||
@@ -478,6 +554,16 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "SUBS %s, %s, %s %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[shift], imm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f1001011001mmmmmoooiiinnnnnddddd", &a)) {
|
||||
const char* shifts[2][8] = {{ "UXTB", "UXTH", "LSL", "UXTX", "SXTB", "SXTH", "SXTW", "SXTX"}, {"UXTB", "UXTH", "UXTW", "LSL", "SXTB", "SXTH", "SXTW", "SXTX" }};
|
||||
if(((sf==0 && shift==2) || (sf==1 && shift==3)) && imm==0)
|
||||
snprintf(buff, sizeof(buff), "SUB %s, %s, %s", sf?XtSp[Rd]:WtSp[Rd], sf?XtSp[Rn]:WtSp[Rn], sf?XtSp[Rm]:WtSp[Rm]);
|
||||
else if(shift==0)
|
||||
snprintf(buff, sizeof(buff), "SUB %s, %s, %s %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[sf][shift]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "SUB %s, %s, %s %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[sf][shift], imm);
|
||||
return buff;
|
||||
}
|
||||
// ---- LOGIC
|
||||
if(isMask(opcode, "f11100100Nrrrrrrssssssnnnnnddddd", &a)) {
|
||||
uint64_t i = DecodeBitMasks(a.N, imms, immr);
|
||||
@@ -513,6 +599,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "BIC %s, %s, %s, %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[shift], imm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f1101010hh1mmmmmiiiiiinnnnnddddd", &a)) {
|
||||
const char* shifts[] = { "LSL", "LSR", "ASR", "ROR" };
|
||||
if(shift==0 && imm==0)
|
||||
snprintf(buff, sizeof(buff), "BICS %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "BICS %s, %s, %s, %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[shift], imm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f01100100Nrrrrrrssssssnnnnnddddd", &a)) {
|
||||
uint64_t i = DecodeBitMasks(a.N, imms, immr);
|
||||
if(!sf) i&=0xffffffff;
|
||||
@@ -659,8 +753,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], lsb, width);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "BFI %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], lsb, width);
|
||||
} else
|
||||
snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);
|
||||
} else {
|
||||
if(Rn==31 && immr==0)
|
||||
snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], immr, imms-immr+1);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
// ---- BRANCH / TEST
|
||||
@@ -684,17 +782,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
}
|
||||
if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) {
|
||||
int offset = signExtend(imm, 19)<<2;
|
||||
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
|
||||
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", sf?Xt[Rt]:Wt[Rt], offset>>2, (void*)(addr + offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f0110101iiiiiiiiiiiiiiiiiiittttt", &a)) {
|
||||
int offset = signExtend(imm, 19)<<2;
|
||||
snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) {
|
||||
int offset = signExtend(imm, 19)<<2;
|
||||
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
|
||||
snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", sf?Xt[Rt]:Wt[Rt], offset>>2, (void*)(addr + offset));
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "s0110110sssssiiiiiiiiiiiiiittttt", &a)) {
|
||||
@@ -739,6 +832,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "CSEL %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f1111010010mmmmmcccc00nnnnn0iiii", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CCMP %s, %s, %s 0x%x", sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond], imm);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// MISC Bits
|
||||
if(isMask(opcode, "f10110101100000000010onnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CL%c %s, %s", option?'S':'Z', sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn]);
|
||||
@@ -767,7 +865,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "10011011U10mmmmm011111nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "%cMULH %s, %s, %s", a.U?'U':'S', Xt[Rd], Wt[Rn], Wt[Rm]);
|
||||
snprintf(buff, sizeof(buff), "%cMULH %s, %s, %s", a.U?'U':'S', Xt[Rd], Xt[Rn], Xt[Rm]);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "f0011011000mmmmm0aaaaannnnnddddd", &a)) {
|
||||
@@ -851,7 +949,6 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
}
|
||||
// UMOV
|
||||
if(isMask(opcode, "0Q001110000rrrrr001111nnnnnddddd", &a)) {
|
||||
char q = a.Q?'Q':'D';
|
||||
char s = '?';
|
||||
int sz=0;
|
||||
if(a.Q==0 && immr&1) {s='B'; sz=0; }
|
||||
@@ -860,9 +957,24 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; }
|
||||
int index = (immr)>>(sz+1);
|
||||
if(sz>2)
|
||||
snprintf(buff, sizeof(buff), "MOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);
|
||||
snprintf(buff, sizeof(buff), "MOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "UMOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);
|
||||
snprintf(buff, sizeof(buff), "UMOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
|
||||
return buff;
|
||||
}
|
||||
// SMOV
|
||||
if(isMask(opcode, "0Q001110000rrrrr001011nnnnnddddd", &a)) {
|
||||
char s = '?';
|
||||
int sz=0;
|
||||
if(a.Q==0 && immr&1) {s='B'; sz=0; }
|
||||
else if(/*a.Q==0 &&*/ (immr&3)==2) {s='H'; sz=1; }
|
||||
else if(/*a.Q==0 &&*/ (immr&7)==4) {s='S'; sz=2; }
|
||||
else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; }
|
||||
int index = (immr)>>(sz+1);
|
||||
if(sz>2)
|
||||
snprintf(buff, sizeof(buff), "MOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "SMOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
|
||||
return buff;
|
||||
}
|
||||
// VEOR
|
||||
@@ -887,6 +999,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "VMUL V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);
|
||||
return buff;
|
||||
}
|
||||
// VBIT / VBIF
|
||||
if(isMask(opcode, "0Q1011101o1mmmmm000111nnnnnddddd", &a)) {
|
||||
char q = a.Q?'Q':'D';
|
||||
snprintf(buff, sizeof(buff), "VBI%c %c%d, %c%d, %c%d", a.o?'F':'T', q, Rd, q, Rn, q, Rm);
|
||||
return buff;
|
||||
}
|
||||
// CMP
|
||||
if(isMask(opcode, "0Q101110ff1mmmmm100011nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
@@ -894,6 +1012,67 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "VCMEQ V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);
|
||||
return buff;
|
||||
}
|
||||
// CMP zero
|
||||
if(isMask(opcode, "0QU01110ff100000100o10nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Z[] = {"GT", "GE", "EQ", "LE"};
|
||||
const char* Vd = Y[((sf)<<1) | a.Q];
|
||||
const char* Cond = Z[(a.o << 1 | a.U)];
|
||||
snprintf(buff, sizeof(buff), "VCM%s V%d.%s, V%d.%s, #0", Cond, Rd, Vd, Rn, Vd);
|
||||
return buff;
|
||||
}
|
||||
// CMPLT zero
|
||||
if(isMask(opcode, "0Q001110ff100000101010nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Vd = Y[((sf)<<1) | a.Q];
|
||||
snprintf(buff, sizeof(buff), "VCMLT V%d.%s, V%d.%s, #0", Rd, Vd, Rn, Vd);
|
||||
return buff;
|
||||
}
|
||||
// MIN/MAX
|
||||
if(isMask(opcode, "0QU01110ff1mmmmm0110o1nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Vd = Y[((sf)<<1) | a.Q];
|
||||
snprintf(buff, sizeof(buff), "%c%s V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.o?"MIN":"MAX", Rd, Vd, Rn, Vd, Rm, Vd);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// MOV immediate (not)shifted 8bits
|
||||
if(isMask(opcode, "0Q00111100000iii111001iiiiiddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B"};
|
||||
const char* Vd = Y[a.Q];
|
||||
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm);
|
||||
return buff;
|
||||
}
|
||||
// MOV immediate notshifted 16bits & 32bits
|
||||
if(isMask(opcode, "0Q00111100000iiif00001iiiiiddddd", &a)) {
|
||||
const char* Y[] = {"2S", "4S", "4H", "8H"};
|
||||
const char* Vd = Y[(sf<<1)| a.Q];
|
||||
int sh = 0;
|
||||
|
||||
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm<<sh);
|
||||
return buff;
|
||||
}
|
||||
// MOV immediate shifted 16bits
|
||||
if(isMask(opcode, "0Q00111100000iii101001iiiiiddddd", &a)) {
|
||||
const char* Y[] = {"4H", "8H"};
|
||||
const char* Vd = Y[a.Q];
|
||||
|
||||
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm<<8);
|
||||
return buff;
|
||||
}
|
||||
// MOV immediate 64bits
|
||||
if(isMask(opcode, "0Q10111100000iii111001iiiiiddddd", &a)) {
|
||||
uint64_t tmp64u = 0;
|
||||
for(int i=0; i<8; ++i)
|
||||
if((imm)&(1<<i))
|
||||
tmp64u |= 0xffLL<<(i*8);
|
||||
|
||||
if(a.Q)
|
||||
snprintf(buff, sizeof(buff), "MOVI V%d.2D, #0x%016lx", Rd, tmp64u);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "MOVI D%d, #0x%016lx", Rd, tmp64u);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// Shift
|
||||
if(isMask(opcode, "0QU011110hhhhrrr000001nnnnnddddd", &a)) {
|
||||
@@ -930,6 +1109,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
return buff;
|
||||
}
|
||||
|
||||
// ADR
|
||||
if(isMask(opcode, "0ss10000iiiiiiiiiiiiiiiiiiiddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "ADR, %s, %ld", Xt[Rd], signExtend((imm)<<2|(imms), 20));
|
||||
return buff;
|
||||
}
|
||||
|
||||
// LDR / STR
|
||||
if(isMask(opcode, "ss111101cciiiiiiiiiiiinnnnnttttt", &a)) {
|
||||
char s = '?';
|
||||
@@ -950,7 +1135,30 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
if(!offset)
|
||||
snprintf(buff, sizeof(buff), "%s %c%d, [%s]", op?"STR":"LDR", s, Rt, XtSp[Rn]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "%s %c%d, [%s, %d]", op?"STR":"LDR", s, Rt, XtSp[Rn], offset);
|
||||
snprintf(buff, sizeof(buff), "%s %c%d, [%s, 0x%x]", op?"STR":"LDR", s, Rt, XtSp[Rn], offset);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "ss111100cc1mmmmmoooS10nnnnnttttt", &a)) {
|
||||
char s = '?';
|
||||
int size=imms;
|
||||
int op=0;
|
||||
if(size==0 && opc==1) {s='B';}
|
||||
else if(size==1 && opc==1) {s='H';}
|
||||
else if(size==2 && opc==1) {s='S';}
|
||||
else if(size==3 && opc==1) {s='D';}
|
||||
else if(size==0 && opc==3) {s='Q'; size = 4;}
|
||||
else if(size==0 && opc==0) {s='B'; op=1;}
|
||||
else if(size==1 && opc==0) {s='H'; op=1;}
|
||||
else if(size==2 && opc==0) {s='S'; op=1;}
|
||||
else if(size==3 && opc==0) {s='D'; op=1;}
|
||||
else if(size==0 && opc==2) {s='Q'; op=1; size = 4;}
|
||||
|
||||
const char* extend[] = {"?0", "?1", "UXTW", "LSL", "?4", "?5", "SXTW", "SXTX"};
|
||||
int amount = size*a.S;
|
||||
if(option==3 && !amount)
|
||||
snprintf(buff, sizeof(buff), "%s %c%d, [%s, %s]", op?"STR":"LDR", s, Rt, XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "%s %c%d, [%s, %s, %s %d]", op?"STR":"LDR", s, Rt, XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm], extend[option], amount);
|
||||
return buff;
|
||||
}
|
||||
|
||||
@@ -1010,6 +1218,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
return buff;
|
||||
}
|
||||
|
||||
// FADDP
|
||||
if(isMask(opcode, "0Q1011100f1mmmmm110101nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFADDP %c%d.%d%c, %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d, s, Rm, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "011111100f110000110110nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FADDP %c%d, %c%d, %c%d", s, Rd, s, Rn, s, Rm);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// SQRT
|
||||
if(isMask(opcode, "0Q1011101f100001111110nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
@@ -1023,6 +1245,84 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "FSQRT %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FPRINTX
|
||||
if(isMask(opcode, "0Q1011100f100001100110nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTX %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if (isMask(opcode, "00011110ff100111010000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTX %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FRINTI
|
||||
if(isMask(opcode, "0Q1011101f100001100110nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTI %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "00011110ff100111110000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTI %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FRINTN
|
||||
if(isMask(opcode, "0Q0011100f100001100010nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTN %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "000111100f100100010000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTN %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FRINTM
|
||||
if(isMask(opcode, "0Q0011100f100001100110nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTM %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "000111100f100101010000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTM %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FRINTP
|
||||
if(isMask(opcode, "0Q0011101f100001100010nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTP %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "000111100f100100110000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTP %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
// FRINTZ
|
||||
if(isMask(opcode, "0Q0011101f100001100110nnnnnddddd", &a)) {
|
||||
char s = a.Q?'V':'D';
|
||||
char d = sf?'D':'S';
|
||||
int n = (a.Q && !sf)?4:2;
|
||||
snprintf(buff, sizeof(buff), "VFRINTZ %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "000111100f100101110000nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "FRINTZ %c%d, %c%d", s, Rd, s, Rn);
|
||||
return buff;
|
||||
}
|
||||
|
||||
//CMP
|
||||
if(isMask(opcode, "00011110ff1mmmmm001000nnnnn0c000", &a)) {
|
||||
@@ -1033,10 +1333,26 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "FCMP %c%d, %c%d", s, Rn, s, Rm);
|
||||
return buff;
|
||||
}
|
||||
//FCMEQ
|
||||
if(isMask(opcode, "000111100f1mmmmm111001nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':'D';
|
||||
snprintf(buff, sizeof(buff), "FCMEQ %c%d, %c%d, %c%d", s, Rd, s, Rn, s, Rm);
|
||||
return buff;
|
||||
}
|
||||
//FCMP vector
|
||||
if(isMask(opcode, "0QU01110cf1mmmmm111001nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
int n = (sf==0)?2:1;
|
||||
n *= a.Q?2:1;
|
||||
int op = (a.c<<1) | (a.U);
|
||||
const char* OP[] = {"EQ", "GE", "??", "GT"};
|
||||
snprintf(buff, sizeof(buff), "FCMP%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", OP[op], a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
//FMIN/FMAX
|
||||
if(isMask(opcode, "00011110ff1mmmmm01oo10nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
snprintf(buff, sizeof(buff), "F%s %c%d, %c%d, %c%d", (option==3)?"MINNM":((option==2)?"MINNMP":((!option)?"MAXNM":"MAXNMP")), s, Rd, s, Rn, s, Rm);
|
||||
snprintf(buff, sizeof(buff), "F%s %c%d, %c%d, %c%d", (option==3)?"MINNM":((option==2)?"MAXNM":((!option)?"MAX":"MIN")), s, Rd, s, Rn, s, Rm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0Q001110of1mmmmm110001nnnnnddddd", &a)) {
|
||||
@@ -1046,6 +1362,49 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "F%sNM%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0Q001110of1mmmmm111101nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
int n = (sf==0)?2:1;
|
||||
n *= a.Q?2:1;
|
||||
snprintf(buff, sizeof(buff), "F%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
// FMADD
|
||||
if(isMask(opcode, "00011111tt0mmmmmoaaaaannnnnddddd", &a)) {
|
||||
char s = (a.t==0b00)?'S':((a.t==0b01)?'D':'?');
|
||||
int n = (a.t==0)?1:2;
|
||||
snprintf(buff, sizeof(buff), "FM%s V%d.%d%c, V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"SUB":"ADD", Rd, n, s, Ra, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
// FNMADD
|
||||
if(isMask(opcode, "00011111tt1mmmmmoaaaaannnnnddddd", &a)) {
|
||||
char s = (a.t==0b00)?'S':((a.t==0b01)?'D':'?');
|
||||
int n = (a.t==0)?1:2;
|
||||
snprintf(buff, sizeof(buff), "FNM%s V%d.%d%c, V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"SUB":"ADD", Rd, n, s, Ra, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
// FMLA
|
||||
if(isMask(opcode, "0Q001110of1mmmmm110011nnnnnddddd", &a)) {
|
||||
char s = (sf==0)?'S':((sf==1)?'D':'?');
|
||||
int n = (sf==0)?2:1;
|
||||
n *= a.Q?2:1;
|
||||
snprintf(buff, sizeof(buff), "FML%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"S":"A", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
|
||||
return buff;
|
||||
}
|
||||
// NEG
|
||||
if(isMask(opcode, "0Q101110ff100000101110nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Vd = Y[(sf<<1) | a.Q];
|
||||
snprintf(buff, sizeof(buff), "NEG%s V%d.%s, V%d.%s", a.Q?"Q":"", Rd, Vd, Rn, Vd);
|
||||
return buff;
|
||||
}
|
||||
// SSHL vector
|
||||
if(isMask(opcode, "0QU01110ff1mmmmm010rS1nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Vd = Y[(sf<<1) | a.Q];
|
||||
snprintf(buff, sizeof(buff), "%c%s%sSHL%s V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.r?"R":"", a.S?"Q":"", a.Q?"Q":"", Rd, Vd, Rn, Vd, Rm, Vd);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// FCVT
|
||||
if(isMask(opcode, "f0011110pp10010U000000nnnnnddddd", &a)) {
|
||||
@@ -1109,6 +1468,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "FCVT%sS %s, %c%d", roundings[a.c], sf?Xt[Rd]:Wt[Rd], s, Rn);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0QU01110of100001101o10nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"2S", "4S", "??", "2D"};
|
||||
const char* Z[] = {"S", "S", "??", "D"};
|
||||
const char* Vd = Y[(sf<<1) | a.Q];
|
||||
const char* roundings[] = {"N", "M", "P", "Z"};
|
||||
snprintf(buff, sizeof(buff), "VFCVT%s%s%s%s V%d.%s, V%d.%s", roundings[option], a.U?"U":"S", a.Q?"Q":"", Z[(sf<<1)|a.Q], Rd, Vd, Rn, Vd);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// FMOV
|
||||
if(isMask(opcode, "00011110pp100000010000nnnnnddddd", &a)) {
|
||||
@@ -1125,8 +1492,8 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
else if(sf==0 && type==0 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Wt[Rn], Rd);}
|
||||
else if(sf==1 && type==1 && rmode==0 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV D%d, %s", Rd, Xt[Rn]);}
|
||||
else if(sf==1 && type==2 && rmode==1 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV V%d.D[1], %s", Rd, Xt[Rn]);}
|
||||
else if(sf==1 && type==1 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Xt[Rn], Rd);}
|
||||
else if(sf==1 && type==2 && rmode==1 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, V%d.D[1]", Xt[Rn], Rd);}
|
||||
else if(sf==1 && type==1 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, D%d", Xt[Rd], Rn);}
|
||||
else if(sf==1 && type==2 && rmode==1 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, V%d.D[1]", Xt[Rd], Rn);}
|
||||
else snprintf(buff, sizeof(buff), "FMOV ????");
|
||||
return buff;
|
||||
}
|
||||
@@ -1221,21 +1588,13 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
return buff;
|
||||
}
|
||||
|
||||
// MOV immediate
|
||||
if(isMask(opcode, "0Q00111100000iii111001iiiiiddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B"};
|
||||
const char* Vd = Y[a.Q];
|
||||
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// LD1/ST1 single structure
|
||||
if(isMask(opcode, "0Q0011010L000000cc0Sffnnnnnttttt", &a)) {
|
||||
if(isMask(opcode, "0Q0011010Lo00000cc0Sffnnnnnttttt", &a)) {
|
||||
int scale = a.c;
|
||||
int idx = 0;
|
||||
const char* Y[] = {"B", "H", "S", "D"};
|
||||
switch(scale) {
|
||||
case 3: scale = sf; /* rep = 1; */ break;
|
||||
case 3: scale = sf; /* rep = 1; */ idx=(8*(a.Q+1))>>scale; break;
|
||||
case 0: idx = (a.Q<<3) | (a.S<<2) | sf; break;
|
||||
case 1: idx = (a.Q<<2) | (a.S<<1) | (sf>>1); break;
|
||||
case 2: if(!(sf&1))
|
||||
@@ -1246,7 +1605,10 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
}
|
||||
break;
|
||||
}
|
||||
snprintf(buff, sizeof(buff), "%s1 {V%d.%s}[%d], [%s]", a.L?"LD":"ST", Rt, Y[scale], idx, XtSp[Rn]);
|
||||
if(!option && a.L && scale==3)
|
||||
snprintf(buff, sizeof(buff), "LD1R {V%d.%d%s}, [%s]", Rt, idx, Y[scale], XtSp[Rn]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "%s1 {V%d.%s}[%d], [%s]", a.L?"LD":"ST", Rt, Y[scale], idx, XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// LDUR/STUR
|
||||
@@ -1257,9 +1619,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
sz = 4;
|
||||
int offset = signExtend(imm, 9);
|
||||
if(!offset)
|
||||
snprintf(buff, sizeof(buff), "%sUR %s%d, [%s]", a.L?"LD":"ST", Y[sz], Rd, XtSp[Rn]);
|
||||
snprintf(buff, sizeof(buff), "%sUR %s%d, [%s]", a.L?"LD":"ST", Y[sz], Rt, XtSp[Rn]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "%sUR %s%d, [%s, %+d]", a.L?"LD":"ST", Y[sz], Rd, XtSp[Rn], imm);
|
||||
snprintf(buff, sizeof(buff), "%sUR %s%d, [%s, %s0x%x]", a.L?"LD":"ST", Y[sz], Rt, XtSp[Rn], (offset<0)?"-":"", abs(offset));
|
||||
return buff;
|
||||
}
|
||||
// LDR/STR vector immediate
|
||||
@@ -1270,9 +1632,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
sz = 4;
|
||||
int offset = imm<<sz;
|
||||
if(!offset)
|
||||
snprintf(buff, sizeof(buff), "%sR %s%d, [%s]", a.L?"LD":"ST", Y[sz], Rd, XtSp[Rn]);
|
||||
snprintf(buff, sizeof(buff), "%sR %s%d, [%s]", a.L?"LD":"ST", Y[sz], Rt, XtSp[Rn]);
|
||||
else
|
||||
snprintf(buff, sizeof(buff), "%sR %s%d, [%s, %+d]", a.L?"LD":"ST", Y[sz], Rd, XtSp[Rn], imm);
|
||||
snprintf(buff, sizeof(buff), "%sR %s%d, [%s, %+d]", a.L?"LD":"ST", Y[sz], Rt, XtSp[Rn], imm);
|
||||
return buff;
|
||||
}
|
||||
|
||||
@@ -1293,6 +1655,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "%cQXTN%s V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Va);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01U11110ff100001010010nnnnnddddd", &a)) {
|
||||
const char Z[] = {'B', 'H', 'S', 'D', '?'};
|
||||
snprintf(buff, sizeof(buff), "SQXT%sN %c%d, %c%d", a.U?"U":"", Z[sf], Rd, Z[sf+1], Rn);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// (S/U)SSHL(2) / (U/S)XTL(2)
|
||||
if(isMask(opcode, "0QU011110hhhhiii101001nnnnnddddd", &a)) {
|
||||
@@ -1311,9 +1678,229 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
|
||||
snprintf(buff, sizeof(buff), "%cSHLL%s V%d.%s, V%d.%s, #%d", a.U?'U':'S', a.Q?"2":"", Rd, Va, Rn, Vd, sh);
|
||||
return buff;
|
||||
}
|
||||
|
||||
if(isMask(opcode, "0Q0011110hhhhiii010101nnnnnddddd", &a) && (a.h != 0b1000)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
int sz = 3;
|
||||
if((a.h&0b1111)==0b0001) sz=0;
|
||||
else if((a.h&0b1110)==0b0010) sz=1;
|
||||
else if((a.h&0b1100)==0b0100) sz=2;
|
||||
int sh=(((a.h)<<3)|(imm)) - (8<<sz);
|
||||
const char* Vd = Y[(sz<<1)|a.Q];
|
||||
snprintf(buff, sizeof(buff), "SHL%s V%d.%s, V%d.%s, #%d", a.Q?"Q":"", Rd, Vd, Rn, Vd, sh);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// CNT
|
||||
if(isMask(opcode, "0Q00111000100000010110nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B"};
|
||||
const char* Vd = Y[a.Q];
|
||||
const char* Va = Y[a.Q];
|
||||
snprintf(buff, sizeof(buff), "CNT V%d.%s, V%d.%s", Rd, Vd, Rn, Va);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// DUP
|
||||
if(isMask(opcode, "0Q001110000iiiii000001nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
const char* Z[] = {"B", "H", "S", "D"};
|
||||
int sz = 3;
|
||||
if((imm&0b0001)==0b0001) sz=0;
|
||||
else if((imm&0b0011)==0b0010) sz=1;
|
||||
else if((imm&0b0111)==0b0100) sz=2;
|
||||
int sh=(imm>>sz) - 1;
|
||||
const char* Vd = Y[(sz<<1)|a.Q];
|
||||
const char* Vn = Z[sz];
|
||||
snprintf(buff, sizeof(buff), "DUP V%d.%s, V%d.%s[%d]", Rd, Vd, Rn, Vn, sh);
|
||||
return buff;
|
||||
}
|
||||
|
||||
if(isMask(opcode, "0Q001110000iiiii000011nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
int sz = 3;
|
||||
if((imm&0b0001)==0b0001) sz=0;
|
||||
else if((imm&0b0011)==0b0010) sz=1;
|
||||
else if((imm&0b0111)==0b0100) sz=2;
|
||||
const char* Vd = Y[(sz<<1)|a.Q];
|
||||
snprintf(buff, sizeof(buff), "DUP V%d.%s, X%d", Rd, Vd, Rn);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// AES
|
||||
if(isMask(opcode, "0100111000101000010f10nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "AES%c V%d.16B, V%d.16B", sf?'D':'E', Rd, Rn);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0100111000101000011f10nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "AES%sMC V%d.16B, V%d.16B", sf?"I":"", Rd, Rn);
|
||||
return buff;
|
||||
}
|
||||
// PMULL
|
||||
if(isMask(opcode, "0Q001110ff1mmmmm111000nnnnnddddd", &a)) {
|
||||
const char* Y[] = {"8B", "16B", "??", "??", "??", "??", "1D", "2D"};
|
||||
const char* Z[] = {"8H", "??", "??", "1Q"};
|
||||
int sz = sf;
|
||||
const char* Vn = Y[(sz<<1)|a.Q];
|
||||
const char* Vd = Z[sz];
|
||||
snprintf(buff, sizeof(buff), "PMULL%s V%d.%s, V%d.%s, V%d.%s", a.Q?"2":"", Rd, Vd, Rn, Vn, Rm, Vn);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// DMB
|
||||
if(isMask(opcode, "11010101000000110011nnnn10111111", &a)) {
|
||||
const char* barrier[] = {
|
||||
"???", "???", "???", "???", // 0-3
|
||||
"???", "???", "???", "???", // 4-7
|
||||
"???", "ISHLD", "ISHST", "ISH", // 8-11
|
||||
"???", "LD", "ST", "SY" // 12-15
|
||||
};
|
||||
snprintf(buff, sizeof(buff), "DMB %s", barrier[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// DSB
|
||||
if(isMask(opcode, "11010101000000110011nnnn10011111", &a)) {
|
||||
const char* barrier[] = {
|
||||
"???", "???", "???", "???", // 0-3
|
||||
"???", "???", "???", "???", // 4-7
|
||||
"???", "ISHLD", "ISHST", "ISH", // 8-11
|
||||
"???", "LD", "ST", "SY" // 12-15
|
||||
};
|
||||
snprintf(buff, sizeof(buff), "DSB %s", barrier[Rn]);
|
||||
return buff;
|
||||
}
|
||||
|
||||
// CASxw
|
||||
if(isMask(opcode, "1f0010001L1ssssso11111nnnnnttttt", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CAS%s%s %s, %s, [%s]", a.o?"A":"", a.L?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// CAS B/H
|
||||
if(isMask(opcode, "0f0010001L1ssssso11111nnnnnttttt", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CAS%s%s%s %s, %s, [%s]", a.o?"A":"", a.L?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// CASPxw
|
||||
if(isMask(opcode, "0f0010000L1ssssso11111nnnnnttttt", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CASP%s%s %s,%s, %s,%s, [%s]", a.o?"A":"", a.L?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rs+1]:Wt[Rs+1], sf?Xt[Rt]:Wt[Rt], sf?Xt[Rt+1]:Wt[Rt+1], XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// SWPxw
|
||||
if(isMask(opcode, "1f111000AR1sssss100000nnnnnttttt", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SWP%s%s %s, %s, [%s]", a.A?"A":"", a.R?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// SWPxw
|
||||
if(isMask(opcode, "0f111000AR1sssss100000nnnnnttttt", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CAS%s%s%s %s, %s, [%s]", a.A?"A":"", a.R?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// LDXXXxw
|
||||
if(isMask(opcode, "1f111000AR1sssss0ooo00nnnnnttttt", &a)) {
|
||||
const char* ops[] = { "ADD", "CLR", "EOR", "SET", "SMAX, SMIN", "UMAX", "UMIN" };
|
||||
if((Rt == 0b11111) && !a.A) {
|
||||
snprintf(buff, sizeof(buff), "ST%s%s %s, [%s]", ops[a.o], a.R?"L":"", sf?Xt[Rs]:Wt[Rs], XtSp[Rn]);
|
||||
} else {
|
||||
snprintf(buff, sizeof(buff), "LD%s%s%s %s, %s, [%s]", ops[a.o], a.A?"A":"", a.R?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
// LDXXX B/H
|
||||
if(isMask(opcode, "0f111000AR1sssss0ooo00nnnnnttttt", &a)) {
|
||||
const char* ops[] = { "ADD", "CLR", "EOR", "SET", "SMAX, SMIN", "UMAX", "UMIN" };
|
||||
if((Rt == 0b11111) && !a.A) {
|
||||
snprintf(buff, sizeof(buff), "ST%s%s%s %s, [%s]", ops[a.o], a.R?"L":"", sf?"H":"B", Xt[Rs], XtSp[Rn]);
|
||||
} else {
|
||||
snprintf(buff, sizeof(buff), "LD%s%s%s%s %s, %s, [%s]", ops[a.o], a.A?"A":"", a.R?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
// AXFLAG
|
||||
if(isMask(opcode, "11010101000000000100000001011111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "AXFLAG");
|
||||
return buff;
|
||||
}
|
||||
// XAFLAG
|
||||
if(isMask(opcode, "11010101000000000100000000111111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "XAFLAG");
|
||||
return buff;
|
||||
}
|
||||
// CFINV
|
||||
if(isMask(opcode, "11010101000000000100000000011111", &a)) {
|
||||
snprintf(buff, sizeof(buff), "CFINV");
|
||||
return buff;
|
||||
}
|
||||
// RMIF
|
||||
if(isMask(opcode, "10111010000iiiiii00001nnnnn0oooo", &a)) {
|
||||
snprintf(buff, sizeof(buff), "RMIF %s, #%d, #0x%x", Xt[Rn], imm, opc);
|
||||
return buff;
|
||||
}
|
||||
// SETF
|
||||
if(isMask(opcode, "00111010000000000f0010nnnnn01101", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SETF%d %s", 8<<sf, Xt[Rn]);
|
||||
return buff;
|
||||
}
|
||||
// REV64
|
||||
if(isMask(opcode, "0Q001110ff100000000010nnnnnddddd", &a)) {
|
||||
const char* T[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "??"};
|
||||
int sz = sf;
|
||||
const char* Vn = T[(sz<<1)|a.Q];
|
||||
const char* Vd = T[(sz<<1)|a.Q];
|
||||
snprintf(buff, sizeof(buff), "REV64 V%d.%s, V%d.%s",Rd, Vd, Rn, Vn);
|
||||
return buff;
|
||||
}
|
||||
//TRNx
|
||||
if(isMask(opcode, "0Q001110ff0mmmmm0o1010nnnnnddddd", &a)) {
|
||||
const char* T[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
|
||||
int sz = sf;
|
||||
const char* Vn = T[(sz<<1)|a.Q];
|
||||
const char* Vm = T[(sz<<1)|a.Q];
|
||||
const char* Vd = T[(sz<<1)|a.Q];
|
||||
snprintf(buff, sizeof(buff), "TRN%d V%d.%s, V%d.%s, V%d.%s", a.o+1, Rd, Vd, Rn, Vn, Rm, Vm);
|
||||
return buff;
|
||||
}
|
||||
//SHA1 stuffs
|
||||
if(isMask(opcode, "0101111000101000000010nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA1H S%d, S%d", Rd, Rn);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "0101111000101000000110nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA1SU1 V%d.4S, V%d.4S", Rd, Rn);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm000000nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA1C Q%d, S%d, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm001000nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA1M Q%d, S%d, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm000100nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA1P Q%d, S%d, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
//SHA256 stuffs
|
||||
if(isMask(opcode, "0101111000101000001010nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA256SU0 V%d.4S, V%d.4S", Rd, Rn);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm011000nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA256SU1 V%d.4S, V%d.4S, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm010000nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA256H Q%d, Q%d, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
if(isMask(opcode, "01011110000mmmmm010100nnnnnddddd", &a)) {
|
||||
snprintf(buff, sizeof(buff), "SHA256H2 Q%d, Q%d, V%d.4S", Rd, Rn, Rm);
|
||||
return buff;
|
||||
}
|
||||
// UDF
|
||||
if(isMask(opcode, "0000000000000000iiiiiiiiiiiiiiii", &a)) {
|
||||
snprintf(buff, sizeof(buff), "UDF 0x%x", a.i);
|
||||
return buff;
|
||||
}
|
||||
|
||||
snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
Executable → Regular
+6
-2
@@ -9,13 +9,13 @@
|
||||
.global arm64_prolog
|
||||
arm64_prolog:
|
||||
//save all 18 used register
|
||||
stp lr, fp, [sp, -16]! // save lr
|
||||
stp x30, x29, [sp, -16]! // save lr
|
||||
sub sp, sp, (8 * 18)
|
||||
stp x19, x20, [sp, (8 * 0)]
|
||||
stp x21, x22, [sp, (8 * 2)]
|
||||
stp x23, x24, [sp, (8 * 4)]
|
||||
stp x25, x26, [sp, (8 * 6)]
|
||||
str x27, [sp, (8 * 8)]
|
||||
stp x27, X28, [sp, (8 * 8)]
|
||||
stp d8, d9, [sp, (8 *10)]
|
||||
stp d10, d11, [sp, (8 *12)]
|
||||
stp d12, d13, [sp, (8 *14)]
|
||||
@@ -31,5 +31,9 @@ arm64_prolog:
|
||||
ldp x22, x23, [x0, (8 * 12)]
|
||||
ldp x24, x25, [x0, (8 * 14)]
|
||||
ldp x26, x27, [x0, (8 * 16)]
|
||||
// Push a jump next on the stack
|
||||
stp xzr, xzr, [sp, -16]!
|
||||
// Save old xSP in x28
|
||||
add x28, sp, 16
|
||||
//jump to function
|
||||
br x1
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,278 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
uint8_t gd, ed, wb1, wback;
|
||||
int64_t j64;
|
||||
int16_t i16;
|
||||
int v0, v1;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(j64);
|
||||
|
||||
GETREX();
|
||||
|
||||
/*if(rex.w && opcode!=0x0f) { // rex.w cancels "66", but not for 66 0f type of prefix
|
||||
MESSAGE(LOG_DUMP, "Here!\n");
|
||||
return dynarec64_64(dyn, addr-2, ip, ninst, rex, rep, ok, need_epilog);
|
||||
}*/
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x0F:
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
case 0x2E:
|
||||
// no special check...
|
||||
case 0x2F:
|
||||
if(opcode==0x2F) {INST_NAME("COMISD Gx, Ex");} else {INST_NAME("UCOMISD Gx, Ex");}
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
|
||||
} else {
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
v1 = fpu_get_scratch(dyn, ninst);
|
||||
VLD64(v1, ed, fixedaddress);
|
||||
}
|
||||
FCMPD(v0, v1);
|
||||
FCOMI(x1, x2);
|
||||
break;
|
||||
|
||||
case 0x6F:
|
||||
INST_NAME("MOVDQA Gx,Ex");
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
VMOVQ(v0, v1);
|
||||
} else {
|
||||
GETGX_empty(v0);
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
|
||||
SMREAD();
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
VLD128(v0, ed, fixedaddress);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7F:
|
||||
INST_NAME("MOVDQA Ex,Gx");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
|
||||
VMOVQ(v1, v0);
|
||||
} else {
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
VST128(v0, ed, fixedaddress);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD6:
|
||||
INST_NAME("MOVQ Ex, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
|
||||
FMOVD(v1, v0);
|
||||
} else {
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
VST64(v0, ed, fixedaddress);
|
||||
SMWRITE();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
nextop = F8;
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: //ADD
|
||||
if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOVZw(x5, i16);
|
||||
emit_add16(dyn, ninst, ed, x5, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 1: //OR
|
||||
if(opcode==0x81) {INST_NAME("OR Ew, Iw");} else {INST_NAME("OR Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_or16c(dyn, ninst, x1, i16, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 2: //ADC
|
||||
if(opcode==0x81) {INST_NAME("ADC Ew, Iw");} else {INST_NAME("ADC Ew, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOVZw(x5, i16);
|
||||
emit_adc16(dyn, ninst, x1, x5, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 3: //SBB
|
||||
if(opcode==0x81) {INST_NAME("SBB Ew, Iw");} else {INST_NAME("SBB Ew, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOVZw(x5, i16);
|
||||
emit_sbb16(dyn, ninst, x1, x5, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 4: //AND
|
||||
if(opcode==0x81) {INST_NAME("AND Ew, Iw");} else {INST_NAME("AND Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_and16c(dyn, ninst, x1, i16, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 5: //SUB
|
||||
if(opcode==0x81) {INST_NAME("SUB Ew, Iw");} else {INST_NAME("SUB Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOVZw(x5, i16);
|
||||
emit_sub16(dyn, ninst, x1, x5, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 6: //XOR
|
||||
if(opcode==0x81) {INST_NAME("XOR Ew, Iw");} else {INST_NAME("XOR Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_xor16c(dyn, ninst, x1, i16, x2, x4);
|
||||
EWBACK;
|
||||
break;
|
||||
case 7: //CMP
|
||||
if(opcode==0x81) {INST_NAME("CMP Ew, Iw");} else {INST_NAME("CMP Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
|
||||
GETEWO(x1, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
if(i16) {
|
||||
MOVZw(x2, i16);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5);
|
||||
} else
|
||||
emit_cmp16_0(dyn, ninst, x1, x3, x4);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ew, Gw");
|
||||
nextop = F8;
|
||||
GETGD; // don't need GETGW here
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
if(rex.w) {
|
||||
MOVx_REG(ed, gd);
|
||||
} else {
|
||||
if(ed!=gd) {
|
||||
BFIx(ed, gd, 0, 16);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
if(rex.w) {
|
||||
STx(gd, ed, fixedaddress);
|
||||
} else {
|
||||
STH(gd, ed, fixedaddress);
|
||||
}
|
||||
SMWRITE();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gw, FS:Ew");
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if(MODREG) { // reg <= reg
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
if(rex.w) {
|
||||
MOVx_REG(gd, ed);
|
||||
} else {
|
||||
if(ed!=gd) {
|
||||
BFIx(gd, ed, 0, 16);
|
||||
}
|
||||
}
|
||||
} else { // mem <= reg
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
ed = x4;
|
||||
if(rex.w) {
|
||||
LDx(gd, ed, fixedaddress);
|
||||
} else {
|
||||
LDH(x1, ed, fixedaddress);
|
||||
BFIx(gd, x1, 0, 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
|
||||
uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)rep; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
uint8_t gd, ed, u8;
|
||||
uint8_t wback, wb1, wb2, gb1, gb2;
|
||||
int16_t i16;
|
||||
int64_t i64, j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(j64);
|
||||
|
||||
while((opcode==0xF2) || (opcode==0xF3)) {
|
||||
rep = opcode-0xF1;
|
||||
opcode = F8;
|
||||
}
|
||||
|
||||
GETREX();
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x01:
|
||||
INST_NAME("LOCK ADD Ew, Gw");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
GETGW(x5);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_add16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
UFLAG_IF {
|
||||
LDADDALH(x5, x1, wback);
|
||||
emit_add16(dyn, ninst, x1, x5, x3, x4);
|
||||
} else {
|
||||
STADDLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_add16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
INST_NAME("LOCK OR Ew, Gw");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
GETGW(x5);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_or16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
UFLAG_IF {
|
||||
LDSETALH(x5, x1, wback);
|
||||
emit_or16(dyn, ninst, x1, x5, x3, x4);
|
||||
} else {
|
||||
STSETLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_or16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0F:
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
|
||||
case 0xB1:
|
||||
INST_NAME("LOCK CMPXCHG Ew, Gw");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
UXTHw(x6, xRAX);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
wback = 0;
|
||||
UXTHw(x1, ed);
|
||||
CMPSxw_REG(x6, x1);
|
||||
B_MARK(cNE);
|
||||
BFIx(ed, gd, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
if(arm64_uscat) {
|
||||
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
|
||||
CMPSw_U12(x1, 0xF);
|
||||
B_MARK3(cGE);
|
||||
} else {
|
||||
TSTx_mask(wback, 1, 0, 0); // mask=1
|
||||
B_MARK3(cNE);
|
||||
}
|
||||
}
|
||||
// Aligned version
|
||||
if(arm64_atomics) {
|
||||
MOVw_REG(x1, x6);
|
||||
CASALH(x1, gd, wback);
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
CMPSw_REG(x6, x1);
|
||||
B_MARK(cNE);
|
||||
// EAX == Ed
|
||||
STLXRH(x4, gd, wback);
|
||||
CBNZx_MARKLOCK(x4);
|
||||
// done
|
||||
}
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
B_MARK_nocond;
|
||||
// Unaligned version
|
||||
MARK3;
|
||||
LDRH_U12(x1, wback, 0);
|
||||
LDAXRB(x3, wback); // dummy read, to arm the write...
|
||||
SUBw_UXTB(x3, x3, x1);
|
||||
CBNZw_MARK3(x3);
|
||||
CMPSw_REG(x6, x1);
|
||||
B_MARK(cNE);
|
||||
// EAX == Ed
|
||||
STLXRB(x4, gd, wback);
|
||||
CBNZx_MARK3(x4);
|
||||
STRH_U12(gd, wback, 0);
|
||||
}
|
||||
}
|
||||
MARK;
|
||||
SMDMB();
|
||||
// Common part (and fallback for EAX != Ed)
|
||||
UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);}
|
||||
BFIx(xRAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
case 0xC1:
|
||||
INST_NAME("LOCK XADD Gw, Ew");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
|
||||
UXTHx(x5, gd);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
BFIx(gd, ed, 0, 16);
|
||||
emit_add16(dyn, ninst, x5, gd, x3, x4);
|
||||
BFIx(ed, x5, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
LDADDALH(x5, x1, wback);
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
ADDxw_REG(x4, x1, x5);
|
||||
STLXRH(x3, x4, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
IFX(X_ALL|X_PEND) {
|
||||
MOVxw_REG(x2, x1);
|
||||
emit_add16(dyn, ninst, x2, x5, x3, x4);
|
||||
}
|
||||
BFIx(gd, x1, 0, 16);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
INST_NAME("LOCK ADC Ew, Gw");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
GETGW(x5);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_adc16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_adc16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
INST_NAME("LOCK AND Ew, Gw");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
nextop = F8;
|
||||
GETGW(x5);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_and16(dyn, ninst, x6, gd, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
MVNw_REG(x3, gd);
|
||||
UFLAG_IF {
|
||||
LDCLRALH(x3, x1, wback);
|
||||
emit_and16(dyn, ninst, x1, gd, x3, x4);
|
||||
} else {
|
||||
STCLRLH(x3, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_and16(dyn, ninst, x1, gd, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
case 0x83:
|
||||
nextop = F8;
|
||||
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);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
MOV32w(x5, i16);
|
||||
UXTHw(x6, ed);
|
||||
emit_add16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOV32w(x5, i16);
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
if(arm64_uscat) {
|
||||
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
|
||||
CMPSw_U12(x1, 0xF);
|
||||
B_MARK(cGE);
|
||||
} else {
|
||||
TSTx_mask(wback, 1, 0, 0); // mask=1
|
||||
B_MARK(cNE);
|
||||
}
|
||||
}
|
||||
if(arm64_atomics) {
|
||||
UFLAG_IF {
|
||||
LDADDALH(x5, x1, wback);
|
||||
} else {
|
||||
STADDLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
ADDw_REG(x4, x1, x5);
|
||||
STLXRH(x3, x4, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
B_MARK2_nocond;
|
||||
MARK; // unaligned! also, not enough
|
||||
LDRH_U12(x1, wback, 0);
|
||||
LDAXRB(x4, wback);
|
||||
SUBw_UXTB(x4, x4, x1);
|
||||
CBNZw_MARK(x4);
|
||||
ADDw_REG(x4, x1, x5);
|
||||
STLXRB(x3, x4, wback);
|
||||
CBNZx_MARK(x3);
|
||||
STRH_U12(x4, wback, 0); // put the whole value
|
||||
SMDMB();
|
||||
}
|
||||
MARK2;
|
||||
UFLAG_IF {
|
||||
emit_add16(dyn, ninst, x1, x5, x3, x4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: //OR
|
||||
if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_or16c(dyn, ninst, x6, i16, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
if(!i64) {MOV32w(x5, i16);}
|
||||
if(arm64_atomics) {
|
||||
UFLAG_IF {
|
||||
LDSETALH(x5, x1, wback);
|
||||
emit_or16c(dyn, ninst, x1, i16, x3, x4);
|
||||
} else {
|
||||
STSETLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
i64 = convert_bitmask_w(i16);
|
||||
if(!i64) {MOV32w(x5, i16);}
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
if(i64) {
|
||||
emit_or16c(dyn, ninst, x1, i16, x3, x4);
|
||||
} else {
|
||||
emit_or16(dyn, ninst, x1, x5, x3, x4);
|
||||
}
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
case 2: //ADC
|
||||
if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
MOV32w(x5, i16);
|
||||
UXTHw(x6, ed);
|
||||
emit_adc16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOV32w(x5, i16);
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_adc16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
case 3: //SBB
|
||||
if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");}
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
MOV32w(x5, i16);
|
||||
UXTHw(x6, ed);
|
||||
emit_sbb16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOV32w(x5, i16);
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_sbb16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
case 4: //AND
|
||||
if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_and16c(dyn, ninst, x6, i16, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
i64 = convert_bitmask_w(i16);
|
||||
if(arm64_atomics) {
|
||||
MOV32w(x5, ~i16);
|
||||
UFLAG_IF {
|
||||
LDCLRALH(x5, x1, wback);
|
||||
if(i64) {
|
||||
emit_and16c(dyn, ninst, x1, i16, x3, x4);
|
||||
} else {
|
||||
MVNw_REG(x5, x5);
|
||||
emit_and16(dyn, ninst, x1, x5, x3, x4);
|
||||
}
|
||||
} else {
|
||||
STCLRLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
if(!i64) {MOV32w(x5, i16);}
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
if(i64) {
|
||||
emit_and16c(dyn, ninst, x1, i16, x3, x4);
|
||||
} else {
|
||||
emit_and16(dyn, ninst, x1, x5, x3, x4);
|
||||
}
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
SMDMB();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5: //SUB
|
||||
if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
MOV32w(x5, i16);
|
||||
UXTHw(x6, ed);
|
||||
emit_sub16(dyn, ninst, x6, x5, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
MOV32w(x5, i16);
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
if(arm64_uscat) {
|
||||
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
|
||||
CMPSw_U12(x1, 0xF);
|
||||
B_MARK(cGE);
|
||||
} else {
|
||||
TSTx_mask(wback, 1, 0, 0); // mask=1
|
||||
B_MARK(cNE);
|
||||
}
|
||||
}
|
||||
if(arm64_atomics) {
|
||||
NEGw_REG(x4, x5);
|
||||
UFLAG_IF {
|
||||
LDADDALH(x4, x1, wback);
|
||||
} else {
|
||||
STADDLH(x4, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
SUBw_REG(x4, x1, x5);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
if(!ALIGNED_ATOMICH) {
|
||||
B_MARK2_nocond;
|
||||
MARK; // unaligned! also, not enough
|
||||
LDRH_U12(x1, wback, 0);
|
||||
LDAXRB(x4, wback);
|
||||
SUBw_UXTB(x4, x4, x1);
|
||||
CBNZw_MARK(x4);
|
||||
SUBw_REG(x4, x1, x5);
|
||||
STLXRB(x3, x4, wback);
|
||||
CBNZx_MARK(x3);
|
||||
STRH_U12(x4, wback, 0); // put the whole value
|
||||
SMDMB();
|
||||
}
|
||||
MARK2;
|
||||
UFLAG_IF {
|
||||
emit_sub16(dyn, ninst, x1, x5, x3, x4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6: //XOR
|
||||
if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
if(MODREG) {
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_xor16c(dyn, ninst, x6, i16, x3, x4);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
i64 = convert_bitmask_w(i16);
|
||||
if(arm64_atomics) {
|
||||
UFLAG_IF {
|
||||
LDEORALH(x5, x1, wback);
|
||||
emit_xor16c(dyn, ninst, x1, i16, x3, x4);
|
||||
} else {
|
||||
STEORLH(x5, wback);
|
||||
}
|
||||
} else {
|
||||
if(!i64) {MOV32w(x5, i16);}
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
if(i64)
|
||||
emit_xor16c(dyn, ninst, x1, i16, x3, x4);
|
||||
else
|
||||
emit_xor16(dyn, ninst, x1, x5, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
SMDMB();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7: //CMP
|
||||
if(opcode==0x81) {INST_NAME("(LOCK) CMP Ew, Iw");} else {INST_NAME("(LOCK) CMP Ew, Ib");}
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING);
|
||||
GETEW(x6, (opcode==0x81)?2:1);
|
||||
(void)wb1;
|
||||
// No need to LOCK, this is readonly
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
if(i16) {
|
||||
MOV32w(x5, i16);
|
||||
emit_cmp16(dyn, ninst, x6, x5, x3, x4, x6);
|
||||
} else {
|
||||
emit_cmp16_0(dyn, ninst, ed, x3, x4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
switch((nextop>>3)&7)
|
||||
{
|
||||
case 0: // INC Ew
|
||||
INST_NAME("LOCK INC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_inc16(dyn, ninst, x6, x5, x3);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
MOV32w(x3, 1);
|
||||
UFLAG_IF {
|
||||
LDADDALH(x3, x1, wback);
|
||||
emit_inc16(dyn, ninst, x1, x3, x4);
|
||||
} else {
|
||||
STADDLH(x3, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_inc16(dyn, ninst, x1, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
case 1: //DEC Ew
|
||||
INST_NAME("LOCK DEC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
UXTHw(x6, ed);
|
||||
emit_dec16(dyn, ninst, x6, x5, x3);
|
||||
BFIx(ed, x6, 0, 16);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
|
||||
if(arm64_atomics) {
|
||||
MOV32w(x3, -1);
|
||||
UFLAG_IF {
|
||||
LDADDALH(x3, x1, wback);
|
||||
emit_dec16(dyn, ninst, x1, x3, x4);
|
||||
} else {
|
||||
STADDLH(x3, wback);
|
||||
}
|
||||
} else {
|
||||
MARKLOCK;
|
||||
LDAXRH(x1, wback);
|
||||
emit_dec16(dyn, ninst, x1, x3, x4);
|
||||
STLXRH(x3, x1, wback);
|
||||
CBNZx_MARKLOCK(x3);
|
||||
}
|
||||
SMDMB();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "emu/x64compstrings.h"
|
||||
|
||||
uintptr_t dynarec64_66F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
int32_t i32;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2;
|
||||
int64_t j64;
|
||||
uint64_t tmp64u, tmp64u2;
|
||||
int v0, v1;
|
||||
int q0, q1;
|
||||
int d0, d1;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(j64);
|
||||
#if STEP > 1
|
||||
static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
|
||||
static const int8_t mask_string8[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
static const int8_t mask_string16[] = { 15, 14, 13, 12, 11, 10, 9, 8 };
|
||||
static const int8_t round_round[] = { 0, 2, 1, 3};
|
||||
#endif
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x38: // SSE 4.x
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
|
||||
case 0xF1:
|
||||
INST_NAME("CRC32 Gd, Ew");
|
||||
nextop = F8;
|
||||
GETEW(x1, 0);
|
||||
GETGD;
|
||||
if(arm64_crc32) {
|
||||
CRC32CH(gd, gd, ed);
|
||||
} else {
|
||||
MOV32w(x2, 0x82f63b78);
|
||||
for(int j=0; j<2; ++j) {
|
||||
UBFXxw(x3, ed, 8*j, 8);
|
||||
EORw_REG(gd, gd, x3);
|
||||
for(int i=0; i<8; ++i) {
|
||||
LSRw_IMM((i&1)?gd:x4, (i&1)?x4:gd, 1);
|
||||
TBZ((i&1)?x4:gd, 0, 4+4);
|
||||
EORw_REG((i&1)?gd:x4, (i&1)?gd:x4, x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "emu/x64compstrings.h"
|
||||
|
||||
uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
int32_t i32;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2;
|
||||
int64_t j64;
|
||||
uint64_t tmp64u, tmp64u2;
|
||||
int v0, v1;
|
||||
int q0, q1;
|
||||
int d0, d1;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(j64);
|
||||
#if STEP > 1
|
||||
static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
|
||||
static const int8_t mask_string8[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
static const int8_t mask_string16[] = { 15, 14, 13, 12, 11, 10, 9, 8 };
|
||||
static const int8_t round_round[] = { 0, 2, 1, 3};
|
||||
#endif
|
||||
|
||||
switch(opcode) {
|
||||
case 0xB8:
|
||||
INST_NAME("POPCNT Gw, Ew");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
SET_DFNONE();
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1, 0);
|
||||
v1 = fpu_get_scratch(dyn, ninst);
|
||||
VEORQ(v1, v1, v1);
|
||||
VMOVQDfrom(v1, 0, ed);
|
||||
CNT_8(v1, v1);
|
||||
UADDLV_8(v1, v1);
|
||||
VMOVHto(gd, v1, 0);
|
||||
IFX(X_ALL) {
|
||||
IFX(X_AF|X_PF|X_SF|X_OF|X_CF) {
|
||||
MOV32w(x1, (1<<F_OF) | (1<<F_SF) | (1<<F_ZF) | (1<<F_AF) | (1<<F_CF) | (1<<F_PF));
|
||||
BICw(xFlags, xFlags, x1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
CMPSw_U12(gd, 0);
|
||||
IFNATIVE(NF_EQ) {}
|
||||
else {
|
||||
CSETw(x1, cEQ);
|
||||
BFIw(xFlags, x1, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
GWBACK;
|
||||
break;
|
||||
|
||||
case 0xBC:
|
||||
INST_NAME("TZCNT Gw, Ew");
|
||||
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
|
||||
SET_DFNONE();
|
||||
nextop = F8;
|
||||
GETEW(x1, 0);
|
||||
GETGW(x2);
|
||||
TSTxw_REG(ed, ed);
|
||||
IFX(X_CF) {
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
|
||||
}
|
||||
RBITw(x3, ed); // reverse
|
||||
CLZw(gd, x3); // x2 gets leading 0 == TZCNT
|
||||
MOV32w(x3, 16);
|
||||
CSELw(gd, x3, gd, cEQ); // if src is zero, use bit width as res
|
||||
IFX(X_ZF) {
|
||||
TSTxw_REG(gd, gd);
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
|
||||
}
|
||||
GWBACK;
|
||||
break;
|
||||
|
||||
case 0xBD:
|
||||
INST_NAME("LZCNT Gw, Ew");
|
||||
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
|
||||
SET_DFNONE();
|
||||
nextop = F8;
|
||||
GETEW(x1, 0);
|
||||
GETGW(x2);
|
||||
IFX(X_CF) {
|
||||
TSTxw_REG(ed, ed);
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
|
||||
}
|
||||
CLZw(gd, ed);
|
||||
SUBw_U12(gd, gd, 16); // sub zero cnt of high word
|
||||
IFX(X_ZF) {
|
||||
TSTxw_REG(gd, gd);
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
|
||||
}
|
||||
GWBACK;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,161 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
#define GETGm gd = ((nextop&0x38)>>3)
|
||||
|
||||
uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int32_t i32;
|
||||
int64_t j64, i64;
|
||||
int cacheupd = 0;
|
||||
int lock;
|
||||
int v0, v1, s0;
|
||||
MAYUSE(i32);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(v0);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(lock);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
if(!rex.is32bits) {
|
||||
// should do a different file
|
||||
DEFAULT;
|
||||
return addr;
|
||||
}
|
||||
|
||||
rep = 0;
|
||||
while((opcode==0xF2) || (opcode==0xF3)) {
|
||||
rep = opcode-0xF1;
|
||||
opcode = F8;
|
||||
}
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV Seg:Ed, Gd");
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if(MODREG) { // reg <= reg
|
||||
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
|
||||
} else { // mem <= reg
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
STz(gd, x4, fixedaddress);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, Seg:Ed");
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if(MODREG) { // reg => reg
|
||||
MOVxw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
|
||||
} else { // mem => reg
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
LDz(gd, x4, fixedaddress);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP Seg:Ed");
|
||||
nextop=F8;
|
||||
if(MODREG) { // reg <= reg
|
||||
POP1_32(x1);
|
||||
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1);
|
||||
} else { // mem <= reg
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
POP1_32(x1);
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
STz(x1, x4, fixedaddress);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX, Seg:[Od]");
|
||||
i32 = F16;
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, 0);
|
||||
if(i32<4096 && !(i32&3)) {
|
||||
LDRw_U12(xRAX, x4, i32);
|
||||
} else if(i32<256) {
|
||||
LDURw_I9(xRAX, x4, i32);
|
||||
} else {
|
||||
MOV32w(x1, i32);
|
||||
LDRw_REG(xRAX, x4, x1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA3:
|
||||
INST_NAME("MOV Seg:[Od], EAX");
|
||||
i32 = F16;
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, 0);
|
||||
if(i32<4096 && !(i32&3)) {
|
||||
STRw_U12(xRAX, x4, i32);
|
||||
} else if(i32<256) {
|
||||
STURw_I9(xRAX, x4, i32);
|
||||
} else {
|
||||
MOV32w(x1, i32);
|
||||
STRw_REG(xRAX, x4, x1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ew");
|
||||
if (MODREG) {
|
||||
DEFAULT;
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
|
||||
ADDz_REG(x4, x4, ed);
|
||||
LDW(x3, x4, fixedaddress);
|
||||
PUSH1_32(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
#define GETGm gd = ((nextop&0x38)>>3)
|
||||
|
||||
uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int32_t i32;
|
||||
int64_t j64, i64;
|
||||
int cacheupd = 0;
|
||||
int lock;
|
||||
int v0, v1, s0;
|
||||
MAYUSE(i32);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(v0);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(lock);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
if(!rex.is32bits) {
|
||||
// should do a different file
|
||||
DEFAULT;
|
||||
return addr;
|
||||
}
|
||||
|
||||
rep = 0;
|
||||
while((opcode==0xF2) || (opcode==0xF3)) {
|
||||
rep = opcode-0xF1;
|
||||
opcode = F8;
|
||||
}
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 64:
|
||||
addr = dynarec64_6764_32(dyn, addr, ip, ninst, rex, rep, _FS, ok, need_epilog);
|
||||
break;
|
||||
|
||||
#define GO(NO, YES) \
|
||||
BARRIER(BARRIER_MAYBE); \
|
||||
JUMP(addr+i8, 1); \
|
||||
if(dyn->insts[ninst].x64.jmp_insts==-1 || \
|
||||
CHECK_CACHE()) { \
|
||||
/* out of the block */ \
|
||||
i32 = dyn->insts[ninst].epilog-(dyn->native_size); \
|
||||
Bcond(NO, i32); \
|
||||
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
|
||||
if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \
|
||||
fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
|
||||
jump_to_next(dyn, addr+i8, 0, ninst, rex.is32bits); \
|
||||
} else { \
|
||||
CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
|
||||
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size);\
|
||||
SKIP_SEVL(i32); \
|
||||
B(i32); \
|
||||
} \
|
||||
} else { \
|
||||
/* inside the block */ \
|
||||
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
|
||||
SKIP_SEVL(i32); \
|
||||
Bcond(YES, i32); \
|
||||
}
|
||||
case 0xE0:
|
||||
INST_NAME("LOOPNZ (16bits)");
|
||||
READFLAGS(X_ZF);
|
||||
i8 = F8S;
|
||||
UXTHw(x1, xRCX);
|
||||
SUBw_U12(x1, x1, 1);
|
||||
BFIx(xRCX, x1, 0, 16);
|
||||
CBZw_NEXT(x1); // ECX is 0, no LOOP
|
||||
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
|
||||
GO(cNE, cEQ);
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("LOOPZ (16bits)");
|
||||
READFLAGS(X_ZF);
|
||||
i8 = F8S;
|
||||
UXTHw(x1, xRCX);
|
||||
SUBw_U12(x1, x1, 1);
|
||||
BFIx(xRCX, x1, 0, 16);
|
||||
CBZw_NEXT(x1); // ECX is 0, no LOOP
|
||||
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
|
||||
GO(cEQ, cNE);
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("LOOP (16bits)");
|
||||
i8 = F8S;
|
||||
UXTHw(x1, xRCX);
|
||||
SUBSw_U12(x1, x1, 1);
|
||||
BFIx(xRCX, x1, 0, 16);
|
||||
GO(cEQ, cNE);
|
||||
break;
|
||||
case 0xE3:
|
||||
INST_NAME("JCXZ");
|
||||
i8 = F8S;
|
||||
TSTw_mask(xRCX, 0, 15); //mask=0xffff
|
||||
GO(cNE, cEQ);
|
||||
break;
|
||||
#undef GO
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
static const char* avx_prefix_string(uint16_t p)
|
||||
{
|
||||
switch(p) {
|
||||
case VEX_P_NONE: return "0";
|
||||
case VEX_P_66: return "66";
|
||||
case VEX_P_F2: return "F2";
|
||||
case VEX_P_F3: return "F3";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
static const char* avx_map_string(uint16_t m)
|
||||
{
|
||||
switch(m) {
|
||||
case VEX_M_NONE: return "0";
|
||||
case VEX_M_0F: return "0F";
|
||||
case VEX_M_0F38: return "0F38";
|
||||
case VEX_M_0F3A: return "0F3A";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) {
|
||||
switch(opcode) {
|
||||
|
||||
case 0xF6:
|
||||
INST_NAME("MULX Gd, Vd, Ed (,RDX)");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED32(0);
|
||||
GETVD;
|
||||
if(rex.w) {
|
||||
// 64bits mul
|
||||
if((gd==xRDX) || (gd==ed) || (gd==vd))
|
||||
gb1 = x3;
|
||||
else
|
||||
gb1 = gd;
|
||||
UMULH(gb1, xRDX, ed);
|
||||
if(gd!=vd) {MULx(vd, xRDX, ed);}
|
||||
if(gb1==x3) {
|
||||
MOVx_REG(gd, gb1);
|
||||
}
|
||||
} else {
|
||||
// 32bits mul
|
||||
UMULL(x3, xRDX, ed);
|
||||
if(gd!=vd) {MOVw_REG(vd, x3);}
|
||||
LSRx(gd, x3, 32);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
|
||||
}
|
||||
else if((vex.m==VEX_M_0F) && (vex.p==VEX_P_66)) {
|
||||
switch(opcode) {
|
||||
case 0xD6:
|
||||
INST_NAME("VMOVQ Ex, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3));
|
||||
VMOV(v1, v0);
|
||||
YMM0((nextop&7)+(rex.b<<3));
|
||||
} else {
|
||||
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
VSTR64_U12(v0, ed, fixedaddress);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6E:
|
||||
INST_NAME("VMOVD Gx, Ed");
|
||||
nextop = F8;
|
||||
GETGX_empty(v0);
|
||||
GETED(0);
|
||||
VEORQ(v0, v0, v0); // RAZ vector
|
||||
if(rex.w) {
|
||||
FMOVDx(v0, ed);
|
||||
} else {
|
||||
FMOVSw(v0, ed);
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
}
|
||||
else {DEFAULT;}
|
||||
|
||||
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)==1))
|
||||
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || BOX64DRENV(dynarec_dump)) {
|
||||
dynarec_log(LOG_NONE, "Dynarec unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "dynablock.h"
|
||||
#include "x64emu.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "x64run.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "dynarec/dynablock_private.h"
|
||||
#include "dynarec_arm64_arch.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
//order might be important, so define SUPER for the right one
|
||||
#define SUPER() \
|
||||
GO(flags) \
|
||||
GO(x87) \
|
||||
GO(mmx) \
|
||||
GO(sse) \
|
||||
GO(ymm) \
|
||||
|
||||
|
||||
typedef struct arch_flags_s
|
||||
{
|
||||
uint8_t defered:1;
|
||||
uint8_t nf:1;
|
||||
uint8_t eq:1;
|
||||
uint8_t vf:1;
|
||||
uint8_t cf:1;
|
||||
uint8_t inv_cf:1;
|
||||
} arch_flags_t;
|
||||
|
||||
#define X87_ST_D 0
|
||||
#define X87_ST_F 1
|
||||
#define X87_ST_I64 2
|
||||
typedef struct arch_x87_s
|
||||
{
|
||||
int8_t delta; //up to +/-7
|
||||
uint8_t x87; // 1bit is STx present
|
||||
uint16_t x87_type; // 2bits per STx type
|
||||
uint32_t x87_pos; //4bits per STx position (well, 3 would be enough)
|
||||
} arch_x87_t;
|
||||
|
||||
typedef struct arch_mmx_s
|
||||
{
|
||||
uint8_t mmx; //1bit for each mmx reg present
|
||||
} arch_mmx_t;
|
||||
|
||||
typedef struct arch_sse_s
|
||||
{
|
||||
uint16_t sse; //1bit for each sse reg present
|
||||
} arch_sse_t;
|
||||
|
||||
typedef struct arch_ymm_s
|
||||
{
|
||||
uint16_t ymm0; // 1bit for ymm0
|
||||
uint16_t ymm; // 1bit for each ymm present
|
||||
uint64_t ymm_pos; // 4bits for position of each ymm present
|
||||
} arch_ymm_t;
|
||||
|
||||
typedef struct arch_arch_s
|
||||
{
|
||||
#define GO(A) uint16_t A:1;
|
||||
SUPER()
|
||||
#undef GO
|
||||
uint16_t unaligned:1;
|
||||
uint16_t seq:10; // how many instruction on the same values
|
||||
} arch_arch_t;
|
||||
|
||||
typedef struct arch_build_s
|
||||
{
|
||||
#define GO(A) uint8_t A:1;
|
||||
SUPER()
|
||||
#undef GO
|
||||
uint8_t unaligned;
|
||||
#define GO(A) arch_##A##_t A##_;
|
||||
SUPER()
|
||||
#undef GO
|
||||
} arch_build_t;
|
||||
|
||||
static arch_build_t static_build[MAX_INSTS+2] = {0};
|
||||
|
||||
static int arch_build(dynarec_arm_t* dyn, int ninst, arch_build_t* arch)
|
||||
{
|
||||
memset(arch, 0, sizeof(arch_build_t));
|
||||
// flags
|
||||
if((dyn->insts[ninst].f_entry.dfnone==0) || dyn->insts[ninst].need_nat_flags || dyn->insts[ninst].before_nat_flags) {
|
||||
arch->flags = 1;
|
||||
arch->flags_.defered = dyn->insts[ninst].f_entry.dfnone==0;
|
||||
uint8_t flags = dyn->insts[ninst].need_nat_flags | dyn->insts[ninst].before_nat_flags;
|
||||
arch->flags_.vf = flags&NF_VF;
|
||||
arch->flags_.nf = flags&NF_SF;
|
||||
arch->flags_.eq = flags&NF_EQ;
|
||||
arch->flags_.cf = flags&NF_CF;
|
||||
if(arch->flags_.cf)
|
||||
arch->flags_.inv_cf = !dyn->insts[ninst].normal_carry;
|
||||
}
|
||||
// got through all naoncache to gather regs assignments
|
||||
int idx;
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->insts[ninst].n.neoncache[i].v!=-1)
|
||||
switch(dyn->insts[ninst].n.neoncache[i].t) {
|
||||
case NEON_CACHE_XMMW:
|
||||
arch->sse = 1;
|
||||
arch->sse_.sse |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_MM:
|
||||
arch->mmx = 1;
|
||||
arch->mmx_.mmx |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_YMMW:
|
||||
arch->ymm = 1;
|
||||
arch->ymm_.ymm |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
idx = i;
|
||||
if(idx>=EMM0 && idx<=EMM0+8)
|
||||
idx-=EMM0;
|
||||
else
|
||||
idx-=SCRATCH0-8;
|
||||
arch->ymm_.ymm_pos |= idx<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
break;
|
||||
case NEON_CACHE_ST_D:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_D)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_F:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_F)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_I64:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_I64)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_XMMR:
|
||||
case NEON_CACHE_YMMR:
|
||||
default:
|
||||
// doing nothing, it's just a value read in memory
|
||||
break;
|
||||
}
|
||||
// ymm0
|
||||
if(dyn->insts[ninst].ymm0_out) {
|
||||
arch->ymm = 1;
|
||||
arch->ymm_.ymm0 = dyn->insts[ninst].ymm0_out;
|
||||
}
|
||||
// x87 top
|
||||
if(dyn->insts[ninst].n.x87stack) {
|
||||
arch->x87 = 1;
|
||||
arch->x87_.delta = dyn->insts[ninst].n.x87stack;
|
||||
}
|
||||
// opcode can handle unaligned
|
||||
arch->unaligned = dyn->insts[ninst].unaligned;
|
||||
return arch->flags + arch->x87 + arch->mmx + arch->sse + arch->ymm + arch->unaligned;
|
||||
}
|
||||
|
||||
static int sizeof_arch(arch_arch_t* arch)
|
||||
{
|
||||
int sz = sizeof(arch_arch_t);
|
||||
#define GO(A) if(arch->A) sz+=sizeof(arch_##A##_t);
|
||||
SUPER()
|
||||
#undef GO
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int sizeof_arch_build(arch_build_t* build)
|
||||
{
|
||||
int sz = sizeof(arch_arch_t);
|
||||
#define GO(A) if(build->A) sz+=sizeof(arch_##A##_t);
|
||||
SUPER()
|
||||
#undef GO
|
||||
return sz;
|
||||
}
|
||||
|
||||
size_t get_size_arch(dynarec_arm_t* dyn)
|
||||
{
|
||||
arch_build_t* previous = NULL;
|
||||
size_t sz = 0;
|
||||
int seq = 0;
|
||||
int nseq = 0;
|
||||
int last = 0;
|
||||
if(!dyn->size) return 0;
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
arch_build_t* build = static_build+i;
|
||||
last = arch_build(dyn, i, build);
|
||||
if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
|
||||
// same sequence, increment
|
||||
++seq;
|
||||
} else {
|
||||
seq = 0;
|
||||
++nseq;
|
||||
previous = build;
|
||||
sz += sizeof_arch_build(build);
|
||||
}
|
||||
}
|
||||
if(nseq==1 && !last)
|
||||
return 0; //empty, no flags, no nothing
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void build_next(arch_arch_t* arch, arch_build_t* build)
|
||||
{
|
||||
#define GO(A) arch->A = build->A;
|
||||
SUPER()
|
||||
#undef GO
|
||||
arch->unaligned = build->unaligned;
|
||||
arch->seq = 0;
|
||||
void* p = ((void*)arch)+sizeof(arch_arch_t);
|
||||
#define GO(A) \
|
||||
if(build->A) { \
|
||||
memcpy(p, &(build->A##_), sizeof(arch_ ##A##_t)); \
|
||||
p+=sizeof(arch_##A##_t); \
|
||||
}
|
||||
SUPER()
|
||||
#undef GO
|
||||
}
|
||||
|
||||
void* populate_arch(dynarec_arm_t* dyn, void* p, size_t tot_sz)
|
||||
{
|
||||
arch_build_t* previous = NULL;
|
||||
arch_arch_t* arch = p;
|
||||
arch_arch_t* next = p;
|
||||
int seq = 0;
|
||||
size_t total = 0;
|
||||
if(!tot_sz) return NULL;
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
arch_build_t* build = static_build+i;
|
||||
if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
|
||||
// same sequence, increment
|
||||
seq++;
|
||||
arch->seq = seq;
|
||||
} else {
|
||||
int sz = sizeof_arch_build(build);
|
||||
if(total+sz>tot_sz) {
|
||||
printf_log(LOG_INFO, "Warning: populate_arch oversized\n");
|
||||
return NULL;
|
||||
}
|
||||
arch = next;
|
||||
build_next(arch, build);
|
||||
seq = 0;
|
||||
previous = build;
|
||||
total += sz;
|
||||
next = (arch_arch_t*)((uintptr_t)arch+sz);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int getX64AddressInst(dynablock_t* db, uintptr_t x64pc); // define is signal.c
|
||||
|
||||
// NZCV N
|
||||
#define NZCV_N 31
|
||||
// NZCV Z
|
||||
#define NZCV_Z 30
|
||||
// NZCV C
|
||||
#define NZCV_C 29
|
||||
// NZCV V
|
||||
#define NZCV_V 28
|
||||
|
||||
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc)
|
||||
{
|
||||
if(!db->arch_size || !db->arch)
|
||||
return;
|
||||
int ninst = getX64AddressInst(db, x64pc);
|
||||
dynarec_log(LOG_INFO, "adjust_arch(...), db=%p, x64pc=%p, nints=%d", db, (void*)x64pc, ninst);
|
||||
if(ninst<0) {
|
||||
dynarec_log_prefix(0, LOG_INFO, "\n");
|
||||
return;
|
||||
}
|
||||
if(ninst==0) {
|
||||
dynarec_log_prefix(0, LOG_INFO, "\n");
|
||||
CHECK_FLAGS(emu);
|
||||
return;
|
||||
}
|
||||
// look for state at ninst-1
|
||||
arch_arch_t* arch = db->arch;
|
||||
arch_arch_t* next = arch;
|
||||
#define GO(A) arch_##A##_t* A = NULL;
|
||||
SUPER()
|
||||
#undef GO
|
||||
int i = 0;
|
||||
while(i<ninst-1) {
|
||||
arch = next;
|
||||
i += 1+arch->seq;
|
||||
dynarec_log_prefix(0, LOG_INFO, "[ seq=%d%s%s%s%s%s ] ", arch->seq, arch->flags?" Flags":"", arch->x87?" x87":"", arch->mmx?" MMX":"", arch->sse?" SSE":"", arch->ymm?" YMM":"");
|
||||
next = (arch_arch_t*)((uintptr_t)next + sizeof_arch(arch));
|
||||
}
|
||||
int sz = sizeof(arch_arch_t);
|
||||
#define GO(A) \
|
||||
if(arch->A) { \
|
||||
A = (arch_##A##_t*)((uintptr_t)arch + sz); \
|
||||
sz+=sizeof(arch_##A##_t); \
|
||||
}
|
||||
SUPER()
|
||||
#undef GO
|
||||
if(flags) {
|
||||
dynarec_log_prefix(0, LOG_INFO, " flags[%s-%s%s%s%s] ", flags->defered?"defered":"", flags->nf?"S":"", flags->vf?"O":"", flags->eq?"Z":"", flags->cf?(flags->inv_cf?"C(inv)":"C"):"");
|
||||
if(flags->defered) {
|
||||
CHECK_FLAGS(emu);
|
||||
//return;
|
||||
}
|
||||
if(flags->nf) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_N), F_SF);
|
||||
}
|
||||
if(flags->vf) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_V), F_OF);
|
||||
}
|
||||
if(flags->eq) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_Z), F_ZF);
|
||||
}
|
||||
if(flags->cf) {
|
||||
if(flags->inv_cf) {
|
||||
CONDITIONAL_SET_FLAG((p->uc_mcontext.pstate&(1<<NZCV_C))==0, F_CF);
|
||||
} else {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_C), F_CF);
|
||||
}
|
||||
}
|
||||
}
|
||||
struct fpsimd_context *fpsimd = NULL;
|
||||
// find fpsimd struct
|
||||
{
|
||||
struct _aarch64_ctx * ff = (struct _aarch64_ctx*)p->uc_mcontext.__reserved;
|
||||
while (ff->magic && !fpsimd) {
|
||||
if(ff->magic==FPSIMD_MAGIC)
|
||||
fpsimd = (struct fpsimd_context*)ff;
|
||||
else
|
||||
ff = (struct _aarch64_ctx*)((uintptr_t)ff + ff->size);
|
||||
}
|
||||
}
|
||||
if(sse) {
|
||||
dynarec_log_prefix(0, LOG_INFO, " sse[%x (fpsimd=%p)] ", sse->sse, fpsimd);
|
||||
for(int i=0; i<16; ++i)
|
||||
if(fpsimd && (sse->sse>>i)&1) {
|
||||
int idx = 0;
|
||||
if(i>7) {
|
||||
idx = XMM8 + i - 8;
|
||||
} else {
|
||||
idx = XMM0 + i;
|
||||
}
|
||||
emu->xmm[i].u128 = fpsimd->vregs[idx];
|
||||
}
|
||||
}
|
||||
if(ymm) {
|
||||
dynarec_log_prefix(0, LOG_INFO, " ymm[%x, pos=%x, 0=%x (fpsimd=%p)] ", ymm->ymm, ymm->ymm_pos, ymm->ymm0, fpsimd);
|
||||
for(int i=0; i<16; ++i) {
|
||||
if(fpsimd && (ymm->ymm>>i)&1) {
|
||||
int idx = (ymm->ymm_pos>>(i*4))&0xf;
|
||||
if(i>7) {
|
||||
idx = SCRATCH0 + i - 8;
|
||||
} else {
|
||||
idx = EMM0 + i;
|
||||
}
|
||||
emu->ymm[i].u128 = fpsimd->vregs[idx];
|
||||
}
|
||||
if(ymm->ymm0&(1<<i))
|
||||
emu->ymm[i].u128 = 0;
|
||||
}
|
||||
}
|
||||
if(mmx) {
|
||||
dynarec_log_prefix(0, LOG_INFO, " mmx[%x (fpsimd=%p)] ", mmx->mmx, fpsimd);
|
||||
for(int i=0; i<8; ++i)
|
||||
if(fpsimd && (mmx->mmx>>i)&1) {
|
||||
int idx = EMM0 + i;
|
||||
emu->mmx[i].q = fpsimd->vregs[idx]&0xffffffffffffffffLL;
|
||||
}
|
||||
}
|
||||
if(x87) {
|
||||
dynarec_log_prefix(0, LOG_INFO, " x87[%x, pos=%x, type=%x (fpsimd=%p)] ", x87->x87, x87->x87_pos, x87->x87_type, fpsimd);
|
||||
emu->top -= x87->delta;
|
||||
for(int i=0; i<8; ++i) {
|
||||
if(x87->x87&(1<<i)) {
|
||||
int idx = EMM0 + (x87->x87_pos>>(i*4))&0x0f;
|
||||
int t = (x87->x87_type>>(i*2))&0x3;
|
||||
switch (t) {
|
||||
case X87_ST_F:
|
||||
emu->x87[(emu->top+i)&7].d = *(float*)&fpsimd->vregs[idx];
|
||||
break;
|
||||
case X87_ST_I64:
|
||||
emu->x87[(emu->top+i)&7].d = *(int64_t*)&fpsimd->vregs[idx];
|
||||
break;
|
||||
case X87_ST_D:
|
||||
emu->x87[(emu->top+i)&7].d = *(double*)&fpsimd->vregs[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynarec_log_prefix(0, LOG_INFO, "\n");
|
||||
}
|
||||
|
||||
int arch_unaligned(dynablock_t* db, uintptr_t x64pc)
|
||||
{
|
||||
if(!db)
|
||||
return 0;
|
||||
if(!db->arch_size || !db->arch)
|
||||
return 0;
|
||||
int ninst = getX64AddressInst(db, x64pc);
|
||||
if(ninst<0) {
|
||||
return 0;
|
||||
}
|
||||
// look for state at ninst
|
||||
arch_arch_t* arch = db->arch;
|
||||
arch_arch_t* next = arch;
|
||||
int i = -1;
|
||||
while(i<ninst) {
|
||||
arch = next;
|
||||
i += 1+arch->seq;
|
||||
next = (arch_arch_t*)((uintptr_t)next + sizeof_arch(arch));
|
||||
}
|
||||
return arch->unaligned;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef __DYNAREC_ARM_ARCH_H__
|
||||
#define __DYNAREC_ARM_ARCH_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "x64emu.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
|
||||
// get size of arch specific info (can be 0)
|
||||
size_t get_size_arch(dynarec_arm_t* dyn);
|
||||
//populate the array
|
||||
void* populate_arch(dynarec_arm_t* dyn, void* p, size_t sz);
|
||||
//adjust flags and more
|
||||
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc);
|
||||
// get if instruction can be regenerated for unaligned access
|
||||
int arch_unaligned(dynablock_t* db, uintptr_t x64pc);
|
||||
#endif // __DYNAREC_ARM_ARCH_H__
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
static const char* avx_prefix_string(uint16_t p)
|
||||
{
|
||||
switch(p) {
|
||||
case VEX_P_NONE: return "0";
|
||||
case VEX_P_66: return "66";
|
||||
case VEX_P_F2: return "F2";
|
||||
case VEX_P_F3: return "F3";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
static const char* avx_map_string(uint16_t m)
|
||||
{
|
||||
switch(m) {
|
||||
case VEX_M_NONE: return "0";
|
||||
case VEX_M_0F: return "0F";
|
||||
case VEX_M_0F38: return "0F38";
|
||||
case VEX_M_0F3A: return "0F3A";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = PK(0);
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE))
|
||||
addr = dynarec64_AVX_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_NONE))
|
||||
addr = dynarec64_AVX_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3))
|
||||
addr = dynarec64_AVX_F3_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F3))
|
||||
addr = dynarec64_AVX_F3_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else {DEFAULT;}
|
||||
|
||||
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)==1))
|
||||
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || BOX64DRENV(dynarec_dump)) {
|
||||
dynarec_log(LOG_NONE, "Dynarec unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,813 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
#if STEP > 1
|
||||
static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
|
||||
#endif
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x10:
|
||||
INST_NAME("VMOVUPS Gx,Ex");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg(dyn, ninst, x1, ed, 0);
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
if(v0!=v1) VMOVQ(v0, v1);
|
||||
if(vex.l) {
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, ed, 0, gd, -1, -1);
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, ed, -1, -1);
|
||||
if(v0!=v1) VMOVQ(v0, v1);
|
||||
}
|
||||
} else {
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VLDR128_U12(v0, ed, fixedaddress); // no alignment issue with ARMv8 NEON :)
|
||||
if(vex.l) {
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
|
||||
VLDR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x11:
|
||||
INST_NAME("VMOVUPS Ex,Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
|
||||
VMOVQ(v1, v0);
|
||||
if(vex.l) {
|
||||
v0 = ymm_get_reg(dyn, ninst, x1, gd, 0, ed, -1, -1);
|
||||
v1 = ymm_get_reg_empty(dyn, ninst, x1, ed, gd, -1, -1);
|
||||
VMOVQ(v1, v0);
|
||||
}
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VSTR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
v0 = ymm_get_reg(dyn, ninst, x1, gd, 0, ed, -1, -1);
|
||||
VSTR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
nextop = F8;
|
||||
GETVX(v2, 0);
|
||||
if(MODREG) {
|
||||
INST_NAME("VMOVHLPS Gx, Vx, Ex");
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
if((v0!=v2) && (v0!=v1))
|
||||
VMOVQ(v0, v2);
|
||||
VMOVeD(v0, 0, v1, 1);
|
||||
if((v0!=v2) && (v0==v1))
|
||||
VMOVeD(v0, 1, v2, 1);
|
||||
} else {
|
||||
INST_NAME("VMOVLPS Gx, Vx, Ex");
|
||||
GETGX_empty(v0);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(v0!=v2)
|
||||
VMOVQ(v0, v2);
|
||||
VLD1_64(v0, 0, ed);
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x13:
|
||||
nextop = F8;
|
||||
INST_NAME("VMOVLPS Ex, Vx, Gx");
|
||||
GETGX(v0, 0);
|
||||
GETVX(v2, 0);
|
||||
if(v1!=v2)
|
||||
VMOVQ(v0, v2);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
|
||||
if(v0!=v1) VMOVeD(v1, 0, v0, 0);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
VST1_64(v0, 0, ed); // better to use VST1 than VSTR_64, to avoid NEON->VFPU transfert I assume
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
INST_NAME("VUNPCKLPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
SMREAD();
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VZIP1Q_32(v0, v2, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VZIP1Q_32(v0, v2, v1);
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
case 0x15:
|
||||
INST_NAME("VUNPCKHPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
SMREAD();
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VZIP2Q_32(v0, v2, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VZIP2Q_32(v0, v2, v1);
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
case 0x16:
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
INST_NAME("VMOVLHPS Gx, Vx, Ex");
|
||||
GETGX(v0, 1);
|
||||
GETVX(v2, 0);
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
if(v0!=v2 && v0!=v1) VMOVQ(v0, v2);
|
||||
VMOVeD(v0, 1, v1, 0);
|
||||
if(v0!=v2 && v0==v1) VMOVeD(v0, 0, v2, 0);
|
||||
} else {
|
||||
INST_NAME("VMOVHPS Gx, Vx, Ex");
|
||||
SMREAD();
|
||||
GETGX(v0, 1);
|
||||
GETVX(v2, 0);
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
VLD1_64(v0, 1, ed);
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x17:
|
||||
INST_NAME("VMOVHPS Ex,Gx");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
|
||||
VMOVeD(v1, 0, v0, 1);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
VST1_64(v0, 1, ed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x28:
|
||||
INST_NAME("VMOVAPS Gx, Ex");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg(dyn, ninst, x1, ed, 0);
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
VMOVQ(v0, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
VMOVQ(v0, v1);
|
||||
}
|
||||
} else {
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VLDR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
GETGY_empty(v0, -1, -1, -1);
|
||||
VLDR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x29:
|
||||
INST_NAME("VMOVAPS Ex, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
|
||||
VMOVQ(v1, v0);
|
||||
if(vex.l) {
|
||||
GETGYEY_empty(v0, v1);
|
||||
VMOVQ(v1, v0);
|
||||
}
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VSTR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, -1, -1, -1);
|
||||
VSTR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
INST_NAME("VMOVNTPS Ex, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
|
||||
VMOVQ(v1, v0);
|
||||
if(vex.l) {
|
||||
GETGYEY_empty(v0, v1);
|
||||
VMOVQ(v1, v0);
|
||||
}
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VSTR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, -1, -1, -1);
|
||||
VSTR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2E:
|
||||
// no special check...
|
||||
case 0x2F:
|
||||
if(opcode==0x2F) {INST_NAME("VCOMISS Gx, Ex");} else {INST_NAME("VUCOMISS Gx, Ex");}
|
||||
SETFLAGS(X_ALL, SF_SET_NODF);
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
GETEXSS(s0, 0, 0);
|
||||
FCMPS(v0, s0);
|
||||
FCOMI(x1, x2);
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
INST_NAME("VMOVMSPKPS Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
MOV32w(gd, 0);
|
||||
if(MODREG) {
|
||||
// EX is an xmm reg
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETEX_Y(v0, 0, 0); } else { GETEY(v0); }
|
||||
SQXTN_16(q0, v0); // reduces the 4 32bits to 4 16bits
|
||||
VMOVQDto(x1, q0, 0);
|
||||
LSRx(x1, x1, 15);
|
||||
BFIx(gd, x1, 0+(l*4), 1);
|
||||
LSRx(x1, x1, 16);
|
||||
BFIx(gd, x1, 1+(l*4), 1);
|
||||
LSRx(x1, x1, 16);
|
||||
BFIx(gd, x1, 2+(l*4), 1);
|
||||
LSRx(x1, x1, 16);
|
||||
BFIx(gd, x1, 3+(l*4), 1);
|
||||
}
|
||||
} else {
|
||||
// EX is memory
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, (0xfff<<3)-24, 7, rex, NULL, 0, 0);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
LDRx_U12(x1, ed, fixedaddress+16*l);
|
||||
LSRx(x1, x1, 31);
|
||||
BFIx(gd, x1, 0+(l*4), 1);
|
||||
LSRx(x1, x1, 32);
|
||||
BFIx(gd, x1, 1+(l*4), 1);
|
||||
LDRx_U12(x1, ed, fixedaddress+8+16*l);
|
||||
LSRx(x1, x1, 31);
|
||||
BFIx(gd, x1, 2+(l*4), 1);
|
||||
LSRx(x1, x1, 32);
|
||||
BFIx(gd, x1, 3+(l*4), 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x51:
|
||||
INST_NAME("VSQRTPS Gx, Ex");
|
||||
nextop = F8;
|
||||
SKIPTEST(x1);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_EX(q0, q1, 0); } else { GETGY_empty_EY(q0, q1); }
|
||||
VFSQRTQS(q0, q1);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x52:
|
||||
INST_NAME("VRSQRTPS Gx, Ex");
|
||||
nextop = F8;
|
||||
SKIPTEST(x1);
|
||||
v0 = fpu_get_scratch(dyn, ninst);
|
||||
VFMOVSQ_8(v0, 0b01110000); //1.0f
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_EX(q0, q1, 0); } else { GETGY_empty_EY(q0, q1); }
|
||||
#if 0
|
||||
// the aproximation doesn't not work on Death Stranding. code around 0x1419c9100 fail...
|
||||
if(!l) {
|
||||
if(q1==q0)
|
||||
v1 = fpu_get_scratch(dyn, ninst);
|
||||
else
|
||||
v1 = q1;
|
||||
}
|
||||
// more precise
|
||||
VFRSQRTEQS(v0, q1);
|
||||
VFMULQS(v1, v0, q1);
|
||||
VFRSQRTSQS(v1, v1, v0);
|
||||
VFMULQS(q0, v1, v0);
|
||||
#else
|
||||
VFSQRTQS(q0, q1);
|
||||
VFDIVQS(q0, v0, q0);
|
||||
#endif
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x53:
|
||||
INST_NAME("VRCPPS Gx, Ex");
|
||||
nextop = F8;
|
||||
SKIPTEST(x1);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
VFMOVSQ_8(q0, 0b01110000); //1.0f
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETGX_empty_EX(v0, v1, 0);
|
||||
#if 0
|
||||
if(v0==v1)
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
#endif
|
||||
} else {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
}
|
||||
#if 0
|
||||
if(v0!=v1) q1 = v0;
|
||||
VFRECPEQS(q0, v1);
|
||||
VFRECPSQS(q1, q0, v1);
|
||||
VFMULQS(v0, q0, q1);
|
||||
#else
|
||||
VFDIVQS(v0, q0, v1);
|
||||
#endif
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x54:
|
||||
INST_NAME("VANDPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VANDQ(v0, v2, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VANDQ(v0, v2, v1);
|
||||
} else YMM0(gd)
|
||||
break;
|
||||
case 0x55:
|
||||
INST_NAME("VANDNPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VBICQ(v0, v1, v2);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VBICQ(v0, v1, v2);
|
||||
} else YMM0(gd)
|
||||
break;
|
||||
case 0x56:
|
||||
INST_NAME("VORPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VORRQ(v0, v2, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VORRQ(v0, v2, v1);
|
||||
} else YMM0(gd)
|
||||
break;
|
||||
case 0x57:
|
||||
INST_NAME("VXORPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
VEORQ(v0, v2, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
VEORQ(v0, v2, v1);
|
||||
} else YMM0(gd)
|
||||
break;
|
||||
case 0x58:
|
||||
INST_NAME("VADDPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
// check if any input value was NAN
|
||||
VFMAXQS(q0, v2, v1); // propagate NAN
|
||||
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
VFADDQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
|
||||
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
|
||||
VSHLQ_32(q1, q1, 31); // only keep the sign bit
|
||||
VORRQ(v0, v0, q1); // NAN -> -NAN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd)
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("VMULPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
// check if any input value was NAN
|
||||
VFMAXQS(q0, v2, v1); // propagate NAN
|
||||
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
VFMULQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
|
||||
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
|
||||
VSHLQ_32(q1, q1, 31); // only keep the sign bit
|
||||
VORRQ(v0, v0, q1); // NAN -> -NAN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd)
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("VCVTPS2PD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_EX(v0, v1, 0);
|
||||
if(vex.l) {
|
||||
GETGY_empty(q0, -1, -1, -1);
|
||||
FCVTL2(q0, v1);
|
||||
} else YMM0(gd)
|
||||
FCVTL(v0, v1);
|
||||
break;
|
||||
case 0x5B:
|
||||
INST_NAME("VCVTDQ2PS Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGX_empty_EX(v0, v1, 0);
|
||||
SCVTQFS(v0, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
SCVTQFS(v0, v1);
|
||||
} else YMM0(gd)
|
||||
break;
|
||||
case 0x5C:
|
||||
INST_NAME("VSUBPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
// check if any input value was NAN
|
||||
VFMAXQS(q0, v2, v1); // propagate NAN
|
||||
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
VFSUBQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
|
||||
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
|
||||
VSHLQ_32(q1, q1, 31); // only keep the sign bit
|
||||
VORRQ(v0, v0, q1); // NAN -> -NAN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd)
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("VMINPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
// FMIN/FMAX wll not copy a NaN if either is NaN
|
||||
// but x86 will copy src2 if either value is NaN, so lets force a copy of Src2 (Ex) if result is NaN
|
||||
VFMINQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan) && (v2!=v1)) {
|
||||
VFCMEQQS(q0, v0, v0); // 0 is NaN, 1 is not NaN, so MASK for NaN
|
||||
VBIFQ(v0, v1, q0); // copy dest where source is NaN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x5E:
|
||||
INST_NAME("VDIVPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
// check if any input value was NAN
|
||||
VFMAXQS(q0, v2, v1); // propagate NAN
|
||||
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
VFDIVQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
|
||||
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
|
||||
VSHLQ_32(q1, q1, 31); // only keep the sign bit
|
||||
VORRQ(v0, v0, q1); // NAN -> -NAN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd)
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("VMAXPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
// FMIN/FMAX wll not copy a NaN if either is NaN
|
||||
// but x86 will copy src2 if either value is NaN, so lets force a copy of Src2 (Ex) if result is NaN
|
||||
VFMAXQS(v0, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan) && (v2!=v1)) {
|
||||
VFCMEQQS(q0, v0, v0); // 0 is NaN, 1 is not NaN, so MASK for NaN
|
||||
VBIFQ(v0, v1, q0); // copy dest where source is NaN
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x77:
|
||||
if(!vex.l) {
|
||||
INST_NAME("VZEROUPPER");
|
||||
if(vex.v!=0) {
|
||||
UDF(0);
|
||||
} else {
|
||||
for(int i=0; i<(rex.is32bits?8:16); ++i) {
|
||||
YMM0(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
INST_NAME("VZEROALL");
|
||||
if(vex.v!=0) {
|
||||
UDF(0);
|
||||
} else {
|
||||
for(int i=0; i<(rex.is32bits?8:16); ++i) {
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, i);
|
||||
VEORQ(v0, v0, v0);
|
||||
YMM0(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAE:
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
DEFAULT;
|
||||
} else
|
||||
switch((nextop>>3)&7) {
|
||||
case 2:
|
||||
INST_NAME("VLDMXCSR Md");
|
||||
GETED(0);
|
||||
STRw_U12(ed, xEmu, offsetof(x64emu_t, mxcsr));
|
||||
if(BOX64ENV(sse_flushto0)) {
|
||||
MRS_fpcr(x2); // get fpscr
|
||||
LSRw_IMM(x3, ed, 15); // get FZ bit
|
||||
BFIw(x2, x3, 24, 1); // inject FZ bit
|
||||
EORw_REG_LSR(x3, x3, ed, 1); // FZ xor DAZ
|
||||
BFIw(x2, x3, 1, 1); // inject AH bit
|
||||
MSR_fpcr(x2); // put new fpscr
|
||||
}
|
||||
if(BOX64ENV(sse_flushto0)) {
|
||||
// try to sync mxcsr with fpsr on the flag side
|
||||
/* mapping is
|
||||
ARM -> X86
|
||||
0 -> 0 // Invalid operation
|
||||
1 -> 2 // Divide by 0
|
||||
2 -> 3 // Overflow
|
||||
3 -> 4 // underflow
|
||||
4 -> 5 // Inexact
|
||||
5 -> 1 // denormal
|
||||
*/
|
||||
// doing X86 -> ARM here, 0 1 2 3 4 5 -> 0 2 3 4 5 1
|
||||
if(ed!=x1)
|
||||
MOVw_REG(x1, ed); // x1 = 543210
|
||||
RORw(x3, x1, 2); // x3 = 10.....5432
|
||||
BFIw(x1, x3, 1, 4); // x1 = 54320
|
||||
RORw(x3, x3, 32-1); // x3 = 0.....54321
|
||||
BFIw(x1, x3, 5, 1); // x1 = 154320
|
||||
MRS_fpsr(x2);
|
||||
BFIx(x2, x1, 0, 6);
|
||||
MSR_fpsr(x2);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("VSTMXCSR Md");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
LDRw_U12(x4, xEmu, offsetof(x64emu_t, mxcsr));
|
||||
if(BOX64ENV(sse_flushto0)) {
|
||||
// sync with fpsr, with mask from mxcsr
|
||||
MRS_fpsr(x1);
|
||||
// doing ARM -> X86 here, 543210 => 432150
|
||||
UBFXw(x2, x1, 1, 5); // x2 = 54321
|
||||
BFIw(x1, x2, 2, 4); // x1 = 432110
|
||||
LSRw(x2, x2, 4); // x2 = 5
|
||||
BFIw(x1, x2, 1, 1); // x1 = 432150
|
||||
//BFXILw(x3, x4, 7, 6); // this would the mask, but let's ignore that for now
|
||||
BFIw(x4, x1, 0, 6); // inject back the flags
|
||||
}
|
||||
STW(x4, ed, fixedaddress);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
INST_NAME("VCMPPS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8; } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(((u8&15)==3) || ((u8&15)==7) || ((u8&15)==8) || ((u8&15)==9) || ((u8&15)==10) || ((u8&15)==12) || ((u8&15)==13) || ((u8&15)==14)) {
|
||||
VFMAXQS(q0, v2, v1); // propagate NAN
|
||||
VFCMEQQS(((u8&15)==7)?v0:q0, q0, q0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
switch(u8&0xf) {
|
||||
// the inversion of the params in the comparison is there to handle NaN the same way SSE does
|
||||
case 0x00: VFCMEQQS(v0, v2, v1); break; // Equal, not unordered
|
||||
case 0x01: VFCMGTQS(v0, v1, v2); break; // Less than
|
||||
case 0x02: VFCMGEQS(v0, v1, v2); break; // Less or equal
|
||||
case 0x03: VMVNQ(v0, q0); break; // unordered
|
||||
case 0x04: VFCMEQQS(v0, v2, v1); VMVNQ(v0, v0); break; // Not Equal (or unordered on ARM, not on X86...)
|
||||
case 0x05: VFCMGTQS(v0, v1, v2); VMVNQ(v0, v0); break; // Greater or equal or unordered
|
||||
case 0x06: VFCMGEQS(v0, v1, v2); VMVNQ(v0, v0); break; // Greater or unordered
|
||||
case 0x07: break; // ordered
|
||||
case 0x08: VFCMEQQS(v0, v2, v1); VORNQ(v0, v0, q0); break; // Equal, or unordered
|
||||
case 0x09: VFCMGTQS(v0, v1, v2); VORNQ(v0, v0, q0); break; // Less than or unordered
|
||||
case 0x0a: VFCMGEQS(v0, v1, v2); VORNQ(v0, v0, q0); break; // Less or equal or unordered
|
||||
case 0x0b: VEORQ(v0, v0, v0); break; // false
|
||||
case 0x0c: VFCMEQQS(v0, v2, v1); VBICQ(v0, q0, v0); break;
|
||||
case 0x0d: VFCMGEQS(v0, v2, v1); break;
|
||||
case 0x0e: VFCMGTQS(v0, v2, v1); break;
|
||||
case 0x0f: MOVIQ_64(v0, 0xff); break; //true
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xC6:
|
||||
INST_NAME("VSHUFPS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETVX(v2, 0);
|
||||
if(!MODREG) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
|
||||
v1 = -1; // to avoid a warning
|
||||
} else
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
u8 = F8;
|
||||
if(v2==v1 && (u8&0x3)==((u8>>2)&3) && (u8&0xf)==((u8>>4)&0xf)) {
|
||||
VDUPQ_32(v0, v2, u8&3);
|
||||
} else if(v2==v1 && (u8==0xe0)) { // elements 3 2 0 0
|
||||
VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 1, v0, 0);
|
||||
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
|
||||
VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 0, v0, 1);
|
||||
} else if(v2==v1 && (u8==0xa0)) { // elements 2 2 0 0
|
||||
VTRNQ1_32(v0, v1, v2);
|
||||
} else if(v2==v1 && (u8==0xf5)) { // elements 3 3 1 1
|
||||
VTRNQ2_32(v0, v1, v2);
|
||||
} else if(v2==v1 && (u8==0xb1)) { // elements 2 3 0 1
|
||||
VREV64Q_32(v0, v1);
|
||||
} else if(MODREG && u8==0x88) { // elements 2 0 2 0
|
||||
VUZP1Q_32(v0, v2, v1);
|
||||
} else if(MODREG && u8==0xdd) { // elements 3 1 3 1
|
||||
VUZP2Q_32(v0, v2, v1);
|
||||
} else {
|
||||
if((v0==v1) || (v0==v2)) {
|
||||
d0 = fpu_get_scratch(dyn, ninst); s0 = 0;
|
||||
} else {
|
||||
d0 = v0; s0 = 1;
|
||||
}
|
||||
// first two elements from Vx
|
||||
for(int i=0; i<2; ++i) {
|
||||
VMOVeS(d0, i, v2, (u8>>(i*2))&3);
|
||||
}
|
||||
// second two from Ex
|
||||
if(MODREG) {
|
||||
for(int i=2; i<4; ++i) {
|
||||
VMOVeS(d0, i, v1, (u8>>(i*2))&3);
|
||||
}
|
||||
} else {
|
||||
SMREAD();
|
||||
for(int i=2; i<4; ++i) {
|
||||
ADDx_U12(x2, ed, ((u8>>(i*2))&3)*4);
|
||||
VLD1_32(d0, i, x2);
|
||||
}
|
||||
}
|
||||
if(v0!=d0) VMOVQ(v0, d0);
|
||||
}
|
||||
if(vex.l) {
|
||||
if(MODREG)
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, -1);
|
||||
GETGY_empty_VY(v0, v2, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
|
||||
if(v2==v1 && (u8&0x3)==((u8>>2)&3) && (u8&0xf)==((u8>>4)&0xf)) {
|
||||
VDUPQ_32(v0, v2, u8&3);
|
||||
} else if(v2==v1 && (u8==0xe0)) { // elements 3 2 0 0
|
||||
VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 1, v0, 0);
|
||||
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
|
||||
VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 0, v0, 1);
|
||||
} else if(v2==v1 && (u8==0xa0)) { // elements 2 2 0 0
|
||||
VTRNQ1_32(v0, v1, v2);
|
||||
} else if(v2==v1 && (u8==0xf5)) { // elements 3 3 1 1
|
||||
VTRNQ2_32(v0, v1, v2);
|
||||
} else if(v2==v1 && (u8==0xb1)) { // elements 2 3 0 1
|
||||
VREV64Q_32(v0, v1);
|
||||
} else if(MODREG && u8==0x88) { // elements 2 0 2 0
|
||||
VUZP1Q_32(v0, v2, v1);
|
||||
} else if(MODREG && u8==0xdd) { // elements 3 1 3 1
|
||||
VUZP2Q_32(v0, v2, v1);
|
||||
} else {
|
||||
if(s0) d0 = v0;
|
||||
for(int i=0; i<2; ++i) {
|
||||
VMOVeS(d0, i, v2, (u8>>(i*2))&3);
|
||||
}
|
||||
if(MODREG) {
|
||||
for(int i=2; i<4; ++i) {
|
||||
VMOVeS(d0, i, v1, (u8>>(i*2))&3);
|
||||
}
|
||||
} else {
|
||||
SMREAD();
|
||||
for(int i=2; i<4; ++i) {
|
||||
ADDx_U12(x2, ed, 16+((u8>>(i*2))&3)*4);
|
||||
VLD1_32(d0, i, x2);
|
||||
}
|
||||
}
|
||||
VMOVQ(v0, d0);
|
||||
}
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
int need_tst;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0xF2:
|
||||
INST_NAME("ANDN Gd, Vd, Ed");
|
||||
nextop = F8;
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
need_tst = 0;
|
||||
IFX(X_ZF) need_tst = 1;
|
||||
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
|
||||
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
|
||||
IFXNATIVE(X_CF, NF_CF) need_tst = 1;
|
||||
if(need_tst)
|
||||
BICSxw(gd, ed, vd);
|
||||
else
|
||||
BICxw(gd, ed, vd);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETw(x1, cEQ);
|
||||
BFIw(xFlags, x1, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_OF) {
|
||||
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
}
|
||||
IFX(X_CF) {
|
||||
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
|
||||
}
|
||||
IFX(X_SF) {
|
||||
IFNATIVE(NF_SF) {} else {
|
||||
LSRxw_IMM(x1, gd, rex.w?63:31);
|
||||
BFIw(xFlags, x1, F_SF, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xF3:
|
||||
nextop = F8;
|
||||
switch((nextop>>3)&7) {
|
||||
case 1:
|
||||
INST_NAME("BLSR Vd, Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETED(0);
|
||||
GETVD;
|
||||
IFX(X_CF) {
|
||||
TSTxw_REG(ed, ed);
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_CF, 1);
|
||||
}
|
||||
SUBxw_U12(x3, ed, 1);
|
||||
need_tst = 0;
|
||||
IFX(X_ZF) need_tst = 1;
|
||||
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
|
||||
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
|
||||
if(need_tst)
|
||||
ANDSxw_REG(vd, ed, x3);
|
||||
else
|
||||
ANDxw_REG(vd, ed, x3);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_SF) {
|
||||
IFNATIVE(NF_SF) {} else {
|
||||
LSRxw(x3, vd, rex.w?63:31);
|
||||
BFIw(xFlags, x3, F_SF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
if (BOX64ENV(dynarec_test)) {
|
||||
IFX(X_AF) BFCw(xFlags, F_AF, 1);
|
||||
IFX(X_PF) BFCw(xFlags, F_PF, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
INST_NAME("BLSMSK Vd, Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETED(0);
|
||||
GETVD;
|
||||
IFX(X_CF) {
|
||||
TSTxw_REG(ed, ed);
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_CF, 1);
|
||||
}
|
||||
SUBxw_U12(x3, ed, 1);
|
||||
need_tst = 0;
|
||||
IFX(X_ZF) need_tst = 1;
|
||||
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
|
||||
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
|
||||
EORxw_REG(vd, ed, x3);
|
||||
if(need_tst)
|
||||
TSTxw_REG(vd, vd);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_SF) {
|
||||
IFNATIVE(NF_SF) {} else {
|
||||
LSRxw(x3, vd, rex.w?63:31);
|
||||
BFIw(xFlags, x3, F_SF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
if (BOX64ENV(dynarec_test)) {
|
||||
IFX(X_AF) BFCw(xFlags, F_AF, 1);
|
||||
IFX(X_PF) BFCw(xFlags, F_PF, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
INST_NAME("BLSI Vd, Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETED(0);
|
||||
GETVD;
|
||||
IFX(X_CF) {
|
||||
TSTxw_REG(ed, ed);
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_CF, 1);
|
||||
}
|
||||
NEGxw_REG(x3, ed);
|
||||
need_tst = 0;
|
||||
IFX(X_ZF) need_tst = 1;
|
||||
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
|
||||
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
|
||||
if(need_tst)
|
||||
ANDSxw_REG(vd, ed, x3);
|
||||
else
|
||||
ANDxw_REG(vd, ed, x3);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETMw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_SF) {
|
||||
IFNATIVE(NF_SF) {} else {
|
||||
LSRxw(x3, vd, rex.w?63:31);
|
||||
BFIw(xFlags, x3, F_SF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
if (BOX64ENV(dynarec_test)) {
|
||||
IFX(X_AF) BFCw(xFlags, F_AF, 1);
|
||||
IFX(X_PF) BFCw(xFlags, F_PF, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xF5:
|
||||
INST_NAME("BZHI Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
UXTBw(x1, vd);
|
||||
CMPSw_U12(x1, rex.w?64:32);
|
||||
CSETMxw(x2, cPL);
|
||||
IFX(X_CF) {
|
||||
BFIw(xFlags, x2, F_CF, 1);
|
||||
}
|
||||
MVNxw_REG(x2, x2); //prepare mask
|
||||
B_MARK(cPL);
|
||||
LSLxw_REG(x2, x2, x1);
|
||||
MARK;
|
||||
need_tst = 0;
|
||||
IFX(X_ZF) need_tst = 1;
|
||||
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
|
||||
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
|
||||
if(need_tst) {
|
||||
BICSxw(gd, ed, x2);
|
||||
} else
|
||||
BICxw(gd, ed, x2);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_SF) {
|
||||
IFNATIVE(NF_SF) {} else {
|
||||
LSRxw(x3, gd, rex.w?63:31);
|
||||
BFIw(xFlags, x3, F_SF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_AF) BFCw(xFlags, F_AF, 1);
|
||||
IFX(X_PF) BFCw(xFlags, F_PF, 1);
|
||||
IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
break;
|
||||
|
||||
case 0xF7:
|
||||
INST_NAME("BEXTR Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
MOV64xw(x1, 0);
|
||||
UXTBw(x2, vd); // start
|
||||
BFXILw(x3, vd, 8, 8); // length
|
||||
TSTw_REG(x3, x3);
|
||||
B_MARK(cEQ);
|
||||
LSRxw_REG(x1, ed, x2);
|
||||
CMPSw_U12(x3, rex.w?64:32);
|
||||
B_MARK(cGE);
|
||||
MOV32w(x2, rex.w?64:32);
|
||||
SUBw_REG(x2, x2, x3);
|
||||
LSLxw_REG(x1, x1, x2);
|
||||
LSRxw_REG(x1, x1, x2);
|
||||
TSTxw_REG(x1, x1);
|
||||
MARK;
|
||||
MOVxw_REG(gd, x1);
|
||||
IFX(X_ZF) {
|
||||
IFNATIVE(NF_EQ) {} else {
|
||||
CSETw(x3, cEQ);
|
||||
BFIw(xFlags, x3, F_ZF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_AF) BFCw(xFlags, F_AF, 1);
|
||||
IFX(X_PF) BFCw(xFlags, F_PF, 1);
|
||||
IFX(X_CF) BFCw(xFlags, F_CF, 1);
|
||||
IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
|
||||
IFX(X_SF) IFNATIVE(NF_SF) {} else {BFCw(xFlags, F_SF, 1);}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,835 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
#if STEP > 1
|
||||
static const int8_t round_round[] = { 0, 2, 1, 3};
|
||||
#endif
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
if(opcode) {INST_NAME("VPERMPD Gx, Ex, Imm8");} else {INST_NAME("VPERMQ Gx, Ex, Imm8");}
|
||||
nextop = F8;
|
||||
GETGX_empty_EX(v0, q0, 1);
|
||||
u8 = F8;
|
||||
if(v0==q0) d0 = fpu_get_scratch(dyn, ninst);
|
||||
if(v0==q0 || !MODREG) d1 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = d1;
|
||||
GETGY_empty_EY(v1, q1);
|
||||
if(v0==q0) { VMOVQ(d0, q0); VMOVQ(d1, q1); } else {d1 = q1; d0 = q0;}
|
||||
VMOVeD(v0, 0, ((u8>>1)&1)?d1:d0, (u8>>0)&1);
|
||||
VMOVeD(v0, 1, ((u8>>3)&1)?d1:d0, (u8>>2)&1);
|
||||
VMOVeD(v1, 0, ((u8>>5)&1)?d1:d0, (u8>>4)&1);
|
||||
VMOVeD(v1, 1, ((u8>>7)&1)?d1:d0, (u8>>6)&1);
|
||||
break;
|
||||
case 0x02:
|
||||
INST_NAME("VPBLENDD Gx, Vx, Ex, u8");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8;} else { GETGY_empty_VYEY(v0, v2, v1); u8 >>=4;}
|
||||
wb1 = 0; // mask
|
||||
for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<i))
|
||||
wb1 |= (3<<(i*2));
|
||||
MOVI_64(q0, wb1); // load 8bits value as a 8bytes mask
|
||||
SXTL_16(q0, q0); // expand 16bits to 32bits...
|
||||
if(v0==v1) {
|
||||
VBIFQ(v0, v2, q0);
|
||||
} else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VBITQ(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
INST_NAME("VPERMILPS Gx, Ex, Imm8");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETGX_empty_EX(v0, v1, 1);
|
||||
u8 = F8;
|
||||
if(v0==v1) {q1 = fpu_get_scratch(dyn, ninst); VMOVQ(q1, v1);}
|
||||
} else {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
if(v0==v1) {VMOVQ(q1, v1);}
|
||||
}
|
||||
if(u8==0x00 || u8==0x55 || u8==0xAA || u8==0xFF)
|
||||
VDUPQ_32(v0, (v0==v1)?q1:v1, u8&3);
|
||||
else if(u8==0x50)
|
||||
VZIP1Q_32(v0, v1, v1);
|
||||
else if(u8==0xFA)
|
||||
VZIP2Q_32(v0, v1, v1);
|
||||
else if(u8==0xA0)
|
||||
VTRNQ1_32(v0, v1, v1);
|
||||
else if(u8==0xF5)
|
||||
VTRNQ2_32(v0, v1, v1);
|
||||
else for(int i=0; i<4; ++i)
|
||||
VMOVeS(v0, i, (v0==v1)?q1:v1, (u8>>(i*2))&3);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x05:
|
||||
INST_NAME("VPERMILD Gx, Ex, Imm8");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETGX_empty_EX(v0, v1, 1);
|
||||
u8 = F8;
|
||||
} else {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
}
|
||||
switch(((u8>>(l*2))&3)) {
|
||||
case 0b00:
|
||||
case 0b11:
|
||||
VDUPQ_64(v0, v1, ((u8>>(l*2))&1));
|
||||
break;
|
||||
case 0b10:
|
||||
if(v0!=v1) VMOVQ(v0, v1);
|
||||
break;
|
||||
case 0b01:
|
||||
VEXTQ_8(v0, v1, v1, 8); // invert 64bits values
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x46:
|
||||
if(opcode==0x06) { INST_NAME("VPERM2F128 Gx, Vx, Ex, Imm8"); } else { INST_NAME("VPERM2I128 Gx, Vx, Ex, Imm8"); }
|
||||
nextop = F8;
|
||||
if(!vex.l) UDF(0);
|
||||
if(MODREG) {
|
||||
s0 = (nextop&7)+(rex.b<<3);
|
||||
v1 = sse_get_reg(dyn, ninst, x1, s0, 0);
|
||||
} else {
|
||||
s0 = -1;
|
||||
v1 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
}
|
||||
u8 = F8;
|
||||
GETVX(v2, 0);
|
||||
GETGX_empty(v0);
|
||||
if((v0==v2) && ((u8&0xf0)==0)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
VMOVQ(q0, v2);
|
||||
v2 = q0;
|
||||
}
|
||||
if((v0==v1) && ((u8&0xf0)==0x20)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
VMOVQ(q1, v1);
|
||||
v1 = q1;
|
||||
}
|
||||
switch(u8&0x0f) {
|
||||
case 0: if(v0!=v2) VMOVQ(v0, v2); break;
|
||||
case 1: d2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, s0, -1); VMOVQ(v0, d2); break;
|
||||
case 2: if(MODREG) { if(v0!=v1) VMOVQ(v0, v1); } else { VLDR128_U12(v0, ed, fixedaddress); } break;
|
||||
case 3: if(MODREG) { d1 = ymm_get_reg(dyn, ninst, x1, s0, 0, gd, vex.v, -1); VMOVQ(v0, d1); } else { VLDR128_U12(v0, ed, fixedaddress+16); } break;
|
||||
default: VEORQ(v0, v0, v0);
|
||||
}
|
||||
if((u8&0xf0)==0x10) { if((u8&0x0f)!=1) d2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, s0, -1); }
|
||||
if(MODREG && ((u8&0xf0)==0x30)) { if((u8&0x0f)!=3) d1 = ymm_get_reg(dyn, ninst, x1, s0, 0, gd, vex.v, -1); }
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, s0, -1);
|
||||
switch((u8>>4)&0x0f) {
|
||||
case 0: VMOVQ(v0, v2); break;
|
||||
case 1: if(v0!=d2) VMOVQ(v0, d2); break;
|
||||
case 2: if(MODREG) { if(v0!=v1) VMOVQ(v0, v1); } else { VLDR128_U12(v0, ed, fixedaddress); } break;
|
||||
case 3: if(MODREG) { if(v0!=d1) VMOVQ(v0, d1); } else { VLDR128_U12(v0, ed, fixedaddress+16); } break;
|
||||
default: VEORQ(v0, v0, v0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
INST_NAME("VROUNDPS Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_EX(v0, v1, 1); u8 = F8; } else { GETGY_empty_EY(v0, v1); }
|
||||
if(u8&4) {
|
||||
if(!l) wb1 = sse_setround(dyn, ninst, x1, x2, x4);
|
||||
VFRINTISQ(v0, v1);
|
||||
if(l || !vex.l) x87_restoreround(dyn, ninst, wb1);
|
||||
} else {
|
||||
VFRINTRSQ(v0, v1, round_round[u8&3]);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x09:
|
||||
INST_NAME("VROUNDPD Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_EX(v0, v1, 1); u8 = F8; } else { GETGY_empty_EY(v0, v1); }
|
||||
if(u8&4) {
|
||||
if(!l) wb1 = sse_setround(dyn, ninst, x1, x2, x4);
|
||||
VFRINTIDQ(v0, v1);
|
||||
if(l || !vex.l) x87_restoreround(dyn, ninst, wb1);
|
||||
} else {
|
||||
VFRINTRDQ(v0, v1, round_round[u8&3]);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x0A:
|
||||
INST_NAME("VROUNDSS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETEXSS(v1, 0, 1);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
u8 = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
if(u8&4) {
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x3);
|
||||
FRINTXS(d1, v1);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
} else {
|
||||
FRINTRRS(d1, v1, round_round[u8&3]);
|
||||
}
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x0B:
|
||||
INST_NAME("VROUNDSD Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETEXSD(v1, 0, 1);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
u8 = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
if(u8&4) {
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x3);
|
||||
FRINTXD(d1, v1);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
} else {
|
||||
FRINTRRD(d1, v1, round_round[u8&3]);
|
||||
}
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVeD(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x0C:
|
||||
INST_NAME("VBLENDPS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(q0, q2, q1, 1);
|
||||
u8 = F8;
|
||||
if((u8&0xf)==0xf) {
|
||||
if(q0!=q1) VMOVQ(q0, q1);
|
||||
} else if(q0==q1) {
|
||||
for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<i)) {
|
||||
VMOVeS(q0, i, q1, i);
|
||||
} else if(q0!=q2)
|
||||
VMOVeS(q0, i, q2, i);
|
||||
} else {
|
||||
if(q0!=q2)
|
||||
VMOVQ(q0, q2);
|
||||
if((u8&15)==0b0011) {
|
||||
VMOVeD(q0, 0, q1, 0);
|
||||
} else if((u8&15)==0b1100) {
|
||||
VMOVeD(q0, 1, q1, 1);
|
||||
} else for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<i)) {
|
||||
VMOVeS(q0, i, q1, i);
|
||||
}
|
||||
}
|
||||
if(vex.l) {
|
||||
GETGY_empty_VYEY(q0, q2, q1);
|
||||
if((u8&0xf0)==0xf0) {
|
||||
if(q0!=q1) VMOVQ(q0, q1);
|
||||
} else if(q0==q1) {
|
||||
for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<(i+4))) {
|
||||
VMOVeS(q0, i, q1, i);
|
||||
} else if(q0!=q2)
|
||||
VMOVeS(q0, i, q2, i);
|
||||
} else {
|
||||
if(q0!=q2)
|
||||
VMOVQ(q0, q2);
|
||||
if((u8>>4)==0b0011) {
|
||||
VMOVeD(q0, 0, q1, 0);
|
||||
} else if((u8>>4)==0b1100) {
|
||||
VMOVeD(q0, 1, q1, 1);
|
||||
} else for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<(i+4))) {
|
||||
VMOVeS(q0, i, q1, i);
|
||||
}
|
||||
}
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
case 0x0D:
|
||||
INST_NAME("VBLENDPD Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(q0, q2, q1, 1); u8 = F8; } else { GETGY_empty_VYEY(q0, q2, q1); }
|
||||
switch(u8>>(l*2)&3) {
|
||||
case 0b00: if(q0!=q2) VMOVQ(q0, q2); break; // VxVx
|
||||
case 0b01: if(q0!=q1) VMOVeD(q0, 0, q1, 0); if(q0!=q2) VMOVeD(q0, 1, q2, 1); break; // Ex[0]Vx[1]
|
||||
case 0b10: if(q0!=q2) VMOVeD(q0, 0, q2, 0); if(q0!=q1) VMOVeD(q0, 1, q1, 1); break; // Vx[0]Ex[1]
|
||||
case 0b11: if(q0!=q1) VMOVQ(q0, q1); break; // ExEx
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x0E:
|
||||
INST_NAME("VPBLENDW Gx, Vx, Ex, u8");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8;} else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(!l) {
|
||||
MOVI_64(q0, u8);
|
||||
SXTL_8(q0, q0); // expand 8bits to 16bits...
|
||||
}
|
||||
if(v0==v1) {
|
||||
VBIFQ(v0, v2, q0);
|
||||
} else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VBITQ(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x0F:
|
||||
INST_NAME("VPALIGNR Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
u8 = F8;
|
||||
} else {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
}
|
||||
if(u8>31) {
|
||||
VEORQ(v0, v0, v0);
|
||||
} else if(u8>15) {
|
||||
if(!l) VEORQ(d0, d0, d0);
|
||||
VEXTQ_8(v0, v2, d0, u8-16);
|
||||
} else {
|
||||
VEXTQ_8(v0, v1, v2, u8);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
INST_NAME("VPEXTRB Ed, Gx, imm8");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff, 0, rex, NULL, 0, 1);
|
||||
ed = x1;
|
||||
}
|
||||
u8 = F8;
|
||||
VMOVBto(ed, v0, u8&0x0f);
|
||||
if(!MODREG) {
|
||||
STB(ed, wback, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 0x15:
|
||||
INST_NAME("VPEXTRW Ed, Gx, imm8");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 1);
|
||||
ed = x1;
|
||||
}
|
||||
u8 = F8;
|
||||
VMOVHto(ed, v0, u8&7);
|
||||
if(!MODREG) {
|
||||
STH(ed, wback, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 0x16:
|
||||
INST_NAME("VPEXTRD/Q Ed, Gx, imm8");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 1);
|
||||
ed = x1;
|
||||
}
|
||||
u8 = F8;
|
||||
if(rex.w) {
|
||||
VMOVQDto(ed, v0, u8&1);
|
||||
} else {
|
||||
VMOVSto(ed, v0, u8&3);
|
||||
}
|
||||
if(!MODREG) {
|
||||
STxw(ed, wback, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 0x17:
|
||||
INST_NAME("VEXTRACTPS Ed, Gx, imm8");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
ed = TO_NAT((nextop & 7) + (rex.b << 3));
|
||||
} else {
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 1);
|
||||
ed = x1;
|
||||
}
|
||||
u8 = F8;
|
||||
VMOVSto(ed, v0, u8&3);
|
||||
if(!MODREG) {
|
||||
STW(ed, wback, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 0x18:
|
||||
case 0x38:
|
||||
if(opcode==0x18) {INST_NAME("VINSERTF128 Gx, Vx, Ex, imm8");} else {INST_NAME("VINSERTI128 Gx, Vx, Ex, imm8");}
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
|
||||
v1 = -1; // to avoid a warning
|
||||
}
|
||||
u8 = F8;
|
||||
GETVX(v2, 0);
|
||||
GETGX_empty(v0);
|
||||
if(v0==v2 && u8==1) {
|
||||
GETGY_empty(q0, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
|
||||
q2 = q0;
|
||||
} else {
|
||||
GETGY_empty_VY(q0, q2, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
|
||||
}
|
||||
if(MODREG)
|
||||
VMOVQ((u8&1)?q0:v0, v1);
|
||||
else
|
||||
VLD128((u8&1)?q0:v0, ed, fixedaddress);
|
||||
if(v0!=v2)
|
||||
VMOVQ((u8&1)?v0:q0, (u8&1)?v2:q2);
|
||||
break;
|
||||
case 0x19:
|
||||
case 0x39:
|
||||
if(opcode==0x19) {INST_NAME("VEXTRACTF128 Ex, Gx, imm8");} else {INST_NAME("VEXTRACTI128 Ex, Gx, imm8");}
|
||||
nextop = F8;
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop);
|
||||
GETGX(v0, 0);
|
||||
if(u8&1) {GETGY(v0, ((nextop&7)+(rex.b<<3)==gd && MODREG)?1:0, -1, -1, -1);}
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3));
|
||||
VMOVQ(v1, v0);
|
||||
if((nextop&7)+(rex.b<<3)==gd && (u8&1))
|
||||
VEORQ(v0, v0, v0); // special case like vextractf128 xmm3, ymm3, 0x01
|
||||
else
|
||||
YMM0((nextop&7)+(rex.b<<3));
|
||||
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
|
||||
VST128(v0, ed, fixedaddress);
|
||||
}
|
||||
F8; // read u8, but it's been already handled
|
||||
break;
|
||||
|
||||
case 0x1D:
|
||||
INST_NAME("VCVTPS2PH Ex, Gx");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x3, (nextop&7)+(rex.b<<3));
|
||||
} else {
|
||||
v1 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<(3+vex.l), vex.l?15:7, rex, NULL, 0, 1);
|
||||
}
|
||||
if(vex.l && v0==v1) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
VMOVQ(q0, v0);
|
||||
v0 = q0;
|
||||
}
|
||||
u8 = F8;
|
||||
if(u8&4) {
|
||||
s0 = sse_setround(dyn, ninst, x1, x2, x6);
|
||||
} else {
|
||||
u8&=3;
|
||||
if(u8==1) u8=2;
|
||||
else if(u8==2) u8=1;
|
||||
MRS_fpcr(x1); // get fpscr
|
||||
MOV32w(x2, u8);
|
||||
MOVx_REG(x6, x1);
|
||||
BFIx(x1, x2, 22, 2); // inject new round
|
||||
MSR_fpcr(x1); // put new fpscr
|
||||
s0 = x6;
|
||||
}
|
||||
FCVTN16(v1, v0);
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, MODREG?((nextop&7)+(rex.b<<3)):-1, -1,-1);
|
||||
FCVTN162(v1, v0);
|
||||
}
|
||||
x87_restoreround(dyn, ninst, s0);
|
||||
if(MODREG) {
|
||||
YMM0((nextop&7)+(rex.b<<3));
|
||||
} else {
|
||||
if(vex.l) {
|
||||
VST128(v1, ed, fixedaddress);
|
||||
} else {
|
||||
VST64(v1, ed, fixedaddress);
|
||||
}
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
INST_NAME("VINSERTD Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETGX_empty_VX(v0, v2);
|
||||
GETED(1);
|
||||
u8 = F8;
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVQBfrom(v0, u8&0xf, ed);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x21:
|
||||
INST_NAME("VINSERTPS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
if (MODREG) {
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
u8 = F8;
|
||||
if(v0==v1) {
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
VMOVQ(d0, v1);
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVeS(v0, (u8>>4)&3, d0, (u8>>6)&3);
|
||||
} else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVeS(v0, (u8>>4)&3, v1, (u8>>6)&3);
|
||||
}
|
||||
} else {
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 1);
|
||||
u8 = F8;
|
||||
LDW(x2, wback, fixedaddress);
|
||||
VMOVQSfrom(v0, (u8>>4)&3, x2);
|
||||
}
|
||||
uint8_t zmask = u8 & 0xf;
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
if (zmask & (1<<i)) {
|
||||
VMOVQSfrom(v0, i, wZR);
|
||||
}
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x22:
|
||||
INST_NAME("VINSERTD Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETGX_empty_VX(v0, v2);
|
||||
GETED(1);
|
||||
u8 = F8;
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
if(rex.w)
|
||||
VMOVQDfrom(v0, u8&1, ed);
|
||||
else
|
||||
VMOVQSfrom(v0, u8&3, ed);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
INST_NAME("VDPPS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// first mask
|
||||
if((u8&0x0f)!=0x0f) {
|
||||
wb1 = 0; // mask
|
||||
for(int i=0; i<4; ++i)
|
||||
if(u8&(1<<i))
|
||||
wb1 |= (3<<(i*2));
|
||||
MOVI_64(q0, wb1); // load 8bits value as a 8bytes mask
|
||||
SXTL_16(q0, q0); // expand 16bits to 32bits...
|
||||
}
|
||||
if((u8&0xf0)!=0xf0) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
// second mask
|
||||
wb1 = 0; // mask
|
||||
for(int i=0; i<4; ++i)
|
||||
if((u8>>4)&(1<<i))
|
||||
wb1 |= (3<<(i*2));
|
||||
MOVI_64(q1, wb1); // load 8bits value as a 8bytes mask
|
||||
SXTL_16(q1, q1); // expand 16bits to 32bits...
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8; } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
VFMULQS(v0, v2, v1);
|
||||
if((u8&0xf0)!=0xf0) {
|
||||
VANDQ(v0, v0, q1); // second mask
|
||||
}
|
||||
VFADDPQS(v0, v0, v0);
|
||||
FADDPS(v0, v0);
|
||||
VDUPQ_32(v0, v0, 0);
|
||||
if((u8&0x0f)!=0x0f) {
|
||||
VANDQ(v0, v0, q0); // first mask
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
INST_NAME("VDPPD Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETGX_empty_VXEX(v0, v1, v2, 0);
|
||||
u8 = F8;
|
||||
VFMULQD(v0, v1, v2);
|
||||
// mask some, duplicate all, mask some
|
||||
for(int i=0; i<2; ++i)
|
||||
if(!(u8&(1<<(4+i)))) {
|
||||
VMOVQDfrom(v0, i, xZR);
|
||||
}
|
||||
FADDPD(v0, v0);
|
||||
VDUPQ_64(v0, v0, 0);
|
||||
for(int i=0; i<2; ++i)
|
||||
if(!(u8&(1<<i))) {
|
||||
VMOVQDfrom(v0, i, xZR);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
INST_NAME("PCLMULQDQ Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
if(arm64_pmull) {
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
u8 = F8;
|
||||
} else {
|
||||
GETGY_empty_VYEY(v0, v2, v1);
|
||||
}
|
||||
switch (u8&0b00010001) {
|
||||
case 0b00000000:
|
||||
PMULL_128(v0, v2, v1);
|
||||
break;
|
||||
case 0b00010001:
|
||||
PMULL2_128(v0, v2, v1);
|
||||
break;
|
||||
case 0b00000001:
|
||||
VEXTQ_8(d0, v2, v2, 8); // Swap Up/Lower 64bits parts
|
||||
PMULL_128(v0, d0, v1);
|
||||
break;
|
||||
case 0b00010000:
|
||||
VEXTQ_8(d0, v2, v2, 8); // Swap Up/Lower 64bits parts
|
||||
PMULL2_128(v0, d0, v1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETG;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
sse_reflect_reg(dyn, ninst, vex.v);
|
||||
}
|
||||
MOV32w(x1, gd); // gx
|
||||
MOV32w(x2, vex.v); // vx
|
||||
if(MODREG) {
|
||||
if(!l) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
sse_forget_reg(dyn, ninst, ed);
|
||||
}
|
||||
MOV32w(x3, ed);
|
||||
} else {
|
||||
if(!l) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
|
||||
if(ed!=x3) {
|
||||
MOVx_REG(x3, ed);
|
||||
}
|
||||
} else {
|
||||
ADDx_U12(x3, ed, 16);
|
||||
}
|
||||
}
|
||||
if(!l) u8 = F8;
|
||||
MOV32w(x4, u8);
|
||||
CALL_(l?native_pclmul_y:native_pclmul_x, -1, x3);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
//case 0x46: // see 0x06
|
||||
|
||||
case 0x4A:
|
||||
INST_NAME("VBLENDVPS Gx, Vx, Ex, XMMImm8");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
q1 = sse_get_reg(dyn, ninst, x1, u8, 0);
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
F8;
|
||||
} else {
|
||||
v2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
if(MODREG)
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, u8);
|
||||
else
|
||||
VLDR128_U12(v1, ed, fixedaddress+16);
|
||||
q1 = ymm_get_reg(dyn, ninst, x1, u8, 0, vex.v, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
}
|
||||
VSSHRQ_32(q0, q1, 31); // create mask
|
||||
if(v0==v1)
|
||||
VBIFQ(v0, v2, q0);
|
||||
else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VBITQ(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x4B:
|
||||
INST_NAME("VBLENDVPD Gx, Vx, Ex, XMMImm8");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
q1 = sse_get_reg(dyn, ninst, x1, u8, 0);
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
F8;
|
||||
} else {
|
||||
v2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
if(MODREG)
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, u8);
|
||||
else
|
||||
VLDR128_U12(v1, ed, fixedaddress+16);
|
||||
q1 = ymm_get_reg(dyn, ninst, x1, u8, 0, vex.v, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
}
|
||||
VSSHRQ_64(q0, q1, 63); // create mask
|
||||
if(v0==v1)
|
||||
VBIFQ(v0, v2, q0);
|
||||
else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VBITQ(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x4C:
|
||||
INST_NAME("VBLENDPVB Gx, Vx, Ex, XMMImm8");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
q1 = sse_get_reg(dyn, ninst, x1, u8, 0);
|
||||
GETGX_empty_VXEX(v0, v2, v1, 1);
|
||||
F8;
|
||||
} else {
|
||||
v2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
if(MODREG)
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, u8);
|
||||
else
|
||||
VLDR128_U12(v1, ed, fixedaddress+16);
|
||||
q1 = ymm_get_reg(dyn, ninst, x1, u8, 0, vex.v, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
|
||||
}
|
||||
VSSHRQ_8(q0, q1, 7); // create mask
|
||||
if(v0==v1)
|
||||
VBIFQ(v0, v2, q0);
|
||||
else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VBITQ(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xDF:
|
||||
INST_NAME("VAESKEYGENASSIST Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd); // gx
|
||||
if(MODREG) {
|
||||
ed = (nextop&7)+(rex.b<<3);
|
||||
sse_forget_reg(dyn, ninst, ed);
|
||||
MOV32w(x2, ed);
|
||||
MOV32w(x3, 0); //p = NULL
|
||||
} else {
|
||||
MOV32w(x2, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
|
||||
if(ed!=x3) {
|
||||
MOVx_REG(x3, ed);
|
||||
}
|
||||
}
|
||||
u8 = F8;
|
||||
MOV32w(x4, u8);
|
||||
CALL(native_aeskeygenassist, -1);
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u, u64;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x10:
|
||||
INST_NAME("VMOVSD Gx, [Vx,] Ex");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
if(v0!=v1) VMOVeD(v0, 0, v1, 0);
|
||||
if(v0!=v2) VMOVeD(v0, 1, v2, 1);
|
||||
} else {
|
||||
SMREAD();
|
||||
GETGX_empty(v0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
VLD64(v0, ed, fixedaddress); // upper part reseted
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x11:
|
||||
INST_NAME("VMOVSD Ex, Vx, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if(MODREG) {
|
||||
GETVXEX(v2, 0, v1, 1, 0);
|
||||
if(v0!=v1) VMOVeD(v1, 0, v0, 0);
|
||||
if(v1!=v2) VMOVeD(v1, 1, v2, 1);
|
||||
YMM0((nextop&7)+(rex.b<<3));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
VST64(v0, ed, fixedaddress);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
INST_NAME("VMOVDDUP Gx, Ex");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
VDUPQ_64(v0, v1, 0);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
VDUPQ_64(v0, v1, 0);
|
||||
}
|
||||
} else {
|
||||
SMREAD();
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
VLDQ1R_64(v0, ed);
|
||||
if(vex.l) {
|
||||
GETGY_empty(v0, -1, -1, -1);
|
||||
ADDx_U12(x3, ed, 16);
|
||||
VLDQ1R_64(v0, x3);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x2A:
|
||||
INST_NAME("VCVTSI2SD Gx, Vx, Ed");
|
||||
nextop = F8;
|
||||
GETGX_empty_VX(v0, v1);
|
||||
GETED(0);
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
if(rex.w) {
|
||||
SCVTFDx(d1, ed);
|
||||
} else {
|
||||
SCVTFDw(d1, ed);
|
||||
}
|
||||
if(v0!=v1) VMOVQ(v0, v1);
|
||||
VMOVeD(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x2C:
|
||||
INST_NAME("VCVTTSD2SI Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEXSD(q0, 0, 0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
}
|
||||
FCVTZSxwD(gd, q0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBZ_NEXT(x5, FPSR_IOC);
|
||||
if(rex.w) {
|
||||
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
|
||||
} else {
|
||||
MOV32w(gd, 0x80000000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("VCVTSD2SI Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEXSD(q0, 0, 0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
}
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x3);
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
FRINTID(d1, q0);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
FCVTZSxwD(gd, d1);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBZ_NEXT(x5, FPSR_IOC);
|
||||
if(rex.w) {
|
||||
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
|
||||
} else {
|
||||
MOV32w(gd, 0x80000000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
INST_NAME("VSQRTSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FCMEQD(q0, v1, v1); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
FSQRTD(d1, v1);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
FCMEQD(q1, d1, d1); // 0 => out is NAN
|
||||
VBIC(q1, q0, q1); // forget it in any input was a NAN already
|
||||
VSHLQ_64(q1, q1, 63); // only keep the sign bit
|
||||
VORR(d1, d1, q1); // NAN -> -NAN
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, d1, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
INST_NAME("VADDSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXD(q1, v0, v1); // propagate NAN
|
||||
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FADDD(q2, v1, v2); // the high part of the vector is erased...
|
||||
FCMEQD(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
SHL_64(q0, q0, 63); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FADDD(q2, v1, v2); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("VMULSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXD(q1, v0, v1); // propagate NAN
|
||||
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FMULD(q2, v1, v2); // the high part of the vector is erased...
|
||||
FCMEQD(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
SHL_64(q0, q0, 63); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FMULD(q2, v1, v2); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, q2, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("VCVTSD2SS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(BOX64ENV(dynarec_fastround)==2) {
|
||||
FCVT_S_D(d1, v1);
|
||||
} else {
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x3);
|
||||
FCVT_S_D(d1, v1);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, d1, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
|
||||
case 0x5C:
|
||||
INST_NAME("VSUBSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXD(q1, v0, v1); // propagate NAN
|
||||
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FSUBD(q2, v2, v1); // the high part of the vector is erased...
|
||||
FCMEQD(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
SHL_64(q0, q0, 63); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FSUBD(q2, v2, v1); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("VMINSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
// VMINSD: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
|
||||
FCMPD(v2, v1);
|
||||
FCSELD(d1, v1, v2, cCS);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, d1, 0); // to not erase uper part
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5E:
|
||||
INST_NAME("VDIVSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXD(q1, v0, v1); // propagate NAN
|
||||
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FDIVD(q2, v2, v1); // the high part of the vector is erased...
|
||||
FCMEQD(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
SHL_64(q0, q0, 63); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FDIVD(q2, v2, v1); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("VMAXSD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSD(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
FCMPD(v1, v2);
|
||||
FCSELD(d1, v1, v2, cCS);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeD(v0, 0, d1, 0); // to not erase uper part
|
||||
YMM0(gd)
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
INST_NAME("VPSHUFLW Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETEX_Y(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
|
||||
if(u8==0b00000000 || u8==0b01010101 || u8==0b10101010 || u8==0b11111111) {
|
||||
if(v0==v1) {
|
||||
VMOVQ(d0, v1);
|
||||
}
|
||||
VDUP_16(v0, v1, u8&3);
|
||||
if(v0==v1)
|
||||
v1 = d0;
|
||||
} else {
|
||||
// only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
|
||||
if(!l) {
|
||||
u64 = 0;
|
||||
for (int i=0; i<4; ++i) {
|
||||
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0);
|
||||
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8);
|
||||
}
|
||||
MOV64x(x2, u64);
|
||||
}
|
||||
VMOVQDfrom(d0, 0, x2);
|
||||
VTBL1_8(d0, v1, d0);
|
||||
VMOVeD(v0, 0, d0, 0);
|
||||
}
|
||||
if(v0!=v1) {
|
||||
VMOVeD(v0, 1, v1, 1);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x7C:
|
||||
INST_NAME("VHADDPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
VFADDPQS(v0, v2, v1);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x7D:
|
||||
INST_NAME("VHSUBPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
if(MODREG || (v1==v2)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
} else
|
||||
q1 = v1;
|
||||
if(vex.l)
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
else
|
||||
q2 = q0;
|
||||
// q0 will contains -1 / 0 / -1 / 0
|
||||
MOVIQ_64(q0, 0xf0);
|
||||
VSHLQ_32(q0, q0, 31); // keep sign bit
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
VEORQ(q1, v1, q0);
|
||||
VEORQ(q2, v2, q0);
|
||||
VFADDPQS(v0, q2, q1);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
INST_NAME("CMPSD Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETEXSD(v1, 0, 1);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
u8 = F8;
|
||||
FCMPD(v2, v1);
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
switch(u8&7) {
|
||||
case 0: CSETMx(x2, cEQ); break; // Equal
|
||||
case 1: CSETMx(x2, cCC); break; // Less than
|
||||
case 2: CSETMx(x2, cLS); break; // Less or equal
|
||||
case 3: CSETMx(x2, cVS); break; // NaN
|
||||
case 4: CSETMx(x2, cNE); break; // Not Equal or unordered
|
||||
case 5: CSETMx(x2, cCS); break; // Greater or equal or unordered
|
||||
case 6: CSETMx(x2, cHI); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
|
||||
case 7: CSETMx(x2, cVC); break; // not NaN
|
||||
}
|
||||
VMOVQDfrom(v0, 0, x2);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
INST_NAME("VADDSUBPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
static float addsubps[4] = {-1.f, 1.f, -1.f, 1.f};
|
||||
MAYUSE(addsubps);
|
||||
MOV64x(x2, (uintptr_t)&addsubps);
|
||||
VLDR128_U12(q0, x2, 0);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
|
||||
if(v0==v1) {
|
||||
//TODO: find a better way
|
||||
if(!l) q1 = fpu_get_scratch(dyn, ninst);
|
||||
VMOVQ(q1, v2);
|
||||
VFMLAQS(q1, v1, q0);
|
||||
VMOVQ(v0, q1);
|
||||
} else {
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VFMLAQS(v0, v1, q0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xE6:
|
||||
INST_NAME("VCVTPD2DQ Gx, Ex");
|
||||
nextop = F8;
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x6);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) {
|
||||
GETEX_Y(v1, 0, 0);
|
||||
GETGX_empty(v0);
|
||||
if(!BOX64ENV(dynarec_fastround) || vex.l)
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
} else {
|
||||
GETEY(v1);
|
||||
}
|
||||
if(BOX64ENV(dynarec_fastround)) {
|
||||
VFRINTIDQ(l?d0:v0, v1);
|
||||
VFCVTNSQD(l?d0:v0, l?d0:v0); // convert double -> int64
|
||||
if(!l)
|
||||
SQXTN_32(v0, v0); // convert int64 -> int32 with saturation in lower part, RaZ high part
|
||||
else
|
||||
SQXTN2_32(v0, d0); // convert int64 -> int32 with saturation in higher part
|
||||
} else {
|
||||
if(!l) {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
ORRw_mask(x4, xZR, 1, 0); //0x80000000
|
||||
}
|
||||
for(int i=0; i<2; ++i) {
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
if(i) {
|
||||
VMOVeD(d0, 0, v1, i);
|
||||
FRINTID(d0, d0);
|
||||
} else {
|
||||
FRINTID(d0, v1);
|
||||
}
|
||||
FCVTZSwD(x1, d0);
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TSTw_mask(x5, 0, 0); // mask = 1 = FPSR_IOC
|
||||
CSELx(x1, x1, x4, cEQ);
|
||||
VMOVQSfrom(v0, i+l*2, x1);
|
||||
}
|
||||
if(!vex.l && !l) VMOVQDfrom(v0, 1, xZR);
|
||||
}
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xF0:
|
||||
INST_NAME("LDDQU Gx,Ex");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
VMOVQ(v0, v1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(v0, v1);
|
||||
VMOVQ(v0, v1);
|
||||
}
|
||||
} else {
|
||||
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 7, rex, NULL, 0, 0);
|
||||
VLDR128_U12(v0, ed, fixedaddress);
|
||||
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
|
||||
VLDR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_F2_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
case 0xF5:
|
||||
INST_NAME("PDEP Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
if(gd==ed || gd==vd) {
|
||||
gb1 = gd;
|
||||
gd = x4;
|
||||
} else {
|
||||
gb1 = 0;
|
||||
}
|
||||
// x3 = mask of mask, loop while not 0
|
||||
MOV32w(gd, 0);
|
||||
MOV64x(x2, 1);
|
||||
MOV64x(x3, 1);
|
||||
MARK;
|
||||
TSTxw_REG(ed, x3);
|
||||
B_MARK2(cEQ);
|
||||
TSTxw_REG(vd, x2);
|
||||
B_MARK3(cEQ);
|
||||
ORRxw_REG(gd, gd, x3);
|
||||
MARK3;
|
||||
LSLxw_IMM(x2, x2, 1);
|
||||
MARK2;
|
||||
LSLxw_IMM(x3, x3, 1);
|
||||
CBNZxw_MARK(x3);
|
||||
if(gb1)
|
||||
MOVxw_REG(gb1, gd);
|
||||
break;
|
||||
case 0xF6:
|
||||
INST_NAME("MULX Gd, Vd, Ed (,RDX)");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
if(rex.w) {
|
||||
// 64bits mul
|
||||
if((gd==xRDX) || (gd==ed) || (gd==vd))
|
||||
gb1 = x3;
|
||||
else
|
||||
gb1 = gd;
|
||||
UMULH(gb1, xRDX, ed);
|
||||
if(gd!=vd) {MULx(vd, xRDX, ed);}
|
||||
if(gb1==x3) {
|
||||
MOVx_REG(gd, gb1);
|
||||
}
|
||||
} else {
|
||||
// 32bits mul
|
||||
UMULL(x3, xRDX, ed);
|
||||
if(gd!=vd) {MOVw_REG(vd, x3);}
|
||||
LSRx(gd, x3, 32);
|
||||
}
|
||||
break;
|
||||
case 0xF7:
|
||||
INST_NAME("SHRX Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
ANDx_mask(x3, vd, 1, 0, rex.w?5:4); // mask 0x3f/0x1f
|
||||
LSRxw_REG(gd, ed, x3);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_F2_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0xF0:
|
||||
INST_NAME("RORX Gd, Ed, Ib");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(1);
|
||||
u8 = F8;
|
||||
u8&=rex.w?0x3f:0x1f;
|
||||
RORxw(gd, ed, u8);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,582 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u, u64;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0x10:
|
||||
INST_NAME("VMOVSS Gx, Ex [,Vx]");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
GETGX_empty_VXEX(v0, v2, v1, 0);
|
||||
if((v0!=v2) && (v0!=v1)) VMOVQ(v0, v2);
|
||||
if(v0!=v1) VMOVeS(v0, 0, v1, 0);
|
||||
if((v0!=v2) && (v0==v1)) { VMOVeS(v0, 1, v2, 1); VMOVeD(v0, 1, v2, 1);}
|
||||
} else {
|
||||
GETGX_empty(v0);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v0, ed, fixedaddress);
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x11:
|
||||
INST_NAME("VMOVSS Ex, Gx [,Vx]");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
if(MODREG) {
|
||||
GETGXVXEX_empty(v0, v2, v1, 0);
|
||||
if((v2!=v1) && (v2!=v0)) VMOVQ(v2, v1);
|
||||
if(v2!=v0) VMOVeS(v2, 0, v0, 0);
|
||||
if((v2!=v1) && (v2==v0)) { VMOVeS(v2, 1, v0, 1); VMOVeD(v2, 1, v0, 1);}
|
||||
YMM0((nextop&7)+(rex.b<<3));
|
||||
} else {
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VST32(v0, ed, fixedaddress);
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
INST_NAME("VMOVSLDUP Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX_Y(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
VTRNQ1_32(q0, q1, q1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(q0, q1);
|
||||
VTRNQ1_32(q0, q1, q1);
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x16:
|
||||
INST_NAME("MOVSHDUP Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX_Y(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
VTRNQ2_32(q0, q1, q1);
|
||||
if(vex.l) {
|
||||
GETGY_empty_EY(q0, q1);
|
||||
VTRNQ2_32(q0, q1, q1);
|
||||
} else YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x2A:
|
||||
INST_NAME("VCVTSI2SS Gx, Vx, Ed");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETGX_empty_VX(v0, v1);
|
||||
GETED(0);
|
||||
if(rex.w) {
|
||||
SCVTFSx(d1, ed);
|
||||
} else {
|
||||
SCVTFSw(d1, ed);
|
||||
}
|
||||
if(v0!=v1) VMOVQ(v0, v1);
|
||||
VMOVeS(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x2C:
|
||||
INST_NAME("VCVTTSS2SI Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEXSS(d0, 0, 0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
}
|
||||
FCVTZSxwS(gd, d0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBZ_NEXT(x5, FPSR_IOC);
|
||||
if(rex.w) {
|
||||
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
|
||||
} else {
|
||||
ORRw_mask(gd, xZR, 1, 0); //0x80000000
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("VCVTSS2SI Gd, Ex");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEXSS(q0, 0, 0);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
}
|
||||
u8 = sse_setround(dyn, ninst, x1, x2, x3);
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
FRINTIS(d1, q0);
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
FCVTZSxwS(gd, d1);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBZ_NEXT(x5, FPSR_IOC);
|
||||
if(rex.w) {
|
||||
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
|
||||
} else {
|
||||
ORRw_mask(gd, xZR, 1, 0); //0x80000000
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
INST_NAME("SQRTSS Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEXSS(d0, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
FSQRTS(d1, d0);
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
VMOVeS(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x52:
|
||||
INST_NAME("VRSQRTSS Gx, Vx Ex");
|
||||
nextop = F8;
|
||||
GETGX(v0, 1);
|
||||
GETVX(v2, 0);
|
||||
GETEXSS(v1, 0, 0);
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
// so here: F32: Imm8 = abcd efgh that gives => aBbbbbbc defgh000 00000000 00000000
|
||||
// and want 1.0f = 0x3f800000
|
||||
// so 00111111 10000000 00000000 00000000
|
||||
// a = 0, b = 1, c = 1, d = 1, efgh=0
|
||||
// 0b01110000
|
||||
FMOVS_8(d0, 0b01110000);
|
||||
FSQRTS(d1, v1);
|
||||
FDIVS(d0, d0, d1);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, d0, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x53:
|
||||
INST_NAME("VRCPSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGX(v0, 1);
|
||||
GETVX(v2, 0);
|
||||
GETEXSS(v1, 0, 0);
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
FMOVS_8(d0, 0b01110000); //1.0f
|
||||
FDIVS(d0, d0, v1);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, d0, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
INST_NAME("VADDSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXS(q1, v0, v1); // propagate NAN
|
||||
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FADDS(q2, v1, v2); // the high part of the vector is erased...
|
||||
FCMEQS(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
VSHL_32(q0, q0, 31); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FADDS(q2, v1, v2); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("VMULSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXS(q1, v0, v1); // propagate NAN
|
||||
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FMULS(q2, v1, v2); // the high part of the vector is erased...
|
||||
FCMEQS(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
VSHL_32(q0, q0, 31); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FMULS(q2, v1, v2); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("VCVTSS2SD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(v0!=v2) {
|
||||
if(v0==v1) {
|
||||
VMOV(d1, v1);
|
||||
v1 = d1;
|
||||
}
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
FCVT_D_S(d1, v1);
|
||||
VMOVeD(v0, 0, d1, 0);
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x5B:
|
||||
INST_NAME("VCVTTPS2DQ Gx, Ex");
|
||||
nextop = F8;
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
MRS_fpsr(x5);
|
||||
ORRw_mask(x4, xZR, 1, 0); //0x80000000
|
||||
}
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETGX_empty_EX(v0, v1, 0); } else { GETGY_empty_EY(v0, v1); }
|
||||
if(BOX64ENV(dynarec_fastround)) {
|
||||
VFCVTZSQS(v0, v1);
|
||||
} else {
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
for(int i=0; i<4; ++i) {
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
MSR_fpsr(x5);
|
||||
VMOVeS(d0, 0, v1, i);
|
||||
VFCVTZSs(d0, d0);
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBZ(x5, FPSR_IOC, 4+4);
|
||||
VMOVQSfrom(d0, 0, x4);
|
||||
VMOVeS(v0, i, d0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x5C:
|
||||
INST_NAME("VSUBSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXS(q1, v0, v1); // propagate NAN
|
||||
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FSUBS(q2, v2, v1); // the high part of the vector is erased...
|
||||
FCMEQS(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
VSHL_32(q0, q0, 31); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FSUBS(q2, v2, v1); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("VMINSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
FCMPS(v2, v1);
|
||||
FCSELS(d1, v1, v2, cCS);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, d1, 0); // to not erase uper part
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5E:
|
||||
INST_NAME("VDIVSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
q2 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FMAXS(q1, v0, v1); // propagate NAN
|
||||
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
|
||||
FDIVS(q2, v2, v1); // the high part of the vector is erased...
|
||||
FCMEQS(q0, q2, q2); // 0 => out is NAN
|
||||
VBIC(q0, q1, q0); // forget it in any input was a NAN already
|
||||
VSHL_32(q0, q0, 31); // only keep the sign bit
|
||||
VORR(q2, q2, q0); // NAN -> -NAN
|
||||
} else {
|
||||
FDIVS(q2, v2, v1); // the high part of the vector is erased...
|
||||
}
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, q2, 0);
|
||||
YMM0(gd)
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("VMAXSS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
d1 = fpu_get_scratch(dyn, ninst);
|
||||
GETEXSS(v1, 0, 0);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
FCMPS(v1, v2);
|
||||
FCSELS(d1, v1, v2, cCS);
|
||||
if(v0!=v2) {
|
||||
VMOVQ(v0, v2);
|
||||
}
|
||||
VMOVeS(v0, 0, d1, 0); // to not erase uper part
|
||||
YMM0(gd)
|
||||
break;
|
||||
|
||||
case 0x6F:
|
||||
INST_NAME("VMOVDQU Gx, Ex");// no alignment constraint on NEON here, so same as MOVDQA
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
VMOVQ(v0, v1);
|
||||
if(vex.l) {
|
||||
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, -12, -1);
|
||||
GETGY_empty(v0, (nextop&7)+(rex.b<<3), -1, -1);
|
||||
VMOVQ(v0, v1);
|
||||
}
|
||||
} else {
|
||||
GETGX_empty(v0);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VLDR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
GETGY_empty(v0, -1, -1, -1);
|
||||
VLDR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
case 0x70:
|
||||
INST_NAME("VPSHUFHW Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
for(int l=0; l<1+vex.l; ++l) {
|
||||
if(!l) { GETEX_Y(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
|
||||
if(u8==0b00000000 || u8==0b01010101 || u8==0b10101010 || u8==0b11111111) {
|
||||
VDUP_16(d0, v1, 4+(u8&3));
|
||||
} else {
|
||||
// only high part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
|
||||
if(!l) {
|
||||
u64 = 0;
|
||||
for (int i=0; i<4; ++i) {
|
||||
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+8)<<(i*16+0);
|
||||
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+9)<<(i*16+8);
|
||||
}
|
||||
MOV64x(x2, u64);
|
||||
}
|
||||
VMOVQDfrom(d0, 0, x2);
|
||||
VTBL1_8(d0, v1, d0);
|
||||
}
|
||||
VMOVeD(v0, 1, d0, 0);
|
||||
if(v0!=v1) {
|
||||
VMOVeD(v0, 0, v1, 0);
|
||||
}
|
||||
}
|
||||
if(!vex.l) YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0x7E:
|
||||
INST_NAME("MOVQ Gx, Ex");
|
||||
nextop = F8;
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
|
||||
GETGX_empty(v0);
|
||||
FMOVD(v0, v1);
|
||||
} else {
|
||||
GETGX_empty(v0);
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
VLD64(v0, ed, fixedaddress);
|
||||
}
|
||||
YMM0(gd);
|
||||
break;
|
||||
case 0x7F:
|
||||
INST_NAME("VMOVDQU Ex, Gx");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if(MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
|
||||
VMOVQ(v1, v0);
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, (nextop&7) + (rex.b<<3), -1, -1);
|
||||
v1 = ymm_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3), gd, -1, -1);
|
||||
VMOVQ(v1, v0);
|
||||
} // no ymm raz here it seems
|
||||
} else {
|
||||
IF_UNALIGNED(ip) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(wback!=x1) {
|
||||
MOVx_REG(x1, wback);
|
||||
wback = x1;
|
||||
}
|
||||
for(int i=0; i<16; ++i) {
|
||||
VST1_8(v0, i, wback);
|
||||
ADDx_U12(wback, wback, 1);
|
||||
}
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, -1, -1, -1);
|
||||
for(int i=0; i<16; ++i) {
|
||||
VST1_8(v0, i, wback);
|
||||
ADDx_U12(wback, wback, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
|
||||
VSTR128_U12(v0, ed, fixedaddress);
|
||||
if(vex.l) {
|
||||
GETGY(v0, 0, -1, -1, -1);
|
||||
VSTR128_U12(v0, ed, fixedaddress+16);
|
||||
}
|
||||
}
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
INST_NAME("VCMPSS Gx, Vx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETEXSS(v1, 0, 1);
|
||||
GETGX_empty_VX(v0, v2);
|
||||
u8 = F8;
|
||||
if(((u8&15)!=11) && ((u8&15)!=15)) {
|
||||
if((u8&15)>7)
|
||||
FCMPS(v1, v2);
|
||||
else
|
||||
FCMPS(v2, v1);
|
||||
}
|
||||
// TODO: create a test for this one, there might be an issue with cases 9, 10 and 13
|
||||
if(v0!=v2) VMOVQ(v0, v2);
|
||||
switch(u8&15) {
|
||||
case 0x00: CSETMw(x2, cEQ); break; // Equal
|
||||
case 0x01: CSETMw(x2, cCC); break; // Less than
|
||||
case 0x02: CSETMw(x2, cLS); break; // Less or equal
|
||||
case 0x03: CSETMw(x2, cVS); break; // NaN
|
||||
case 0x04: CSETMw(x2, cNE); break; // Not Equal or unordered
|
||||
case 0x05: CSETMw(x2, cCS); break; // Greater or equal or unordered
|
||||
case 0x06: CSETMw(x2, cHI); break; // Greater or unordered
|
||||
case 0x07: CSETMw(x2, cVC); break; // not NaN
|
||||
case 0x08: CSETMw(x2, cEQ); CSETMw(x3, cVS); ORRw_REG(x2, x2, x3); break; // Equal or unordered
|
||||
case 0x09: CSETMw(x2, cHI); break; // Less than or unordered
|
||||
case 0x0a: CSETMw(x2, cCS); break; // Less or equal or unordered
|
||||
case 0x0b: MOV32w(x2, 0); break; // false
|
||||
case 0x0c: CSETMw(x2, cNE); CSETMw(x3, cVS); BICw(x2, x2, x3); break; // Not Equal not unordered
|
||||
case 0x0d: CSETMw(x2, cLS); break; // Greater or equal not unordered
|
||||
case 0x0e: CSETMw(x2, cCC); break; // Greater not unordered
|
||||
case 0x0f: MOV32w(x2, 0xffffffff); break; // true
|
||||
}
|
||||
VMOVQSfrom(v0, 0, x2);
|
||||
YMM0(gd);
|
||||
break;
|
||||
|
||||
case 0xE6:
|
||||
INST_NAME("VCVTDQ2PD Gx, Ex");
|
||||
nextop = F8;
|
||||
if(vex.l) {
|
||||
GETEX_Y(v1, 0, 0);
|
||||
} else {
|
||||
GETEXSD(v1, 0, 0);
|
||||
}
|
||||
GETGX_empty(v0);
|
||||
d0 = fpu_get_scratch(dyn, ninst);
|
||||
if(vex.l) {
|
||||
q0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
|
||||
SXTL2_32(q0, v1);
|
||||
SCVTQFD(q0, q0);
|
||||
} else YMM0(gd);
|
||||
SXTL_32(v0, v1);
|
||||
SCVTQFD(v0, v0);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "my_cpuid.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "emu/x64shaext.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_F3_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop, u8;
|
||||
uint8_t gd, ed, vd;
|
||||
uint8_t wback, wb1, wb2;
|
||||
uint8_t eb1, eb2, gb1, gb2;
|
||||
int32_t i32, i32_;
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
MAYUSE(wb1);
|
||||
MAYUSE(wb2);
|
||||
MAYUSE(eb1);
|
||||
MAYUSE(eb2);
|
||||
MAYUSE(gb1);
|
||||
MAYUSE(gb2);
|
||||
MAYUSE(q0);
|
||||
MAYUSE(q1);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(d1);
|
||||
MAYUSE(s0);
|
||||
MAYUSE(j64);
|
||||
MAYUSE(cacheupd);
|
||||
|
||||
rex_t rex = vex.rex;
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
case 0xF5:
|
||||
INST_NAME("PEXT Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
if(gd==ed || gd==vd) {
|
||||
gb1 = gd;
|
||||
gd = x4;
|
||||
} else {
|
||||
gb1 = 0;
|
||||
}
|
||||
// x3 = mask of mask, loop while not 0
|
||||
MOV32w(gd, 0);
|
||||
MOV64x(x3, 1LL<<(rex.w?63:31));
|
||||
MARK;
|
||||
TSTxw_REG(ed, x3);
|
||||
B_MARK2(cEQ); // mask not set
|
||||
TSTxw_REG(vd, x3);
|
||||
CSINCxw(gd, gd, gd, cEQ); // return gd if TRUE, else gd+1
|
||||
RORxw(gd, gd, 1);
|
||||
MARK2;
|
||||
LSRxw_IMM(x3, x3, 1);
|
||||
CBNZxw_MARK(x3);
|
||||
RBITxw(gd, gd);
|
||||
if(gb1)
|
||||
MOVxw_REG(gb1, gd);
|
||||
break;
|
||||
|
||||
case 0xF7:
|
||||
INST_NAME("SARX Gd, Ed, Vd");
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETED(0);
|
||||
GETVD;
|
||||
ANDx_mask(x3, vd, 1, 0, rex.w?5:4); // mask 0x3f/0x1f
|
||||
ASRxw_REG(gd, ed, x3);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
|
||||
uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)rep; (void)need_epilog;
|
||||
|
||||
uint8_t nextop = F8;
|
||||
uint8_t ed;
|
||||
uint8_t u8;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
|
||||
if(MODREG)
|
||||
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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FADDS(v1, v1, v2);
|
||||
} else {
|
||||
FADDD(v1, v1, v2);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FMULS(v1, v1, v2);
|
||||
} else {
|
||||
FMULD(v1, v1, v2);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
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)) {
|
||||
FCMPS(v1, v2);
|
||||
} else {
|
||||
FCMPD(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2, x3);
|
||||
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)) {
|
||||
FCMPS(v1, v2);
|
||||
} else {
|
||||
FCMPD(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2, x3);
|
||||
X87_POP_OR_FAIL(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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FSUBS(v1, v1, v2);
|
||||
} else {
|
||||
FSUBD(v1, v1, v2);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FSUBS(v1, v2, v1);
|
||||
} else {
|
||||
FSUBD(v1, v2, v1);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FDIVS(v1, v1, v2);
|
||||
} else {
|
||||
FDIVD(v1, v1, v2);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
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(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FDIVS(v1, v2, v1);
|
||||
} else {
|
||||
FDIVD(v1, v2, v1);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
break;
|
||||
} else
|
||||
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(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FADDS(v1, v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FADDD(v1, v1, s0);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FMUL ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FMULS(v1, v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FMULD(v1, v1, s0);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FCOM ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(ST_IS_F(0)) {
|
||||
FCMPS(v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FCMPD(v1, s0);
|
||||
}
|
||||
FCOM(x1, x2, x3);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FCOMP ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(ST_IS_F(0)) {
|
||||
FCMPS(v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FCMPD(v1, s0);
|
||||
}
|
||||
FCOM(x1, x2, x3);
|
||||
X87_POP_OR_FAIL(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(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FSUBS(v1, v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FSUBD(v1, v1, s0);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FSUBR ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FSUBS(v1, s0, v1);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FSUBD(v1, s0, v1);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FDIV ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FDIVS(v1, v1, s0);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FDIVD(v1, v1, s0);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FDIVR ST0, float[ED]");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(s0, ed, fixedaddress);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FDIVS(v1, s0, v1);
|
||||
} else {
|
||||
FCVT_D_S(s0, s0);
|
||||
FDIVD(v1, s0, v1);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
|
||||
uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)rep; (void)need_epilog;
|
||||
|
||||
uint8_t nextop = F8;
|
||||
uint8_t ed;
|
||||
uint8_t wback, wb1;
|
||||
uint8_t u8;
|
||||
int64_t fixedaddress, j64;
|
||||
int unscaled;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
int i1, i2, i3;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
|
||||
if(MODREG)
|
||||
switch(nextop) {
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
case 0xC4:
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
INST_NAME("FLD STx");
|
||||
X87_PUSH_OR_FAIL(v2, dyn, ninst, x1, 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)) {
|
||||
FMOVS(v2, v1);
|
||||
} else {
|
||||
FMOVD(v2, v1);
|
||||
}
|
||||
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_get_st(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
|
||||
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
|
||||
// should set C1 to 0
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
INST_NAME("FNOP");
|
||||
break;
|
||||
|
||||
case 0xD8:
|
||||
INST_NAME("FSTPNCE ST0, ST0");
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xD9:
|
||||
case 0xDA:
|
||||
case 0xDB:
|
||||
case 0xDC:
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF:
|
||||
INST_NAME("FSTPNCE ST0, STx");
|
||||
// copy the cache value for st0 to stx
|
||||
x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
|
||||
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xE0:
|
||||
INST_NAME("FCHS");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
FNEGS(v1, v1);
|
||||
} else {
|
||||
FNEGD(v1, v1);
|
||||
}
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("FABS");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
FABSS(v1, v1);
|
||||
} else {
|
||||
FABSD(v1, v1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE4:
|
||||
INST_NAME("FTST");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(ST_IS_F(0)) {
|
||||
FCMPS_0(v1);
|
||||
} else {
|
||||
FCMPD_0(v1);
|
||||
}
|
||||
FCOM(x1, x2, x3); // 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) {
|
||||
if(fpu_is_st_freed(dyn, ninst, 0)) {
|
||||
MOV32w(x4, 0b100000100000000);
|
||||
B_MARK3_nocond;
|
||||
} else {
|
||||
// not in cache, so check Empty status and load it
|
||||
i2 = -dyn->n.x87stack;
|
||||
LDRw_U12(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if(i2) {
|
||||
if(i2<0) {
|
||||
ADDw_U12(x3, x3, -i2);
|
||||
} else {
|
||||
SUBw_U12(x3, x3, i2);
|
||||
}
|
||||
}
|
||||
CMPSw_U12(x3, 0);
|
||||
MOV32w(x4, 0b100000100000000); // empty: C3,C2,C0 = 101
|
||||
B_MARK3(cLE);
|
||||
// x5 will be the actual top
|
||||
LDRw_U12(x5, xEmu, offsetof(x64emu_t, top));
|
||||
if(i2) {
|
||||
if(i2<0) {
|
||||
SUBw_U12(x5, x5, -i2);
|
||||
} else {
|
||||
ADDw_U12(x5, x5, i2);
|
||||
}
|
||||
ANDw_mask(x5, x5, 0, 2); // (emu->top + i)&7
|
||||
}
|
||||
// load x2 with ST0 anyway, for sign extraction
|
||||
ADDx_REG_LSL(x1, xEmu, x5, 3);
|
||||
LDRx_U12(x2, x1, offsetof(x64emu_t, x87));
|
||||
// load tag
|
||||
if(i2>=0) {
|
||||
LDRH_U12(x3, xEmu, offsetof(x64emu_t, fpu_tags));
|
||||
if(i2>0) {
|
||||
ORRw_mask(x3, x3, 0b010000, 0b001111); // 0xffff0000
|
||||
LSRw_IMM(x3, x3, i2*2);
|
||||
}
|
||||
TSTw_mask(x3, 0, 1); // 0b11
|
||||
B_MARK3(cNE); // empty: C3,C2,C0 = 101
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// simply move from cache reg to x2
|
||||
v1 = dyn->n.x87reg[i1];
|
||||
VMOVQDto(x2, v1, 0);
|
||||
}
|
||||
// get exponant in x1
|
||||
LSRx_IMM(x1, x2, 20+32);
|
||||
ANDSx_mask(x1, x1, 1, 0b00000, 0b001010); // 0x7ff
|
||||
B_MARK(cNE); // not zero or denormal
|
||||
ANDSx_mask(x1, x2, 1, 0, 0b111110); // 0x7fffffffffffffff
|
||||
MOV32w(x4, 0b100000000000000); // Zero: C3,C2,C0 = 100
|
||||
MOV32w(x5, 0b100010000000000); // Denormal: C3,C2,C0 = 110
|
||||
CSELx(x4, x4, x5, cEQ);
|
||||
B_MARK3(c__);
|
||||
MARK;
|
||||
CMPSx_U12(x1, 0x7ff); // infinite/NaN?
|
||||
MOV32w(x5, 0b000010000000000); // normal: C3,C2,C0 = 010
|
||||
CSELx(x4, x5, x4, cNE);
|
||||
B_MARK3(cNE);
|
||||
TSTx_mask(x2, 1, 0b000000, 0b110011); // 0x000fffffffffffff
|
||||
MOV32w(x4, 0b000010100000000); // infinity: C3,C2,C0 = 011
|
||||
MOV32w(x3, 0b000000100000000); // NaN: C3,C2,C0 = 001
|
||||
CSELx(x4, x4, x3, cEQ);
|
||||
MARK3;
|
||||
// Extract signa & Update SW
|
||||
LSRx_IMM(x1, x2, 63);
|
||||
BFIx(x4, x1, 9, 1); //C1
|
||||
LDRH_U12(x1, xEmu, offsetof(x64emu_t, sw));
|
||||
MOV32w(x2, 0b01000111);
|
||||
BICw_REG_LSL(x1, x1, x2, 8);
|
||||
ORRw_REG(x4, x4, x1);
|
||||
STRH_U12(x4, xEmu, offsetof(x64emu_t, sw));
|
||||
#else
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
CALL(fpu_fxam, -1); // should be possible inline, but is it worth it?
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xE8:
|
||||
INST_NAME("FLD1");
|
||||
if(ninst<dyn->size+2 && (dyn->insts[ninst+1].pred_sz==1) && (dyn->insts[ninst+2].pred_sz==1)
|
||||
&& PK(0)==0xD9 && PK(1)==0xE8
|
||||
&& PK(2)==0xD9 && PK(3)==0xF3
|
||||
) {
|
||||
MESSAGE(LOG_DUMP, "Hack for FLD1 FLD1 FPATAN");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
|
||||
FTABLE64(v1, PI/4.0);
|
||||
addr+=4;
|
||||
} else {
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
FMOVS_8(v1, 0b01110000);
|
||||
} else {
|
||||
FMOVD_8(v1, 0b01110000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xE9:
|
||||
INST_NAME("FLDL2T");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
FTABLE64(v1, L2T);
|
||||
break;
|
||||
case 0xEA:
|
||||
INST_NAME("FLDL2E");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
FTABLE64(v1, L2E);
|
||||
break;
|
||||
case 0xEB:
|
||||
INST_NAME("FLDPI");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
FTABLE64(v1, PI);
|
||||
break;
|
||||
case 0xEC:
|
||||
INST_NAME("FLDLG2");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
FTABLE64(v1, LG2);
|
||||
break;
|
||||
case 0xED:
|
||||
INST_NAME("FLDLN2");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
FTABLE64(v1, LN2);
|
||||
break;
|
||||
case 0xEE:
|
||||
INST_NAME("FLDZ");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
|
||||
VEOR(v1, v1, v1);
|
||||
break;
|
||||
|
||||
case 0xF0:
|
||||
INST_NAME("F2XM1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (F2XM1)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
CALL(native_f2xm1, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
case 0xF1:
|
||||
INST_NAME("FYL2X");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FYL2X)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(native_fyl2x, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xF2:
|
||||
INST_NAME("FPTAN");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FPTAN)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_ftan, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
if(PK(0)==0xdd && PK(1)==0xd8) {
|
||||
MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emitting 1\n");
|
||||
u8 = F8;
|
||||
u8 = F8;
|
||||
} else {
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0)) {
|
||||
FMOVS_8(v1, 0b01110000);
|
||||
} else {
|
||||
FMOVD_8(v1, 0b01110000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xF3:
|
||||
INST_NAME("FPATAN");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FPATAN)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_fpatan, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xF4:
|
||||
INST_NAME("FXTRACT");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FXTRACT)\n");
|
||||
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(native_fxtract, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
case 0xF5:
|
||||
INST_NAME("FPREM1");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(native_fprem1, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
#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(dyn, ninst);
|
||||
FDIVD(s0, v1, v2);
|
||||
FRINTRRD(s0, s0, 0b00); // Nearest == TieToEven?
|
||||
FCVTZSxD(x4, s0);
|
||||
FMULD(s0, s0, v2);
|
||||
FSUBD(v1, v1, s0);
|
||||
LDRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
|
||||
// set C2 = 0
|
||||
BFCw(x1, 10, 1);
|
||||
// set C1 = Q0
|
||||
BFIw(x1, x4, 9, 1);
|
||||
// set C3 = Q1
|
||||
LSRx_IMM(x4, x4, 1);
|
||||
BFIw(x1, x4, 14, 1);
|
||||
// Set C0 = Q2
|
||||
LSRx(x4, x4, 1);
|
||||
BFIw(x1, x4, 8, 1);
|
||||
STRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
|
||||
#endif
|
||||
break;
|
||||
case 0xF6:
|
||||
INST_NAME("FDECSTP");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
|
||||
SUBw_U12(x2, x2, 1);
|
||||
ANDw_mask(x2, x2, 0, 2); //mask=7
|
||||
STRw_U12(x2, xEmu, offsetof(x64emu_t, top));
|
||||
break;
|
||||
case 0xF7:
|
||||
INST_NAME("FINCSTP");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
|
||||
ADDw_U12(x2, x2, 1);
|
||||
ANDw_mask(x2, x2, 0, 2); //mask=7
|
||||
STRw_U12(x2, xEmu, offsetof(x64emu_t, top));
|
||||
break;
|
||||
case 0xF8:
|
||||
INST_NAME("FPREM");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(native_fprem, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
#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(dyn, ninst);
|
||||
FDIVD(s0, v1, v2);
|
||||
FRINTZD(s0, s0);
|
||||
FCVTZSxD(x4, s0);
|
||||
FMULD(s0, s0, v2);
|
||||
FSUBD(v1, v1, s0);
|
||||
LDRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
|
||||
// set C2 = 0
|
||||
BFCw(x1, 10, 1);
|
||||
// set C1 = Q0
|
||||
BFIw(x1, x4, 9, 1);
|
||||
// set C3 = Q1
|
||||
LSRx_IMM(x4, x4, 1);
|
||||
BFIw(x1, x4, 14, 1);
|
||||
// Set C0 = Q2
|
||||
LSRx(x4, x4, 1);
|
||||
BFIw(x1, x4, 8, 1);
|
||||
STRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
|
||||
#endif
|
||||
break;
|
||||
case 0xF9:
|
||||
INST_NAME("FYL2XP1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FYL2XP1)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
CALL(native_fyl2xp1, -1);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 0xFA:
|
||||
INST_NAME("FSQRT");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
if(ST_IS_F(0)) {
|
||||
FSQRTS(v1, v1);
|
||||
} else {
|
||||
FSQRTD(v1, v1);
|
||||
}
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 0xFB:
|
||||
INST_NAME("FSINCOS");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FSINCOS)\n");
|
||||
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_fsincos, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
case 0xFC:
|
||||
INST_NAME("FRNDINT");
|
||||
#if 0
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
// use C helper for now, nothing staightforward is available
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
CALL(native_frndint, -1);
|
||||
#else
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x3);
|
||||
if(ST_IS_F(0)) {
|
||||
FRINTIS(v1, v1);
|
||||
} else {
|
||||
FRINTID(v1, v1);
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
#endif
|
||||
break;
|
||||
case 0xFD:
|
||||
INST_NAME("FSCALE");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FSCALE)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
x87_forget(dyn, ninst, x1, x2, 1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_fscale, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
case 0xFE:
|
||||
INST_NAME("FSIN");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FSIN)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_fsin, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
case 0xFF:
|
||||
INST_NAME("FCOS");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FCOS)\n");
|
||||
i1 = x87_stackcount(dyn, ninst, x1);
|
||||
x87_forget(dyn, ninst, x1, x2, 0);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_(native_fcos, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
x87_unstackcount(dyn, ninst, x1, i1);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
break;
|
||||
} else
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FLD ST0, float[ED]");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, BOX64ENV(dynarec_x87double)?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v1, ed, fixedaddress);
|
||||
if(!ST_IS_F(0)) {
|
||||
FCVT_D_S(v1, v1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FST float[ED], ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
|
||||
if(ST_IS_F(0))
|
||||
s0 = v1;
|
||||
else {
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
FCVT_S_D(s0, v1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VST32(s0, ed, fixedaddress);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FSTP float[ED], ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
if(!ST_IS_F(0)) {
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FCVT_S_D(v1, v1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
VST32(v1, ed, fixedaddress);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FLDENV Ed");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FLDENV)\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(ed!=x1) {
|
||||
MOVx_REG(x1, ed);
|
||||
}
|
||||
MOV32w(x2, 0);
|
||||
CALL(fpu_loadenv, -1);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FLDCW Ew");
|
||||
GETEW(x1, 0);
|
||||
STRH_U12(x1, xEmu, offsetof(x64emu_t, cw)); // hopefully cw is not too far for an imm8
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FNSTENV Ed");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FNSTENV)\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(ed!=x1) {
|
||||
MOVx_REG(x1, ed);
|
||||
}
|
||||
MOV32w(x2, 0);
|
||||
CALL(fpu_savenv, -1);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FNSTCW Ew");
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
|
||||
ed = x1;
|
||||
wb1 = 1;
|
||||
LDRH_U12(x1, xEmu, offsetof(x64emu_t, cw));
|
||||
EWBACK;
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
|
||||
uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop = F8;
|
||||
int64_t j64;
|
||||
uint8_t ed;
|
||||
uint8_t wback;
|
||||
uint8_t u8;
|
||||
int v1, v2;
|
||||
int d0;
|
||||
int s0;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(d0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(ed);
|
||||
MAYUSE(j64);
|
||||
|
||||
if(MODREG)
|
||||
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));
|
||||
TSTw_mask(xFlags, 0, 0); //mask=1<<F_CF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cNE); // F_CF==1
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cNE); // 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));
|
||||
TSTw_mask(xFlags, 0b011010, 0); //mask=1<<F_ZF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cNE);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cNE); // F_ZF==0
|
||||
}
|
||||
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));
|
||||
MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
|
||||
TSTw_REG(xFlags, x1);
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cNE);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cNE); // 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("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));
|
||||
TSTw_mask(xFlags, 0b011110, 0); //mask=1<<F_PF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cNE);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cNE); // F_PF==0
|
||||
}
|
||||
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)) {
|
||||
FCMPS(v1, v2);
|
||||
} else {
|
||||
FCMPD(v1, v2);
|
||||
}
|
||||
FCOM(x1, x2, x3);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
break;
|
||||
} else
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FIADD ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FADDD(v1, v1, v2);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FIMUL ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FMULD(v1, v1, v2);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FICOM ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
FCMPD(v1, v2);
|
||||
FCOM(x1, x2, x3);
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("FICOMP ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
FCMPD(v1, v2);
|
||||
FCOM(x1, x2, x3);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 4:
|
||||
INST_NAME("FISUB ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FSUBD(v1, v1, v2);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FISUBR ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FSUBD(v1, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("FIDIV ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FDIVD(v1, v1, v2);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FIDIVR ST0, Ed");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
v2 = fpu_get_scratch(dyn, ninst);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v2, ed, fixedaddress);
|
||||
SXTL_32(v2, v2); // i32 -> i64
|
||||
SCVTFDD(v2, v2); // i64 -> double
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x5, x4);
|
||||
FDIVD(v1, v2, v1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64run.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#include "dynarec_native.h"
|
||||
|
||||
#include "arm64_printer.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_arm64_functions.h"
|
||||
|
||||
|
||||
uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)rep; (void)need_epilog;
|
||||
|
||||
uint8_t nextop = F8;
|
||||
uint8_t ed;
|
||||
uint8_t wback;
|
||||
uint8_t u8;
|
||||
int64_t fixedaddress;
|
||||
int unscaled;
|
||||
int v1, v2;
|
||||
int s0;
|
||||
int64_t j64;
|
||||
|
||||
MAYUSE(s0);
|
||||
MAYUSE(v2);
|
||||
MAYUSE(v1);
|
||||
MAYUSE(j64);
|
||||
|
||||
if(MODREG)
|
||||
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));
|
||||
TSTw_mask(xFlags, 0, 0); //mask=1<<F_CF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cEQ);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cEQ); // 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));
|
||||
TSTw_mask(xFlags, 0b011010, 0); //mask=1<<F_ZF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cEQ);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cEQ); // 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));
|
||||
MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
|
||||
TSTw_REG(xFlags, x1);
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cEQ);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cEQ); // 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));
|
||||
TSTw_mask(xFlags, 0b011110, 0); //mask=1<<F_PF
|
||||
if(ST_IS_F(0)) {
|
||||
FCSELS(v1, v2, v1, cEQ);
|
||||
} else {
|
||||
FCSELD(v1, v2, v1, cEQ); // F_PF==0
|
||||
}
|
||||
break;
|
||||
case 0xE1:
|
||||
INST_NAME("FDISI8087_NOP"); // so.. NOP?
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("FNCLEX");
|
||||
LDRH_U12(x2, xEmu, offsetof(x64emu_t, sw));
|
||||
BFCw(x2, 0, 8); // IE .. PE, SF, ES
|
||||
BFCw(x2, 15, 1); // B
|
||||
STRH_U12(x2, xEmu, offsetof(x64emu_t, sw));
|
||||
break;
|
||||
case 0xE3:
|
||||
INST_NAME("FNINIT");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization (FNINIT)\n");
|
||||
x87_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
CALL(reset_fpu, -1);
|
||||
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)) {
|
||||
FCMPS(v1, v2);
|
||||
} else {
|
||||
FCMPD(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)) {
|
||||
FCMPS(v1, v2);
|
||||
} else {
|
||||
FCMPD(v1, v2);
|
||||
}
|
||||
FCOMI(x1, x2);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
break;
|
||||
} else
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("FILD ST0, Ed");
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
VLD32(v1, ed, fixedaddress);
|
||||
SXTL_32(v1, v1); // i32 -> i64
|
||||
SCVTFDD(v1, v1); // i64 -> double
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("FISTTP Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
if(arm64_frintts) {
|
||||
FRINT32ZD(s0, v1);
|
||||
FCVTZSwD(x5, s0);
|
||||
STW(x5, wback, fixedaddress);
|
||||
} else {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
BFCw(x5, FPSR_QC, 1); // reset QC bit
|
||||
MSR_fpsr(x5);
|
||||
FRINTZD(s0, v1);
|
||||
VFCVTZSd(s0, s0);
|
||||
SQXTN_S_D(s0, s0);
|
||||
VST32(s0, wback, fixedaddress);
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBNZ_MARK2(x5, FPSR_IOC);
|
||||
TBNZ_MARK2(x5, FPSR_QC);
|
||||
B_MARK3_nocond;
|
||||
MARK2;
|
||||
MOV32w(x5, 0x80000000);
|
||||
STW(x5, wback, fixedaddress);
|
||||
MARK3;
|
||||
}
|
||||
X87_POP_OR_FAIL(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(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
if(arm64_frintts) {
|
||||
FRINT32XD(s0, v1);
|
||||
FCVTZSwD(x5, s0);
|
||||
STW(x5, wback, fixedaddress);
|
||||
} else {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
BFCw(x5, FPSR_QC, 1); // reset QC bit
|
||||
MSR_fpsr(x5);
|
||||
FRINTXD(s0, v1);
|
||||
VFCVTZSd(s0, s0);
|
||||
SQXTN_S_D(s0, s0);
|
||||
VST32(s0, wback, fixedaddress);
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBNZ_MARK2(x5, FPSR_IOC);
|
||||
TBNZ_MARK2(x5, FPSR_QC);
|
||||
B_MARK3_nocond;
|
||||
MARK2;
|
||||
MOV32w(x5, 0x80000000);
|
||||
STW(x5, wback, fixedaddress);
|
||||
MARK3;
|
||||
}
|
||||
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(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
|
||||
s0 = fpu_get_scratch(dyn, ninst);
|
||||
if(arm64_frintts) {
|
||||
FRINT32XD(s0, v1);
|
||||
FCVTZSwD(x5, s0);
|
||||
STW(x5, wback, fixedaddress);
|
||||
} else {
|
||||
MRS_fpsr(x5);
|
||||
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
|
||||
BFCw(x5, FPSR_QC, 1); // reset QC bit
|
||||
MSR_fpsr(x5);
|
||||
FRINTXD(s0, v1);
|
||||
VFCVTZSd(s0, s0);
|
||||
SQXTN_S_D(s0, s0);
|
||||
VST32(s0, wback, fixedaddress);
|
||||
MRS_fpsr(x5); // get back FPSR to check the IOC bit
|
||||
TBNZ_MARK2(x5, FPSR_IOC);
|
||||
TBNZ_MARK2(x5, FPSR_QC);
|
||||
B_MARK3_nocond;
|
||||
MARK2;
|
||||
MOV32w(x5, 0x80000000);
|
||||
STW(x5, wback, fixedaddress);
|
||||
MARK3;
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("FLD tbyte");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if((PK(0)==0xDB && ((PK(1)>>3)&7)==7) || (!rex.is32bits && PK(0)>=0x40 && PK(0)<=0x4f && PK(1)==0xDB && ((PK(2)>>3)&7)==7)) {
|
||||
NOTEST(x5);
|
||||
// the FLD is immediatly followed by an FSTP
|
||||
LDRx_U12(x5, ed, 0);
|
||||
LDRH_U12(x6, ed, 8);
|
||||
// no persistant scratch register, so unrool both instruction here...
|
||||
MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n");
|
||||
nextop = F8; // 0xDB or rex
|
||||
if(!rex.is32bits && nextop>=0x40 && nextop<=0x4f) {
|
||||
rex.rex = nextop;
|
||||
nextop = F8; //0xDB
|
||||
} else
|
||||
rex.rex = 0;
|
||||
nextop = F8; //modrm
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
STRx_U12(x5, ed, 0);
|
||||
STRH_U12(x6, ed, 8);
|
||||
} else {
|
||||
if(BOX64ENV(x87_no80bits)) {
|
||||
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
|
||||
VLDR64_U12(v1, ed, fixedaddress);
|
||||
} else {
|
||||
if(ed!=x1) {
|
||||
MOVx_REG(x1, ed);
|
||||
}
|
||||
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
|
||||
// sync top
|
||||
x87_reflectcount(dyn, ninst, x3, x4);
|
||||
CALL(native_fld, -1);
|
||||
// go back with the top & stack counter
|
||||
x87_unreflectcount(dyn, ninst, x3, x4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("FSTP tbyte");
|
||||
if(BOX64ENV(x87_no80bits)) {
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
|
||||
VST64(v1, wback, fixedaddress);
|
||||
} else {
|
||||
if(!BOX64ENV(dynarec_fastround)) {
|
||||
x87_forget(dyn, ninst, x1, x3, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(ed!=x1) {MOVx_REG(x1, ed);}
|
||||
x87_reflectcount(dyn, ninst, x3, x4);
|
||||
CALL(native_fstp, -1);
|
||||
x87_unreflectcount(dyn, ninst, x3, x4);
|
||||
} else {
|
||||
// Painfully long, straight conversion from the C code, shoud be optimized
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
FMOVxD(x1, v1);
|
||||
// do special value first
|
||||
TSTx_mask(x1, 1, 0b00000, 0b111110); //0x7fffffffffffffffL
|
||||
B_MARK(cNE);
|
||||
// Zero
|
||||
LSRx(x3, x1, 63-15); //x3 = sign+exp
|
||||
MOVZw(x5, 0); // x5 = mantisse
|
||||
B_MARK3_nocond;
|
||||
MARK;
|
||||
// get sign, in main ouput x5 for sign+exp
|
||||
ANDx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
|
||||
LSRx(x5, x5, 63-15); // x5 = sign
|
||||
// get exp
|
||||
LSRx(x3, x1, 52); // x3 = exp11
|
||||
ANDw_mask(x3, x3, 0, 0b1010); //0x7ff
|
||||
ANDSx_mask(x1, x1, 1, 0, 0b110011); //0x000fffffffffffffL
|
||||
LSLx_IMM(x1, x1, 11); // mantice
|
||||
CMPSw_U12(x3, 0x7ff);
|
||||
B_MARK2(cNE);
|
||||
// NaN and Infinite
|
||||
ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff
|
||||
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
|
||||
B_MARK3_nocond;
|
||||
MARK2;
|
||||
// regular / denormals
|
||||
MOVZw(x4, 16383-1023); //BIAS80 - BIAS64
|
||||
CBZw(x3, 4+4*4); // exp11 == 0?
|
||||
// normals
|
||||
ADDw_REG(x3, x3, x4); // x3 = exp16
|
||||
ORRw_REG(x3, x3, x5); // x3 = sign | exp
|
||||
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000 x5 = mantisse
|
||||
B_MARK3_nocond;
|
||||
// denormals
|
||||
CLZx(x6, x1);
|
||||
ADDw_U12(x6, x6, 1); // "one"
|
||||
SUBw_REG(x3, x4, x6); // x3 = exp16
|
||||
ORRw_REG(x3, x3, x5); // x3 = sign | exp16
|
||||
LSLx_REG(x5, x1, x6); // x5 = mantisse
|
||||
MARK3;
|
||||
STRx_U12(x5, wback, 0);
|
||||
STRH_U12(x3, wback, 8);
|
||||
}
|
||||
}
|
||||
X87_POP_OR_FAIL(dyn, ninst, x3);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
Loaded 100 of 2172 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user