mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-17 00:00:39 +02:00
Compare commits
3913
Commits
FEX-2412
...
FEX-2609.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fbdc00bd6 | ||
|
|
116053cd29 | ||
|
|
536722f59d | ||
|
|
395b132f34 | ||
|
|
566a5e266d | ||
|
|
cc5686de37 | ||
|
|
049c932675 | ||
|
|
84fabf4ed8 | ||
|
|
310c2504f6 | ||
|
|
021c4fa4bf | ||
|
|
319c5bf023 | ||
|
|
023d0cdaa6 | ||
|
|
5a4f84cad9 | ||
|
|
eb27391954 | ||
|
|
ffaa5d6316 | ||
|
|
8bf22b6382 | ||
|
|
42c663269b | ||
|
|
983c5defc1 | ||
|
|
c92805475d | ||
|
|
50e6eee95a | ||
|
|
31cda95039 | ||
|
|
970ce4bc13 | ||
|
|
e4c6154be2 | ||
|
|
064a6e96c7 | ||
|
|
d704bd3cef | ||
|
|
9f511d5d78 | ||
|
|
a77d00acae | ||
|
|
5d11b8b0d5 | ||
|
|
bf70dee3ae | ||
|
|
4a065ad1a2 | ||
|
|
96d955e7b1 | ||
|
|
abec314720 | ||
|
|
ec63be4028 | ||
|
|
179b4423a7 | ||
|
|
9956a528b9 | ||
|
|
e3c6b37f70 | ||
|
|
b78bde7ec8 | ||
|
|
6ff7e82e3b | ||
|
|
37675e0351 | ||
|
|
38c9f14dbd | ||
|
|
7187bc0e59 | ||
|
|
c5700cb0cc | ||
|
|
8ed4c52d58 | ||
|
|
bd65c3e568 | ||
|
|
7052f91495 | ||
|
|
040d3115d2 | ||
|
|
7236c2bf0a | ||
|
|
ed3fa2f1c6 | ||
|
|
a454845ffd | ||
|
|
40bfff985f | ||
|
|
96d65cd6bc | ||
|
|
e4e45bcc59 | ||
|
|
45fbab212a | ||
|
|
8243b93e4d | ||
|
|
52cc5689db | ||
|
|
cfef3d2cbf | ||
|
|
fd64ea54fe | ||
|
|
d1b2333195 | ||
|
|
97fbd11177 | ||
|
|
e7836f26dd | ||
|
|
cf6da6ac26 | ||
|
|
a0cb91daa4 | ||
|
|
e010e8adf0 | ||
|
|
7fe7c39a00 | ||
|
|
b03dc847f5 | ||
|
|
ac6be77592 | ||
|
|
35330df728 | ||
|
|
bd9897b164 | ||
|
|
e704275ffd | ||
|
|
e33cb3c831 | ||
|
|
91264f05e2 | ||
|
|
30e4650a8b | ||
|
|
add92f681b | ||
|
|
21b8f8e20d | ||
|
|
ca055cd7d5 | ||
|
|
42e207932b | ||
|
|
3157685f0f | ||
|
|
d833f3ae67 | ||
|
|
fbf5187794 | ||
|
|
f2c8adf7a3 | ||
|
|
d472ce190c | ||
|
|
c4c82f23ee | ||
|
|
20e9e2044e | ||
|
|
1a0412969b | ||
|
|
55c80e6c4f | ||
|
|
83469208c9 | ||
|
|
3471ca67c4 | ||
|
|
4048faa54b | ||
|
|
61d94ac117 | ||
|
|
511c45c4c6 | ||
|
|
bce8b13366 | ||
|
|
4a7fda4516 | ||
|
|
b29561e131 | ||
|
|
5a68359f37 | ||
|
|
00b1249e53 | ||
|
|
8be7c1bf8e | ||
|
|
aaca8772bd | ||
|
|
ab6e67596f | ||
|
|
433091c326 | ||
|
|
c01bfcd52f | ||
|
|
673a387808 | ||
|
|
a6e74cdbe6 | ||
|
|
ff4da8a620 | ||
|
|
1558a2c65d | ||
|
|
66cad978c3 | ||
|
|
c11a0cef68 | ||
|
|
8cf2bf7ad8 | ||
|
|
ef5439e5ae | ||
|
|
c0b24b2f2e | ||
|
|
0d3a5f96f0 | ||
|
|
73dc3b3edd | ||
|
|
01bc89b82e | ||
|
|
2f663db52c | ||
|
|
e17fdf9e90 | ||
|
|
b695c5ae11 | ||
|
|
f5935b4006 | ||
|
|
eca6569bd3 | ||
|
|
51c241d1f8 | ||
|
|
83ead40b78 | ||
|
|
dea5c62a44 | ||
|
|
b3f902166b | ||
|
|
98964c5527 | ||
|
|
8ccc8dab49 | ||
|
|
e1d8881f57 | ||
|
|
9742a560f5 | ||
|
|
7a8b9dd341 | ||
|
|
063af711af | ||
|
|
aed71ed5e9 | ||
|
|
8b9237fd52 | ||
|
|
fd180a16d3 | ||
|
|
2a82f58195 | ||
|
|
34ffd2d6e2 | ||
|
|
62c9c130c4 | ||
|
|
fca23d88c3 | ||
|
|
3a179a3a40 | ||
|
|
fe17c447d9 | ||
|
|
b21a8dafa7 | ||
|
|
926a871dd4 | ||
|
|
79ef5031eb | ||
|
|
f0135eb332 | ||
|
|
566b25a35b | ||
|
|
e6748ea1ed | ||
|
|
5ab2c723ff | ||
|
|
cac8785aca | ||
|
|
0814780c2f | ||
|
|
753bce5e73 | ||
|
|
d04ad79eaf | ||
|
|
baca86bc3f | ||
|
|
adfff26d58 | ||
|
|
ef3a6963f3 | ||
|
|
19dba4a3ec | ||
|
|
49c1cda5c0 | ||
|
|
2ea749c7ea | ||
|
|
9d4b493ec0 | ||
|
|
7e3e4f81ac | ||
|
|
e740af05b0 | ||
|
|
4ed80fd071 | ||
|
|
59116a06b9 | ||
|
|
a409220e54 | ||
|
|
485f1c6acf | ||
|
|
6646a5cc72 | ||
|
|
2a76d3b153 | ||
|
|
7614e48322 | ||
|
|
631b8c3f58 | ||
|
|
b4b38a92ef | ||
|
|
c3769a6937 | ||
|
|
8d69852785 | ||
|
|
b83dd97762 | ||
|
|
22498dc871 | ||
|
|
96172840f1 | ||
|
|
e8880e4e98 | ||
|
|
26f6cda589 | ||
|
|
f0b45010ec | ||
|
|
ad3939a44f | ||
|
|
c9b23eb0e7 | ||
|
|
44f69f4dd7 | ||
|
|
c3fb6ccaaa | ||
|
|
b47a36a47b | ||
|
|
af9b438eec | ||
|
|
fa9bbf081b | ||
|
|
db3817a260 | ||
|
|
635befb4c8 | ||
|
|
a69daa2524 | ||
|
|
b563703701 | ||
|
|
0717f4689b | ||
|
|
bf30f6af4c | ||
|
|
dfcbdac347 | ||
|
|
8d12f3d5aa | ||
|
|
02f8ab5f87 | ||
|
|
b2b6b263bb | ||
|
|
e3f208f61f | ||
|
|
008d990f20 | ||
|
|
c038bb5794 | ||
|
|
efc5eaf9c7 | ||
|
|
c1e9d19809 | ||
|
|
85efb47a3b | ||
|
|
bc69693b6c | ||
|
|
c9c5a75b76 | ||
|
|
f50279a2e7 | ||
|
|
561c32b45d | ||
|
|
f42dc71972 | ||
|
|
ea67665bbf | ||
|
|
c3b4d4b7bb | ||
|
|
492dac719f | ||
|
|
9377bac5e7 | ||
|
|
e0bbfdda84 | ||
|
|
9618b5adef | ||
|
|
a3d609ebb1 | ||
|
|
2b0d94536f | ||
|
|
73ab3bc56d | ||
|
|
412c49a8ce | ||
|
|
6f29dfcbb8 | ||
|
|
f3ab82a73f | ||
|
|
6734c9ed3e | ||
|
|
71afe47675 | ||
|
|
7075377a63 | ||
|
|
7c1036df09 | ||
|
|
a312347589 | ||
|
|
f386c62dba | ||
|
|
30a81484d7 | ||
|
|
00a6b046a8 | ||
|
|
c156498c5c | ||
|
|
adea3e410f | ||
|
|
40940ae0b3 | ||
|
|
1bab28dad4 | ||
|
|
4838265589 | ||
|
|
f6d20a1a88 | ||
|
|
11be444d45 | ||
|
|
363bf85b5b | ||
|
|
720039ca6d | ||
|
|
4e9399e029 | ||
|
|
466ee3cbcf | ||
|
|
390d5d2fb4 | ||
|
|
b543df8299 | ||
|
|
de16c18961 | ||
|
|
2158309c51 | ||
|
|
430846d7f2 | ||
|
|
f4e362c477 | ||
|
|
7966bfb077 | ||
|
|
a4e04dd7b4 | ||
|
|
b161a74365 | ||
|
|
fd141ed6d7 | ||
|
|
e2ff0dd1cd | ||
|
|
6284c39eb3 | ||
|
|
7f0bdf8d63 | ||
|
|
015beff4cc | ||
|
|
92e43c25d4 | ||
|
|
69fe85274f | ||
|
|
0122ef9e83 | ||
|
|
c772c0e4e7 | ||
|
|
c171c06192 | ||
|
|
9365e6240b | ||
|
|
f8e3571c66 | ||
|
|
6ebcf65451 | ||
|
|
4844729e93 | ||
|
|
9686454161 | ||
|
|
167d79f0fa | ||
|
|
b1275edb63 | ||
|
|
e869aa644a | ||
|
|
68740b3c65 | ||
|
|
4caad9bf55 | ||
|
|
7629323548 | ||
|
|
681636cd68 | ||
|
|
2fdbff3d1c | ||
|
|
5c7df98768 | ||
|
|
efe38f2ee2 | ||
|
|
08031a2767 | ||
|
|
34a87cc94c | ||
|
|
d295d9f08e | ||
|
|
61d033f21e | ||
|
|
27315e33ab | ||
|
|
e8b5cd18bd | ||
|
|
1a77f41846 | ||
|
|
d1947f715c | ||
|
|
3f7971b7d2 | ||
|
|
2cbd5cb3e6 | ||
|
|
151b4d4c2d | ||
|
|
7a3fdefafb | ||
|
|
86c20d0519 | ||
|
|
464ec9d0bc | ||
|
|
35518a5fa0 | ||
|
|
d028c7942b | ||
|
|
585286a617 | ||
|
|
4904fd43e9 | ||
|
|
9e3f287c1f | ||
|
|
f5e4e26e08 | ||
|
|
6c5a39e164 | ||
|
|
7469fdb0d6 | ||
|
|
fcf9fd77d7 | ||
|
|
0589d9b872 | ||
|
|
6d4c80adff | ||
|
|
56dd470528 | ||
|
|
6741f53d87 | ||
|
|
19550c5417 | ||
|
|
cfa3dfaac7 | ||
|
|
0ed0bc1dd5 | ||
|
|
074743d6e8 | ||
|
|
8b446de059 | ||
|
|
f2e35f336f | ||
|
|
10a0fe2e71 | ||
|
|
c9add0d292 | ||
|
|
c239d09ea0 | ||
|
|
a652a5811b | ||
|
|
d2c92808f5 | ||
|
|
2464633431 | ||
|
|
15e76e88b4 | ||
|
|
fe1ac1bc1d | ||
|
|
9edd27b214 | ||
|
|
eb7e02ea1d | ||
|
|
53befc68c9 | ||
|
|
19f95d89ec | ||
|
|
ecb9b3b7f8 | ||
|
|
d619e36523 | ||
|
|
fa80d11960 | ||
|
|
2893d2b64f | ||
|
|
99b8df4e6f | ||
|
|
331655182d | ||
|
|
ec95330dcd | ||
|
|
3959863462 | ||
|
|
c00b2c9584 | ||
|
|
6c354f3987 | ||
|
|
3bd4d244a4 | ||
|
|
9888de25fe | ||
|
|
58c247b30c | ||
|
|
22bd10f3b1 | ||
|
|
f374b4775a | ||
|
|
ff213bbc5e | ||
|
|
56a4ca6e6a | ||
|
|
d6b38b6b1c | ||
|
|
04d06d386f | ||
|
|
aa26a780ed | ||
|
|
f73b93dbc2 | ||
|
|
c4a5ac892f | ||
|
|
f129ca0c61 | ||
|
|
941f0fbf8d | ||
|
|
6e37dca566 | ||
|
|
1cffa009fe | ||
|
|
83f4c9d101 | ||
|
|
c0c95da796 | ||
|
|
8b612a87c6 | ||
|
|
2ac95f446b | ||
|
|
c5eddd922d | ||
|
|
b58be2c073 | ||
|
|
a3d0b67777 | ||
|
|
0467d523c0 | ||
|
|
b0af054a95 | ||
|
|
6846f10510 | ||
|
|
e24f232f52 | ||
|
|
a1cc5d034e | ||
|
|
b478f54aea | ||
|
|
7bb380a086 | ||
|
|
228c351396 | ||
|
|
4bb675a530 | ||
|
|
8d62773570 | ||
|
|
9e26c57643 | ||
|
|
35bc502062 | ||
|
|
7189e1e280 | ||
|
|
4b4aa1cdbe | ||
|
|
3680282b30 | ||
|
|
a4d5fbae63 | ||
|
|
2943b87c83 | ||
|
|
9575506391 | ||
|
|
31c2449d6e | ||
|
|
70eafc4f6f | ||
|
|
38cbd2aeb2 | ||
|
|
ba762a9326 | ||
|
|
921ce59054 | ||
|
|
a7627ba39a | ||
|
|
34ef28dea5 | ||
|
|
0f2463dda2 | ||
|
|
5ec852637c | ||
|
|
ba8b0afe7a | ||
|
|
98d45a6a9b | ||
|
|
6bc808cb06 | ||
|
|
1325fef703 | ||
|
|
d2d0ef1803 | ||
|
|
d6fb60d512 | ||
|
|
ef35474f88 | ||
|
|
372891361c | ||
|
|
50c75d1f43 | ||
|
|
30f2a7b23b | ||
|
|
f2212a497b | ||
|
|
12e8cf008a | ||
|
|
9e8e87bbb2 | ||
|
|
76c4ebb36f | ||
|
|
9ff322eeed | ||
|
|
4afa49824e | ||
|
|
23402bf31b | ||
|
|
50be718b72 | ||
|
|
903e7db427 | ||
|
|
5e5e9e0803 | ||
|
|
ce27754b9d | ||
|
|
4254c0f5a9 | ||
|
|
7efc3ecaba | ||
|
|
2934b01d58 | ||
|
|
192e363701 | ||
|
|
1287365616 | ||
|
|
4fa539fbb2 | ||
|
|
28cdae4687 | ||
|
|
842e22915c | ||
|
|
bd150233ce | ||
|
|
24720b67da | ||
|
|
356d461123 | ||
|
|
3cbcc7b9f8 | ||
|
|
329f12a888 | ||
|
|
c0b2eec5de | ||
|
|
9b8ae25491 | ||
|
|
c0ee865e3e | ||
|
|
46ec2797ff | ||
|
|
fb2cdc8541 | ||
|
|
850ef70496 | ||
|
|
9d3c388664 | ||
|
|
f2b679f602 | ||
|
|
b9d97dffe7 | ||
|
|
7ff0466c2c | ||
|
|
a135325185 | ||
|
|
a6c8f0d300 | ||
|
|
046750354e | ||
|
|
e23d703873 | ||
|
|
ca2d2520d2 | ||
|
|
bc16f902d1 | ||
|
|
f5ae888597 | ||
|
|
376e3af058 | ||
|
|
af63c0a9e1 | ||
|
|
7d149ebec4 | ||
|
|
37c809471b | ||
|
|
12baceb859 | ||
|
|
3e6b3c8c40 | ||
|
|
25f2021711 | ||
|
|
8b30f7dbb5 | ||
|
|
76b35dfeb0 | ||
|
|
4518d5831b | ||
|
|
066250851f | ||
|
|
341a5196ba | ||
|
|
c878a89e95 | ||
|
|
c72d59a3f1 | ||
|
|
995e2657bb | ||
|
|
fe6d6397d6 | ||
|
|
c7f52bcee4 | ||
|
|
fb4d8a6d14 | ||
|
|
929f9a7ad2 | ||
|
|
48ce5bf6e6 | ||
|
|
617a518714 | ||
|
|
480f45f2f3 | ||
|
|
0e8b01c1b5 | ||
|
|
b750d6772f | ||
|
|
7ce172a497 | ||
|
|
821dfe5b98 | ||
|
|
6c57b2f8f9 | ||
|
|
6e0c9d159d | ||
|
|
a90a7dbec7 | ||
|
|
2250bd58a2 | ||
|
|
126be45ed1 | ||
|
|
e021a55abd | ||
|
|
2ad6254894 | ||
|
|
5bd97c2f63 | ||
|
|
570d1f2271 | ||
|
|
613e9ef701 | ||
|
|
5080c6ffc5 | ||
|
|
f16bc12b7d | ||
|
|
d2f096187c | ||
|
|
bd1e61befd | ||
|
|
b97165bec9 | ||
|
|
8b0f07b2dc | ||
|
|
c0ba45f6de | ||
|
|
017c898ed0 | ||
|
|
b193a0c9fd | ||
|
|
db0c7b0562 | ||
|
|
85b8e91b57 | ||
|
|
87301ca154 | ||
|
|
650f5b784d | ||
|
|
c8dd9eefa6 | ||
|
|
0bdf15977f | ||
|
|
8a844f9cca | ||
|
|
8fbde84380 | ||
|
|
00826d3327 | ||
|
|
d5572e322f | ||
|
|
37814111de | ||
|
|
1417888a89 | ||
|
|
5d846c3ca9 | ||
|
|
5dd0477440 | ||
|
|
c6f823f855 | ||
|
|
2af7c24e79 | ||
|
|
94ccfefa84 | ||
|
|
46f3bec37e | ||
|
|
f5d2e0db29 | ||
|
|
88ee56f471 | ||
|
|
8436154276 | ||
|
|
150b25f29e | ||
|
|
f4c50105ba | ||
|
|
3395bedc2b | ||
|
|
7a14210e2b | ||
|
|
d206b67ca8 | ||
|
|
0bfef9008b | ||
|
|
401e542fcd | ||
|
|
210514f74b | ||
|
|
dd838d4ad3 | ||
|
|
5f2d19c7aa | ||
|
|
d5ae87b5ca | ||
|
|
95e7c866cf | ||
|
|
02028eb1ad | ||
|
|
2effdb04bd | ||
|
|
ab31e3e3bb | ||
|
|
37b1432514 | ||
|
|
6e8bc337aa | ||
|
|
8347566815 | ||
|
|
ede09a03db | ||
|
|
849d60253c | ||
|
|
b5660c8a92 | ||
|
|
54263bb5a7 | ||
|
|
4069a9f7d5 | ||
|
|
77467eaf0c | ||
|
|
caa030714b | ||
|
|
facbc78e0a | ||
|
|
6488dcbb01 | ||
|
|
37265b109a | ||
|
|
ebe7342d10 | ||
|
|
523bbef034 | ||
|
|
84e127a637 | ||
|
|
4a091df8cc | ||
|
|
92a171ce53 | ||
|
|
1b1e46ff6c | ||
|
|
3370d9af15 | ||
|
|
9306de79ad | ||
|
|
ff7a54add8 | ||
|
|
c3d1157696 | ||
|
|
d0f03cb148 | ||
|
|
9b7c9f0fb6 | ||
|
|
e508b6df0d | ||
|
|
710b85be70 | ||
|
|
66455b708a | ||
|
|
8b8000b98a | ||
|
|
54236df6e0 | ||
|
|
6cd2a48910 | ||
|
|
fe08b96844 | ||
|
|
4d78901420 | ||
|
|
c06468025c | ||
|
|
148e539025 | ||
|
|
92b96ff30d | ||
|
|
778df0c93b | ||
|
|
9d18ecc5cb | ||
|
|
5f2455c502 | ||
|
|
6bc67609a3 | ||
|
|
1bd3945dd9 | ||
|
|
168f4b1e6b | ||
|
|
8a8827c980 | ||
|
|
21a968b84d | ||
|
|
84fab84b3f | ||
|
|
3d65c030a8 | ||
|
|
59097bab20 | ||
|
|
4cbacd9261 | ||
|
|
655102fc7d | ||
|
|
f718f46545 | ||
|
|
71d4e2c320 | ||
|
|
41241d7500 | ||
|
|
b90c9836cb | ||
|
|
aff3fcf76d | ||
|
|
ec2aa4063a | ||
|
|
718f2e01f7 | ||
|
|
ba9f7fb1b5 | ||
|
|
0ac6b3e8f3 | ||
|
|
dddad1c2ca | ||
|
|
95bfff20a4 | ||
|
|
7a6f0def85 | ||
|
|
103d4d76be | ||
|
|
db9414a756 | ||
|
|
5a0bf1bb5f | ||
|
|
444c37fe2e | ||
|
|
d3d735370f | ||
|
|
852e93aa74 | ||
|
|
dc1be2efe8 | ||
|
|
f2734ac608 | ||
|
|
57ca49dc5c | ||
|
|
5ef3134a4d | ||
|
|
5b91642883 | ||
|
|
1eb5abb8db | ||
|
|
a65e1bf7e5 | ||
|
|
3f98202b0f | ||
|
|
e7727c39f3 | ||
|
|
17e5637664 | ||
|
|
7fd9b897c2 | ||
|
|
f8967aa207 | ||
|
|
5145324806 | ||
|
|
4233fb6270 | ||
|
|
d11b19fd2b | ||
|
|
684c568033 | ||
|
|
ab4fb7b3ad | ||
|
|
91017dbedb | ||
|
|
f5e8a051a8 | ||
|
|
1d695f6db4 | ||
|
|
d4bdfd0592 | ||
|
|
1cc4b93e7a | ||
|
|
b4e2f5118a | ||
|
|
812b6398e5 | ||
|
|
1db45e2a70 | ||
|
|
6bcadde658 | ||
|
|
5f1c8efe0e | ||
|
|
b9aeccf13b | ||
|
|
16f90b33f3 | ||
|
|
5d8d052a77 | ||
|
|
7fa4d78269 | ||
|
|
6bf0db7df6 | ||
|
|
110313e7de | ||
|
|
44e24c9e6b | ||
|
|
6c58fef220 | ||
|
|
3d593ce87d | ||
|
|
36e1b5107e | ||
|
|
f89123f489 | ||
|
|
b7280a765d | ||
|
|
37b010795e | ||
|
|
a4f89b79a3 | ||
|
|
5bde4d875a | ||
|
|
a79c471c31 | ||
|
|
c1e29f9013 | ||
|
|
4c27dfd5eb | ||
|
|
201216ba54 | ||
|
|
d3a85e14d9 | ||
|
|
417bd8604c | ||
|
|
3d289f4489 | ||
|
|
d138c854f3 | ||
|
|
e26a792b70 | ||
|
|
7e2d3b07c0 | ||
|
|
394a6f28db | ||
|
|
72e01274c9 | ||
|
|
9f2e982944 | ||
|
|
c6b0f360fe | ||
|
|
ef19242be3 | ||
|
|
2cb4f8b6f5 | ||
|
|
59919a0b0c | ||
|
|
bf1857ecc7 | ||
|
|
b40920596a | ||
|
|
3b14c322e8 | ||
|
|
3e60aa5738 | ||
|
|
6ca2d27c82 | ||
|
|
d2f26d1969 | ||
|
|
fc25443827 | ||
|
|
986800885a | ||
|
|
52c6ab1cec | ||
|
|
83a989c6dc | ||
|
|
32b96c259b | ||
|
|
954581c750 | ||
|
|
24da43f823 | ||
|
|
600e2ddecf | ||
|
|
9740f488cf | ||
|
|
f81467fd30 | ||
|
|
2ec2c39cf1 | ||
|
|
c85e426cc5 | ||
|
|
41fc57f46c | ||
|
|
a215bb9709 | ||
|
|
b23fa30099 | ||
|
|
848c4b2d68 | ||
|
|
4f995cbc1c | ||
|
|
b21c49352e | ||
|
|
3470dd1e7b | ||
|
|
2ba35286ef | ||
|
|
bbd8212ced | ||
|
|
4564325bc7 | ||
|
|
b9052ed7f0 | ||
|
|
4160a92621 | ||
|
|
201bb73980 | ||
|
|
78832cc0d0 | ||
|
|
a5ecb71993 | ||
|
|
6d86dca20b | ||
|
|
e24f84504f | ||
|
|
ee2fb57f4e | ||
|
|
11fe95d8ea | ||
|
|
70fe9a4405 | ||
|
|
c09225f868 | ||
|
|
126bcd365d | ||
|
|
fe4d2bc6c5 | ||
|
|
dbaf22372c | ||
|
|
43bd243457 | ||
|
|
c0251dc8be | ||
|
|
26266c6a94 | ||
|
|
64392b2d45 | ||
|
|
d555ee8bcc | ||
|
|
0c1a35f297 | ||
|
|
9ac608ca43 | ||
|
|
7ae55d73c1 | ||
|
|
8102a0974a | ||
|
|
f8491794d3 | ||
|
|
d5be15c90e | ||
|
|
e91efc6694 | ||
|
|
3d66be9e5a | ||
|
|
ec1b24d05b | ||
|
|
d93997c1cb | ||
|
|
e19aa975c8 | ||
|
|
3f02dd0a36 | ||
|
|
ab4e0f653a | ||
|
|
fda023e7dc | ||
|
|
ad618be979 | ||
|
|
5881266256 | ||
|
|
e03187852b | ||
|
|
b846cb6c2c | ||
|
|
62ecdd650f | ||
|
|
9f195ff377 | ||
|
|
27a5f09185 | ||
|
|
01b0b4e653 | ||
|
|
ff5dfff5bb | ||
|
|
e3e9777ee6 | ||
|
|
7dc2dc8749 | ||
|
|
4eb5694872 | ||
|
|
681c5e8097 | ||
|
|
5ad06b0255 | ||
|
|
a2889a09e3 | ||
|
|
a4cd5f7584 | ||
|
|
cf098a0de6 | ||
|
|
1619374252 | ||
|
|
c13064e201 | ||
|
|
20647f2287 | ||
|
|
37e32fbcb9 | ||
|
|
27acbba52e | ||
|
|
6f33d2b4c4 | ||
|
|
a2e4209f4f | ||
|
|
73d6716828 | ||
|
|
1fb2419be2 | ||
|
|
3394808c06 | ||
|
|
c252b58a15 | ||
|
|
39ae8c3ea0 | ||
|
|
eb8c2d964c | ||
|
|
bd9cf9ca11 | ||
|
|
280568df2f | ||
|
|
b87ff1e2dc | ||
|
|
55c90cfc38 | ||
|
|
500d2374a5 | ||
|
|
d78963c021 | ||
|
|
9ab0920f01 | ||
|
|
a6e7fba433 | ||
|
|
8905e39439 | ||
|
|
df41b85827 | ||
|
|
9fa3b9345e | ||
|
|
42af6c8508 | ||
|
|
b7df1bc259 | ||
|
|
b40f9db735 | ||
|
|
938841c658 | ||
|
|
34344e5769 | ||
|
|
538a9624ec | ||
|
|
c4c69ca8de | ||
|
|
90330ab3e4 | ||
|
|
c5880e7618 | ||
|
|
9d0c05d9cc | ||
|
|
f6a68cb7fd | ||
|
|
462c785418 | ||
|
|
a1f90dd8d3 | ||
|
|
2a67261eac | ||
|
|
1d3403fdc2 | ||
|
|
53301b0f56 | ||
|
|
8989ce1766 | ||
|
|
faa121e9ef | ||
|
|
f48759e83a | ||
|
|
2eca733603 | ||
|
|
14b65cec43 | ||
|
|
f5477039fa | ||
|
|
9fa3221687 | ||
|
|
c8c63faf15 | ||
|
|
ee4794c99e | ||
|
|
3a23bb4b73 | ||
|
|
46ffb25f84 | ||
|
|
069a4025c5 | ||
|
|
edd044752d | ||
|
|
3929d25dcc | ||
|
|
99baa4f3d9 | ||
|
|
f64d4c571b | ||
|
|
9372fa169a | ||
|
|
f98ac7f268 | ||
|
|
daaa6ec129 | ||
|
|
88afc22d5b | ||
|
|
23099100b6 | ||
|
|
b7ea9e30df | ||
|
|
844c3bb197 | ||
|
|
208c6d3eac | ||
|
|
886a2e74ac | ||
|
|
adad3c27dd | ||
|
|
470aeab215 | ||
|
|
db1d90ec9d | ||
|
|
124ce8420a | ||
|
|
4433eaf242 | ||
|
|
5ba070f600 | ||
|
|
2d1a42aa00 | ||
|
|
74d9f5a3e2 | ||
|
|
634fbb5a73 | ||
|
|
e16948bf80 | ||
|
|
76c9833ee5 | ||
|
|
99662b70ff | ||
|
|
fcde9eabbf | ||
|
|
4ef15951a8 | ||
|
|
1bc51c2290 | ||
|
|
be1025901a | ||
|
|
1a606de29f | ||
|
|
454c0b31cb | ||
|
|
223e0f4e53 | ||
|
|
3a84091945 | ||
|
|
a0e8f1097f | ||
|
|
08ed4fb983 | ||
|
|
0b1f336e03 | ||
|
|
0258fcb116 | ||
|
|
3272aa3f08 | ||
|
|
d9ea6651f8 | ||
|
|
32b11603d8 | ||
|
|
538fd2672d | ||
|
|
3e37724e3e | ||
|
|
1b249ba76b | ||
|
|
df1295fbd0 | ||
|
|
dcd71fe126 | ||
|
|
610ee5db76 | ||
|
|
9d5494d9f0 | ||
|
|
dd44bc8d00 | ||
|
|
110c7cb62b | ||
|
|
09aa5abbdf | ||
|
|
1d8b6df630 | ||
|
|
195058752e | ||
|
|
c62805e86d | ||
|
|
d15b175c33 | ||
|
|
6cb73adfd5 | ||
|
|
6d1cd67900 | ||
|
|
e12bd27106 | ||
|
|
cb018257cf | ||
|
|
e02953dc17 | ||
|
|
ba56f8e0c5 | ||
|
|
ac12dd55c3 | ||
|
|
24647820d7 | ||
|
|
7e8aa711ef | ||
|
|
329e561eff | ||
|
|
d848cbbc0f | ||
|
|
cd46e43c20 | ||
|
|
98674c1cc8 | ||
|
|
8bfae631b1 | ||
|
|
d00c7cf3a3 | ||
|
|
b45665fee4 | ||
|
|
1b58664541 | ||
|
|
ed6a178ae3 | ||
|
|
e925ca509d | ||
|
|
ca310cf815 | ||
|
|
6fa27aac42 | ||
|
|
a5c3fc4751 | ||
|
|
65b05fa8c1 | ||
|
|
3ee556d858 | ||
|
|
fd3546a999 | ||
|
|
f5fafa5b96 | ||
|
|
7ff2069e60 | ||
|
|
154ff43d7f | ||
|
|
b754fe4810 | ||
|
|
a1071ec01a | ||
|
|
92dce9a2ea | ||
|
|
5fd917ec2f | ||
|
|
d7cda23b25 | ||
|
|
cae5da5777 | ||
|
|
97f1f47fa5 | ||
|
|
53c269ee25 | ||
|
|
1420d3cc10 | ||
|
|
ce401b5ca1 | ||
|
|
cd412bd0f5 | ||
|
|
f33f88072e | ||
|
|
1240a00fa5 | ||
|
|
83f325de0d | ||
|
|
0b871bf54e | ||
|
|
07f7aa3c8f | ||
|
|
7208bc6cdd | ||
|
|
fef5a98602 | ||
|
|
5cce65cdfa | ||
|
|
268081e5d0 | ||
|
|
f5f179117e | ||
|
|
8c85096f98 | ||
|
|
c5e7675c4b | ||
|
|
03009912ac | ||
|
|
e4a1138291 | ||
|
|
a5bc54d2d5 | ||
|
|
df73e84725 | ||
|
|
5bf07c2e77 | ||
|
|
bb0d142a65 | ||
|
|
c98cef0da1 | ||
|
|
1d9c52be02 | ||
|
|
a6c9df1a64 | ||
|
|
f66368b191 | ||
|
|
e4daea406e | ||
|
|
6216f22cb9 | ||
|
|
d4c80d9094 | ||
|
|
27324ded87 | ||
|
|
7d1c625e32 | ||
|
|
b4fe65f2c0 | ||
|
|
f5efdac2e5 | ||
|
|
23de875516 | ||
|
|
82030b8286 | ||
|
|
af4da43bb8 | ||
|
|
33f3b8659c | ||
|
|
ed724a61a7 | ||
|
|
053bd74aa3 | ||
|
|
3c0410e59f | ||
|
|
e621f6c753 | ||
|
|
b05f000f42 | ||
|
|
e60bfc6d23 | ||
|
|
9a3d3201f9 | ||
|
|
abf9724424 | ||
|
|
ab9a8c62ab | ||
|
|
e2fe936152 | ||
|
|
1d71650379 | ||
|
|
a040740974 | ||
|
|
5be0dc9fc5 | ||
|
|
52ad434d24 | ||
|
|
d69d111bb6 | ||
|
|
50f4494875 | ||
|
|
8a4982383a | ||
|
|
0d72890482 | ||
|
|
9be7d6d112 | ||
|
|
3c4121ba07 | ||
|
|
b6e44b04d6 | ||
|
|
02c11afbc6 | ||
|
|
2b8f5b57eb | ||
|
|
0519c9467c | ||
|
|
84d968c7d2 | ||
|
|
a04b0241c2 | ||
|
|
670fd19d33 | ||
|
|
a66544f3f4 | ||
|
|
1bfb3aefcc | ||
|
|
b7bfbc3fcd | ||
|
|
e517f3259c | ||
|
|
8afda92a64 | ||
|
|
ed216c8d4d | ||
|
|
7506cb4ea1 | ||
|
|
60bc5944db | ||
|
|
8f0572283a | ||
|
|
b13b46eefe | ||
|
|
4db2a98d7f | ||
|
|
05ebb07753 | ||
|
|
694e68b838 | ||
|
|
78320e1433 | ||
|
|
082e7b2695 | ||
|
|
cdbffb80c7 | ||
|
|
cb6c8cce55 | ||
|
|
47e173e549 | ||
|
|
162bd4be97 | ||
|
|
f0764aeafe | ||
|
|
1efed71696 | ||
|
|
06d77c1c19 | ||
|
|
942d0c631a | ||
|
|
abae5dd93b | ||
|
|
93015a0266 | ||
|
|
d238db69d3 | ||
|
|
e0ead236b6 | ||
|
|
c548262664 | ||
|
|
bfc51e577f | ||
|
|
85773995e1 | ||
|
|
00b4777290 | ||
|
|
197e6de194 | ||
|
|
9908ea4c2f | ||
|
|
c402b15bd3 | ||
|
|
a3f3118ac5 | ||
|
|
b1aab0e498 | ||
|
|
927c0ce54a | ||
|
|
57d9dc037d | ||
|
|
e3cfe28848 | ||
|
|
ac91f583b8 | ||
|
|
215658bf29 | ||
|
|
92b1a6ea8a | ||
|
|
8ab00758be | ||
|
|
e91bda7765 | ||
|
|
9db211ac97 | ||
|
|
b1381fd3b7 | ||
|
|
e5f6a7d85e | ||
|
|
feae76fc4f | ||
|
|
015f3cffb9 | ||
|
|
3e5c17ae80 | ||
|
|
9a1d06c6ab | ||
|
|
3e278b42f8 | ||
|
|
fa953445e9 | ||
|
|
a412b1d3b7 | ||
|
|
fc680388e3 | ||
|
|
7c260b45e1 | ||
|
|
098c4c57b4 | ||
|
|
7c826e35b4 | ||
|
|
1bd2ff3fc3 | ||
|
|
e2fc91fc15 | ||
|
|
cf20647b25 | ||
|
|
8d7071e549 | ||
|
|
fb006b2c6d | ||
|
|
9039eeb3cd | ||
|
|
dd0702d30f | ||
|
|
886faf0bd4 | ||
|
|
86e28c6d34 | ||
|
|
821efab8aa | ||
|
|
5295365dd0 | ||
|
|
788959a98c | ||
|
|
dd145aaa88 | ||
|
|
34b3adc23d | ||
|
|
ab14882761 | ||
|
|
7dc1f54fb6 | ||
|
|
c09fb03eda | ||
|
|
dbf2761fb7 | ||
|
|
fd1378f778 | ||
|
|
819dcee3ad | ||
|
|
4b02c04afc | ||
|
|
deed99e7a3 | ||
|
|
7bffc4a177 | ||
|
|
701555e400 | ||
|
|
49fa86d0b5 | ||
|
|
adbace8810 | ||
|
|
050138bcea | ||
|
|
db50b04663 | ||
|
|
59755ec115 | ||
|
|
856fb1e636 | ||
|
|
d41d52b889 | ||
|
|
18f69fb16d | ||
|
|
739e85032b | ||
|
|
d165711f2e | ||
|
|
6bf19ffe37 | ||
|
|
441116e1e6 | ||
|
|
ce97ef0ab1 | ||
|
|
2ea0de92f4 | ||
|
|
14580c4675 | ||
|
|
9681559d56 | ||
|
|
b478e4845f | ||
|
|
1fa5104076 | ||
|
|
ce65f5376f | ||
|
|
0695249fc8 | ||
|
|
51144c99a7 | ||
|
|
251398a7cb | ||
|
|
2e6a7f869c | ||
|
|
f308162334 | ||
|
|
db4867839c | ||
|
|
73ffff7d22 | ||
|
|
dc48a4f73c | ||
|
|
efbccccdc0 | ||
|
|
3e7cd88dcc | ||
|
|
12cfe8fc37 | ||
|
|
c6d2ce043f | ||
|
|
5c34c574c8 | ||
|
|
d3cfdcb431 | ||
|
|
4018d23c39 | ||
|
|
81d4e8fe9d | ||
|
|
34b48c4069 | ||
|
|
01a3ab6ca7 | ||
|
|
476c242d7f | ||
|
|
ae3fa6a836 | ||
|
|
ba93bdd66d | ||
|
|
1fa0b37fac | ||
|
|
5b4a5969cc | ||
|
|
941a7934ef | ||
|
|
474439ab4b | ||
|
|
4428aea5ee | ||
|
|
e9a9cc5bc3 | ||
|
|
2291c5b230 | ||
|
|
f78e194cf7 | ||
|
|
b77ddcf1a7 | ||
|
|
3ef677537d | ||
|
|
1df1265ed1 | ||
|
|
f0854a16fe | ||
|
|
6bd476fb03 | ||
|
|
b9c0af7c3b | ||
|
|
5149ebc70e | ||
|
|
e92a6a5803 | ||
|
|
6da963a695 | ||
|
|
2a74489858 | ||
|
|
65a436ca98 | ||
|
|
bc533c8050 | ||
|
|
fd6cea4698 | ||
|
|
a1aa1658ec | ||
|
|
5c4c468d13 | ||
|
|
69ef1658cc | ||
|
|
8c72aa76a0 | ||
|
|
928a932a43 | ||
|
|
83601055dc | ||
|
|
68480f6e43 | ||
|
|
42291540ab | ||
|
|
194eb69838 | ||
|
|
c1d27fa453 | ||
|
|
9d5f7caa79 | ||
|
|
a1d78dceb0 | ||
|
|
2bcf435e0a | ||
|
|
30e853305d | ||
|
|
600f4bb2b6 | ||
|
|
5868814c91 | ||
|
|
e862f8f86c | ||
|
|
85c1ecd035 | ||
|
|
68ad448672 | ||
|
|
c18fb3cb78 | ||
|
|
53702f989c | ||
|
|
c547b1bec3 | ||
|
|
740350c8ea | ||
|
|
9f9b20eac0 | ||
|
|
c67ffb82a8 | ||
|
|
1ea24f3d6c | ||
|
|
226bd51afe | ||
|
|
293568be36 | ||
|
|
152fe81d16 | ||
|
|
494dd64c50 | ||
|
|
56de0d1ab4 | ||
|
|
73c1f4cc54 | ||
|
|
6a6a82385e | ||
|
|
fc8ef0e723 | ||
|
|
de11c05d2a | ||
|
|
addbc8cad8 | ||
|
|
63e37b7cbb | ||
|
|
9ee329034f | ||
|
|
f3e904207b | ||
|
|
e4ae6ce635 | ||
|
|
f7d76255ad | ||
|
|
ea45f9c694 | ||
|
|
1d449c0f58 | ||
|
|
9ecc991043 | ||
|
|
4ef834859c | ||
|
|
fa082bc5c4 | ||
|
|
67caab026a | ||
|
|
91c55facb2 | ||
|
|
321d4d84d7 | ||
|
|
22faa58e0b | ||
|
|
ebd559f662 | ||
|
|
d27c9d3f98 | ||
|
|
fbef482265 | ||
|
|
a57926ac57 | ||
|
|
70a7137e62 | ||
|
|
2d3a08a362 | ||
|
|
cc02edb3f6 | ||
|
|
f894cd90f3 | ||
|
|
24675969cc | ||
|
|
a0cba1194e | ||
|
|
0952fa95f4 | ||
|
|
6177ab957b | ||
|
|
5c1300a2b9 | ||
|
|
af9dd0827a | ||
|
|
dc0162122f | ||
|
|
ae491fb15b | ||
|
|
957c1fc420 | ||
|
|
86acfb35aa | ||
|
|
e27d12ee5e | ||
|
|
63d52c2a1a | ||
|
|
9d4a71b57a | ||
|
|
3462dc3e14 | ||
|
|
d21351e66e | ||
|
|
3204d20335 | ||
|
|
a519489d80 | ||
|
|
5558c3a35a | ||
|
|
58d9755314 | ||
|
|
498ba0a384 | ||
|
|
5a5477e895 | ||
|
|
a17d7ce6ba | ||
|
|
afc7248912 | ||
|
|
6bb578fea8 | ||
|
|
bed5f293dc | ||
|
|
9eb639e891 | ||
|
|
4968dc4bab | ||
|
|
e14c440795 | ||
|
|
4edd139967 | ||
|
|
366e760f7a | ||
|
|
3b1a38621a | ||
|
|
3c4de59674 | ||
|
|
08a1bc8d97 | ||
|
|
c8f3772753 | ||
|
|
c7b6231cd5 | ||
|
|
1cec200638 | ||
|
|
b046942a28 | ||
|
|
4c49036b8a | ||
|
|
6909d49683 | ||
|
|
32471953ed | ||
|
|
60272479a1 | ||
|
|
fb7681ddc5 | ||
|
|
8b581a0a0f | ||
|
|
33a01f2773 | ||
|
|
3c517f514f | ||
|
|
48680d68ed | ||
|
|
871fc0a40a | ||
|
|
5a3a499f37 | ||
|
|
5ee18388c4 | ||
|
|
c98a30f82b | ||
|
|
427206abf7 | ||
|
|
2eb4267e6e | ||
|
|
f547b63bca | ||
|
|
fd71928e3a | ||
|
|
77c0177d23 | ||
|
|
b10bcca047 | ||
|
|
4618ca7b6e | ||
|
|
27dea3bc57 | ||
|
|
b275068569 | ||
|
|
9d86c3270c | ||
|
|
7ea3d7b9b4 | ||
|
|
d81a370fca | ||
|
|
5849001d00 | ||
|
|
f75ea6ea24 | ||
|
|
35e4d452c0 | ||
|
|
7c31ca2ac2 | ||
|
|
35bba14b2c | ||
|
|
89b976121f | ||
|
|
f5b08bbea6 | ||
|
|
ca2bdbca19 | ||
|
|
8dfdfdf6ef | ||
|
|
f8b8d21698 | ||
|
|
d6d4f84c3b | ||
|
|
12fcf96e93 | ||
|
|
5875a121db | ||
|
|
19ff098db5 | ||
|
|
c0724d904f | ||
|
|
97bc2c5c66 | ||
|
|
b130d14de4 | ||
|
|
cec52253fb | ||
|
|
31d5805681 | ||
|
|
fda087e24f | ||
|
|
1d8935d0ab | ||
|
|
b49730f255 | ||
|
|
537d1599f3 | ||
|
|
7eb7b9f802 | ||
|
|
73822b9e54 | ||
|
|
a71adc5950 | ||
|
|
49a37c7d6f | ||
|
|
df3d236408 | ||
|
|
8c536e4d58 | ||
|
|
6f7f0867af | ||
|
|
7bdf53291b | ||
|
|
44a6bfd874 | ||
|
|
76551e5648 | ||
|
|
64482ed07b | ||
|
|
c0ec3d92db | ||
|
|
c1a2f418a2 | ||
|
|
6d23625601 | ||
|
|
094d429ff0 | ||
|
|
2a574e8c92 | ||
|
|
da766dd84f | ||
|
|
e2d11ce0fc | ||
|
|
fd5c5a18a4 | ||
|
|
011fe6a8d2 | ||
|
|
9275f09cf9 | ||
|
|
43a14c986c | ||
|
|
9d5aecc51d | ||
|
|
a4498925d6 | ||
|
|
36ec090ee3 | ||
|
|
079038b09e | ||
|
|
11a5229f37 | ||
|
|
1387aecceb | ||
|
|
6edde868e6 | ||
|
|
1cade38b79 | ||
|
|
e9fd3005b9 | ||
|
|
40815c9c78 | ||
|
|
397fe29bb2 | ||
|
|
9e3525408f | ||
|
|
55a2688dc0 | ||
|
|
f4b0ecd0a0 | ||
|
|
6fc4ffef0a | ||
|
|
cf3c41acc7 | ||
|
|
9bf9c00474 | ||
|
|
a2cdd72db0 | ||
|
|
8230b5faf4 | ||
|
|
9e934738b5 | ||
|
|
5a3b3d797f | ||
|
|
6331635f25 | ||
|
|
0ff9277dea | ||
|
|
5dce162a29 | ||
|
|
adc45149ae | ||
|
|
29bdbfc10f | ||
|
|
57504f2359 | ||
|
|
c2a1d188c9 | ||
|
|
bd8b9b3336 | ||
|
|
2bcbfe8747 | ||
|
|
98617a4ba5 | ||
|
|
0a6e13b153 | ||
|
|
93eee39355 | ||
|
|
f791c70643 | ||
|
|
51afcc5ca8 | ||
|
|
7a0ed4c462 | ||
|
|
45376f0dab | ||
|
|
34c426a549 | ||
|
|
1ed3b22db4 | ||
|
|
085d80792f | ||
|
|
aabddede8f | ||
|
|
d62038e509 | ||
|
|
e0095d235f | ||
|
|
5270983dc4 | ||
|
|
0cf3108af7 | ||
|
|
217d039bb7 | ||
|
|
fda4d386c9 | ||
|
|
2fc664f12a | ||
|
|
3d989dbaff | ||
|
|
f281b4b4cb | ||
|
|
8bfa6b817f | ||
|
|
f295212360 | ||
|
|
7b2b639d1e | ||
|
|
c6031a7806 | ||
|
|
d111518352 | ||
|
|
a5ceb2a61d | ||
|
|
bd72eb5693 | ||
|
|
e3dcb4b0dc | ||
|
|
b6b64c6dc5 | ||
|
|
030d332a79 | ||
|
|
54d3e33616 | ||
|
|
1c465b55e6 | ||
|
|
687b66da43 | ||
|
|
710ab4ae3f | ||
|
|
06f4ca6983 | ||
|
|
8cedcccfb0 | ||
|
|
70a8bea8f6 | ||
|
|
8512a26319 | ||
|
|
778a2866e4 | ||
|
|
08a74989b7 | ||
|
|
68522c82a6 | ||
|
|
ec2d1547c9 | ||
|
|
eb6c050cf0 | ||
|
|
0e5ce3e07e | ||
|
|
14791ce7eb | ||
|
|
a8bee07d8f | ||
|
|
184d3e158a | ||
|
|
f8679f06aa | ||
|
|
102e6dd2fb | ||
|
|
7806ad8ac8 | ||
|
|
da23514424 | ||
|
|
e39201147e | ||
|
|
c8d5f9edc5 | ||
|
|
9248964191 | ||
|
|
5cc4d02b80 | ||
|
|
1b18f85e42 | ||
|
|
e3cb700cf7 | ||
|
|
82b1763431 | ||
|
|
cc54724ff1 | ||
|
|
5eebc9e093 | ||
|
|
ba2b0ef809 | ||
|
|
2531d33880 | ||
|
|
d66cb54a82 | ||
|
|
e28dbfb377 | ||
|
|
83caa146d1 | ||
|
|
cf61d7349a | ||
|
|
87de3ec3e3 | ||
|
|
311b373455 | ||
|
|
7f13185f2f | ||
|
|
612138db4f | ||
|
|
c39eef1d5a | ||
|
|
41bb09e361 | ||
|
|
6b9590a6a9 | ||
|
|
8583f38ec1 | ||
|
|
6e11a46b2a | ||
|
|
801443a7d0 | ||
|
|
2284247b56 | ||
|
|
33986848f3 | ||
|
|
a55928dbee | ||
|
|
6536ccf003 | ||
|
|
548dfdc26d | ||
|
|
4428dbf885 | ||
|
|
f11dc7e3f6 | ||
|
|
b91dc754b0 | ||
|
|
b2c1ad7abc | ||
|
|
730f80447e | ||
|
|
90743e68d4 | ||
|
|
23f56e4c1b | ||
|
|
c16d631b58 | ||
|
|
e000905aca | ||
|
|
85685afc68 | ||
|
|
dfd81fd125 | ||
|
|
78fd9b4fe4 | ||
|
|
504d1e3004 | ||
|
|
b4a87d8c0b | ||
|
|
884b96c300 | ||
|
|
14667c1756 | ||
|
|
b324cfbfde | ||
|
|
7047d08ca4 | ||
|
|
28c486dad5 | ||
|
|
d6fd82c1ab | ||
|
|
bcf53458ad | ||
|
|
15a6ba791e | ||
|
|
5bce7e0616 | ||
|
|
696f69e442 | ||
|
|
96b8904d88 | ||
|
|
6438a838ce | ||
|
|
d7d870cb4c | ||
|
|
6b33613bb0 | ||
|
|
1caa9d5294 | ||
|
|
251a3babad | ||
|
|
a0d3aed347 | ||
|
|
5cc074ec3b | ||
|
|
4c7b9fd6e5 | ||
|
|
f76170eab4 | ||
|
|
a63da98032 | ||
|
|
1d411df274 | ||
|
|
4c50a92e12 | ||
|
|
92e71b2d08 | ||
|
|
ff69959acc | ||
|
|
10f3ce070d | ||
|
|
e2d3e6f02a | ||
|
|
867b7466f4 | ||
|
|
e95e465a0a | ||
|
|
e5a8ce5ecb | ||
|
|
227256e6ba | ||
|
|
875956f966 | ||
|
|
50ff4cc45e | ||
|
|
a26aee4afe | ||
|
|
a76f5e4143 | ||
|
|
0bff771c03 | ||
|
|
0620f27c10 | ||
|
|
1188c90c10 | ||
|
|
b29a78c068 | ||
|
|
751fd70293 | ||
|
|
d7c2b8f513 | ||
|
|
5627ddff8f | ||
|
|
291e261a65 | ||
|
|
817a927e31 | ||
|
|
c7eb4c8447 | ||
|
|
ac3cabec07 | ||
|
|
6c06f47cf5 | ||
|
|
c7df064d58 | ||
|
|
ed1d49520f | ||
|
|
651ef64617 | ||
|
|
f3ee822968 | ||
|
|
d592e2afb0 | ||
|
|
a25d90de8a | ||
|
|
fedebf4b66 | ||
|
|
ece38a5411 | ||
|
|
785c20c68d | ||
|
|
7e4e01789d | ||
|
|
8e9f593c39 | ||
|
|
ec13e5d503 | ||
|
|
721ceecd70 | ||
|
|
3728f5f178 | ||
|
|
3a3e887622 | ||
|
|
7eca40f093 | ||
|
|
3005abc3aa | ||
|
|
69eddaebbf | ||
|
|
992d4411e1 | ||
|
|
e97b18e244 | ||
|
|
e1c6a910d2 | ||
|
|
b40768895d | ||
|
|
96033fd225 | ||
|
|
855ef1ade9 | ||
|
|
62383a1c72 | ||
|
|
eb275769a5 | ||
|
|
543a435b9f | ||
|
|
281981e619 | ||
|
|
1ec8c8763e | ||
|
|
7dba1a3552 | ||
|
|
f4dec5d25e | ||
|
|
cb7de45b48 | ||
|
|
f098b415db | ||
|
|
2faf2eb5b6 | ||
|
|
a69539e583 | ||
|
|
a3779be9e1 | ||
|
|
488959600e | ||
|
|
9fa8148cc6 | ||
|
|
edff3dfa4a | ||
|
|
6b583ee697 | ||
|
|
c8d72eabe5 | ||
|
|
063136c293 | ||
|
|
0b92d431f5 | ||
|
|
b87bb1dec6 | ||
|
|
dbd802c85c | ||
|
|
1f6b3d50b6 | ||
|
|
2b4492c3f9 | ||
|
|
b75a2414dc | ||
|
|
872aec20b8 | ||
|
|
51f6722277 | ||
|
|
9c0c969b48 | ||
|
|
528e93c81a | ||
|
|
217bbf423b | ||
|
|
fd2ee4e990 | ||
|
|
5bcdb3d478 | ||
|
|
2f1017efed | ||
|
|
b794b9ed2c | ||
|
|
3fd86a953b | ||
|
|
5eb416df15 | ||
|
|
efa78ee0c6 | ||
|
|
8269d04b57 | ||
|
|
5e782cc1c2 | ||
|
|
0ff3fb7f47 | ||
|
|
aa631c5585 | ||
|
|
5c53583456 | ||
|
|
a1a30cd9a6 | ||
|
|
851fbaec2d | ||
|
|
9e8463d6d7 | ||
|
|
ba5fa35f09 | ||
|
|
a480793708 | ||
|
|
477b72ba52 | ||
|
|
f63ba7e3be | ||
|
|
54dca47e09 | ||
|
|
53e0c8d5bf | ||
|
|
8588c22170 | ||
|
|
c2d5ee43c6 | ||
|
|
c7c6855740 | ||
|
|
79f2832591 | ||
|
|
cb432548bf | ||
|
|
900c1790d3 | ||
|
|
1b7bce283a | ||
|
|
702d981925 | ||
|
|
5bbbe4d2e9 | ||
|
|
c54dfd9edd | ||
|
|
5a47565ee1 | ||
|
|
085cf027dc | ||
|
|
299df773ce | ||
|
|
9101e704ce | ||
|
|
212a3f45f8 | ||
|
|
0107338020 | ||
|
|
668e0275c3 | ||
|
|
b258546f34 | ||
|
|
f24f88e46c | ||
|
|
5747d1c5fc | ||
|
|
eb95a959bc | ||
|
|
0edf961ce9 | ||
|
|
6234297f62 | ||
|
|
9c29ae486c | ||
|
|
588fec3b89 | ||
|
|
e42dd5ddfb | ||
|
|
ecc16033be | ||
|
|
30d0dbd2f0 | ||
|
|
f2bbc0eccd | ||
|
|
0152f3adb2 | ||
|
|
ce9824a479 | ||
|
|
2edee2855c | ||
|
|
b41b967ba5 | ||
|
|
43173df446 | ||
|
|
f153d86bce | ||
|
|
4ebcdf8720 | ||
|
|
bd8f6f16aa | ||
|
|
ec1d9aeafa | ||
|
|
7cdef04fc7 | ||
|
|
cbd9093e27 | ||
|
|
f2a1243892 | ||
|
|
144c4bf408 | ||
|
|
499970db68 | ||
|
|
bc069f2ec8 | ||
|
|
440aa490ce | ||
|
|
528afbfd3b | ||
|
|
064a48e965 | ||
|
|
86211e18d7 | ||
|
|
974ba78a93 | ||
|
|
6196a3a6a4 | ||
|
|
e7ec8e3613 | ||
|
|
a5d4ea8004 | ||
|
|
0653426793 | ||
|
|
ba352cebc8 | ||
|
|
6e712bf1b6 | ||
|
|
b23dc6a9b3 | ||
|
|
c2177bff09 | ||
|
|
8d95172118 | ||
|
|
d582356815 | ||
|
|
9d3acb362a | ||
|
|
f2d0238f84 | ||
|
|
d6f290f6d2 | ||
|
|
d2b9bfd6ee | ||
|
|
0a18ea8f4d | ||
|
|
f819999884 | ||
|
|
dc764db35d | ||
|
|
6a49b8cec8 | ||
|
|
eb425fe640 | ||
|
|
5ca549ef5f | ||
|
|
d242ba7a52 | ||
|
|
da46d51f82 | ||
|
|
304b0e0e8e | ||
|
|
2573bcb90f | ||
|
|
b98b377fc0 | ||
|
|
28029092b9 | ||
|
|
7eb2ce827c | ||
|
|
07f9426879 | ||
|
|
7ba6cfe651 | ||
|
|
50939df6b5 | ||
|
|
89e9046042 | ||
|
|
67e3bb8596 | ||
|
|
3025a10808 | ||
|
|
a94a9eb268 | ||
|
|
47a8fc4b49 | ||
|
|
64ad853a5c | ||
|
|
2d6dbd5600 | ||
|
|
93f6a8cb4d | ||
|
|
fef1993dd7 | ||
|
|
71c8436877 | ||
|
|
9a128686a1 | ||
|
|
8fcb84112b | ||
|
|
aa73cbc8b0 | ||
|
|
651fca36ff | ||
|
|
2f4cd33950 | ||
|
|
bcf48c21eb | ||
|
|
9571a1bc30 | ||
|
|
4044b39a2f | ||
|
|
2878583627 | ||
|
|
f0c7dc48d2 | ||
|
|
d197300be7 | ||
|
|
6f846db863 | ||
|
|
9e8915ef9e | ||
|
|
805a4c1ab1 | ||
|
|
c57df7309a | ||
|
|
956f97efd4 | ||
|
|
19d3450cb3 | ||
|
|
ebdbf58474 | ||
|
|
37b0e9e275 | ||
|
|
cd934b73ca | ||
|
|
e4816b5849 | ||
|
|
cf1701f1e1 | ||
|
|
c578df0bf1 | ||
|
|
f6dab33190 | ||
|
|
7c8fdc1651 | ||
|
|
ec6767060a | ||
|
|
4157efaaf7 | ||
|
|
70eff81f19 | ||
|
|
602ecece50 | ||
|
|
a957f1f749 | ||
|
|
98f66d5028 | ||
|
|
da14b12e88 | ||
|
|
356f1a205b | ||
|
|
bf9ab7ffbe | ||
|
|
e849c1b702 | ||
|
|
a44627df29 | ||
|
|
91fab07ef1 | ||
|
|
6f027941b4 | ||
|
|
53925dcc3d | ||
|
|
b821022247 | ||
|
|
296988be02 | ||
|
|
788e8a6d87 | ||
|
|
2423849196 | ||
|
|
609e3e2e97 | ||
|
|
2a5c1684de | ||
|
|
31d89bec66 | ||
|
|
cf5435e477 | ||
|
|
e8591090f2 | ||
|
|
486c8805ed | ||
|
|
2e2563adc0 | ||
|
|
c4258be693 | ||
|
|
f7eedc1f06 | ||
|
|
ba1b4744c5 | ||
|
|
bd13c02451 | ||
|
|
2c63bde7b3 | ||
|
|
5902b175f9 | ||
|
|
d0e47f9073 | ||
|
|
bd7215d36f | ||
|
|
f3f134f9de | ||
|
|
cdbf5d57bd | ||
|
|
1ae50bd670 | ||
|
|
d28c9f9843 | ||
|
|
fe7d52aa78 | ||
|
|
fc0907f8c1 | ||
|
|
e57678d7a6 | ||
|
|
45e594e806 | ||
|
|
87e7a0effa | ||
|
|
4fd1a35b2a | ||
|
|
c460cf0678 | ||
|
|
983802da61 | ||
|
|
49273e0d59 | ||
|
|
76b8459cdc | ||
|
|
e269eb6f65 | ||
|
|
7b4774f375 | ||
|
|
70e9a25112 | ||
|
|
9fb83ea56a | ||
|
|
8bb3398376 | ||
|
|
d42fbb3d4d | ||
|
|
53b2245dc1 | ||
|
|
db14975828 | ||
|
|
a5139d2710 | ||
|
|
9f584c8014 | ||
|
|
6f1b98fb52 | ||
|
|
c258a90505 | ||
|
|
eb47ef43a7 | ||
|
|
1876d6b923 | ||
|
|
90c8fcf393 | ||
|
|
6af90575e9 | ||
|
|
994613260c | ||
|
|
1430fa8220 | ||
|
|
33e06058c6 | ||
|
|
b032d1e1f7 | ||
|
|
d6b43b1fe6 | ||
|
|
fc771c8683 | ||
|
|
f91ac09f87 | ||
|
|
e4fa399412 | ||
|
|
952e949e10 | ||
|
|
3d093d66fb | ||
|
|
05fe2893c7 | ||
|
|
6fc17294b6 | ||
|
|
6607921bee | ||
|
|
0b0793438f | ||
|
|
3dd591e760 | ||
|
|
f290d2f899 | ||
|
|
a676ad7193 | ||
|
|
096c408ef6 | ||
|
|
00b65f76b6 | ||
|
|
39fb266282 | ||
|
|
3969d0ac78 | ||
|
|
439c6bb3c0 | ||
|
|
5cedbf9d34 | ||
|
|
427b235eb5 | ||
|
|
92d5ba580f | ||
|
|
bc2f331c8b | ||
|
|
ca58aef676 | ||
|
|
379dc405f6 | ||
|
|
d74b5c42da | ||
|
|
6004971439 | ||
|
|
a12b8927bc | ||
|
|
57e23b289a | ||
|
|
8214ffccf0 | ||
|
|
547135dc2d | ||
|
|
9c72113161 | ||
|
|
8cc967fa22 | ||
|
|
4bd30bb72d | ||
|
|
5eeb4dabbd | ||
|
|
a27c4b3860 | ||
|
|
dfee08f74f | ||
|
|
0e2629bdd4 | ||
|
|
05c8630b07 | ||
|
|
1cffe618d2 | ||
|
|
98c7bb23b5 | ||
|
|
922853cee1 | ||
|
|
a251e61859 | ||
|
|
9c19799023 | ||
|
|
f423b110a8 | ||
|
|
6fd471e652 | ||
|
|
3d69029d33 | ||
|
|
2258f2e424 | ||
|
|
cca5a68e20 | ||
|
|
da5c9bff68 | ||
|
|
5b87f0699b | ||
|
|
a67fe561a1 | ||
|
|
e2f4065376 | ||
|
|
d3bf87f4f4 | ||
|
|
6d351ec47f | ||
|
|
4dc1dd2511 | ||
|
|
5205ae40fa | ||
|
|
32f1dcde7e | ||
|
|
6772581c53 | ||
|
|
387201815b | ||
|
|
24d61e1125 | ||
|
|
04259f031d | ||
|
|
6403da3715 | ||
|
|
90cb76312c | ||
|
|
b6cff01abb | ||
|
|
b34b711161 | ||
|
|
709d767d61 | ||
|
|
e075916154 | ||
|
|
de10154f29 | ||
|
|
ba71e79e54 | ||
|
|
2cc70b8051 | ||
|
|
9d965f94de | ||
|
|
40c2db4744 | ||
|
|
9a7285dca4 | ||
|
|
8c00ac78b1 | ||
|
|
cf4478eeee | ||
|
|
85c8e7f1bb | ||
|
|
efd95efb40 | ||
|
|
99ad7ea45c | ||
|
|
aba0c57f73 | ||
|
|
8c4f6b648e | ||
|
|
3b83bdd88d | ||
|
|
8d71e08b44 | ||
|
|
c31063a8ef | ||
|
|
28d101f1dd | ||
|
|
aaef344ae3 | ||
|
|
42d0324304 | ||
|
|
2a0019347a | ||
|
|
e0305ea1b9 | ||
|
|
105ff47ae3 | ||
|
|
5ee190a41e | ||
|
|
cf37617c25 | ||
|
|
2e9c8f0f51 | ||
|
|
06c2319851 | ||
|
|
da0668c7cc | ||
|
|
b34df334cb | ||
|
|
9e9f2ccae1 | ||
|
|
15b8f75730 | ||
|
|
9d6b9aa574 | ||
|
|
64724886af | ||
|
|
c088369f4a | ||
|
|
39dbf46422 | ||
|
|
3c1b0bb917 | ||
|
|
2227170dbb | ||
|
|
e08f421e1c | ||
|
|
42c58c5420 | ||
|
|
4afbdd9afb | ||
|
|
06b9e13904 | ||
|
|
29473b43cb | ||
|
|
0427d48b98 | ||
|
|
b228746f1d | ||
|
|
0be8485116 | ||
|
|
5d0279ff08 | ||
|
|
5d908d902c | ||
|
|
3a014f80f2 | ||
|
|
fbefd7855c | ||
|
|
11f9135be6 | ||
|
|
7bb0ce810e | ||
|
|
993b832771 | ||
|
|
013ac1e627 | ||
|
|
d7977a02fa | ||
|
|
73a32ff22c | ||
|
|
ee4ae5390b | ||
|
|
f71db11035 | ||
|
|
9497288b97 | ||
|
|
a00260d801 | ||
|
|
cad48e07e4 | ||
|
|
d91e8a4278 | ||
|
|
faf74eee90 | ||
|
|
0b52e1cd14 | ||
|
|
b62890f136 | ||
|
|
de1d37eef8 | ||
|
|
a57c557485 | ||
|
|
3c9f6c845b | ||
|
|
ff25e9a92e | ||
|
|
6a60f72a9e | ||
|
|
94b690df43 | ||
|
|
94edbc3436 | ||
|
|
5eab1e559a | ||
|
|
53db3ad6f2 | ||
|
|
581f3263ed | ||
|
|
1e3c642be6 | ||
|
|
22c3cd553f | ||
|
|
e5743f8dae | ||
|
|
bddc2f227d | ||
|
|
686c04ea93 | ||
|
|
b38369199e | ||
|
|
e862c904a9 | ||
|
|
43d9384b1c | ||
|
|
cb9af0b86a | ||
|
|
b8c17a843c | ||
|
|
7ad7f181d7 | ||
|
|
eb0bf55033 | ||
|
|
f4e3e4ad30 | ||
|
|
5ae82410cc | ||
|
|
2febb524e9 | ||
|
|
b9e452133c | ||
|
|
747ea0a1f7 | ||
|
|
f8c52ca34a | ||
|
|
663fd5a98b | ||
|
|
93e58bc15e | ||
|
|
3ccdf6508e | ||
|
|
fd33cf1ce5 | ||
|
|
2bb64ad1c6 | ||
|
|
e3de62058b | ||
|
|
6ee9984280 | ||
|
|
e1df548ae9 | ||
|
|
79a685c15e | ||
|
|
a61ab2803c | ||
|
|
209ad27332 | ||
|
|
df08981475 | ||
|
|
5ce6039a02 | ||
|
|
6c3fdf723a | ||
|
|
1a617c1eb2 | ||
|
|
3a9b801400 | ||
|
|
6e663acdad | ||
|
|
ae1023bb7a | ||
|
|
9cf25e276d | ||
|
|
8db3670ecc | ||
|
|
baee367532 | ||
|
|
8da4e72d87 | ||
|
|
b4a84a2317 | ||
|
|
43d6347212 | ||
|
|
438501e49c | ||
|
|
c034e99aaf | ||
|
|
d2d0ca2de9 | ||
|
|
cbe2b442b2 | ||
|
|
c5b1cd6e7d | ||
|
|
8d20d1dae3 | ||
|
|
1f2d702c4e | ||
|
|
d2d35d0553 | ||
|
|
1e7f54dd7e | ||
|
|
8430a2f7e6 | ||
|
|
326cde78e6 | ||
|
|
bbc2b0b42f | ||
|
|
231a2c54aa | ||
|
|
36ae4cee73 | ||
|
|
62e5ee2201 | ||
|
|
b89ebd931e | ||
|
|
d1b4ddaf61 | ||
|
|
734a0b236b | ||
|
|
2229c04d4d | ||
|
|
07cff27fa2 | ||
|
|
2cf86998bc | ||
|
|
6ed15a6fd6 | ||
|
|
7610243b0c | ||
|
|
e11349b577 | ||
|
|
9b425697cb | ||
|
|
42596ff91e | ||
|
|
b3c2ff47f3 | ||
|
|
75a0bc79be | ||
|
|
5a002ad08d | ||
|
|
fbac6f86d1 | ||
|
|
ca18bf2a3d | ||
|
|
199effdff7 | ||
|
|
8212f4b7fb | ||
|
|
e1a45a2720 | ||
|
|
bd7edd8651 | ||
|
|
4e1d10a46f | ||
|
|
70b6bc2bae | ||
|
|
46d019fe02 | ||
|
|
d56f689e15 | ||
|
|
90702b4102 | ||
|
|
0cf105b64a | ||
|
|
5c74d9458c | ||
|
|
75391bf834 | ||
|
|
63304a1d88 | ||
|
|
1ab79bd72e | ||
|
|
985bdf2b6c | ||
|
|
b57ea83aea | ||
|
|
d716e22476 | ||
|
|
bbb8e1ccab | ||
|
|
96f20779c6 | ||
|
|
908313e378 | ||
|
|
12e5c60633 | ||
|
|
11946ffc4c | ||
|
|
f44cd9c545 | ||
|
|
9c5ccb13de | ||
|
|
e9bcfd4784 | ||
|
|
fd1e8d4566 | ||
|
|
68dcce0739 | ||
|
|
3c554cd787 | ||
|
|
9e5f2269d9 | ||
|
|
81fc502c6c | ||
|
|
eda8ca5449 | ||
|
|
35dd8972e2 | ||
|
|
643dd56b74 | ||
|
|
b748eab4ed | ||
|
|
f4eaab6977 | ||
|
|
900c114831 | ||
|
|
7937b7e52d | ||
|
|
b40e707771 | ||
|
|
edde5c8516 | ||
|
|
197facb845 | ||
|
|
ca697d0d5d | ||
|
|
32ddf790d5 | ||
|
|
2cfba8c6d0 | ||
|
|
cf6c0765fa | ||
|
|
ad93f27271 | ||
|
|
92428e5cbc | ||
|
|
02c00a87dd | ||
|
|
6c77bc12c1 | ||
|
|
fbb428c249 | ||
|
|
854a741ea4 | ||
|
|
ed1952a79a | ||
|
|
39e8f5122f | ||
|
|
6ee77eb1a1 | ||
|
|
46fc45b952 | ||
|
|
79d90f3c7f | ||
|
|
eb41cb2261 | ||
|
|
87e8a9b6aa | ||
|
|
69f5aa8e35 | ||
|
|
d654f55c3c | ||
|
|
eb1689e79f | ||
|
|
cf6472df90 | ||
|
|
bc6295a78d | ||
|
|
ed5774b88f | ||
|
|
40a29ca9a7 | ||
|
|
a1e1838b11 | ||
|
|
4731dbab2f | ||
|
|
f2841ccb5e | ||
|
|
81a474fe12 | ||
|
|
5af2477d00 | ||
|
|
4cbba94a29 | ||
|
|
2a57428314 | ||
|
|
f9ac57205b | ||
|
|
3c6246f99a | ||
|
|
072e7bd241 | ||
|
|
4080dca816 | ||
|
|
c22fb80129 | ||
|
|
123fcd4bea | ||
|
|
e0c17672f2 | ||
|
|
53d484c5f4 | ||
|
|
a2ea767b77 | ||
|
|
4bd51a4be0 | ||
|
|
474f2dc267 | ||
|
|
033310234e | ||
|
|
10835c4b62 | ||
|
|
3e741df77b | ||
|
|
31d4b4a201 | ||
|
|
678985cbf5 | ||
|
|
e83e9cb6b3 | ||
|
|
48a51679b8 | ||
|
|
987fc925ee | ||
|
|
b6cbb23781 | ||
|
|
cbb9017c12 | ||
|
|
832d1e8d2c | ||
|
|
34af7f942b | ||
|
|
5f390c16be | ||
|
|
f36ac0498d | ||
|
|
18bdd9b665 | ||
|
|
5fd3852fd3 | ||
|
|
764432c77c | ||
|
|
55c43229ca | ||
|
|
dbc4daaaa4 | ||
|
|
acdbbec78d | ||
|
|
3247e777c0 | ||
|
|
c6e60ff3f5 | ||
|
|
b7df102919 | ||
|
|
f5d450b95c | ||
|
|
972aaf9f5f | ||
|
|
b98d5f30c0 | ||
|
|
d2e2e189d8 | ||
|
|
17d110575c | ||
|
|
a967976420 | ||
|
|
7e1e1ccccc | ||
|
|
502452602e | ||
|
|
f8ff46f3e3 | ||
|
|
8f572deaed | ||
|
|
601dd1d2b5 | ||
|
|
673e826e46 | ||
|
|
f1f81f9de2 | ||
|
|
8513c02ec1 | ||
|
|
320c5f1847 | ||
|
|
282f091e85 | ||
|
|
8647033029 | ||
|
|
3b88947cbe | ||
|
|
f05be0120e | ||
|
|
10c3b2fb5d | ||
|
|
74ae89865c | ||
|
|
a2445904e7 | ||
|
|
bd5188e7bc | ||
|
|
d89c119d9d | ||
|
|
802f3bed47 | ||
|
|
9c606a278d | ||
|
|
7aa5bc0503 | ||
|
|
d94b9fae94 | ||
|
|
05fcaaa758 | ||
|
|
9626a64340 | ||
|
|
c1cfd4db83 | ||
|
|
bfda91ac16 | ||
|
|
b7117b86ea | ||
|
|
a94059ad81 | ||
|
|
2cab87fbd0 | ||
|
|
2017100ff3 | ||
|
|
72cb29d36b | ||
|
|
a2b0d594fb | ||
|
|
a16d4ff1f3 | ||
|
|
305b1ecf2d | ||
|
|
3cc0cae249 | ||
|
|
137aa59254 | ||
|
|
5f8cb0dc54 | ||
|
|
45978474f3 | ||
|
|
75206c7a51 | ||
|
|
06ff0a45a7 | ||
|
|
c948d532a7 | ||
|
|
3825483f79 | ||
|
|
0b238d942e | ||
|
|
16b09a9dd3 | ||
|
|
4f6800b768 | ||
|
|
c84801adb3 | ||
|
|
69f990c1f8 | ||
|
|
8a83564678 | ||
|
|
43d93f836f | ||
|
|
7c2c0f7fe5 | ||
|
|
3ff47cf677 | ||
|
|
3165dce89e | ||
|
|
d4fad0a3b0 | ||
|
|
15fcaa794f | ||
|
|
6a1a505336 | ||
|
|
85937a7bfb | ||
|
|
3baa598b9e | ||
|
|
6f83b10af6 | ||
|
|
f52bcb49ab | ||
|
|
9cef8ff7ce | ||
|
|
a499ad6404 | ||
|
|
7c8767ab32 | ||
|
|
38a8559943 | ||
|
|
48c6acbc87 | ||
|
|
b5d93bc4a0 | ||
|
|
a9fffe771b | ||
|
|
69f3ab14b9 | ||
|
|
a7b9a34ec9 | ||
|
|
f45be1f59e | ||
|
|
012c2ba851 | ||
|
|
a0c2ce0068 | ||
|
|
86898035da | ||
|
|
05eeffe0f7 | ||
|
|
70cffce5eb | ||
|
|
0258e914e0 | ||
|
|
c35b81d2c5 | ||
|
|
fc63dcedb6 | ||
|
|
c879650c4b | ||
|
|
c4d019939b | ||
|
|
3841cc4aa5 | ||
|
|
468f2f2d2d | ||
|
|
be5db91c13 | ||
|
|
6e7d0a520a | ||
|
|
e37996873a | ||
|
|
25e851b570 | ||
|
|
d41b21a626 | ||
|
|
d65c54ba21 | ||
|
|
a5d3bf0f48 | ||
|
|
f76e8c7185 | ||
|
|
96145e8e3f | ||
|
|
530821fc4a | ||
|
|
e4a4a529dd | ||
|
|
863d1e0007 | ||
|
|
c64d6f2b36 | ||
|
|
a798880ac8 | ||
|
|
9db9be9612 | ||
|
|
6a19c77184 | ||
|
|
c17b9dea30 | ||
|
|
7564b6c69a | ||
|
|
5858c5041f | ||
|
|
18d0dec416 | ||
|
|
752046108c | ||
|
|
773ddbf5c4 | ||
|
|
88e90a6f3a | ||
|
|
84325d6b5c | ||
|
|
1b8e03e1de | ||
|
|
569d7297f0 | ||
|
|
d9520c9498 | ||
|
|
6b61093037 | ||
|
|
74b09d5581 | ||
|
|
08da8f6f5c | ||
|
|
7f8fffbb24 | ||
|
|
b08e5f9821 | ||
|
|
1758648f56 | ||
|
|
418ce0aed9 | ||
|
|
4e926076c9 | ||
|
|
3f0aaeba68 | ||
|
|
6ecec77a74 | ||
|
|
79917dc9bb | ||
|
|
b0b60fb761 | ||
|
|
7463152f50 | ||
|
|
cbd8217c60 | ||
|
|
4de1762c21 | ||
|
|
73962402df | ||
|
|
d90ccceec7 | ||
|
|
0c5ef1ce1d | ||
|
|
e5680e031d | ||
|
|
eee0cffa57 | ||
|
|
c480b0ba41 | ||
|
|
e7a47a647c | ||
|
|
500c82bbf8 | ||
|
|
008528af91 | ||
|
|
13199ad203 | ||
|
|
533dd1a54b | ||
|
|
b6f2e10416 | ||
|
|
c58db36a7c | ||
|
|
4593099882 | ||
|
|
21e29af48b | ||
|
|
892e44a900 | ||
|
|
bca29c2549 | ||
|
|
330e7f628c | ||
|
|
efe401c7a4 | ||
|
|
b3d88c043d | ||
|
|
edd36dac91 | ||
|
|
6de5fb2885 | ||
|
|
3b2ebafd83 | ||
|
|
dd4f508b77 | ||
|
|
3058a825b7 | ||
|
|
bdbeef3b9a | ||
|
|
8ead4a3c34 | ||
|
|
2d53a9b0dc | ||
|
|
8f47b46219 | ||
|
|
4f0d35bae0 | ||
|
|
de6d907e27 | ||
|
|
c9fc347de1 | ||
|
|
85e67f92c5 | ||
|
|
034a27ce5a | ||
|
|
056abb5901 | ||
|
|
af28406dbc | ||
|
|
376d6ba72c | ||
|
|
736a73453f | ||
|
|
6ced309c5c | ||
|
|
a30593efd6 | ||
|
|
3fa400bc55 | ||
|
|
90ea16325a | ||
|
|
be84a4332a | ||
|
|
cfeba859ac | ||
|
|
38ed7c9bb1 | ||
|
|
315ee90837 | ||
|
|
278574ce91 | ||
|
|
6c225d5469 | ||
|
|
d6a466ac0b | ||
|
|
58526d4faa | ||
|
|
3c90a82e75 | ||
|
|
06a27deebb | ||
|
|
f607f877c9 | ||
|
|
7273041314 | ||
|
|
997d041a84 | ||
|
|
226233ddce | ||
|
|
6c8edcbea5 | ||
|
|
e0f27bb855 | ||
|
|
4a14003f34 | ||
|
|
216a37348b | ||
|
|
ef7b2a9d4f | ||
|
|
ffb1cf4c7c | ||
|
|
964165eabe | ||
|
|
dca2d74eb6 | ||
|
|
e136ff52ab | ||
|
|
0df4944a7b | ||
|
|
2bb296df3b | ||
|
|
52380a3927 | ||
|
|
732f725a24 | ||
|
|
8887b16299 | ||
|
|
75c8b08d9b | ||
|
|
9741dc214d | ||
|
|
8b4b80c725 | ||
|
|
e3b6cccca1 | ||
|
|
d28ef1859d | ||
|
|
74b59f458d | ||
|
|
4ae04c2a9a | ||
|
|
7bd0789402 | ||
|
|
eb9fb9e834 | ||
|
|
c0ef0a7503 | ||
|
|
61719115e5 | ||
|
|
4a8cbe2ab8 | ||
|
|
c966f44189 | ||
|
|
193ef8b232 | ||
|
|
ad70a60d05 | ||
|
|
9dfd5b5526 | ||
|
|
09ec374eec | ||
|
|
8c1e9eda12 | ||
|
|
0eedd55dfd | ||
|
|
58c86d16f3 | ||
|
|
4a9170e981 | ||
|
|
b5b8ff01d5 | ||
|
|
6c86ffdeb7 | ||
|
|
70a1d92d9f | ||
|
|
0749477eb9 | ||
|
|
fb54341a1f | ||
|
|
db601d333b | ||
|
|
af1c2cccac | ||
|
|
bf1b76dcd2 | ||
|
|
48787ab460 | ||
|
|
7d4bf84304 | ||
|
|
5cf5d3e3a2 | ||
|
|
8ddb229447 | ||
|
|
9fdd96af61 | ||
|
|
7fbdd0607f | ||
|
|
0c0a1d8f12 | ||
|
|
30dd9ed267 | ||
|
|
5f0a1d55e5 | ||
|
|
17bef26708 | ||
|
|
58b5620f97 | ||
|
|
327b62ea45 | ||
|
|
91c6d693df | ||
|
|
aa3df3914b | ||
|
|
ad3a024b69 | ||
|
|
b9ec94264e | ||
|
|
fee9e91c4f | ||
|
|
1dc560d45a | ||
|
|
258e2b80f4 | ||
|
|
dcb889704d | ||
|
|
93096c27f9 | ||
|
|
3c6eba561f | ||
|
|
d2714f3338 | ||
|
|
b917db34c7 | ||
|
|
c45abaaa6b | ||
|
|
a2286cb00a | ||
|
|
481787d45c | ||
|
|
756002eef8 | ||
|
|
6789919fca | ||
|
|
d8c615ec65 | ||
|
|
6a1eb0e508 | ||
|
|
984b0260d5 | ||
|
|
785e59e889 | ||
|
|
671be5b191 | ||
|
|
b4e556e63a | ||
|
|
2128943b57 | ||
|
|
6ddb1094b6 | ||
|
|
b9d93b19d4 | ||
|
|
97a5da232d | ||
|
|
0d77af5366 | ||
|
|
a3435f2d22 | ||
|
|
154dd46b6d | ||
|
|
782952d55d | ||
|
|
a6bd293ae8 | ||
|
|
decd112a84 | ||
|
|
f9c15fa0a5 | ||
|
|
1121f2a1fb | ||
|
|
a7989eb79f | ||
|
|
80c199cefb | ||
|
|
317f92f4c8 | ||
|
|
dd344710d4 | ||
|
|
e4e8683c7b | ||
|
|
b2407352a9 | ||
|
|
e1b5e3e112 | ||
|
|
09793d295f | ||
|
|
e9f8c01e04 | ||
|
|
f69821d7db | ||
|
|
1e03219ca3 | ||
|
|
de8b4438e3 | ||
|
|
2cfd3330f0 | ||
|
|
1988b432ab | ||
|
|
6b2363d3f6 | ||
|
|
e76af56c86 | ||
|
|
b7173a3ae2 | ||
|
|
3f71517e1f | ||
|
|
17fbe52cf6 | ||
|
|
ecc526a9d8 | ||
|
|
436f4aa953 | ||
|
|
fd10ce0600 | ||
|
|
d9cd40eb48 | ||
|
|
9b9ab16b55 | ||
|
|
14256e7a90 | ||
|
|
d36c387c1f | ||
|
|
7e61b172b2 | ||
|
|
bd0cae9298 | ||
|
|
6ae94581bb | ||
|
|
ea8ae2bf2c | ||
|
|
694bc3312e | ||
|
|
f565939437 | ||
|
|
272d2747cd | ||
|
|
675956c92d | ||
|
|
03410ed4a2 | ||
|
|
ac88e7fabf | ||
|
|
71d42d7e73 | ||
|
|
2613762ac2 | ||
|
|
831b21cd39 | ||
|
|
7869d80073 | ||
|
|
ea39d80e83 | ||
|
|
62e481a608 | ||
|
|
bac7148d69 | ||
|
|
62f16a3c4b | ||
|
|
248ecd54e4 | ||
|
|
1f59accb4e | ||
|
|
dd7e4375cf | ||
|
|
3df3999138 | ||
|
|
1ca6443c9d | ||
|
|
a804cb5d07 | ||
|
|
a0883c9615 | ||
|
|
03c968a8fe | ||
|
|
e34de22cf4 | ||
|
|
3db1f1e01f | ||
|
|
5e467c737f | ||
|
|
dfc42fa7c5 | ||
|
|
f1016e82c7 | ||
|
|
5e099a5dbd | ||
|
|
8dceec9316 | ||
|
|
6f51092998 | ||
|
|
4e83ca67f5 | ||
|
|
76e6c6f8ea | ||
|
|
343a529e63 | ||
|
|
c6ccc68607 | ||
|
|
8009f4a6ee | ||
|
|
e126cecb16 | ||
|
|
5e19202540 | ||
|
|
06466bac0e | ||
|
|
156edcacb2 | ||
|
|
bf4b8d246a | ||
|
|
abc37ec35e | ||
|
|
dd735464a2 | ||
|
|
7041bdb144 | ||
|
|
19e8c3fcb6 | ||
|
|
06c5135d4e | ||
|
|
f66066cbd8 | ||
|
|
a144622a06 | ||
|
|
05c814b8c1 | ||
|
|
e0af51fb06 | ||
|
|
7b749558df | ||
|
|
1797c3c617 | ||
|
|
28a1c28cb4 | ||
|
|
20fcbb9c62 | ||
|
|
7c9c97f2b9 | ||
|
|
d72e121fd4 | ||
|
|
003fc3dab5 | ||
|
|
2c883d7cdc | ||
|
|
fcba49768c | ||
|
|
959af9c3af | ||
|
|
1edacf05e9 | ||
|
|
1f756fb386 | ||
|
|
5ebdc01783 | ||
|
|
aa29201e00 | ||
|
|
b98acdf97a | ||
|
|
7aeb4788ed | ||
|
|
7b1db40d4a | ||
|
|
dcaa90a855 | ||
|
|
0a74efe3f8 | ||
|
|
5a73134c7c | ||
|
|
43d535cf8d | ||
|
|
4a71edf7bc | ||
|
|
ae90040ed2 | ||
|
|
fbf982f001 | ||
|
|
839e3ac775 | ||
|
|
65d230f32b | ||
|
|
0882b0db0c | ||
|
|
3d92c1fb32 | ||
|
|
d4e679432c | ||
|
|
54c8cb9fd7 | ||
|
|
221ee1a122 | ||
|
|
2b29f90c92 | ||
|
|
d7ec0e570f | ||
|
|
86c2144943 | ||
|
|
ee85230db2 | ||
|
|
fde99a8dc1 | ||
|
|
2e692a1146 | ||
|
|
73f36fb5b3 | ||
|
|
f866ad52dc | ||
|
|
9566910574 | ||
|
|
4188d4d10b | ||
|
|
d75152cb74 | ||
|
|
add54b8089 | ||
|
|
7431495f13 | ||
|
|
5ed5566106 | ||
|
|
2d9a4412a4 | ||
|
|
982abd5719 | ||
|
|
f09db0cbe5 | ||
|
|
80cacc462e | ||
|
|
1a2b2f8870 | ||
|
|
e8c576047f | ||
|
|
995d3152eb | ||
|
|
ddc40cc273 | ||
|
|
5ee311b831 | ||
|
|
ea90296e22 | ||
|
|
58c1a8d148 | ||
|
|
87a19c7938 | ||
|
|
5b0709de2f | ||
|
|
87db37c65e | ||
|
|
100db13f99 | ||
|
|
d2061b27a2 | ||
|
|
002dfb9b84 | ||
|
|
0ab1241f09 | ||
|
|
aa63656ff1 | ||
|
|
6ba32da73a | ||
|
|
1129e71069 | ||
|
|
3b32fd5c49 | ||
|
|
7df1ed271f | ||
|
|
67e9b40bab | ||
|
|
62b80903f0 | ||
|
|
993d917478 | ||
|
|
ac20880a14 | ||
|
|
99cfe05ee5 | ||
|
|
7c187e82b7 | ||
|
|
2a760660a9 | ||
|
|
4b11826a7d | ||
|
|
887f586874 | ||
|
|
db94c04179 | ||
|
|
51e64c69f3 | ||
|
|
97c46843d2 | ||
|
|
16310c91c9 | ||
|
|
220e421c22 | ||
|
|
a156752fae | ||
|
|
5d1c574dc5 | ||
|
|
6310c20217 | ||
|
|
0dfc30fdd8 | ||
|
|
f050571696 | ||
|
|
6db5bc3721 | ||
|
|
4f84c281ef | ||
|
|
0ca438e081 | ||
|
|
2472aee473 | ||
|
|
714856f74c | ||
|
|
e98932df92 | ||
|
|
95623dac63 | ||
|
|
827015a8e3 | ||
|
|
a379818386 | ||
|
|
4516e4e9f6 | ||
|
|
83e44961fc | ||
|
|
bc2e959897 | ||
|
|
1b0b4ba416 | ||
|
|
25a0752e58 | ||
|
|
b0a7e0bbcc | ||
|
|
af561abc71 | ||
|
|
3bf323aa2b | ||
|
|
c9a33c638a | ||
|
|
8d1042859d | ||
|
|
9072571fc1 | ||
|
|
d8748b8216 | ||
|
|
2f930b201a | ||
|
|
26b4195f1f | ||
|
|
5c078d13c0 | ||
|
|
2825ac282a | ||
|
|
cd31a79f41 | ||
|
|
52eb9f46d2 | ||
|
|
08c430dcfb | ||
|
|
b486aeeac5 | ||
|
|
13da6102b3 | ||
|
|
1e1c4e017e | ||
|
|
ceaaab5a86 | ||
|
|
2b7d03d4f9 | ||
|
|
c8810557c1 | ||
|
|
2a4bfe49f5 | ||
|
|
b71879e90e | ||
|
|
63ae262752 | ||
|
|
2c3a4fef26 | ||
|
|
e696e32b95 | ||
|
|
3f9df49e3e | ||
|
|
1ac3d3c5a6 | ||
|
|
b3d1aade71 | ||
|
|
c300c723f7 | ||
|
|
d0ec069dcb | ||
|
|
6811406b24 | ||
|
|
0879994aff | ||
|
|
b2b5ccf69c | ||
|
|
6f5d4fbf30 | ||
|
|
8ad1ea499d | ||
|
|
4df17abea7 | ||
|
|
972c8a97dc | ||
|
|
135d17fbd3 | ||
|
|
095b2a8926 | ||
|
|
297677c2c6 | ||
|
|
2a00f23459 | ||
|
|
68ad916a91 | ||
|
|
0f3883152b | ||
|
|
60baee4020 | ||
|
|
5a7ff4780f | ||
|
|
dd2845401c | ||
|
|
a47c947065 | ||
|
|
203ac51681 | ||
|
|
a7986993bf | ||
|
|
ce59d40570 | ||
|
|
19f33e22d7 | ||
|
|
7d818e18be | ||
|
|
52af0aceea | ||
|
|
cd1cf6f615 | ||
|
|
2f925aeb22 | ||
|
|
f99b42da5e | ||
|
|
40beef061f | ||
|
|
f0a434c167 | ||
|
|
92b66dbf17 | ||
|
|
f336261d6b | ||
|
|
c6324b83ea | ||
|
|
54873992ab | ||
|
|
38d568a807 | ||
|
|
dcef1212c6 | ||
|
|
2030b70ff8 | ||
|
|
41a188eaec | ||
|
|
f3ddaf455c | ||
|
|
aa979e4bc7 | ||
|
|
baddc56f01 | ||
|
|
9836e43d10 | ||
|
|
c8cecd9f46 | ||
|
|
38c59a44de | ||
|
|
fddc86c2b1 | ||
|
|
0dddc9b5cb | ||
|
|
8b14bd4e87 | ||
|
|
5c77969e83 | ||
|
|
e049596252 | ||
|
|
afa1327242 | ||
|
|
da3b7f5a41 | ||
|
|
100f61ee24 | ||
|
|
dcd2794ff5 | ||
|
|
8d1d3fe12b | ||
|
|
87ae0f058a | ||
|
|
7e1be6625f | ||
|
|
0c6fcd1678 | ||
|
|
37ac46273d | ||
|
|
1e21416ccb | ||
|
|
e2353959c1 | ||
|
|
61d3d5b068 | ||
|
|
572e5ed9c6 | ||
|
|
4dbfa2febb | ||
|
|
0293d2027d | ||
|
|
c28b94890c | ||
|
|
63a910d2fc | ||
|
|
fbef5c6a6a | ||
|
|
674b6e9f43 | ||
|
|
7897b6ad55 | ||
|
|
6769b54e1c | ||
|
|
734ab4429f | ||
|
|
5db6a64f3f | ||
|
|
dcc458ea94 | ||
|
|
7354e7e3c9 | ||
|
|
07ef765f7e | ||
|
|
c58ad8b593 | ||
|
|
31091c1053 | ||
|
|
59659a7184 | ||
|
|
e6de17e72e | ||
|
|
0457bdc7ce | ||
|
|
7e54c2735c | ||
|
|
7bcc58687f | ||
|
|
6a03df7b8d | ||
|
|
7ee5a8065c | ||
|
|
2f2353765f | ||
|
|
8b4c2f5093 | ||
|
|
d80662a9ba | ||
|
|
68c5c72dbc | ||
|
|
b460cbc91a | ||
|
|
f7939078c2 | ||
|
|
e103af3b93 | ||
|
|
45bec06d5b | ||
|
|
c82efe7621 | ||
|
|
ba85dbf526 | ||
|
|
e624e87b29 | ||
|
|
6ff8d0953f | ||
|
|
9f2fcdf0b3 | ||
|
|
cecb9bfe32 | ||
|
|
6a989d844a | ||
|
|
318b3115a8 | ||
|
|
017952e89e | ||
|
|
b0c74e1b66 | ||
|
|
a190086504 | ||
|
|
84704d1cc2 | ||
|
|
b1ef8bbc5a | ||
|
|
f19a6343dd | ||
|
|
23d0d7d4a4 | ||
|
|
ed7bc28c21 | ||
|
|
05dcb160bd | ||
|
|
e49155ff90 | ||
|
|
265525e472 | ||
|
|
d4dcbfa90b | ||
|
|
6724673482 | ||
|
|
d04f75df29 | ||
|
|
a5260f4233 | ||
|
|
369ca5cb72 | ||
|
|
a3e02cbafa | ||
|
|
4cca2f6915 | ||
|
|
64ca48c4b1 | ||
|
|
74a897271f | ||
|
|
c95f9f5e6a | ||
|
|
93c3eb064d | ||
|
|
b13162c5bf | ||
|
|
ee1725684a | ||
|
|
c6733a6eec | ||
|
|
f7e99678b4 | ||
|
|
976b68ffec | ||
|
|
a07b234659 | ||
|
|
7b656fb009 | ||
|
|
20331d52c3 | ||
|
|
2556acb82d | ||
|
|
248f0948b8 | ||
|
|
6c12db500e | ||
|
|
2a8f4dbbb6 | ||
|
|
91598d5178 | ||
|
|
a6bb9739d4 | ||
|
|
aa871c797b | ||
|
|
153d20ca59 | ||
|
|
03b04771be | ||
|
|
392fa62dae | ||
|
|
af3918491c | ||
|
|
c0762bbd82 | ||
|
|
b68272b413 | ||
|
|
90b9414b5f | ||
|
|
5db494d4f7 | ||
|
|
d073066293 | ||
|
|
e80270ae43 | ||
|
|
cd56b85e88 | ||
|
|
64fbf55bdd | ||
|
|
14c1ee10b6 | ||
|
|
96ae671738 | ||
|
|
16552d1194 | ||
|
|
6470c98ee2 | ||
|
|
126c4efa0e | ||
|
|
f6fd9e18d9 | ||
|
|
1f554867e0 | ||
|
|
d226331ccc | ||
|
|
123f8c93b5 | ||
|
|
6e93b0a9df | ||
|
|
a5d6d8c928 | ||
|
|
561ee6601b | ||
|
|
f44a7c95f6 | ||
|
|
ac420347d1 | ||
|
|
493a7ccdb6 | ||
|
|
387db78120 | ||
|
|
1338a99add | ||
|
|
f9edd20bf6 | ||
|
|
6b3c7319c4 | ||
|
|
bf51fc7c36 | ||
|
|
e910a81c12 | ||
|
|
027bd93df9 | ||
|
|
57c0d0f25e | ||
|
|
24ff6bfde5 | ||
|
|
78770683fc | ||
|
|
c0008af877 | ||
|
|
bffb81241a | ||
|
|
53ff6d54c3 | ||
|
|
2278e3334e | ||
|
|
b0c61e2b69 | ||
|
|
a402c308ad | ||
|
|
6d83a195c6 | ||
|
|
0d69e88d53 | ||
|
|
7309a5c3e1 | ||
|
|
9e3c7aa9b3 | ||
|
|
30fb992cf7 | ||
|
|
8e5db99ba1 | ||
|
|
8103cdbec4 | ||
|
|
b11835aab5 | ||
|
|
5b855d9baf | ||
|
|
56b6b96def | ||
|
|
3744cad3d8 | ||
|
|
bf8b5ed9ad | ||
|
|
49482fe963 | ||
|
|
3497870a45 | ||
|
|
9a1efacefe | ||
|
|
3efb2379ee | ||
|
|
20efadbe66 | ||
|
|
31f8abfa61 | ||
|
|
cf4cc71010 | ||
|
|
44107757a3 | ||
|
|
45ba1af388 | ||
|
|
ba9884a26a | ||
|
|
a40d53497b | ||
|
|
261b7f1110 | ||
|
|
c604893944 | ||
|
|
2f16d25ab8 | ||
|
|
132de3160a | ||
|
|
d67b1645c9 | ||
|
|
68270ad425 | ||
|
|
963a8c2f08 | ||
|
|
a80581e52b | ||
|
|
882cdaaeda | ||
|
|
fd58f17dbe | ||
|
|
7e5c0d7174 | ||
|
|
525462e982 | ||
|
|
507b3a69f0 | ||
|
|
b15e49910a | ||
|
|
573d0858ac | ||
|
|
c3c2789cdf | ||
|
|
e9f14e32dd | ||
|
|
9b65d819f4 | ||
|
|
287344986c | ||
|
|
7386b4b037 | ||
|
|
9a2f62c479 | ||
|
|
726656d0bf | ||
|
|
fe61aabc52 | ||
|
|
564e966730 | ||
|
|
98abfa4395 | ||
|
|
8e6fbe7615 | ||
|
|
27fd5505be | ||
|
|
e383cc89eb | ||
|
|
a71a0ed137 | ||
|
|
ab6fc279ce | ||
|
|
dd5c17291a | ||
|
|
5fe06b7413 | ||
|
|
2a8efa9891 | ||
|
|
cf43e5eaaf | ||
|
|
cafc906b9e | ||
|
|
3387f51e24 | ||
|
|
ccf1bb26af | ||
|
|
fc1ca01a0b | ||
|
|
e508f0900c | ||
|
|
5123ca52ba | ||
|
|
7e1ee5bb07 | ||
|
|
b7ac641aa0 | ||
|
|
251ac145d9 | ||
|
|
e17c2c8c73 | ||
|
|
4473054d33 | ||
|
|
5267cde60e | ||
|
|
3c7ece2ef3 | ||
|
|
3b322d8f37 | ||
|
|
1d4b6c6a74 | ||
|
|
f5efe1d251 | ||
|
|
09db3aba0a | ||
|
|
aec7deca9d | ||
|
|
8f1d4bc710 | ||
|
|
7edc8417b6 | ||
|
|
5b01682641 | ||
|
|
a615f8970a | ||
|
|
708ea9d50a | ||
|
|
e36a64ecc0 | ||
|
|
82be09b6a3 | ||
|
|
eb7655d93c | ||
|
|
c1fe841bf3 | ||
|
|
82ffb379c4 | ||
|
|
befae52993 | ||
|
|
48597d7682 | ||
|
|
05d45ccb7f | ||
|
|
e0ca04bfec | ||
|
|
34566861ba | ||
|
|
dfe3b4502a | ||
|
|
4884aeef20 | ||
|
|
219ab44a82 | ||
|
|
29fccd0e1b | ||
|
|
35e4ac5a64 | ||
|
|
43bba77840 | ||
|
|
0361274366 | ||
|
|
5b0e703811 | ||
|
|
05742a8e28 | ||
|
|
170fbb596c | ||
|
|
b72bdf9948 | ||
|
|
678e03b470 | ||
|
|
0f45f3a24d | ||
|
|
9b503f3702 | ||
|
|
7f3f619518 | ||
|
|
f7d59880cc | ||
|
|
ec9e266c3c | ||
|
|
ed62c02494 | ||
|
|
d5b166bdd9 | ||
|
|
648c726bb1 | ||
|
|
88f30afb26 | ||
|
|
e6f319d6b3 | ||
|
|
a80d8b15c2 | ||
|
|
2a372895e4 | ||
|
|
3b67e573b5 | ||
|
|
a3a55d19b8 | ||
|
|
4e25bce616 | ||
|
|
135477e539 | ||
|
|
147b1f2293 | ||
|
|
401dc69586 | ||
|
|
0dff992fab | ||
|
|
4f605739f1 | ||
|
|
e71e10adcb | ||
|
|
9f1bc05644 | ||
|
|
603878b3e9 | ||
|
|
70ce323537 | ||
|
|
b5f8dd93f7 | ||
|
|
2e7b86e452 | ||
|
|
b2eeaf75a9 | ||
|
|
5d4bddcfb9 | ||
|
|
13ef676115 | ||
|
|
67bfd3877c | ||
|
|
2be619b011 | ||
|
|
ebd0a3ceaf | ||
|
|
d8da14d550 | ||
|
|
076c156cbb | ||
|
|
6eaaab8dc2 | ||
|
|
46bc8e499a | ||
|
|
21865d09a2 | ||
|
|
31903d0c0b | ||
|
|
c7b7cbcac1 | ||
|
|
d0af858a9c | ||
|
|
2e5c6283f5 | ||
|
|
261df26cff | ||
|
|
96bd6ce3e5 | ||
|
|
14eed89bb6 | ||
|
|
3feb354186 | ||
|
|
d41cb3b69d | ||
|
|
cdef1ed0c5 | ||
|
|
4f79acc32a | ||
|
|
9328b099c3 | ||
|
|
378d0351cf | ||
|
|
793e3adbb4 | ||
|
|
2f4f4253e7 | ||
|
|
10c69d561e | ||
|
|
bbf6e8e0c5 | ||
|
|
d8a4d03501 | ||
|
|
8ecc8ef75d | ||
|
|
cfd4318080 | ||
|
|
d23bb01e96 | ||
|
|
60f63ca467 | ||
|
|
40378cd4d8 | ||
|
|
f44af48751 | ||
|
|
d01a48b773 | ||
|
|
bd136eae71 | ||
|
|
e669370629 | ||
|
|
26215d5425 | ||
|
|
baa5c6f79b | ||
|
|
c0fcb27aa5 | ||
|
|
02b7938b93 | ||
|
|
00fec3d51f | ||
|
|
0f6ceaac05 | ||
|
|
635816c07f | ||
|
|
2fac5c23ff | ||
|
|
ff4c1cf0d5 | ||
|
|
c2e2d1e92f | ||
|
|
0ab56bad95 | ||
|
|
407c5a0f78 | ||
|
|
3ba84ad06a | ||
|
|
c6aae9e05a | ||
|
|
95b4618833 | ||
|
|
1fe17d55d9 | ||
|
|
ead73371d9 | ||
|
|
6f089a4323 | ||
|
|
640f024551 | ||
|
|
99920f89dd | ||
|
|
8ea276267f | ||
|
|
6ebbd91245 | ||
|
|
fa0a54deb9 | ||
|
|
046043090f | ||
|
|
61150a18cc | ||
|
|
95ca20cfee | ||
|
|
5a536d47fd | ||
|
|
afbc7da027 | ||
|
|
c093c08c40 | ||
|
|
360d8c629e | ||
|
|
abb41d39e4 | ||
|
|
d4eb4ef594 | ||
|
|
02f45854e8 | ||
|
|
62de1004df | ||
|
|
7f216ca02f | ||
|
|
492b0fdda8 | ||
|
|
bb072c0112 | ||
|
|
afabe7cb47 | ||
|
|
38e0fc2434 | ||
|
|
16a70eafc6 | ||
|
|
de4becc26e | ||
|
|
af23f4325f | ||
|
|
94af96df8f | ||
|
|
e685ab818e | ||
|
|
5f2a72b65b | ||
|
|
c1842a6167 | ||
|
|
3f3907b5d1 | ||
|
|
1899465390 | ||
|
|
18360d4ccb | ||
|
|
a691c3cd99 | ||
|
|
70bc561bbf | ||
|
|
b9222d8431 | ||
|
|
a5fad89e57 | ||
|
|
a14360b89d | ||
|
|
c9aaedd217 | ||
|
|
cda15ce9ea | ||
|
|
3f3b6ad337 | ||
|
|
62410c4381 | ||
|
|
cf82b56dd8 | ||
|
|
4a74bea7ab | ||
|
|
c6d8e60ef8 | ||
|
|
1212cd526a | ||
|
|
79a8ed53b6 | ||
|
|
a6ce115d9c | ||
|
|
646a5a7f9e | ||
|
|
7f71b6f1b2 | ||
|
|
16d5ca447f | ||
|
|
3d0c20a263 | ||
|
|
1c38b8b046 | ||
|
|
e1124480be | ||
|
|
5243f50ed1 | ||
|
|
cde805147f | ||
|
|
7e39eb3df2 | ||
|
|
af366d4480 | ||
|
|
33ef98aae7 | ||
|
|
c16db2db4a | ||
|
|
059d980c33 | ||
|
|
581381fd86 | ||
|
|
0072b289bb | ||
|
|
e2bd79087e | ||
|
|
6cd78fc90d | ||
|
|
c346aca241 | ||
|
|
bf83569f0b | ||
|
|
1502f04a8a | ||
|
|
7bd9d0ae23 | ||
|
|
cf57afdf26 | ||
|
|
43e6aebc7a | ||
|
|
22780993e1 | ||
|
|
578dcee9af | ||
|
|
61d77e3f9b | ||
|
|
4ce0acba80 | ||
|
|
d137212222 | ||
|
|
9ad4e3a6a0 | ||
|
|
57627d4fcf | ||
|
|
23b69271eb | ||
|
|
9d2f557666 | ||
|
|
4f9e352ff0 | ||
|
|
3e85e60a30 | ||
|
|
febce21b21 | ||
|
|
755364e2df | ||
|
|
df63979773 | ||
|
|
992d86bbc1 | ||
|
|
534b338161 | ||
|
|
ef250f936c | ||
|
|
e57130e364 | ||
|
|
eedcb35270 | ||
|
|
1eb470083c | ||
|
|
1f15a4e35b | ||
|
|
7ed9bea16b | ||
|
|
8b1383d235 | ||
|
|
a73fab3bb5 | ||
|
|
7bd64d9c53 | ||
|
|
1786c2f157 | ||
|
|
958b671736 | ||
|
|
6549b66cf6 | ||
|
|
0c855a5ce3 | ||
|
|
6864d48dcf | ||
|
|
99816a23a8 | ||
|
|
2ff9546523 | ||
|
|
06541f21d6 | ||
|
|
45a37edd4a | ||
|
|
2a713a1f51 | ||
|
|
3e104de377 | ||
|
|
b22b316e70 | ||
|
|
df461546c5 | ||
|
|
1c1c43cd86 | ||
|
|
3eac9f937e | ||
|
|
f13a0d8e84 | ||
|
|
ca12dc9213 | ||
|
|
365ed2cd70 | ||
|
|
7efbfed0bf | ||
|
|
ed502738c6 | ||
|
|
ba162bb058 | ||
|
|
f194d35913 | ||
|
|
e81c84e00a | ||
|
|
68dc9030bc | ||
|
|
fedad275e7 | ||
|
|
f6b4c76d76 | ||
|
|
27854aa091 | ||
|
|
d966ae145e | ||
|
|
4cb37e6a1b | ||
|
|
d9da81e99b | ||
|
|
7d734740be | ||
|
|
06299cca4b | ||
|
|
af5aaab38b | ||
|
|
77bb01d384 | ||
|
|
a9eb1bd4e6 | ||
|
|
83ef2da95f | ||
|
|
ba13ccadb8 | ||
|
|
4a2dee873d | ||
|
|
589906e6e6 | ||
|
|
f0fcf6d9e6 | ||
|
|
1591ced5a7 | ||
|
|
0d235d63d0 | ||
|
|
820d5c1447 | ||
|
|
8093e8f5f1 | ||
|
|
802857e411 | ||
|
|
bf3a1839a2 | ||
|
|
ad7844d7da | ||
|
|
3ff9128a8a | ||
|
|
c865eb98ea | ||
|
|
217a9228f8 | ||
|
|
105d0a36ad | ||
|
|
263279d5dd | ||
|
|
861ecbec0f | ||
|
|
5ff9bb3669 | ||
|
|
e794584bb5 | ||
|
|
a792dd0703 | ||
|
|
a9a6a645bf | ||
|
|
7c93becd5f | ||
|
|
4bbaef58e9 | ||
|
|
95791a985a | ||
|
|
0dfefe9730 | ||
|
|
8481c797df | ||
|
|
a503b5e20b | ||
|
|
4078840ef1 | ||
|
|
ab51958b26 | ||
|
|
3376587b6a | ||
|
|
6681d7dcf9 | ||
|
|
34224481c6 | ||
|
|
1837aaabe4 | ||
|
|
5811914a78 | ||
|
|
a109a4efa1 | ||
|
|
a08a6ce5de | ||
|
|
3dc8a3ddc1 | ||
|
|
5e103365f7 | ||
|
|
cdea8d7f74 | ||
|
|
ef6dc3d802 | ||
|
|
e6edb349ba | ||
|
|
ad132267ec | ||
|
|
6f837281ef | ||
|
|
2a1d29d2df | ||
|
|
bdceb4ca89 | ||
|
|
656bb928cf | ||
|
|
0fbe69ebcf | ||
|
|
ece817c691 | ||
|
|
3fbc8204b7 | ||
|
|
44a5481254 | ||
|
|
cf2ff90f87 | ||
|
|
b8dd5d95b0 | ||
|
|
7cd52febc2 | ||
|
|
8e079c1965 | ||
|
|
4928af5a64 | ||
|
|
289df740cd | ||
|
|
6ad7392cd7 | ||
|
|
b15d5f299c | ||
|
|
5c7c959dd9 | ||
|
|
6927c7577a | ||
|
|
88682a457a | ||
|
|
61ae53cc03 | ||
|
|
0e67f30103 | ||
|
|
babd6e9a7b | ||
|
|
76caa2c6e3 | ||
|
|
dc9f8aa855 | ||
|
|
ded8b3284a | ||
|
|
2e24ee7a5f | ||
|
|
048ae597d2 | ||
|
|
0147f7aa19 | ||
|
|
23cda2c961 | ||
|
|
feb67658e1 | ||
|
|
65ee1fafa8 | ||
|
|
49f8332c5b | ||
|
|
afce108ed7 | ||
|
|
30f3b545af | ||
|
|
bf1597920c | ||
|
|
f66bf3811e | ||
|
|
a01e29ac99 | ||
|
|
3136a5e2f8 | ||
|
|
c4f00a05df | ||
|
|
e9a8f8a9ff | ||
|
|
261ae7a195 | ||
|
|
7eaf5ae9e0 | ||
|
|
10a02449b1 | ||
|
|
debc57e8c7 | ||
|
|
7a4fff8e5b | ||
|
|
ec0a2a8671 | ||
|
|
b8b516f7b6 | ||
|
|
3b1e91b1fc | ||
|
|
8532593d91 | ||
|
|
55bd16e2c8 | ||
|
|
c7797d56c9 | ||
|
|
9b573effd1 | ||
|
|
dfd1aedae5 | ||
|
|
221ae2d7b4 | ||
|
|
9127d206b5 | ||
|
|
ecc6fea54e | ||
|
|
99446da7c1 | ||
|
|
ad75563a26 | ||
|
|
197af972d9 | ||
|
|
fbd706c191 | ||
|
|
6b85fa5611 | ||
|
|
fae66a921f | ||
|
|
e6fc462e9d | ||
|
|
d11a265a53 | ||
|
|
395d870814 | ||
|
|
fec1ffaa6b | ||
|
|
d4fdb28e72 | ||
|
|
39a5c2021e | ||
|
|
f41501444d | ||
|
|
86b26b80ce | ||
|
|
ae9a5b1125 | ||
|
|
38579807c2 | ||
|
|
c19119bcd6 | ||
|
|
47f1ad693d | ||
|
|
2164d7bb96 | ||
|
|
c326e2d669 | ||
|
|
8eaf45414c | ||
|
|
b3297d106e | ||
|
|
2d0e19e6a7 | ||
|
|
fd2ee4dc46 | ||
|
|
b1bbc37c59 | ||
|
|
56409d4f2b | ||
|
|
ec0683b729 | ||
|
|
89e5041e70 | ||
|
|
8b3e7312e0 | ||
|
|
3c76a9176d | ||
|
|
a37def2c22 | ||
|
|
ee4ef0fe87 | ||
|
|
1dff7073de | ||
|
|
92a82c3134 | ||
|
|
a6a203c483 | ||
|
|
cdaa65f6fd | ||
|
|
31e5f706b8 | ||
|
|
00e05558ce | ||
|
|
c02b88baff | ||
|
|
794c80edad | ||
|
|
fb939600e2 | ||
|
|
9dbbd44d09 | ||
|
|
afcd93fe5f | ||
|
|
118faa5380 | ||
|
|
7ed17f68c5 | ||
|
|
96363143de | ||
|
|
cf5fcb2371 | ||
|
|
7d3699050e | ||
|
|
40e0a71f49 | ||
|
|
cdbcdfe397 | ||
|
|
4f2d2e646e | ||
|
|
f97cd24647 | ||
|
|
e5e75ad1ef | ||
|
|
fc052efb91 | ||
|
|
c5754145c5 | ||
|
|
9986e69622 | ||
|
|
00acf4d327 | ||
|
|
00ff549044 | ||
|
|
75a39c8939 | ||
|
|
5b9354cc74 | ||
|
|
f7049a6478 | ||
|
|
e1d032b5a6 | ||
|
|
f99691b0eb | ||
|
|
10d18f2f17 | ||
|
|
a236700c55 | ||
|
|
34d62fcea6 | ||
|
|
791502afef | ||
|
|
99114e1fc2 | ||
|
|
3c8bb53d1a | ||
|
|
bd0682b518 | ||
|
|
e89a913b69 | ||
|
|
293d77d412 | ||
|
|
6beb4b0f8b | ||
|
|
23a8462688 | ||
|
|
02f90fbc66 | ||
|
|
8cc23d0cf8 | ||
|
|
60b5b1414d | ||
|
|
cbab344822 | ||
|
|
32764ddf81 | ||
|
|
e31127e39e | ||
|
|
735f537846 | ||
|
|
b7790e10e9 | ||
|
|
3f7ad04054 | ||
|
|
670ddf9cd8 | ||
|
|
d377e26106 | ||
|
|
674f939690 | ||
|
|
64abfb1afe | ||
|
|
adcefe62cf | ||
|
|
bf77fa4275 | ||
|
|
e7fce2de40 | ||
|
|
8864637602 | ||
|
|
1a0d97d5f7 | ||
|
|
9ba46e395d | ||
|
|
be99fa0b05 | ||
|
|
c42b1858c5 | ||
|
|
cc11de16bf | ||
|
|
3ea7c2b014 | ||
|
|
e0e9f5aa16 | ||
|
|
63a2d1e1db | ||
|
|
644263a764 | ||
|
|
f912295690 | ||
|
|
79e57c320c | ||
|
|
4e6f183f77 | ||
|
|
23017af874 | ||
|
|
4d02126b77 | ||
|
|
30fefbd57d | ||
|
|
38304fa63a | ||
|
|
6525b8dd14 | ||
|
|
0155719b1a | ||
|
|
966dce6e95 | ||
|
|
e3088686db | ||
|
|
771162cf14 | ||
|
|
1a2398d2ce | ||
|
|
0f0e969d8f | ||
|
|
c8371087e6 | ||
|
|
3da6fc3972 | ||
|
|
0cbbd91e72 | ||
|
|
d71aca9e9b | ||
|
|
63035fd5f3 | ||
|
|
0fe28129a0 | ||
|
|
c44d8eed35 | ||
|
|
6f5588f71e | ||
|
|
68f8c244b4 | ||
|
|
d7a08fc7d4 | ||
|
|
572d6e0395 | ||
|
|
156b6745a2 | ||
|
|
b4eb38e2b7 | ||
|
|
bafcc8762b | ||
|
|
ec6ff7899d | ||
|
|
6330b398a5 | ||
|
|
86c492da13 | ||
|
|
8ff7497d59 | ||
|
|
73593ad4f1 | ||
|
|
572a58ed27 | ||
|
|
d7df4be379 | ||
|
|
f227722898 | ||
|
|
f371bf2bc4 | ||
|
|
e6841ea46d | ||
|
|
edbfe45a20 | ||
|
|
5f83e89be5 | ||
|
|
5850b26de5 | ||
|
|
416267a238 | ||
|
|
94499ed8fc | ||
|
|
da1868288d | ||
|
|
c8d6b39585 | ||
|
|
00f8181c3a | ||
|
|
60565cc2ef | ||
|
|
bfee39ae70 | ||
|
|
753c5e72be | ||
|
|
571a533543 | ||
|
|
222fcfd70e | ||
|
|
95c8a70ce6 | ||
|
|
0f6bec4d5e | ||
|
|
5fb0522c78 | ||
|
|
7c0bc2d972 | ||
|
|
cb972e165b | ||
|
|
fb319a352a | ||
|
|
e10646b436 | ||
|
|
211bec65d2 | ||
|
|
66807539ce | ||
|
|
2919c32a8f | ||
|
|
05be9e9c37 | ||
|
|
039aaae041 | ||
|
|
890653ae39 | ||
|
|
8644fdd595 | ||
|
|
4fca8fb8e6 | ||
|
|
9625201cbf | ||
|
|
e7dea56adf | ||
|
|
5b802d17d1 | ||
|
|
a43ddba87c | ||
|
|
f1d007ca4c | ||
|
|
c2111e7384 | ||
|
|
a1c6378317 | ||
|
|
f064013b9a | ||
|
|
d4480c3566 | ||
|
|
b3a4de7aa8 | ||
|
|
60d8131a4d | ||
|
|
6d78aefa13 | ||
|
|
badd953600 | ||
|
|
5d385c540d | ||
|
|
52351902ee | ||
|
|
6e697e5ec1 | ||
|
|
c55c8979f1 | ||
|
|
7ca757bb6d | ||
|
|
c2d59b02bd | ||
|
|
45b638fc45 | ||
|
|
5767c61a91 | ||
|
|
e3f8a817e0 | ||
|
|
4377603d7e | ||
|
|
bc72239181 | ||
|
|
2d7f37386e | ||
|
|
dffba2d83c | ||
|
|
0fbb6aa02f | ||
|
|
7364affd69 | ||
|
|
09e622d5a0 | ||
|
|
21ccaf56e6 | ||
|
|
d8cd807520 | ||
|
|
6069d05aa9 | ||
|
|
09a3d4851a | ||
|
|
d41374c55a | ||
|
|
dd8a1f00fc | ||
|
|
ffca27cbde | ||
|
|
82edd901fe | ||
|
|
a8c1a36c12 | ||
|
|
acfb24f871 | ||
|
|
ecff5aea71 | ||
|
|
74cb225ccb | ||
|
|
d5db2ccf18 | ||
|
|
cebcf50c65 | ||
|
|
3a3c9101c7 | ||
|
|
ec1c7797f4 | ||
|
|
313528c34b | ||
|
|
907fd6b04b | ||
|
|
aa0fc9071e | ||
|
|
0bd924eb7e | ||
|
|
852109c142 | ||
|
|
9b0bb29d78 | ||
|
|
c3e71de1d7 | ||
|
|
0256d6820c | ||
|
|
1b18bfaff5 | ||
|
|
6065e7a62b | ||
|
|
8aecdc536c | ||
|
|
86a2e9e655 | ||
|
|
8f50106187 | ||
|
|
02d3a319f9 | ||
|
|
d18d0435ae | ||
|
|
cdaf1c5262 | ||
|
|
4b0e3bff54 | ||
|
|
c4f7b27459 | ||
|
|
3eb8be9953 | ||
|
|
1f08f8df0d | ||
|
|
0038a0b19c | ||
|
|
166a7c7e53 | ||
|
|
8ac296bd6f | ||
|
|
e092a38e0f | ||
|
|
b145e894e4 | ||
|
|
63a8b66b28 | ||
|
|
a16cc87852 | ||
|
|
1050b60057 | ||
|
|
9188e85164 | ||
|
|
f9b369c550 | ||
|
|
949b205f42 | ||
|
|
31ee8d8178 | ||
|
|
3155590e87 | ||
|
|
feab0bce4b | ||
|
|
0599d80b13 | ||
|
|
d58e12c5e4 | ||
|
|
68939c5a5c | ||
|
|
25c4fb8508 | ||
|
|
88e6c48db7 | ||
|
|
218b0d491a | ||
|
|
bfba74dab9 | ||
|
|
5708846a07 | ||
|
|
fd28783f85 | ||
|
|
0ca34d11ad | ||
|
|
bf3275ba4a | ||
|
|
d8e4e00b2b | ||
|
|
8b38a6dd08 | ||
|
|
63f72621fc | ||
|
|
580a8c9c61 | ||
|
|
249351cef4 | ||
|
|
46690ae352 | ||
|
|
68b5a90518 | ||
|
|
cb54823622 | ||
|
|
3a2ca41724 | ||
|
|
dd4e6d29ca | ||
|
|
497ee32f59 | ||
|
|
d34c287f69 | ||
|
|
b744ca16e1 | ||
|
|
573c262bb2 | ||
|
|
ff2c2f1e1f | ||
|
|
8058391955 | ||
|
|
54dbb9f248 | ||
|
|
7d1351f402 | ||
|
|
21233430aa | ||
|
|
bd1d6820b7 | ||
|
|
18e84ae2e8 | ||
|
|
f9c29056e6 | ||
|
|
40b1c32008 | ||
|
|
b5ed804578 | ||
|
|
fbe3a86c4e | ||
|
|
498c86b47d | ||
|
|
b8b6f81c44 | ||
|
|
aab9e1b751 | ||
|
|
ec976f3f75 | ||
|
|
f169fa5da2 | ||
|
|
35ee12e7e9 | ||
|
|
4497ab8844 | ||
|
|
9f399f3313 | ||
|
|
3939213336 | ||
|
|
cc27a0f666 | ||
|
|
1ff2216063 | ||
|
|
b8165813b4 | ||
|
|
2215b153db | ||
|
|
cb91d585c3 | ||
|
|
c971d4044f | ||
|
|
fdb4a078f2 | ||
|
|
42ea711850 | ||
|
|
96721978c0 | ||
|
|
d64698e4c9 | ||
|
|
4565f2b689 | ||
|
|
5fa7f1d50d | ||
|
|
2cfc42bd6a | ||
|
|
003de2b659 | ||
|
|
4ab6c2252d | ||
|
|
8f9d818368 | ||
|
|
4ebc307744 | ||
|
|
0b519b29d9 | ||
|
|
8881e8d96e | ||
|
|
9a99608f68 | ||
|
|
26c26308db | ||
|
|
123c5d809e | ||
|
|
7c42c7798c | ||
|
|
0f98daf1d9 | ||
|
|
c3de7c63b4 | ||
|
|
ab9123a427 | ||
|
|
e504a8c979 | ||
|
|
f6dd87a3a1 | ||
|
|
89c530054d | ||
|
|
f87edbe1cb | ||
|
|
4aa477de3e | ||
|
|
694e674fe6 | ||
|
|
7ebc0f32b8 | ||
|
|
68cacc2fc3 | ||
|
|
43eb597044 | ||
|
|
7efd827e78 | ||
|
|
2f6f8b93e9 | ||
|
|
d48413cbec | ||
|
|
6bafca688b | ||
|
|
53356f1aa7 | ||
|
|
51281f6a3a | ||
|
|
7a5e08c5ab | ||
|
|
642903a7bf | ||
|
|
f51fd6c78d | ||
|
|
03cf15a9e1 | ||
|
|
fe19c04f6a | ||
|
|
b86cbda03d | ||
|
|
b1af6e23cf | ||
|
|
e26b9b12fa | ||
|
|
9bf47b3f23 | ||
|
|
2887416b2e | ||
|
|
9a92f6f743 | ||
|
|
4929480719 | ||
|
|
c8437d2303 | ||
|
|
ef25ae4d3b | ||
|
|
9399790c11 | ||
|
|
ab7f6484cf | ||
|
|
2d8c5da379 | ||
|
|
b18f148575 | ||
|
|
6426428718 | ||
|
|
af2ee426f5 | ||
|
|
6c4e9ff42d | ||
|
|
62a37a7d70 | ||
|
|
ef83addc74 | ||
|
|
fb308f5947 | ||
|
|
cedb93c11c | ||
|
|
61d2a09827 | ||
|
|
9c6423f37a | ||
|
|
e18a661b50 | ||
|
|
16e5777816 | ||
|
|
64020e8828 | ||
|
|
30798556fc | ||
|
|
cd3518d99d | ||
|
|
bc87c3d494 | ||
|
|
726228c418 | ||
|
|
929b111648 | ||
|
|
1700a73382 | ||
|
|
0f9d791911 | ||
|
|
61acc76be7 | ||
|
|
0f8ba5bf32 | ||
|
|
2cb8a96f0e | ||
|
|
1102122639 | ||
|
|
66e026a9e8 | ||
|
|
b901b42417 | ||
|
|
9f2f10a65f | ||
|
|
b0b41d00ee | ||
|
|
2d56f5eba0 | ||
|
|
8ffc6fbc6b | ||
|
|
0ffd94dadb | ||
|
|
585320093a | ||
|
|
bdd351a42c | ||
|
|
feaee702e9 | ||
|
|
d89fc84fcf | ||
|
|
688cd1a4bb | ||
|
|
c056875a00 | ||
|
|
054118139f | ||
|
|
447148d95a | ||
|
|
f6b1e42a0b | ||
|
|
90e74e5572 | ||
|
|
e4fc5fe5be | ||
|
|
809b2c6115 | ||
|
|
659538ef4b | ||
|
|
4b677f4b42 | ||
|
|
87699ea5a0 | ||
|
|
a2ae113ee9 | ||
|
|
901e2c75d4 | ||
|
|
871d140b7c | ||
|
|
2f6ae1ad02 | ||
|
|
806e98925c | ||
|
|
c7dbd2fac2 | ||
|
|
1b7729efed | ||
|
|
6d1d5aeffb | ||
|
|
9ae04b5771 | ||
|
|
fc61e3b1b5 | ||
|
|
fa1d9910e4 | ||
|
|
d425873eed | ||
|
|
d89c54dd95 | ||
|
|
5e023c55bd | ||
|
|
2487172df3 | ||
|
|
bdd078df17 | ||
|
|
db75335ad0 | ||
|
|
531ab5b5b1 | ||
|
|
0601a863f9 | ||
|
|
10d34c9564 | ||
|
|
a37d6a3841 | ||
|
|
d5234a43da | ||
|
|
b7733540c1 | ||
|
|
2ae02ded74 | ||
|
|
2e57ad644d | ||
|
|
031afbfb18 | ||
|
|
377ce2e2f6 | ||
|
|
a2fd3c077d | ||
|
|
0f5aff73ab | ||
|
|
f0b208e692 | ||
|
|
7fcb5fc590 | ||
|
|
b76f819759 | ||
|
|
4b36d4f1ea | ||
|
|
f4d0c6c807 | ||
|
|
79ab76b42e | ||
|
|
8c3ac61f8d | ||
|
|
a8bc20f76b | ||
|
|
53a55baf23 | ||
|
|
63d6800cf3 | ||
|
|
44492b4828 | ||
|
|
8ed9f8aef5 | ||
|
|
711021e24e | ||
|
|
55dea335fe | ||
|
|
7097532ddf | ||
|
|
66841ce35c | ||
|
|
3d814cb7c1 | ||
|
|
07afdca58b | ||
|
|
93ed346fd2 | ||
|
|
c9eee9bf7f | ||
|
|
d1a4029bc5 | ||
|
|
97070aad25 | ||
|
|
39640185a3 | ||
|
|
4b17506ffe | ||
|
|
2435ebecbe | ||
|
|
410a35b968 | ||
|
|
c8d234a767 | ||
|
|
2bf87ff40f | ||
|
|
ba347c49c9 | ||
|
|
81434cd233 | ||
|
|
46d0df9cba | ||
|
|
b7f58e68c5 | ||
|
|
6ba2accbdc | ||
|
|
29ee94d331 | ||
|
|
cdae654fe4 | ||
|
|
a506c84bc7 | ||
|
|
8e4a47181b | ||
|
|
b5241e0f60 | ||
|
|
57ed466a7f | ||
|
|
4f46f55f2d | ||
|
|
69cfc78ee1 | ||
|
|
04f1ab8571 | ||
|
|
95694b2017 | ||
|
|
00bed2f0c0 | ||
|
|
e718fc35f8 | ||
|
|
717015bae8 | ||
|
|
530d3d809b | ||
|
|
596b32d15c | ||
|
|
8d3918b4f0 | ||
|
|
4c7e31513b | ||
|
|
765509d7f5 | ||
|
|
dbb58d10a6 | ||
|
|
d448976b3c | ||
|
|
de6931b1f5 | ||
|
|
35268d185e | ||
|
|
beef9eee0a | ||
|
|
34a274d4e6 | ||
|
|
ef28a6c19a | ||
|
|
50b5971ee5 | ||
|
|
9a70ae18ea | ||
|
|
d10853b775 | ||
|
|
cdf6a16efc | ||
|
|
02d7261f51 | ||
|
|
9c9ddeffbe | ||
|
|
afa8b3a5c9 | ||
|
|
bbcd4c168c | ||
|
|
d22bd9cac7 | ||
|
|
5ccf25196e | ||
|
|
caf15a2dac | ||
|
|
982a05450c | ||
|
|
3e381b742c | ||
|
|
6b82664166 | ||
|
|
bb30a2eb1e | ||
|
|
b3fdf5c48f | ||
|
|
17d5ed847f | ||
|
|
4335d17fc0 | ||
|
|
ae07958577 | ||
|
|
c51b9ba3d6 | ||
|
|
cc6ff5e9e6 | ||
|
|
b968ea7e7e | ||
|
|
d14b6e160e | ||
|
|
b09b9488ef | ||
|
|
a8120ee7ef | ||
|
|
fb82059750 | ||
|
|
0fc6240d72 | ||
|
|
a7c6fdb1fc | ||
|
|
b76a2963cf | ||
|
|
42b0fbd34c | ||
|
|
f69ef8606f | ||
|
|
afa5ad5f9f | ||
|
|
1fc82708e9 | ||
|
|
917cbbadde | ||
|
|
c37dc81839 | ||
|
|
df718d55ef | ||
|
|
54412f1d5e | ||
|
|
da76023bea | ||
|
|
41e9309a36 | ||
|
|
116268b275 | ||
|
|
73802492b8 | ||
|
|
7cd4d53fa9 | ||
|
|
c44757975e | ||
|
|
f25cdcdf63 | ||
|
|
5d37253e85 | ||
|
|
cd5f42ec79 | ||
|
|
6651f9e94b | ||
|
|
e3ee579f92 | ||
|
|
73e7240574 | ||
|
|
391f9aa97d | ||
|
|
8ad54e7bd5 | ||
|
|
9eccc01dd3 | ||
|
|
39c1f816fc | ||
|
|
a32b892787 | ||
|
|
1b144ba3f0 | ||
|
|
6a39a8db72 | ||
|
|
602c530615 | ||
|
|
c8c27f26f7 | ||
|
|
549cdc4c2c | ||
|
|
3160e0a430 | ||
|
|
dcebe85f3a | ||
|
|
2ba0b66426 | ||
|
|
5c9543f159 | ||
|
|
f6e3689f30 | ||
|
|
a761343717 | ||
|
|
b4c47a3d24 | ||
|
|
906988c49b | ||
|
|
4186b2ad82 | ||
|
|
2943cff73f | ||
|
|
53ac5579fb | ||
|
|
0d7a9f911a | ||
|
|
dce9de222d | ||
|
|
d46722a95c | ||
|
|
3ba4da7736 | ||
|
|
6abf5b90b7 | ||
|
|
00aa4ddea0 | ||
|
|
d0c6f9de22 | ||
|
|
a85cc85081 | ||
|
|
75793300f2 | ||
|
|
672805584e | ||
|
|
5b4fd590d1 | ||
|
|
0ccd38f593 | ||
|
|
b46e5d4488 | ||
|
|
d7223d598f | ||
|
|
7a0368132d | ||
|
|
aff3914a66 | ||
|
|
8876047875 | ||
|
|
78e2aa16f0 | ||
|
|
3ef695cf70 | ||
|
|
c4d8dd6413 | ||
|
|
a49d30f6e2 | ||
|
|
512643d3d6 | ||
|
|
b3a69af752 | ||
|
|
64c0dc47a9 | ||
|
|
923c323d6f | ||
|
|
ee47b5bbc9 | ||
|
|
e8cd655c84 | ||
|
|
d80daf2692 | ||
|
|
0e5c9e8b06 | ||
|
|
6bc4aed82c | ||
|
|
e69e1200f5 | ||
|
|
81e253b06b | ||
|
|
9af52fb642 | ||
|
|
eaddd44d17 | ||
|
|
854e699589 | ||
|
|
43dcc84c07 | ||
|
|
6e9d5f00de | ||
|
|
a65ca9663f | ||
|
|
02b767c0ea | ||
|
|
4b1c1d266d | ||
|
|
d9bf140971 | ||
|
|
1402776ba6 | ||
|
|
e36fb47d98 | ||
|
|
2bb37357c0 | ||
|
|
7494ac7615 | ||
|
|
44bc3fb90b | ||
|
|
20b00ecc9b | ||
|
|
40662f947f | ||
|
|
6e01934edc | ||
|
|
151fc5e97f | ||
|
|
5f431dc776 | ||
|
|
5ec4d3125a | ||
|
|
8e511e7db4 | ||
|
|
99b8046f03 | ||
|
|
d39dea1ae3 | ||
|
|
e94643d5ca | ||
|
|
1becbab0dc | ||
|
|
d49efb451e | ||
|
|
d2a56ebd8c | ||
|
|
0e11a9b7ac | ||
|
|
68c77d12d4 | ||
|
|
423e29ba42 | ||
|
|
dcfbc2f20e | ||
|
|
0b29c99fed | ||
|
|
18556a9f75 | ||
|
|
02d93782ba | ||
|
|
62cfc26262 | ||
|
|
b01a6b94e7 | ||
|
|
713ebf1476 | ||
|
|
26e50efdb2 | ||
|
|
c8928999bf | ||
|
|
e1f378c6cf | ||
|
|
d10222329c | ||
|
|
176fa7ab1d | ||
|
|
ebb7137839 | ||
|
|
d7092a1231 | ||
|
|
55cbb0b340 | ||
|
|
db7fb56e9d | ||
|
|
2bed7440a8 | ||
|
|
0019bdecef | ||
|
|
51d355da30 | ||
|
|
28170fd723 | ||
|
|
44c65c35c8 | ||
|
|
d8f8daf48a | ||
|
|
b148cc6ca3 | ||
|
|
2a4c169fff | ||
|
|
c2c84e4bd8 | ||
|
|
c2f8b5b1ba | ||
|
|
3a33f554a0 | ||
|
|
11ce97655b | ||
|
|
dc866538d4 | ||
|
|
48ad9e9a87 | ||
|
|
c75778abeb | ||
|
|
fb2a59a67f | ||
|
|
f4c92756fc | ||
|
|
657c27556c | ||
|
|
42e68d8544 | ||
|
|
ae69c4d895 | ||
|
|
5a0db4d812 | ||
|
|
ddd241fe39 | ||
|
|
3dc7b8d90a | ||
|
|
0bccb1ece5 | ||
|
|
bf1e319d90 | ||
|
|
bc6ae7feb4 | ||
|
|
8d6a43d708 | ||
|
|
bd1bca2c3a | ||
|
|
9858ab7388 | ||
|
|
1f6b69573c | ||
|
|
1c8c5b77f1 | ||
|
|
e9bd037cf9 | ||
|
|
6f8353ab28 | ||
|
|
c25720429d | ||
|
|
276e9aded3 | ||
|
|
b88ac3359d | ||
|
|
264f3be8b4 | ||
|
|
4282f96d35 | ||
|
|
9cdd759fc1 | ||
|
|
403e8f8702 | ||
|
|
2e989e4262 | ||
|
|
5666a352d4 | ||
|
|
1aa8c6f996 | ||
|
|
9882f53613 | ||
|
|
8760c593ec | ||
|
|
ad695bdd59 | ||
|
|
adff4bb1d7 | ||
|
|
42c931cf22 | ||
|
|
5d44dea47c | ||
|
|
56c95e3b36 | ||
|
|
840f306a7d | ||
|
|
9def89d5f8 | ||
|
|
84c2f93dab | ||
|
|
b30733e2a7 | ||
|
|
da58e6a597 | ||
|
|
229e7c5b61 | ||
|
|
26685143be | ||
|
|
e54b9237c6 | ||
|
|
ac1b6d9482 | ||
|
|
bb6e98a6fc | ||
|
|
32c75f06b3 | ||
|
|
a5de2d1008 | ||
|
|
f841912c75 | ||
|
|
3b8c36882d | ||
|
|
fca4c7e6bf | ||
|
|
5ffc611d13 | ||
|
|
130f02647b | ||
|
|
981eea6ade | ||
|
|
3f788eb4a8 | ||
|
|
486dc974c4 | ||
|
|
3b1fbbc766 | ||
|
|
d01db8f293 | ||
|
|
fd09ded049 | ||
|
|
8e2b4a306d | ||
|
|
1d58f38aa5 | ||
|
|
5ff9a83b07 | ||
|
|
f5decb5f83 | ||
|
|
11fc49a0f8 | ||
|
|
48c03d747a | ||
|
|
643750817a | ||
|
|
a52dd71e44 | ||
|
|
8c02bd43df | ||
|
|
f635a12129 | ||
|
|
8191c4905b | ||
|
|
58a034b79d | ||
|
|
2d53867668 | ||
|
|
8a57fc5838 | ||
|
|
5481e6d79a | ||
|
|
c852a58ee3 | ||
|
|
8cfc016b3f | ||
|
|
8c94b782c6 | ||
|
|
1dce4919f2 | ||
|
|
cbda688e29 | ||
|
|
159ed07e68 | ||
|
|
a18b2d0e17 | ||
|
|
4c9adab58d | ||
|
|
4c9f1b105d | ||
|
|
2290353295 | ||
|
|
c16bf09310 | ||
|
|
90db9486ce | ||
|
|
b79faa6207 | ||
|
|
2293d3067a | ||
|
|
de431f113e | ||
|
|
34e265a801 | ||
|
|
a668492fb7 | ||
|
|
da069571f3 | ||
|
|
d2bac45b49 | ||
|
|
8913c59acc | ||
|
|
c3261b4aeb | ||
|
|
c7fb95aec5 | ||
|
|
c00cef6dc1 | ||
|
|
429ff94dc5 | ||
|
|
a6c67ca749 | ||
|
|
f51812a670 | ||
|
|
686294f1c4 | ||
|
|
a47ed105e7 | ||
|
|
b2d579a268 | ||
|
|
eb1050092f | ||
|
|
b3794f5541 | ||
|
|
1ecfa3253d | ||
|
|
5daf007b6a | ||
|
|
8efa5febd0 | ||
|
|
5fee8028cd | ||
|
|
6bc7a83c64 | ||
|
|
e55b5d0d11 | ||
|
|
19de7f2785 | ||
|
|
e32c5384ab | ||
|
|
b391fe6b92 | ||
|
|
4cfb81156f | ||
|
|
6121708e55 | ||
|
|
6ab214adea | ||
|
|
90b1ac4162 | ||
|
|
3abe6c14a1 | ||
|
|
fc1b500eff | ||
|
|
5d47b9195b | ||
|
|
a8272b74f6 | ||
|
|
12dc16780f | ||
|
|
b8af569841 | ||
|
|
8bee101795 | ||
|
|
2d66bc258a | ||
|
|
d2f86e49f7 | ||
|
|
d66cd16cfb | ||
|
|
04e785e434 | ||
|
|
15a1a0f7d9 | ||
|
|
0a58ce6134 | ||
|
|
8f5607f0e8 | ||
|
|
a21789d3d8 | ||
|
|
efd6e95059 | ||
|
|
9bdb1f4306 | ||
|
|
ae4b7135d5 | ||
|
|
d503366816 | ||
|
|
0fe2827fcc | ||
|
|
cd6722f77b | ||
|
|
ffb745b662 | ||
|
|
bb10f25808 | ||
|
|
aa1076d12b | ||
|
|
1e827ec7a6 | ||
|
|
3fe2650787 | ||
|
|
3e99e814bc | ||
|
|
2019f8138e | ||
|
|
e44d1f136b | ||
|
|
09872402df | ||
|
|
b078a41a02 | ||
|
|
3a5eeb5700 | ||
|
|
9433ae3405 | ||
|
|
4658b24f9a | ||
|
|
4e7d0e6be0 | ||
|
|
4ddd98708f | ||
|
|
c161fd218c | ||
|
|
7e257cc268 | ||
|
|
d8ef70280c | ||
|
|
ec003281be | ||
|
|
e58f67b76c | ||
|
|
57178abcd2 | ||
|
|
73ca4f8314 | ||
|
|
527752c25b | ||
|
|
38fa866c91 | ||
|
|
c902b8807a | ||
|
|
4934c1fd94 | ||
|
|
766fbe3db3 | ||
|
|
29405f2690 | ||
|
|
51f505acca | ||
|
|
77415538f7 | ||
|
|
9fb69ed206 | ||
|
|
735a4f90db | ||
|
|
7ef8dc13ba | ||
|
|
656477ec63 | ||
|
|
d080180e85 | ||
|
|
af1d2d6005 | ||
|
|
90c1282f3a | ||
|
|
d5d7eec8b0 | ||
|
|
5337b9537d | ||
|
|
e72c016230 | ||
|
|
072cf4c5bd | ||
|
|
27ededf47f | ||
|
|
82d7f9fdd7 | ||
|
|
d85153d6b3 | ||
|
|
6b698e6cd1 | ||
|
|
9475f79ec6 | ||
|
|
f906c6a0f4 | ||
|
|
e88c92de57 | ||
|
|
48ed906a7b | ||
|
|
b03b02d2f2 | ||
|
|
d00d476a0a | ||
|
|
ac1e32994a | ||
|
|
800d447f3d | ||
|
|
8111b7cc7f | ||
|
|
a86c922073 | ||
|
|
46fb8583bb | ||
|
|
3487d120ec | ||
|
|
07394d6a6e | ||
|
|
8d3204171c | ||
|
|
7641f722e9 | ||
|
|
b51fa497c5 | ||
|
|
34722bed3d | ||
|
|
981c3009ee | ||
|
|
38cf357d85 | ||
|
|
2533ed4a63 | ||
|
|
5a4691fdfc | ||
|
|
6c035a0d61 | ||
|
|
a234aa300d | ||
|
|
f6abbedbd1 | ||
|
|
b6fe4cd6dd | ||
|
|
bdae4f6915 | ||
|
|
f8b6edfb2b | ||
|
|
0a1ecdf6ae | ||
|
|
beec203f56 | ||
|
|
d323032ec9 | ||
|
|
7472b21f33 | ||
|
|
1058575d3a | ||
|
|
e9867ca35a | ||
|
|
84277319fa | ||
|
|
8f8aa55c7f | ||
|
|
72a4063651 | ||
|
|
0b1229da55 | ||
|
|
1d3ce30e50 | ||
|
|
71187d3ad7 | ||
|
|
dd8a3a9aea | ||
|
|
7b2fc37651 | ||
|
|
426569d74d | ||
|
|
e877d5b82c | ||
|
|
572e0d04d5 | ||
|
|
e3d7161ac5 | ||
|
|
fcbf0de05a |
No files matched your search
+2
-2
@@ -32,7 +32,7 @@ AttributeMacros:
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BreakAfterAttributes: Always # clang 16 required
|
||||
BreakAfterAttributes: Leave
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeInlineASMColon: OnlyMultiline # clang 16 required
|
||||
@@ -60,7 +60,7 @@ IndentRequires: false
|
||||
IndentWidth: 2
|
||||
InsertBraces: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: OuterScope
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: LF # clang 16 required
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: Inner
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# This file is used to ignore files and directories from clang-format
|
||||
|
||||
# Ignore all files in the External directory
|
||||
External/*
|
||||
|
||||
# SoftFloat-3e code doesn't belong to us
|
||||
FEXCore/Source/Common/SoftFloat-3e/*
|
||||
Source/Common/cpp-optparse/*
|
||||
|
||||
# Files with human-indented tables for readability - don't mess with these
|
||||
FEXCore/Source/Interface/Core/X86Tables/*
|
||||
FEXCore/Source/Interface/Core/X86Tables/*.cpp
|
||||
|
||||
# Inline headers with list-like content that can't be processed individually
|
||||
Source/Tools/LinuxEmulation/LinuxSyscalls/x*/SyscallsNames.inl
|
||||
Source/Tools/LinuxEmulation/LinuxSyscalls/x*/Ioctl/*.inl
|
||||
|
||||
# Include files in unittests
|
||||
unittests/*ASM/Includes/*.inc
|
||||
@@ -13,3 +13,15 @@
|
||||
|
||||
# Second reformat to find fixed point PR#3577
|
||||
905aa935f5ce344a48ef4d5edab3c31efa8d793e
|
||||
|
||||
# Reformat of CodeEmitter inl files
|
||||
8760c593ece92d7e9fa94c40da0368fd367c9cad
|
||||
|
||||
# Whole-tree reformat with clang-format-19
|
||||
5267cde60e7642852d18f20ae8568643bb5293d5
|
||||
|
||||
# Minor reformat with clang-format-19
|
||||
9fdd96af61c969cb5732471223f00eda64b7a069
|
||||
|
||||
# Reformat of X86Tables.h
|
||||
ba2b0ef809f66f1a6d334f000798fa2ceafab26f
|
||||
+99
-195
@@ -13,6 +13,7 @@ env:
|
||||
BUILD_TYPE: Release
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
FEX_PORTABLE: 1
|
||||
|
||||
jobs:
|
||||
build_plus_test:
|
||||
@@ -23,236 +24,139 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
- name: Set runner info
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True -DBUILD_FEX_LINUX_TESTS=True -DBUILD_THUNKS=True -DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/build/install
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True \
|
||||
-DENABLE_X86_HOST_DEBUG=True -DBUILD_FEX_LINUX_TESTS=True -DBUILD_THUNKS=True \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD"/build/install
|
||||
|
||||
# These steps make a lot of noise but rarely fail.
|
||||
# Put them in a separate step to make normal build logs easier to parse
|
||||
- name: Noisy Build Targets
|
||||
run: cmake --build build --target asm_files 32bit_asm_files JemallocLibs Catch2 vixl cephes_128bit
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
id: build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target install
|
||||
run: cmake --build build --target install
|
||||
|
||||
- name: gcc target tests 64
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the gvisor tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target gcc_target_tests_64
|
||||
# GCC tests
|
||||
- name: GCC64 Target Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: gcc_target_tests_64
|
||||
|
||||
- name: GCC64 Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_GCC64.log || true
|
||||
- name: GCC32 Target Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: gcc_target_tests_32
|
||||
|
||||
- name: gcc target tests 32
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the gvisor tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target gcc_target_tests_32
|
||||
# API tests
|
||||
- name: API Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: api_tests
|
||||
|
||||
- name: GCC32 Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_GCC32.log || true
|
||||
- name: FEXCore API Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: fexcore_apitests
|
||||
|
||||
- name: APITest tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target api_tests
|
||||
# ARM emission tests
|
||||
- name: ARM Emitter Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: emitter_tests
|
||||
|
||||
- name: APITest Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_APITests.log || true
|
||||
|
||||
- name: FEXCore APITest tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target fexcore_apitests
|
||||
|
||||
- name: FEXCore APITest Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_FEXCoreAPITests.log || true
|
||||
|
||||
- name: ARMEmitter tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target emitter_tests
|
||||
|
||||
- name: ARMEmitter Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ARMEmitterTests.log || true
|
||||
|
||||
- name: FEXLinuxTests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target fex_linux_tests_all
|
||||
|
||||
- name: FEXLinuxTests Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_FEXLinuxTests.log || true
|
||||
# Linux tests
|
||||
- name: FEX Linux Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: fex_linux_tests_all
|
||||
env:
|
||||
FEX_PORTABLE: 0
|
||||
|
||||
# Thunking
|
||||
- name: Thunkgen tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target thunkgen_tests
|
||||
|
||||
- name: Thunkgen Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ThunkgenTests.log || true
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: thunkgen_tests
|
||||
|
||||
- name: Test GL No-Thunks
|
||||
if: matrix.arch[1] == 'x64'
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
if: ${{ steps.build.outcome == 'success' && matrix.arch[1] == 'x64' }}
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: thunk_functional_tests_nothunks
|
||||
env:
|
||||
DISPLAY: ":0"
|
||||
run: cmake --build . --config $BUILD_TYPE --target thunk_functional_tests_nothunks
|
||||
|
||||
- name: No thunks Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_NoThunkResults.log || true
|
||||
DISPLAY: ':0'
|
||||
|
||||
- name: Test GL Thunks
|
||||
if: matrix.arch[1] == 'x64'
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
if: ${{ steps.build.outcome == 'success' && matrix.arch[1] == 'x64' }}
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: thunk_functional_tests_thunks
|
||||
env:
|
||||
DISPLAY: ":0"
|
||||
run: cmake --build . --config $BUILD_TYPE --target thunk_functional_tests_thunks
|
||||
|
||||
- name: Thunks Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ThunkResults.log || true
|
||||
DISPLAY: ':0'
|
||||
|
||||
# ASM tests
|
||||
- name: ASM Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: ASM Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM.log || true
|
||||
# POSIX tests
|
||||
- name: POSIX Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: posix_tests
|
||||
|
||||
- name: Posix Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the posixtest
|
||||
run: cmake --build . --config $BUILD_TYPE --target posix_tests
|
||||
|
||||
- name: Posix Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_Posix.log || true
|
||||
|
||||
- name: gvisor tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the gvisor tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target gvisor_tests
|
||||
|
||||
- name: GVisor Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_GVisor.log || true
|
||||
# GVisor tests
|
||||
- name: GVisor Tests
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: gvisor_tests
|
||||
|
||||
# Struct verifier tests
|
||||
- name: Struct verifier tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target struct_verifier
|
||||
|
||||
- name: Struct verifier Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_StructVerifier.log || true
|
||||
|
||||
- name: Truncate test results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Cap out the log files at 20M in case something crash spins and dumps fault text
|
||||
# ASM tests get quite close to 10MB
|
||||
run: truncate --size="<20M" ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log || true
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: struct_verifier
|
||||
|
||||
- name: Remove old SHM regions
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake --build . --config $BUILD_TYPE --target remove_old_shm_regions
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
run: cmake --build build --target remove_old_shm_regions
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
name: Results-${{ env.runner_name }}-${{ env.runner_label }}
|
||||
path: results/*.log
|
||||
retention-days: 3
|
||||
@@ -20,6 +20,7 @@ env:
|
||||
BUILD_TYPE: Release
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
FEX_PORTABLE: 1
|
||||
|
||||
jobs:
|
||||
glibc_fault_test:
|
||||
@@ -30,164 +31,94 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
- name: Set runner info
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True -DBUILD_FEX_LINUX_TESTS=True -DENABLE_GLIBC_ALLOCATOR_HOOK_FAULT=True -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/build/install
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False \
|
||||
-DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True -DBUILD_FEX_LINUX_TESTS=True \
|
||||
-DENABLE_GLIBC_ALLOCATOR_HOOK_FAULT=True -DENABLE_JEMALLOC_GLIBC_ALLOC=False \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD"/build/install
|
||||
|
||||
# These steps make a lot of noise but rarely fail.
|
||||
# Put them in a separate step to make normal build logs easier to parse
|
||||
- name: Noisy Build Targets
|
||||
run: cmake --build build --target asm_files 32bit_asm_files JemallocLibs Catch2 vixl cephes_128bit
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
run: cmake --build build
|
||||
|
||||
- name: Install
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target install
|
||||
run: cmake --build build --target install
|
||||
|
||||
- name: gcc target tests 64
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the gvisor tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target gcc_target_tests_64
|
||||
|
||||
- name: GCC64 Test Results move
|
||||
# GCC tests
|
||||
- name: GCC64 Target Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_GCC64.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: gcc_target_tests_64
|
||||
|
||||
- name: gcc target tests 32
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the gvisor tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target gcc_target_tests_32
|
||||
|
||||
- name: GCC32 Test Results move
|
||||
- name: GCC32 Target Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_GCC32.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: gcc_target_tests_32
|
||||
|
||||
- name: APITest tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target api_tests
|
||||
|
||||
- name: APITest Test Results move
|
||||
# API Tests
|
||||
- name: API Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_APITests.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: api_tests
|
||||
|
||||
- name: FEXCore APITest tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target fexcore_apitests
|
||||
|
||||
- name: FEXCore APITest Test Results move
|
||||
- name: FEXCore API Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_FEXCoreAPITests.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: fexcore_apitests
|
||||
|
||||
- name: FEXLinuxTests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target fex_linux_tests_all
|
||||
|
||||
- name: FEXLinuxTests Results move
|
||||
# Linux tests
|
||||
- name: FEX Linux Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_FEXLinuxTests.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: fex_linux_tests_all
|
||||
|
||||
# ASM Tests
|
||||
- name: ASM Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
|
||||
- name: ASM Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: Posix Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the posixtest
|
||||
run: cmake --build . --config $BUILD_TYPE --target posix_tests
|
||||
|
||||
- name: Posix Test Results move
|
||||
# POSIX Tests
|
||||
- name: POSIX Tests
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_Posix.log || true
|
||||
|
||||
- name: Truncate test results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Cap out the log files at 20M in case something crash spins and dumps fault text
|
||||
# ASM tests get quite close to 10MB
|
||||
run: truncate --size="<20M" ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: posix_tests
|
||||
|
||||
- name: Remove old SHM regions
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake --build . --config $BUILD_TYPE --target remove_old_shm_regions
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
run: cmake --build build --target remove_old_shm_regions
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
name: Results-${{ env.runner_name }}-${{ env.runner_label }}
|
||||
path: results/*.log
|
||||
retention-days: 3
|
||||
|
||||
@@ -13,6 +13,7 @@ env:
|
||||
BUILD_TYPE: Release
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
FEX_PORTABLE: 1
|
||||
|
||||
jobs:
|
||||
hostrunner_tests:
|
||||
@@ -23,84 +24,45 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
- name: Set runner info
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_LTO=False \
|
||||
-DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
|
||||
# These steps make a lot of noise but rarely fail.
|
||||
# Put them in a separate step to make normal build logs easier to parse
|
||||
- name: Noisy Build Targets
|
||||
run: cmake --build build --target asm_files 32bit_asm_files JemallocLibs Catch2 vixl cephes_128bit
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
run: cmake --build build
|
||||
|
||||
# ASM tests
|
||||
- name: ASM Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
|
||||
- name: ASM Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM.log || true
|
||||
|
||||
- name: Truncate test results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Cap out the log files at 20M in case something crash spins and dumps fault text
|
||||
# ASM tests get quite close to 10MB
|
||||
run: truncate --size="<20M" ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log || true
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
name: Results-${{ env.runner_name }}-${{ env.runner_label }}
|
||||
path: results/*.log
|
||||
retention-days: 3
|
||||
|
||||
@@ -23,124 +23,56 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
- name: Set runner info
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
- name: Set VIXL_SIM_ENABLED
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
|
||||
- name: Set vixl_sim x86
|
||||
if: matrix.arch[1] == 'x64'
|
||||
run: |
|
||||
echo "VIXL_SIM_ENABLED=True" >> $GITHUB_ENV
|
||||
|
||||
- name: Set vixl_sim Arm64
|
||||
if: matrix.arch[1] == 'ARM64'
|
||||
run: |
|
||||
echo "VIXL_SIM_ENABLED=False" >> $GITHUB_ENV
|
||||
case '${{ matrix.arch[1] }}' in
|
||||
x64) _sim=True ;;
|
||||
ARM64) _sim=False ;;
|
||||
esac
|
||||
echo "VIXL_SIM_ENABLED=$_sim" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_VIXL_SIMULATOR=$VIXL_SIM_ENABLED -DENABLE_VIXL_DISASSEMBLER=True -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_VIXL_SIMULATOR=$VIXL_SIM_ENABLED \
|
||||
-DENABLE_VIXL_DISASSEMBLER=True -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
env:
|
||||
FEX_DISABLETELEMETRY: 1
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE --target CodeSizeValidation instcountci_test_files
|
||||
run: cmake --build build --target CodeSizeValidation instcountci_test_files
|
||||
|
||||
- name: Instruction Count Tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target instcountci_tests
|
||||
|
||||
- name: Instruction Count Test Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_InstCountCI.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: instcountci_tests
|
||||
|
||||
- name: Update local repo instcount
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake --build . --config $BUILD_TYPE --target instcountci_update_tests
|
||||
run: cmake --build build --target instcountci_update_tests
|
||||
|
||||
- name: Get instcountCI diff
|
||||
- name: Check InstCountCI diff
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{github.workspace}}/
|
||||
run: git diff --output=${{runner.workspace}}/build/InstCountCI.diff
|
||||
|
||||
- name: Check if InstCountCI Diff exists
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{github.workspace}}/
|
||||
# Check if the file is empty
|
||||
run: sh -c "! test -s ${{runner.workspace}}/build/InstCountCI.diff"
|
||||
|
||||
- name: Truncate test results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Cap out the log files at 20M in case something crash spins and dumps fault text
|
||||
# ASM tests get quite close to 10MB
|
||||
run: truncate --size="<20M" ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log || true
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
name: Results-${{ env.runner_name }}-${{ env.runner_label }}
|
||||
path: results/*.log
|
||||
retention-days: 3
|
||||
|
||||
- name: Upload results InstCountCI
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}-instcountci
|
||||
path: ${{runner.workspace}}/build/InstCountCI.diff
|
||||
retention-days: 3
|
||||
|
||||
@@ -20,7 +20,10 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
@@ -28,74 +31,23 @@ jobs:
|
||||
- name: Add MingGW to PATH
|
||||
run: echo "$HOME/llvm-mingw/build/bin/" >> $GITHUB_PATH
|
||||
|
||||
- name: Set CC x86
|
||||
if: matrix.arch[1] == 'x64'
|
||||
- name: Set CC
|
||||
run: |
|
||||
echo "MINGW_TRIPLE=x86_64-w64-mingw32" >> $GITHUB_ENV
|
||||
case '${{ matrix.arch[1] }}' in
|
||||
x64) _cpu=x86_64 ;;
|
||||
ARM64) _cpu=aarch64 ;;
|
||||
ARM64EC) _cpu=arm64ec ;;
|
||||
esac
|
||||
echo "MINGW_TRIPLE=${_cpu}-w64-mingw32" >> $GITHUB_ENV
|
||||
|
||||
- name: Set CC Arm64
|
||||
if: matrix.arch[1] == 'ARM64'
|
||||
run: |
|
||||
echo "MINGW_TRIPLE=aarch64-w64-mingw32" >> $GITHUB_ENV
|
||||
|
||||
- name: Set CC Arm64EC
|
||||
if: matrix.arch[1] == 'ARM64EC'
|
||||
run: |
|
||||
echo "MINGW_TRIPLE=arm64ec-w64-mingw32" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/toolchain_mingw.cmake -DMINGW_TRIPLE=$MINGW_TRIPLE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True -DBUILD_TESTS=False -DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/build/install
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/Data/CMake/toolchain_mingw.cmake \
|
||||
-DMINGW_TRIPLE=$MINGW_TRIPLE -G Ninja -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True -DBUILD_TESTING=False \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD"/build/install
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
retention-days: 3
|
||||
|
||||
run: cmake --build build
|
||||
@@ -1,7 +1,7 @@
|
||||
# Inspired by LLVM's pr-code-format.yml at
|
||||
# Inspired by LLVM's pr-code-format.yml at
|
||||
# https://github.com/llvm/llvm-project/blob/main/.github/workflows/pr-code-format.yml
|
||||
|
||||
name: "Check code formatting"
|
||||
name: Check code formatting
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
if: github.repository == 'FEX-Emu/FEX'
|
||||
|
||||
steps:
|
||||
- name: Fetch FEX sources
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
@@ -27,50 +27,37 @@ jobs:
|
||||
deepen_length: 500
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v39
|
||||
with:
|
||||
separator: ","
|
||||
skip_initial_fetch: true
|
||||
|
||||
- name: "Listed files"
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
run: |
|
||||
echo "Formatting files:"
|
||||
echo "$CHANGED_FILES"
|
||||
BASE=$(git merge-base main HEAD)
|
||||
FILES=$(git diff --name-only "$BASE" | tr '\n' ',' | sed 's/,$//')
|
||||
echo "CHANGED_FILES=$FILES" >> $GITHUB_ENV
|
||||
|
||||
- name: Check for correct clang-format version
|
||||
run: clang-format --version | grep -qF '16.0.6'
|
||||
echo "Changed files:"
|
||||
echo "$FILES"
|
||||
|
||||
- name: Check git-clang-format-16 exists
|
||||
run: which git-clang-format-16
|
||||
- name: Check git-clang-format-19 exists
|
||||
run: which git-clang-format-19
|
||||
|
||||
- name: Setup Python env
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: './External/code-format-helper/requirements_formatting.txt'
|
||||
python-version: 3.11
|
||||
cache: pip
|
||||
cache-dependency-path: ./External/code-format-helper/requirements_formatting.txt
|
||||
|
||||
- name: Install python dependencies
|
||||
run: pip install -r ./External/code-format-helper/requirements_formatting.txt
|
||||
|
||||
- name: Run code formatter
|
||||
env:
|
||||
CLANG_FORMAT_PATH: 'git-clang-format-16'
|
||||
CLANG_FORMAT_PATH: git-clang-format-19
|
||||
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
START_REV: ${{ github.event.pull_request.base.sha }}
|
||||
END_REV: ${{ github.event.pull_request.head.sha }}
|
||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
# TODO(pmatos): Once we adopt v18, we should be able
|
||||
# to take advantage of the new --diff_from_common_commit option
|
||||
# explicitly in code-format-helper.py and not have to diff starting at
|
||||
# the merge base.
|
||||
run: |
|
||||
python ./External/code-format-helper/code-format-helper.py \
|
||||
--repo "FEX-emu/FEX" \
|
||||
--issue-number $GITHUB_PR_NUMBER \
|
||||
--start-rev $(git merge-base $START_REV $END_REV) \
|
||||
--end-rev $END_REV \
|
||||
--repo "FEX-Emu/FEX" \
|
||||
--issue-number "$GITHUB_PR_NUMBER" \
|
||||
--start-rev "$START_REV" \
|
||||
--end-rev "$END_REV" \
|
||||
--changed-files "$CHANGED_FILES"
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Setup Build Environment
|
||||
description: Setup RootFS and build environment
|
||||
|
||||
inputs:
|
||||
setup-rootfs:
|
||||
description: 'Whether or not to set up the rootfs'
|
||||
default: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set rootfs paths
|
||||
if: ${{ inputs.setup-rootfs == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
if: ${{ inputs.setup-rootfs == 'true' }}
|
||||
shell: bash
|
||||
run: python3 Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name: Checkout Submodules
|
||||
shell: bash
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
shell: bash
|
||||
run: rm -Rf build
|
||||
@@ -0,0 +1,72 @@
|
||||
name: steamrt4 build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
BUILD_TYPE: Release
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
|
||||
jobs:
|
||||
steamrt4_build:
|
||||
runs-on: ${{ matrix.arch }}
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [[self-hosted, ARM64, distrobox]]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
with:
|
||||
setup-rootfs: false
|
||||
|
||||
# Setup everything required.
|
||||
- name : distrobox setup
|
||||
run: |
|
||||
distrobox create -Y -i registry.gitlab.steamos.cloud/steamrt/steamrt4/sdk/arm64:4.0.20251117.183306 steamrt4 || true
|
||||
distrobox upgrade steamrt4
|
||||
distrobox enter --name steamrt4 -- sudo apt-get install -y \
|
||||
git cmake ninja-build ccache \
|
||||
lld clang clang-tools \
|
||||
libclang-dev llvm-dev \
|
||||
libstdc++-14-dev-i386-cross libgcc-14-dev-i386-cross \
|
||||
libstdc++-14-dev-amd64-cross libgcc-14-dev-amd64-cross
|
||||
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
distrobox enter --name steamrt4 -- cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-G Ninja -DBUILD_STEAM_SUPPORT=True -DENABLE_LTO=True -DENABLE_ASSERTIONS=False -DBUILD_THUNKS=True \
|
||||
-DBUILD_FEXCONFIG=False -DBUILD_TESTING=False -DENABLE_CLANG_THUNKS=True -DUSE_LINKER=lld \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr
|
||||
|
||||
- name: Build
|
||||
run: distrobox enter --name steamrt4 -- cmake --build build
|
||||
|
||||
- name: install
|
||||
run: DESTDIR="$PWD"/install distrobox enter --name steamrt4 -- cmake --build build -t install
|
||||
|
||||
- name: Upload libraries
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
overwrite: true
|
||||
name: steamrt4_steampipe_depot
|
||||
path: ${{ github.workspace }}/install/*
|
||||
retention-days: 60
|
||||
compression-level: 9
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Run Test and Store Logs
|
||||
description: Run a test and store the log.
|
||||
inputs:
|
||||
target:
|
||||
description: 'The test target to run'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Run Tests
|
||||
shell: bash
|
||||
run: cmake --build build --target ${{ inputs.target }}
|
||||
|
||||
- name: Move and Truncate Results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p results
|
||||
mv build/Testing/Temporary/LastTest.log results/${{ inputs.target }}.log || true
|
||||
truncate --size="<20M" results/${{ inputs.target }}.log || true
|
||||
@@ -13,6 +13,7 @@ env:
|
||||
BUILD_TYPE: Release
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
FEX_PORTABLE: 1
|
||||
|
||||
jobs:
|
||||
vixl_simulator:
|
||||
@@ -24,112 +25,59 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Set runner label
|
||||
run: echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set rootfs paths
|
||||
- name: Set runner info
|
||||
run: |
|
||||
echo "FEX_ROOTFS_MOUNT=/mnt/AutoNFS/rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS_PATH=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "FEX_ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "ROOTFS=$HOME/Rootfs/" >> $GITHUB_ENV
|
||||
echo "runner_label=${{ matrix.arch[1] }}" >> $GITHUB_ENV
|
||||
echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
|
||||
- name: Update RootFS cache
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
run: $GITHUB_WORKSPACE/Scripts/CI_FetchRootFS.py
|
||||
|
||||
- name : submodule checkout
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean Build Environment
|
||||
run: rm -Rf ${{runner.workspace}}/build
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
- name: Setup Build Environment
|
||||
uses: ./.github/workflows/setup-env
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_VIXL_SIMULATOR=True -DENABLE_VIXL_DISASSEMBLER=True -DENABLE_LTO=False -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G Ninja -DENABLE_VIXL_SIMULATOR=True -DENABLE_LTO=False \
|
||||
-DENABLE_VIXL_DISASSEMBLER=True -DENABLE_ASSERTIONS=True -DENABLE_X86_HOST_DEBUG=True
|
||||
|
||||
# These steps make a lot of noise but rarely fail.
|
||||
# Put them in a separate step to make normal build logs easier to parse
|
||||
- name: Noisy Build Targets
|
||||
run: cmake --build build --target asm_files 32bit_asm_files JemallocLibs Catch2 vixl cephes_128bit
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
run: cmake --build build
|
||||
|
||||
- name: ASM Tests - SVE256
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
|
||||
- name: ASM Test SVE256 Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM_SVE256Bit.log || true
|
||||
uses: ./.github/workflows/test
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: ASM Tests - SVE128
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
if: ${{ always() }}
|
||||
uses: ./.github/workflows/test
|
||||
env:
|
||||
FEX_FORCESVEWIDTH: "128"
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
|
||||
- name: ASM Test 128-bit Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM_SVE128Bit.log || true
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: ASM Tests - ASIMD
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
if: ${{ always() }}
|
||||
uses: ./.github/workflows/test
|
||||
env:
|
||||
FEX_HOSTFEATURES: "disablesve"
|
||||
# Execute the unit tests
|
||||
run: cmake --build . --config $BUILD_TYPE --target asm_tests
|
||||
|
||||
- name: ASM Test ASIMD Results move
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: mv ${{runner.workspace}}/build/Testing/Temporary/LastTest.log ${{runner.workspace}}/build/Testing/Temporary/LastTest_ASM_ASIMD.log || true
|
||||
|
||||
- name: Truncate test results
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Cap out the log files at 20M in case something crash spins and dumps fault text
|
||||
# ASM tests get quite close to 10MB
|
||||
run: truncate --size="<20M" ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log || true
|
||||
|
||||
- name: Set runner name
|
||||
if: ${{ always() }}
|
||||
run: echo "runner_name=$(hostname)" >> $GITHUB_ENV
|
||||
with:
|
||||
target: asm_tests
|
||||
|
||||
- name: Upload results
|
||||
if: ${{ always() }}
|
||||
uses: 'actions/upload-artifact@v3'
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
name: Results-${{ env.runner_name }}
|
||||
path: ${{runner.workspace}}/build/Testing/Temporary/LastTest_*.log
|
||||
name: Results-${{ env.runner_name }}-${{ env.runner_label }}
|
||||
path: results/*.log
|
||||
retention-days: 3
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Wine DLL Build
|
||||
description: Build a wow64 or arm64ec Wine DLL
|
||||
|
||||
inputs:
|
||||
target:
|
||||
description: 'The target (arm64ec or wow64)'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Clean Build Environment
|
||||
shell: bash
|
||||
run: rm -Rf build_${{ inputs.target }}
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
run: |
|
||||
case "${{ inputs.target }}" in
|
||||
wow64) _cc=aarch64 ;;
|
||||
arm64ec) _cc=arm64ec ;;
|
||||
esac
|
||||
|
||||
cmake -S . -B build_${{ inputs.target }} -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=Data/CMake/toolchain_mingw.cmake \
|
||||
-DMINGW_TRIPLE=${_cc}-w64-mingw32 -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -G Ninja \
|
||||
-DENABLE_LTO=False -DENABLE_ASSERTIONS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False \
|
||||
-DBUILD_TESTING=False -DCMAKE_INSTALL_PREFIX=/usr -DTUNE_ARCH=generic -DTUNE_CPU=none -DRANGES_NATIVE=OFF
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cmake --build build_${{ inputs.target }}
|
||||
|
||||
- name: Install
|
||||
shell: bash
|
||||
run: DESTDIR="$PWD"/install cmake --build build_${{ inputs.target }} -t install
|
||||
|
||||
- name: Configure UnixLib
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -S Source/Windows/UnixLib -B build_unixlib_${{ inputs.target }} -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-G Ninja -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-unix -DCMAKE_INSTALL_PREFIX=/usr
|
||||
|
||||
- name: Build UnixLib
|
||||
shell: bash
|
||||
run: cmake --build build_unixlib_${{ inputs.target }}
|
||||
|
||||
- name: Install UnixLib
|
||||
shell: bash
|
||||
run: DESTDIR="$PWD"/install cmake --build build_unixlib_${{ inputs.target }} -t install
|
||||
@@ -0,0 +1,57 @@
|
||||
name: Wine DLL artifacts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
wine_dll_artifacts:
|
||||
runs-on: ${{ matrix.arch }}
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [[self-hosted, ARM64, mingw]]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
fetch-tags: 'true'
|
||||
|
||||
- name: Add MingGW to PATH
|
||||
run: echo "$HOME/llvm-mingw/build/bin/" >> $GITHUB_PATH
|
||||
|
||||
- name: Checkout Submodules
|
||||
# Need to update submodules
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --depth 1
|
||||
|
||||
- name: Clean install directory
|
||||
run: rm -Rf install
|
||||
|
||||
- name: Build (wow64)
|
||||
uses: ./.github/workflows/wine_build
|
||||
with:
|
||||
target: wow64
|
||||
|
||||
- name: Build (arm64ec)
|
||||
uses: ./.github/workflows/wine_build
|
||||
with:
|
||||
target: arm64ec
|
||||
|
||||
- name: Upload libraries
|
||||
uses: actions/upload-artifact@v6
|
||||
timeout-minutes: 1
|
||||
with:
|
||||
overwrite: true
|
||||
name: wine_dll_artifacts
|
||||
path: |
|
||||
${{ github.workspace }}/install/usr/lib/wine/aarch64-windows/lib*.dll
|
||||
${{ github.workspace }}/install/usr/lib/wine/aarch64-unix/lib*.so
|
||||
retention-days: 60
|
||||
compression-level: 9
|
||||
@@ -11,3 +11,5 @@ out/
|
||||
.vs/
|
||||
*.pyc
|
||||
.cache
|
||||
.idea/
|
||||
CMakeLists.txt.user
|
||||
@@ -0,0 +1,71 @@
|
||||
spec:
|
||||
inputs:
|
||||
PROMOTE_BRANCH:
|
||||
description: "Branch to promote the build to. Empty means no promotion."
|
||||
default: "bleeding-edge"
|
||||
|
||||
---
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
- when: always
|
||||
variables:
|
||||
PROMOTE_BRANCH: $[[ inputs.PROMOTE_BRANCH ]]
|
||||
|
||||
variables:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
GIT_DEPTH: 0
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
|
||||
build:
|
||||
stage: build
|
||||
image: registry.gitlab.steamos.cloud/steamrt/steamrt4/sdk/arm64:4.0.20251117.183306
|
||||
tags:
|
||||
- docker
|
||||
- linux
|
||||
- arm64
|
||||
- aarch64
|
||||
script:
|
||||
- apt-get -y update
|
||||
- apt-get install -y
|
||||
git cmake ninja-build ccache
|
||||
lld clang clang-tools
|
||||
libclang-dev llvm-dev
|
||||
libstdc++-14-dev-i386-cross libgcc-14-dev-i386-cross
|
||||
libstdc++-14-dev-amd64-cross libgcc-14-dev-amd64-cross
|
||||
- cmake -E make_directory build/
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release -G Ninja -DBUILD_STEAM_SUPPORT=True -DENABLE_LTO=True -DENABLE_ASSERTIONS=False -DBUILD_THUNKS=True -DBUILD_FEXCONFIG=False -DBUILD_TESTING=False -DENABLE_CLANG_THUNKS=True -DUSE_LINKER=lld -DCMAKE_INSTALL_PREFIX=/usr -DTUNE_ARCH=armv8.2-a -DTUNE_CPU=none -DRANGES_NATIVE=OFF . -B build/
|
||||
- cmake --build build/ --config Release
|
||||
- DESTDIR=$(pwd)/install/ cmake --build build/ --config Release -t install
|
||||
|
||||
artifacts:
|
||||
name: "steamrt artifacts"
|
||||
untracked: false
|
||||
paths:
|
||||
- install/
|
||||
|
||||
promote:
|
||||
stage: deploy
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
image: registry.gitlab.steamos.cloud/steamrt/steamrt4/sdk/arm64:4.0.20251117.183306
|
||||
tags:
|
||||
- docker
|
||||
- linux
|
||||
- arm64
|
||||
- aarch64
|
||||
rules:
|
||||
- if: '$PROMOTE_BRANCH'
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
- apt-get install -y tmux curl
|
||||
script:
|
||||
# comment out to debug: SSH in via GCP, go down the container and attach to the session (with `tmux attach -t debug`)
|
||||
# - tmux new-session -d -s debug
|
||||
# - while tmux has-session -t debug 2>/dev/null; do sleep 1; done
|
||||
|
||||
# ref controls which fex-depot code runs the pipeline, while VERSION_PARAM controls which fex branch's artifacts that pipeline downloads.
|
||||
- >
|
||||
curl --fail --location --request POST --form token=${FEX_DEPOT_TRIGGER_TOKEN} --form ref=master --form "variables[PROMOTE_BRANCH]=${PROMOTE_BRANCH}" --form "variables[VERSION_PARAM]=${CI_COMMIT_REF_NAME}" "${CI_API_V4_URL}/projects/fex%2Ffex-depot/trigger/pipeline"
|
||||
+16
-11
@@ -5,10 +5,6 @@
|
||||
[submodule "External/cpp-optparse"]
|
||||
path = Source/Common/cpp-optparse
|
||||
url = https://github.com/Sonicadvance1/cpp-optparse
|
||||
[submodule "External/xbyak"]
|
||||
shallow = true
|
||||
path = External/xbyak
|
||||
url = https://github.com/herumi/xbyak.git
|
||||
[submodule "External/fex-posixtest-bins"]
|
||||
shallow = true
|
||||
path = External/fex-posixtest-bins
|
||||
@@ -21,9 +17,6 @@
|
||||
shallow = true
|
||||
path = External/fex-gcc-target-tests-bins
|
||||
url = https://github.com/FEX-Emu/fex-gcc-target-tests-bins.git
|
||||
[submodule "External/jemalloc"]
|
||||
path = External/jemalloc
|
||||
url = https://github.com/FEX-Emu/jemalloc.git
|
||||
[submodule "External/fmt"]
|
||||
path = External/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
@@ -36,10 +29,6 @@
|
||||
[submodule "External/Catch2"]
|
||||
path = External/Catch2
|
||||
url = https://github.com/catchorg/Catch2.git
|
||||
[submodule "External/robin-map"]
|
||||
shallow = true
|
||||
path = External/robin-map
|
||||
url = https://github.com/FEX-Emu/robin-map.git
|
||||
[submodule "External/Vulkan-Headers"]
|
||||
shallow = true
|
||||
path = External/Vulkan-Headers
|
||||
@@ -47,3 +36,19 @@
|
||||
[submodule "External/jemalloc_glibc"]
|
||||
path = External/jemalloc_glibc
|
||||
url = https://github.com/FEX-Emu/jemalloc.git
|
||||
[submodule "External/tracy"]
|
||||
path = External/tracy
|
||||
url = https://github.com/wolfpld/tracy
|
||||
[submodule "External/range-v3"]
|
||||
path = External/range-v3
|
||||
url = https://github.com/ericniebler/range-v3.git
|
||||
[submodule "External/zydis"]
|
||||
shallow = true
|
||||
path = External/zydis
|
||||
url = https://github.com/zyantific/zydis.git
|
||||
[submodule "External/unordered_dense"]
|
||||
path = External/unordered_dense
|
||||
url = https://github.com/martinus/unordered_dense.git
|
||||
[submodule "External/rpmalloc"]
|
||||
path = External/rpmalloc
|
||||
url = https://github.com/FEX-Emu/rpmalloc.git
|
||||
@@ -0,0 +1 @@
|
||||
AI must not be used to generate code for contributions to this project.
|
||||
@@ -0,0 +1 @@
|
||||
AI must not be used to generate code for contributions to this project.
|
||||
+355
-236
@@ -1,66 +1,147 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(FEX C CXX ASM)
|
||||
|
||||
INCLUDE (CheckIncludeFiles)
|
||||
CHECK_INCLUDE_FILES ("gdb/jit-reader.h" HAVE_GDB_JIT_READER_H)
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files("gdb/jit-reader.h" HAVE_GDB_JIT_READER_H)
|
||||
|
||||
option(BUILD_TESTS "Build unit tests to ensure sanity" TRUE)
|
||||
option(BUILD_FEX_LINUX_TESTS "Build FEXLinuxTests, requires x86 compiler" FALSE)
|
||||
option(BUILD_FEX_LINUX_TESTS "Build FEXLinuxTests (requires x86 compiler)" FALSE)
|
||||
option(BUILD_THUNKS "Build thunks" FALSE)
|
||||
option(BUILD_FEXCONFIG "Build FEXConfig" TRUE)
|
||||
option(ENABLE_CLANG_THUNKS "Build thunks with clang" FALSE)
|
||||
option(ENABLE_IWYU "Enables include what you use program" FALSE)
|
||||
option(ENABLE_CLANG_THUNKS "Build thunks with clang" TRUE)
|
||||
option(ENABLE_IWYU "Enable the Include What You Use sanitizer" FALSE)
|
||||
option(ENABLE_LTO "Enable LTO with compilation" TRUE)
|
||||
option(ENABLE_XRAY "Enable building with LLVM X-Ray" FALSE)
|
||||
set(USE_LINKER "" CACHE STRING "Allow overriding the linker path directly")
|
||||
option(ENABLE_ASAN "Enables Clang ASAN" FALSE)
|
||||
option(ENABLE_TSAN "Enables Clang TSAN" FALSE)
|
||||
option(ENABLE_COVERAGE "Enables Coverage" FALSE)
|
||||
option(ENABLE_ASSERTIONS "Enables assertions in build" FALSE)
|
||||
option(ENABLE_GDB_SYMBOLS "Enables GDBSymbols integration support" ${HAVE_GDB_JIT_READER_H})
|
||||
option(ENABLE_STRICT_WERROR "Enables stricter -Werror for CI" FALSE)
|
||||
option(ENABLE_WERROR "Enables -Werror" FALSE)
|
||||
option(ENABLE_JEMALLOC "Enables jemalloc allocator" TRUE)
|
||||
option(ENABLE_JEMALLOC_GLIBC_ALLOC "Enables jemalloc glibc allocator" TRUE)
|
||||
option(ENABLE_OFFLINE_TELEMETRY "Enables FEX offline telemetry" TRUE)
|
||||
option(ENABLE_COMPILE_TIME_TRACE "Enables time trace compile option" FALSE)
|
||||
option(ENABLE_LIBCXX "Enables LLVM libc++" FALSE)
|
||||
option(ENABLE_CCACHE "Enables ccache for compile caching" TRUE)
|
||||
option(ENABLE_VIXL_SIMULATOR "Forces the FEX JIT to use the VIXL simulator" FALSE)
|
||||
option(ENABLE_VIXL_DISASSEMBLER "Enables debug disassembler output with VIXL" FALSE)
|
||||
option(USE_LEGACY_BINFMTMISC "Uses legacy method of setting up binfmt_misc" FALSE)
|
||||
option(COMPILE_VIXL_DISASSEMBLER "Compiles the vixl disassembler in to vixl" FALSE)
|
||||
option(ENABLE_FEXCORE_PROFILER "Enables use of the FEXCore timeline profiling capabilities" FALSE)
|
||||
set (FEXCORE_PROFILER_BACKEND "gpuvis" CACHE STRING "Set which backend you want to use for the FEXCore profiler")
|
||||
set(USE_LINKER "" CACHE STRING "Path to a custom linker program")
|
||||
option(ENABLE_UBSAN "Enable the Clang Undefined Behavior Sanitizer" FALSE)
|
||||
option(ENABLE_ASAN "Enable the Clang Address Sanitizer" FALSE)
|
||||
option(ENABLE_TSAN "Enable the Clang Thread Sanitizer" FALSE)
|
||||
option(ENABLE_COVERAGE "Enable Code Coverage" FALSE)
|
||||
option(ENABLE_ASSERTIONS "Enable debug assertions" FALSE)
|
||||
option(ENABLE_GDB_SYMBOLS "Enable GDBSymbols integration support" ${HAVE_GDB_JIT_READER_H})
|
||||
option(ENABLE_STRICT_WERROR "Enable stricter -Werror" FALSE)
|
||||
option(ENABLE_WERROR "Enable -Werror" FALSE)
|
||||
option(ENABLE_FEX_ALLOCATOR "Enable allocator for FEX" TRUE)
|
||||
option(ENABLE_JEMALLOC_GLIBC_ALLOC "Enable jemalloc glibc allocator" TRUE)
|
||||
option(ENABLE_OFFLINE_TELEMETRY "Enable FEX offline telemetry" TRUE)
|
||||
option(ENABLE_COMPILE_TIME_TRACE "Enable time trace compile option" FALSE)
|
||||
option(ENABLE_LIBCXX "Use LLVM's libc++ instead of the GNU libstdc++" FALSE)
|
||||
option(ENABLE_CCACHE "Enable ccache for build caching" TRUE)
|
||||
option(ENABLE_VIXL_SIMULATOR "Use the VIXL simulator for emulation (only useful for CI testing)" FALSE)
|
||||
option(ENABLE_VIXL_DISASSEMBLER "Enable debug disassembler output with VIXL" FALSE)
|
||||
option(ENABLE_ZYDIS "Enable x86/x86-64 guest disassembler output with Zydis" FALSE)
|
||||
option(USE_LEGACY_BINFMTMISC "Use legacy method of setting up binfmt_misc" FALSE)
|
||||
option(ENABLE_FEXCORE_PROFILER "Enable FEXCore's timeline profiling capabilities" FALSE)
|
||||
set(FEXCORE_PROFILER_BACKEND "gpuvis" CACHE STRING "Set which backend to use for FEXCore's profiler")
|
||||
set_property(CACHE FEXCORE_PROFILER_BACKEND PROPERTY STRINGS gpuvis tracy)
|
||||
option(ENABLE_GLIBC_ALLOCATOR_HOOK_FAULT "Enables glibc memory allocation hooking with fault for CI testing")
|
||||
option(USE_PDB_DEBUGINFO "Builds debug info in PDB format" FALSE)
|
||||
option(USE_PDB_DEBUGINFO "Build debug info in PDB format" FALSE)
|
||||
option(BUILD_STEAM_SUPPORT "Enable Steam integration" FALSE)
|
||||
|
||||
set (X86_32_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain_x86_32.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting i686")
|
||||
set (X86_64_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain_x86_64.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting x86_64")
|
||||
set (DATA_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/fex-emu" CACHE PATH "global data directory")
|
||||
set(X86_32_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Data/CMake/toolchain_x86_32.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting i686")
|
||||
set(X86_64_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Data/CMake/toolchain_x86_64.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting x86_64")
|
||||
set(X86_DEV_ROOTFS "/" CACHE FILEPATH "Path to the sysroot used for cross-compiling for i686 and x86_64")
|
||||
set(DATA_DIRECTORY "" CACHE PATH "Global data directory (override)")
|
||||
set(HOSTLIBS_DATA_DIRECTORY "" CACHE PATH "Global data directory (override)")
|
||||
|
||||
string(FIND ${CMAKE_BASE_NAME} mingw CONTAINS_MINGW)
|
||||
if (NOT CONTAINS_MINGW EQUAL -1)
|
||||
message (STATUS "Mingw build")
|
||||
set (MINGW_BUILD TRUE)
|
||||
set (ENABLE_JEMALLOC TRUE)
|
||||
set (ENABLE_JEMALLOC_GLIBC_ALLOC FALSE)
|
||||
if (NOT DATA_DIRECTORY)
|
||||
set(DATA_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/fex-emu")
|
||||
endif()
|
||||
|
||||
if (NOT MINGW_BUILD)
|
||||
message (STATUS "Clang version ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
set (CLANG_MINIMUM_VERSION 13.0)
|
||||
include(GNUInstallDirs)
|
||||
if (NOT HOSTLIBS_DATA_DIRECTORY)
|
||||
set(HOSTLIBS_DATA_DIRECTORY "${CMAKE_INSTALL_FULL_LIBDIR}/fex-emu")
|
||||
endif()
|
||||
|
||||
## Platform Checks ##
|
||||
# Only 64-bit Linux and Windows are supported
|
||||
|
||||
# NB: SIZEOF_VOID_P is in bytes, not bits
|
||||
# On 32-bit systems this is set to 4
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(FATAL_ERROR "Unsupported pointer size ${CMAKE_SIZEOF_VOID_P}."
|
||||
" FEX only supports 64-bit (8-byte pointer) systems."
|
||||
" If you believe this is in error, file an issue.")
|
||||
elseif (NOT (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||
message(FATAL_ERROR "Unsupported system type ${CMAKE_SYSTEM_NAME}."
|
||||
" FEX only supports Linux and Windows."
|
||||
" If you believe this is in error, file an issue.")
|
||||
endif()
|
||||
|
||||
## Compiler Checks ##
|
||||
# GCC and MSVC are unsupported
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
message(FATAL_ERROR "FEX doesn't support GCC! Use Clang instead.")
|
||||
elseif (MSVC)
|
||||
message(FATAL_ERROR "FEX doesn't support MSVC! Use Clang on MinGW instead.")
|
||||
elseif (MINGW)
|
||||
message(STATUS "Building for MinGW")
|
||||
set(ENABLE_FEX_ALLOCATOR TRUE)
|
||||
set(ENABLE_JEMALLOC_GLIBC_ALLOC FALSE)
|
||||
else ()
|
||||
message(STATUS "Clang version ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
set(CLANG_MINIMUM_VERSION 13.0)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${CLANG_MINIMUM_VERSION})
|
||||
message (FATAL_ERROR "Clang version too old for FEX. Need at least ${CLANG_MINIMUM_VERSION} but has ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
message(FATAL_ERROR "Clang version too old for FEX. Need at least ${CLANG_MINIMUM_VERSION} but has ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
## Architecture Handling ##
|
||||
string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} processor)
|
||||
if (processor MATCHES "x86|amd64")
|
||||
option(ENABLE_X86_HOST_DEBUG "Enables compiling on x86_64 host" FALSE)
|
||||
if (NOT ENABLE_X86_HOST_DEBUG)
|
||||
message(FATAL_ERROR
|
||||
" FEX doesn't support compiling for x86-64 hosts!"
|
||||
" This is /only/ a supported configuration for FEX CI and nothing else!")
|
||||
else()
|
||||
message(STATUS "x86_64 debug build")
|
||||
endif()
|
||||
|
||||
set(ARCHITECTURE_x86_64 1)
|
||||
add_compile_definitions(ARCHITECTURE_x86_64=1)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcx16")
|
||||
elseif (processor MATCHES "^aarch64|^arm64|^armv8\.*")
|
||||
set(ARCHITECTURE_arm64 1)
|
||||
add_compile_definitions(ARCHITECTURE_arm64=1)
|
||||
|
||||
# arm64ec needs to define both arm64 and arm64ec
|
||||
if (processor MATCHES "^arm64ec")
|
||||
set(ARCHITECTURE_arm64ec 1)
|
||||
add_compile_definitions(ARCHITECTURE_arm64ec=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT (ARCHITECTURE_arm64 OR ARCHITECTURE_arm64ec OR ARCHITECTURE_x86_64))
|
||||
message(FATAL_ERROR "Unsupported processor type ${processor}."
|
||||
" If you believe this is in error, file an issue.")
|
||||
endif()
|
||||
|
||||
if (BUILD_STEAM_SUPPORT)
|
||||
add_compile_definitions(FEX_STEAM_SUPPORT=1)
|
||||
endif()
|
||||
|
||||
if (ENABLE_FEXCORE_PROFILER)
|
||||
add_definitions(-DENABLE_FEXCORE_PROFILER=1)
|
||||
add_compile_definitions(ENABLE_FEXCORE_PROFILER=1)
|
||||
string(TOUPPER "${FEXCORE_PROFILER_BACKEND}" FEXCORE_PROFILER_BACKEND)
|
||||
|
||||
if (FEXCORE_PROFILER_BACKEND STREQUAL "GPUVIS")
|
||||
add_definitions(-DFEXCORE_PROFILER_BACKEND=1)
|
||||
add_compile_definitions(FEXCORE_PROFILER_BACKEND=1)
|
||||
elseif (FEXCORE_PROFILER_BACKEND STREQUAL "TRACY")
|
||||
add_compile_definitions(FEXCORE_PROFILER_BACKEND=2)
|
||||
add_compile_definitions(TRACY_ENABLE=1)
|
||||
# Required so that Tracy will only start in the selected guest application
|
||||
add_compile_definitions(TRACY_MANUAL_LIFETIME=1)
|
||||
add_compile_definitions(TRACY_DELAYED_INIT=1)
|
||||
# This interferes with FEX's signal handling
|
||||
add_compile_definitions(TRACY_NO_CRASH_HANDLER=1)
|
||||
# Tracy can gather call stack samples in regular intervals, but this
|
||||
# isn't useful for us since it would usually sample opaque JIT code
|
||||
add_compile_definitions(TRACY_NO_SAMPLING=1)
|
||||
# This pulls in libbacktrace which allocators in global constructors (before FEX can set up its allocator hooks)
|
||||
add_compile_definitions(TRACY_NO_CALLSTACK=1)
|
||||
if (MINGW)
|
||||
message(FATAL_ERROR "Tracy profiler not supported on MinGW")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown FEXCore profiler backend ${FEXCORE_PROFILER_BACKEND}")
|
||||
endif()
|
||||
@@ -71,13 +152,13 @@ if (ENABLE_JEMALLOC_GLIBC_ALLOC AND ENABLE_GLIBC_ALLOCATOR_HOOK_FAULT)
|
||||
endif()
|
||||
|
||||
if (ENABLE_GLIBC_ALLOCATOR_HOOK_FAULT)
|
||||
add_definitions(-DGLIBC_ALLOCATOR_FAULT=1)
|
||||
add_compile_definitions(GLIBC_ALLOCATOR_FAULT=1)
|
||||
endif()
|
||||
|
||||
# uninstall target
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeFiles/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Data/CMake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
@@ -86,9 +167,17 @@ if(NOT TARGET uninstall)
|
||||
endif()
|
||||
|
||||
# These options are meant for package management
|
||||
set (TUNE_CPU "native" CACHE STRING "Override the CPU the build is tuned for")
|
||||
set (TUNE_ARCH "generic" CACHE STRING "Override the Arch the build is tuned for")
|
||||
set (OVERRIDE_VERSION "detect" CACHE STRING "Override the FEX version in the format of <MMYY>{.<REV>}")
|
||||
set(TUNE_CPU "native" CACHE STRING "Override the CPU the build is tuned for")
|
||||
set(TUNE_ARCH "generic" CACHE STRING "Override the Arch the build is tuned for")
|
||||
set(OVERRIDE_VERSION "detect" CACHE STRING "Override the FEX version")
|
||||
set(OVERRIDE_HASH "detect" CACHE STRING "Override the FEX git hash")
|
||||
|
||||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release
|
||||
CACHE STRING "Choose the type of build." FORCE)
|
||||
message(STATUS "No build type set, defaulting to a Release build")
|
||||
endif()
|
||||
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
|
||||
if (CMAKE_BUILD_TYPE MATCHES "DEBUG")
|
||||
@@ -97,14 +186,18 @@ endif()
|
||||
|
||||
if (ENABLE_ASSERTIONS)
|
||||
message(STATUS "Assertions enabled")
|
||||
add_definitions(-DASSERTIONS_ENABLED=1)
|
||||
add_compile_definitions(ASSERTIONS_ENABLED=1)
|
||||
endif()
|
||||
|
||||
if (ENABLE_GDB_SYMBOLS)
|
||||
message(STATUS "GDBSymbols support enabled")
|
||||
add_definitions(-DGDB_SYMBOLS_ENABLED=1)
|
||||
add_compile_definitions(GDB_SYMBOLS_ENABLED=1)
|
||||
endif()
|
||||
|
||||
add_compile_definitions(_LARGEFILE64_SOURCE)
|
||||
if (WIN32)
|
||||
add_compile_definitions(UNICODE _UNICODE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
@@ -115,33 +208,7 @@ cmake_policy(SET CMP0083 NEW) # Follow new PIE policy
|
||||
include(CheckPIESupported)
|
||||
check_pie_supported()
|
||||
|
||||
if (ENABLE_LTO)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
else()
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
|
||||
option(ENABLE_X86_HOST_DEBUG "Enables compiling on x86_64 host" FALSE)
|
||||
if (NOT ENABLE_X86_HOST_DEBUG)
|
||||
message(FATAL_ERROR
|
||||
" FEX-Emu doesn't support compiling for x86-64 hosts!"
|
||||
" This is /only/ a supported configuration for FEX CI and nothing else!")
|
||||
endif()
|
||||
set(_M_X86_64 1)
|
||||
add_definitions(-D_M_X86_64=1)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcx16")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64|^arm64|^armv8\.*")
|
||||
set(_M_ARM_64 1)
|
||||
add_definitions(-D_M_ARM_64=1)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm64ec")
|
||||
set(_M_ARM_64EC 1)
|
||||
add_definitions(-D_M_ARM_64EC=1)
|
||||
endif()
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO})
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -Wattributes -Werror=attributes")
|
||||
@@ -157,30 +224,47 @@ check_cxx_source_compiles(
|
||||
HAS_CLANG_PRESERVE_ALL)
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
if (HAS_CLANG_PRESERVE_ALL)
|
||||
if (MINGW_BUILD)
|
||||
if (MINGW)
|
||||
message(STATUS "Ignoring broken clang::preserve_all support")
|
||||
set(HAS_CLANG_PRESERVE_ALL FALSE)
|
||||
else()
|
||||
message(STATUS "Has clang::preserve_all")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (_M_ARM_64 AND HAS_CLANG_PRESERVE_ALL)
|
||||
add_definitions("-DFEX_PRESERVE_ALL_ATTR=__attribute__((preserve_all))" "-DFEX_HAS_PRESERVE_ALL_ATTR=1")
|
||||
else()
|
||||
add_definitions("-DFEX_PRESERVE_ALL_ATTR=" "-DFEX_HAS_PRESERVE_ALL_ATTR=0")
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_arm64 AND HAS_CLANG_PRESERVE_ALL)
|
||||
add_compile_definitions("FEX_PRESERVE_ALL_ATTR=__attribute__((preserve_all))" "FEX_HAS_PRESERVE_ALL_ATTR=1")
|
||||
else()
|
||||
add_compile_definitions("FEX_PRESERVE_ALL_ATTR=" "FEX_HAS_PRESERVE_ALL_ATTR=0")
|
||||
endif()
|
||||
|
||||
check_cxx_source_compiles(
|
||||
"
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
int main() {
|
||||
return program_invocation_name == nullptr;
|
||||
}"
|
||||
HAS_PROGRAM_INVOCATION_NAME)
|
||||
add_compile_definitions("HAS_PROGRAM_INVOCATION_NAME=${HAS_PROGRAM_INVOCATION_NAME}")
|
||||
|
||||
if (ENABLE_VIXL_SIMULATOR)
|
||||
# We can run the simulator on both x86-64 or AArch64 hosts
|
||||
add_definitions(-DVIXL_SIMULATOR=1 -DVIXL_INCLUDE_SIMULATOR_AARCH64=1)
|
||||
add_compile_definitions(VIXL_SIMULATOR=1 VIXL_INCLUDE_SIMULATOR_AARCH64=1)
|
||||
endif()
|
||||
|
||||
if (ENABLE_CCACHE)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
message(STATUS "CCache enabled")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
execute_process(COMMAND "${CCACHE_PROGRAM}" --print-version
|
||||
OUTPUT_VARIABLE CCACHE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Enabling ccache ${CCACHE_VERSION}")
|
||||
if (CCACHE_VERSION VERSION_GREATER_EQUAL "4.8")
|
||||
# Set sloppiness to enable caching even for files that use __DATE__/__TIME__ macros
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM} sloppiness=time_macros")
|
||||
else()
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -194,7 +278,7 @@ if (ENABLE_COMPILE_TIME_TRACE)
|
||||
link_libraries(-ftime-trace)
|
||||
endif()
|
||||
|
||||
set (PTHREAD_LIB pthread)
|
||||
set(PTHREAD_LIB pthread)
|
||||
|
||||
if (USE_LINKER)
|
||||
message(STATUS "Overriding linker to: ${USE_LINKER}")
|
||||
@@ -209,11 +293,24 @@ endif()
|
||||
|
||||
if (NOT ENABLE_OFFLINE_TELEMETRY)
|
||||
# Disable FEX offline telemetry entirely if asked
|
||||
add_definitions(-DFEX_DISABLE_TELEMETRY=1)
|
||||
add_compile_definitions(FEX_DISABLE_TELEMETRY=1)
|
||||
endif()
|
||||
|
||||
if (ENABLE_UBSAN)
|
||||
# See https://github.com/FEX-Emu/FEX/pull/4494#issuecomment-2800608944
|
||||
# and related discussion for the use of -fno-sanitize=alignment -fno-sanitize=function
|
||||
# with UBSAN.
|
||||
# alignment: we don't follow a strict alignment policy, for example IR uses packed structs
|
||||
# that are regularly access unaligned.
|
||||
# function: syscalls cast function pointers to void (*)(unsigned long...), causing warnings
|
||||
# related to this access.
|
||||
add_compile_definitions(ENABLE_UBSAN=1)
|
||||
add_compile_options(-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=function -fno-sanitize-recover=undefined)
|
||||
link_libraries(-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=function -fno-sanitize-recover=undefined)
|
||||
endif()
|
||||
|
||||
if (ENABLE_ASAN)
|
||||
add_definitions(-DENABLE_ASAN=1)
|
||||
add_compile_definitions(ENABLE_ASAN=1)
|
||||
add_compile_options(-fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope)
|
||||
link_libraries(-fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope)
|
||||
endif()
|
||||
@@ -233,20 +330,20 @@ if (ENABLE_JEMALLOC_GLIBC_ALLOC)
|
||||
# Required for thunks to work.
|
||||
# All host native libraries will use this allocator, while *most* other FEX internal allocations will use the other jemalloc allocator.
|
||||
add_subdirectory(External/jemalloc_glibc/)
|
||||
elseif (NOT MINGW_BUILD)
|
||||
message (STATUS
|
||||
elseif (NOT MINGW)
|
||||
message(STATUS
|
||||
" jemalloc glibc allocator disabled!\n"
|
||||
" This is not a recommended configuration!\n"
|
||||
" This will very explicitly break thunk execution!\n"
|
||||
" Use at your own risk!")
|
||||
endif()
|
||||
|
||||
if (ENABLE_JEMALLOC)
|
||||
# The jemalloc subproject that all FEXCore fextl objects allocate through.
|
||||
add_subdirectory(External/jemalloc/)
|
||||
elseif (NOT MINGW_BUILD)
|
||||
if (ENABLE_FEX_ALLOCATOR)
|
||||
# The rpmalloc subproject that all FEXCore fextl objects allocate through.
|
||||
add_subdirectory(External/rpmalloc/)
|
||||
elseif (NOT MINGW)
|
||||
message (STATUS
|
||||
" jemalloc disabled!\n"
|
||||
" FEX allocator is disabled!\n"
|
||||
" This is not a recommended configuration!\n"
|
||||
" This will very explicitly break 32-bit application execution!\n"
|
||||
" Use at your own risk!")
|
||||
@@ -257,48 +354,67 @@ if (USE_PDB_DEBUGINFO)
|
||||
add_link_options(-g -Wl,--pdb=)
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||
set (CMAKE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_LINKER_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||
set(CMAKE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_LINKER_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
set (CMAKE_LINKER_FLAGS_RELEASE "${CMAKE_LINKER_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
set(CMAKE_LINKER_FLAGS_RELEASE "${CMAKE_LINKER_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
|
||||
include_directories(External/robin-map/include/)
|
||||
## Modules ##
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Data/CMake/)
|
||||
|
||||
if (BUILD_TESTS)
|
||||
# Enable vixl disassembler if tests are enabled.
|
||||
set(COMPILE_VIXL_DISASSEMBLER TRUE)
|
||||
include(LinkerGC)
|
||||
|
||||
## Externals ##
|
||||
|
||||
find_package(unordered_dense QUIET CONFIG)
|
||||
if (NOT unordered_dense_FOUND)
|
||||
add_subdirectory(External/unordered_dense)
|
||||
endif()
|
||||
|
||||
if (COMPILE_VIXL_DISASSEMBLER OR ENABLE_VIXL_SIMULATOR)
|
||||
include(CTest)
|
||||
if (BUILD_TESTING OR ENABLE_VIXL_DISASSEMBLER OR ENABLE_VIXL_SIMULATOR)
|
||||
add_subdirectory(External/vixl/)
|
||||
include_directories(SYSTEM External/vixl/src/)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# This means we were attempted to get compiled with GCC
|
||||
message(FATAL_ERROR "FEX doesn't support getting compiled with GCC!")
|
||||
if (ENABLE_ZYDIS)
|
||||
find_package(Zycore 1.5 MODULE QUIET)
|
||||
find_package(Zydis 4.0 MODULE QUIET)
|
||||
|
||||
if (TARGET Zydis::Zydis AND TARGET Zycore::Zycore)
|
||||
message(STATUS "Using system Zydis")
|
||||
else()
|
||||
set(ZYDIS_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
|
||||
set(ZYDIS_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
|
||||
message(STATUS "Using bundled Zydis")
|
||||
add_subdirectory(External/zydis/)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Python 3.0 REQUIRED COMPONENTS Interpreter)
|
||||
if (ENABLE_FEXCORE_PROFILER AND FEXCORE_PROFILER_BACKEND STREQUAL "TRACY")
|
||||
add_subdirectory(External/tracy)
|
||||
endif()
|
||||
|
||||
find_package(Python 3.9 REQUIRED COMPONENTS Interpreter)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
pkg_search_module(xxhash IMPORTED_TARGET xxhash libxxhash)
|
||||
if (TARGET PkgConfig::xxhash AND NOT CMAKE_CROSSCOMPILING)
|
||||
add_library(xxHash::xxhash ALIAS PkgConfig::xxhash)
|
||||
else()
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
find_package(xxhash MODULE QUIET)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET xxHash::xxhash)
|
||||
set(XXHASH_BUNDLED_MODE TRUE)
|
||||
set(XXHASH_BUILD_XXHSUM FALSE)
|
||||
add_subdirectory(External/xxhash/cmake_unofficial/)
|
||||
endif()
|
||||
|
||||
add_definitions(-Wno-trigraphs)
|
||||
add_definitions(-DGLOBAL_DATA_DIRECTORY="${DATA_DIRECTORY}/")
|
||||
add_compile_options(-Wno-trigraphs)
|
||||
add_compile_definitions(GLOBAL_DATA_DIRECTORY="${DATA_DIRECTORY}/")
|
||||
|
||||
if (BUILD_TESTS)
|
||||
find_package(Catch2 QUIET)
|
||||
if (BUILD_TESTING)
|
||||
find_package(Catch2 3 QUIET)
|
||||
if (NOT Catch2_FOUND)
|
||||
add_subdirectory(External/Catch2/)
|
||||
|
||||
@@ -307,17 +423,30 @@ if (BUILD_TESTS)
|
||||
endif()
|
||||
|
||||
include(Catch)
|
||||
else ()
|
||||
# Override any previously generated test list to avoid running stale test binaries
|
||||
file(GENERATE OUTPUT CTestTestfile.cmake CONTENT "# No tests since BUILD_TESTING is disabled")
|
||||
endif()
|
||||
|
||||
find_package(fmt QUIET)
|
||||
if (NOT fmt_FOUND)
|
||||
# Disable fmt install
|
||||
if (MINGW)
|
||||
set(FMT_INSTALL OFF)
|
||||
add_subdirectory(External/fmt/)
|
||||
else()
|
||||
find_package(fmt QUIET)
|
||||
if (NOT fmt_FOUND)
|
||||
# Disable fmt install
|
||||
set(FMT_INSTALL OFF)
|
||||
add_subdirectory(External/fmt/)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(range-v3 QUIET)
|
||||
if (NOT range-v3_FOUND)
|
||||
add_subdirectory(External/range-v3/)
|
||||
target_compile_definitions(range-v3 INTERFACE RANGES_DISABLE_DEPRECATED_WARNINGS)
|
||||
endif()
|
||||
|
||||
add_subdirectory(External/tiny-json/)
|
||||
include_directories(External/tiny-json/)
|
||||
|
||||
include_directories(Source/)
|
||||
include_directories("${CMAKE_BINARY_DIR}/Source/")
|
||||
@@ -341,6 +470,11 @@ if(ENUM_ENUM_WARNING)
|
||||
add_compile_options(-Wno-deprecated-enum-enum-conversion)
|
||||
endif()
|
||||
|
||||
# GCC enables -Wchanges-meaning by default and treats some cases as an error
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(-Wno-error=changes-meaning)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WERROR OR ENABLE_STRICT_WERROR)
|
||||
add_compile_options(-Werror)
|
||||
if (NOT ENABLE_STRICT_WERROR)
|
||||
@@ -351,16 +485,24 @@ endif()
|
||||
|
||||
set(FEX_TUNE_COMPILE_FLAGS)
|
||||
if (NOT TUNE_ARCH STREQUAL "generic")
|
||||
check_cxx_compiler_flag("-march=${TUNE_ARCH}" COMPILER_SUPPORTS_ARCH_TYPE)
|
||||
if(COMPILER_SUPPORTS_ARCH_TYPE)
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-march=${TUNE_ARCH}")
|
||||
else()
|
||||
message(FATAL_ERROR "Trying to compile arch type '${TUNE_ARCH}' but the compiler doesn't support this")
|
||||
set(TUNE_ARCH_STRING "${TUNE_ARCH}")
|
||||
if(ARCHITECTURE_arm64)
|
||||
set(TUNE_ARCH_STRING "${TUNE_ARCH}+crc")
|
||||
endif()
|
||||
check_cxx_compiler_flag("-march=${TUNE_ARCH_STRING}" COMPILER_SUPPORTS_ARCH_TYPE)
|
||||
if(COMPILER_SUPPORTS_ARCH_TYPE)
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-march=${TUNE_ARCH_STRING}")
|
||||
else()
|
||||
message(FATAL_ERROR "Trying to compile arch type '${TUNE_ARCH_STRING}' but the compiler doesn't support this")
|
||||
endif()
|
||||
elseif(ARCHITECTURE_arm64)
|
||||
# Need to always append crc
|
||||
check_cxx_compiler_flag("-march=armv8-a+crc" COMPILER_SUPPORTS_ARCH_TYPE)
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-march=armv8-a+crc")
|
||||
endif()
|
||||
|
||||
if (TUNE_CPU STREQUAL "native")
|
||||
if(_M_ARM_64)
|
||||
if(ARCHITECTURE_arm64)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 999999.0)
|
||||
# Clang 12.0 fixed the -mcpu=native bug with mixed big.little implementers
|
||||
# Clang can not currently check for native Apple M1 type in hypervisor. Currently disabled
|
||||
@@ -369,15 +511,18 @@ if (TUNE_CPU STREQUAL "native")
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-mcpu=native")
|
||||
endif()
|
||||
else()
|
||||
# Due to an oversight in llvm, it declares any reasonably new Kryo CPU to only be ARMv8.0
|
||||
# Manually detect newer CPU revisions until clang and llvm fixes their bug
|
||||
# This script will either provide a supported CPU or 'native'
|
||||
# Additionally -march doesn't work under AArch64+Clang, so you have to use -mcpu or -mtune
|
||||
execute_process(COMMAND python3 "${PROJECT_SOURCE_DIR}/Scripts/aarch64_fit_native.py" "/proc/cpuinfo" "${CMAKE_CXX_COMPILER_VERSION}"
|
||||
OUTPUT_VARIABLE AARCH64_CPU)
|
||||
|
||||
string(STRIP ${AARCH64_CPU} AARCH64_CPU)
|
||||
|
||||
execute_process(COMMAND python3 "${PROJECT_SOURCE_DIR}/Scripts/NeedDisabledSVE.py"
|
||||
RESULT_VARIABLE NEEDS_SVE_DISABLED)
|
||||
if (NEEDS_SVE_DISABLED)
|
||||
message(STATUS "Platform has bugged SVE. Disabling")
|
||||
set(AARCH64_CPU "cortex-a78")
|
||||
endif()
|
||||
|
||||
check_cxx_compiler_flag("-mcpu=${AARCH64_CPU}" COMPILER_SUPPORTS_CPU_TYPE)
|
||||
if(COMPILER_SUPPORTS_CPU_TYPE)
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-mcpu=${AARCH64_CPU}")
|
||||
@@ -389,7 +534,7 @@ if (TUNE_CPU STREQUAL "native")
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-march=native")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
elseif (NOT TUNE_CPU STREQUAL "none")
|
||||
check_cxx_compiler_flag("-mcpu=${TUNE_CPU}" COMPILER_SUPPORTS_CPU_TYPE)
|
||||
if(COMPILER_SUPPORTS_CPU_TYPE)
|
||||
list(APPEND FEX_TUNE_COMPILE_FLAGS "-mcpu=${TUNE_CPU}")
|
||||
@@ -398,8 +543,54 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(GIT_DESCRIBE_STRING "FEX-Unknown")
|
||||
|
||||
if (OVERRIDE_VERSION STREQUAL "detect")
|
||||
find_package(Git)
|
||||
|
||||
if (GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --abbrev=7
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE_STRING
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
else()
|
||||
set(GIT_DESCRIBE_STRING "${OVERRIDE_VERSION}")
|
||||
endif()
|
||||
|
||||
set(GIT_HASH "Unknown")
|
||||
|
||||
if (OVERRIDE_HASH STREQUAL "detect")
|
||||
find_package(Git)
|
||||
|
||||
if (GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
else()
|
||||
set(GIT_HASH "${OVERRIDE_HASH}")
|
||||
endif()
|
||||
|
||||
message(STATUS "FEX version: ${GIT_DESCRIBE_STRING}")
|
||||
message(STATUS "FEX commit: ${GIT_HASH}")
|
||||
|
||||
# Prepends 0x to every two-character sequence in the hash,
|
||||
# OR the final character of the hash, to plumb it for C++ usage. e.g.:
|
||||
# -DOVERRIDE_HASH=123456aa => 0x12, 0x34, 0x56, 0xaa,
|
||||
# -DOVERRIDE_HASH=12345678a => 0x12, 0x34, 0x56, 0x78, 0xa,
|
||||
string(REGEX
|
||||
REPLACE "(..|.$)" "0x\\1, "
|
||||
GIT_HASH_ARRAY "${GIT_HASH}")
|
||||
|
||||
if (ENABLE_IWYU)
|
||||
find_program(IWYU_EXE "iwyu")
|
||||
find_program(IWYU_EXE
|
||||
NAMES iwyu include-what-you-use)
|
||||
if (IWYU_EXE)
|
||||
message(STATUS "IWYU enabled")
|
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${IWYU_EXE}")
|
||||
@@ -408,19 +599,10 @@ endif()
|
||||
|
||||
add_compile_options(-Wall)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.in
|
||||
${CMAKE_BINARY_DIR}/generated/ConfigDefines.h)
|
||||
|
||||
include(CTest)
|
||||
if (BUILD_TESTS)
|
||||
if (BUILD_TESTING)
|
||||
message(STATUS "Unit tests are enabled")
|
||||
if (NOT BUILD_TESTING)
|
||||
# CMake checks this variable before generating CTestTestfile.cmake
|
||||
message(SEND_ERROR "Unit tests require BUILD_TESTING to be enabled")
|
||||
endif()
|
||||
|
||||
set (TEST_JOB_COUNT "" CACHE STRING "Override number of parallel jobs to use while running tests")
|
||||
set(TEST_JOB_COUNT "" CACHE STRING "Override number of parallel jobs to use while running tests")
|
||||
if (TEST_JOB_COUNT)
|
||||
message(STATUS "Running tests with ${TEST_JOB_COUNT} jobs")
|
||||
elseif(CMAKE_VERSION VERSION_LESS "3.29")
|
||||
@@ -429,17 +611,22 @@ if (BUILD_TESTS)
|
||||
set(TEST_JOB_FLAG "-j${TEST_JOB_COUNT}")
|
||||
endif()
|
||||
|
||||
add_subdirectory(External/SoftFloat-3e/)
|
||||
add_subdirectory(External/cephes/)
|
||||
add_subdirectory(FEXHeaderUtils/)
|
||||
add_subdirectory(CodeEmitter/)
|
||||
add_subdirectory(FEXCore/)
|
||||
|
||||
if (_M_ARM_64 AND NOT MINGW_BUILD)
|
||||
if (ARCHITECTURE_arm64 AND NOT MINGW AND NOT BUILD_STEAM_SUPPORT)
|
||||
# Binfmt_misc files must be installed prior to Source/ installs
|
||||
add_subdirectory(Data/binfmts/)
|
||||
endif()
|
||||
|
||||
add_subdirectory(Source/)
|
||||
add_subdirectory(Data/AppConfig/)
|
||||
|
||||
if (NOT BUILD_STEAM_SUPPORT)
|
||||
add_subdirectory(Data/AppConfig/)
|
||||
endif()
|
||||
|
||||
# Install the ThunksDB file
|
||||
file(GLOB CONFIG_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Data/*.json)
|
||||
@@ -447,15 +634,16 @@ file(GLOB CONFIG_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Data/*.js
|
||||
# Any application configuration json file gets installed
|
||||
foreach(CONFIG_SRC ${CONFIG_SOURCES})
|
||||
install(FILES ${CONFIG_SRC}
|
||||
DESTINATION ${DATA_DIRECTORY}/)
|
||||
DESTINATION ${DATA_DIRECTORY}/
|
||||
COMPONENT Runtime)
|
||||
endforeach()
|
||||
|
||||
if (BUILD_TESTS)
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(unittests/)
|
||||
endif()
|
||||
|
||||
if (BUILD_THUNKS)
|
||||
set (FEX_PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR})
|
||||
set(FEX_PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR})
|
||||
add_subdirectory(ThunkLibs/Generator)
|
||||
|
||||
# Thunk targets for both host libraries and IDE integration
|
||||
@@ -479,10 +667,10 @@ if (BUILD_THUNKS)
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
"-DFEX_PROJECT_SOURCE_DIR=${FEX_PROJECT_SOURCE_DIR}"
|
||||
"-DGENERATOR_EXE=$<TARGET_FILE:thunkgen>"
|
||||
"-DX86_DEV_ROOTFS=${X86_DEV_ROOTFS}"
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS ON
|
||||
DEPENDS thunkgen
|
||||
)
|
||||
DEPENDS thunkgen)
|
||||
|
||||
ExternalProject_Add(guest-libs-32
|
||||
PREFIX guest-libs-32
|
||||
@@ -497,108 +685,39 @@ if (BUILD_THUNKS)
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
"-DFEX_PROJECT_SOURCE_DIR=${FEX_PROJECT_SOURCE_DIR}"
|
||||
"-DGENERATOR_EXE=$<TARGET_FILE:thunkgen>"
|
||||
"-DX86_DEV_ROOTFS=${X86_DEV_ROOTFS}"
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS ON
|
||||
DEPENDS thunkgen
|
||||
)
|
||||
DEPENDS thunkgen)
|
||||
|
||||
install(
|
||||
CODE "MESSAGE(\"-- Installing: guest-libs\")"
|
||||
CODE "message(\"-- Installing: guest-libs\")"
|
||||
CODE "
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} --build . --target install
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest
|
||||
)"
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . --target install
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest)"
|
||||
DEPENDS guest-libs
|
||||
)
|
||||
COMPONENT Runtime)
|
||||
|
||||
install(
|
||||
CODE "MESSAGE(\"-- Installing: guest-libs-32\")"
|
||||
CODE "message(\"-- Installing: guest-libs-32\")"
|
||||
CODE "
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} --build . --target install
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest_32
|
||||
)"
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . --target install
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest_32)"
|
||||
DEPENDS guest-libs-32
|
||||
)
|
||||
COMPONENT Runtime)
|
||||
|
||||
add_custom_target(uninstall_guest-libs
|
||||
COMMAND ${CMAKE_COMMAND} "--build" "." "--target" "uninstall"
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest
|
||||
)
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest)
|
||||
|
||||
add_custom_target(uninstall_guest-libs-32
|
||||
COMMAND ${CMAKE_COMMAND} "--build" "." "--target" "uninstall"
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest_32
|
||||
)
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Guest_32)
|
||||
|
||||
add_dependencies(uninstall uninstall_guest-libs)
|
||||
add_dependencies(uninstall uninstall_guest-libs-32)
|
||||
endif()
|
||||
|
||||
set(FEX_VERSION_MAJOR "0")
|
||||
set(FEX_VERSION_MINOR "0")
|
||||
set(FEX_VERSION_PATCH "0")
|
||||
|
||||
if (OVERRIDE_VERSION STREQUAL "detect")
|
||||
find_package(Git)
|
||||
if (GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --abbrev=0
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE_STRING
|
||||
RESULT_VARIABLE GIT_ERROR
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (NOT ${GIT_ERROR} EQUAL 0)
|
||||
# Likely built in a way that doesn't have tags
|
||||
# Setup a version tag that is unknown
|
||||
set(GIT_DESCRIBE_STRING "FEX-0000")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(GIT_DESCRIBE_STRING "FEX-${OVERRIDE_VERSION}")
|
||||
if (NOT MINGW AND BUILD_STEAM_SUPPORT)
|
||||
add_subdirectory(Source/Steam/)
|
||||
endif()
|
||||
|
||||
# Parse the version here
|
||||
# Change something like `FEX-2106.1-76-<hash>` in to a list
|
||||
string(REPLACE "-" ";" DESCRIBE_LIST ${GIT_DESCRIBE_STRING})
|
||||
|
||||
# Extract the `2106.1` element
|
||||
list(GET DESCRIBE_LIST 1 DESCRIBE_LIST)
|
||||
|
||||
# Change `2106.1` in to a list
|
||||
string(REPLACE "." ";" DESCRIBE_LIST ${DESCRIBE_LIST})
|
||||
|
||||
# Calculate list size
|
||||
list(LENGTH DESCRIBE_LIST LIST_SIZE)
|
||||
|
||||
# Pull out the major version
|
||||
list(GET DESCRIBE_LIST 0 FEX_VERSION_MAJOR)
|
||||
|
||||
# Minor version only exists if there is a .1 at the end
|
||||
# eg: 2106 versus 2106.1
|
||||
if (LIST_SIZE GREATER 1)
|
||||
list(GET DESCRIBE_LIST 1 FEX_VERSION_MINOR)
|
||||
endif()
|
||||
|
||||
# Package creation
|
||||
set (CPACK_GENERATOR "DEB")
|
||||
set (CPACK_PACKAGE_NAME fex-emu)
|
||||
set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${GIT_DESCRIBE_STRING}_${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set (CPACK_PACKAGE_CONTACT "FEX-Emu Maintainers <team@fex-emu.com>")
|
||||
set (CPACK_PACKAGE_VERSION_MAJOR "${FEX_VERSION_MAJOR}")
|
||||
set (CPACK_PACKAGE_VERSION_MINOR "${FEX_VERSION_MINOR}")
|
||||
set (CPACK_PACKAGE_VERSION_PATCH "${FEX_VERSION_PATCH}")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/CPack/Description.txt")
|
||||
|
||||
# Debian defines
|
||||
set (CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libstdc++6, libepoxy0, libsdl2-2.0-0, libegl1, libx11-6, squashfuse")
|
||||
set (CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CPack/postinst;${CMAKE_CURRENT_SOURCE_DIR}/CPack/prerm;${CMAKE_CURRENT_SOURCE_DIR}/CPack/triggers")
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
# binfmt_misc conflicts with qemu-user-static
|
||||
# We also only install binfmt_misc on aarch64 hosts
|
||||
set (CPACK_DEBIAN_PACKAGE_CONFLICTS "${CPACK_DEBIAN_PACKAGE_CONFLICTS}, qemu-user-static")
|
||||
endif()
|
||||
include (CPack)
|
||||
@@ -1,132 +0,0 @@
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"BuildPath": "${projectDir}\\out\\build\\${name}",
|
||||
"InstallPath": "${projectDir}\\out\\install\\${name}",
|
||||
"clangcl": "clang-cl.exe",
|
||||
"cc": "clang",
|
||||
"cxx": "clang++"
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "WSL-Clang-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${env.BuildPath}",
|
||||
"installRoot": "${env.InstallPath}",
|
||||
"cmakeExecutable": "/usr/bin/cmake",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"wslPath": "${defaultWSLPath}",
|
||||
"inheritEnvironments": [ "linux_clang_x64" ],
|
||||
"addressSanitizerRuntimeFlags": "detect_leaks=0",
|
||||
"variables": [
|
||||
{
|
||||
"name": "WSL",
|
||||
"value": "TRUE",
|
||||
"type": "BOOL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WSL-Clang-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${env.BuildPath}",
|
||||
"installRoot": "${env.InstallPath}",
|
||||
"cmakeExecutable": "/usr/bin/cmake",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"wslPath": "${defaultWSLPath}",
|
||||
"inheritEnvironments": [ "linux_clang_x64" ],
|
||||
"addressSanitizerRuntimeFlags": "detect_leaks=0",
|
||||
"variables": [
|
||||
{
|
||||
"name": "WSL",
|
||||
"value": "TRUE",
|
||||
"type": "BOOL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x86-Clang-Cross-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${env.BuildPath}",
|
||||
"installRoot": "${env.InstallPath}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x86" ],
|
||||
"variables": [
|
||||
{
|
||||
"name": "CMAKE_C_COMPILER",
|
||||
"value": "${env.cc}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_CXX_COMPILER",
|
||||
"value": "${env.cxx}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_SYSROOT",
|
||||
"value": "${env.fexsysroot}",
|
||||
"type": "STRING"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x64-Clang-Cross-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${env.BuildPath}",
|
||||
"installRoot": "${env.InstallPath}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x86" ],
|
||||
"variables": [
|
||||
{
|
||||
"name": "CMAKE_C_COMPILER",
|
||||
"value": "${env.cc}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_CXX_COMPILER",
|
||||
"value": "${env.cxx}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_SYSROOT",
|
||||
"value": "${env.fexsysroot}",
|
||||
"type": "STRING"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Linux-Clang-Remote-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"cmakeExecutable": "/usr/bin/cmake",
|
||||
"remoteCopySourcesExclusionList": [ ".vs", ".vscode", ".git", ".github", "build", "out", "bin" ],
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "linux_clang_x64" ],
|
||||
"remoteMachineName": "${env.fexremote}",
|
||||
"remoteCMakeListsRoot": "$HOME/projects/.vs/${projectDirName}/src",
|
||||
"remoteBuildRoot": "$HOME/projects/.vs/${projectDirName}/build/${name}",
|
||||
"remoteInstallRoot": "$HOME/projects/.vs/${projectDirName}/install/${name}",
|
||||
"remoteCopySources": true,
|
||||
"rsyncCommandArgs": "-t --delete --delete-excluded",
|
||||
"remoteCopyBuildOutput": false,
|
||||
"remoteCopySourcesMethod": "rsync",
|
||||
"addressSanitizerRuntimeFlags": "detect_leaks=0",
|
||||
"variables": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
No AI/ML/LLM/etc code contributions.
|
||||
@@ -1,3 +0,0 @@
|
||||
x86 and x86-64 Linux emulator
|
||||
|
||||
FEX is very much work in progress, so expect things to change.
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
update_binfmt() {
|
||||
# Check for update-binfmts
|
||||
command -v update-binfmts >/dev/null || return 0
|
||||
|
||||
# Setup binfmt_misc
|
||||
update-binfmts --import FEX-x86
|
||||
update-binfmts --import FEX-x86_64
|
||||
}
|
||||
|
||||
# Install FEXInterpreter hardlink
|
||||
# Needs to be done before setting up binfmt_misc
|
||||
ln -f /usr/bin/FEXLoader /usr/bin/FEXInterpreter
|
||||
|
||||
if [ $(uname -m) = 'aarch64' ]; then
|
||||
update_binfmt
|
||||
fi
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
update_binfmt() {
|
||||
# Check for update-binfmts
|
||||
command -v update-binfmts >/dev/null || return 0
|
||||
|
||||
# Uninstall
|
||||
update-binfmts --unimport FEX-x86
|
||||
update-binfmts --unimport FEX-x86_64
|
||||
}
|
||||
|
||||
if [ $(uname -m) = 'aarch64' ]; then
|
||||
update_binfmt
|
||||
fi
|
||||
|
||||
# Remove FEXInterpreter hardlink
|
||||
unlink /usr/bin/FEXInterpreter
|
||||
@@ -1 +0,0 @@
|
||||
activate-noawait ldconfig
|
||||
+209
-209
@@ -11,6 +11,14 @@
|
||||
* FEX-Emu ALU operations usually have a 32-bit or 64-bit operating size encoded in the IR operation,
|
||||
* This allows FEX to use a single helper function which decodes to both handlers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
#include <CodeEmitter/Emitter.h>
|
||||
namespace ARMEmitter {
|
||||
struct EmitterOps : Emitter {
|
||||
#endif
|
||||
|
||||
private:
|
||||
static bool IsADRRange(int64_t Imm) {
|
||||
return Imm >= -1048576 && Imm <= 1048575;
|
||||
@@ -28,27 +36,31 @@ public:
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
}
|
||||
|
||||
void adr(ARMEmitter::Register rd, BackwardLabel const* Label) {
|
||||
[[nodiscard]] BranchEncodeSucceeded adr(ARMEmitter::Register rd, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(IsADRRange(Imm), "Unscaled offset too large");
|
||||
if (IsADRRange(Imm)) {
|
||||
constexpr uint32_t Op = 0b0001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
constexpr uint32_t Op = 0b0001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void adr(ARMEmitter::Register rd, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::ADR });
|
||||
[[nodiscard]] BranchEncodeSucceeded adr(ARMEmitter::Register rd, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::ADR});
|
||||
constexpr uint32_t Op = 0b0001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void adr(ARMEmitter::Register rd, BiDirectionalLabel *Label) {
|
||||
[[nodiscard]] BranchEncodeSucceeded adr(ARMEmitter::Register rd, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
adr(rd, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
adr(rd, &Label->Forward);
|
||||
return adr(rd, &Label->Backward);
|
||||
} else {
|
||||
return adr(rd, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,43 +69,53 @@ public:
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
}
|
||||
|
||||
void adrp(ARMEmitter::Register rd, BackwardLabel const* Label) {
|
||||
[[nodiscard]] BranchEncodeSucceeded adrp(ARMEmitter::Register rd, const BackwardLabel* Label) {
|
||||
int64_t Imm = reinterpret_cast<int64_t>(Label->Location) - (GetCursorAddress<int64_t>() & ~0xFFFLL);
|
||||
LOGMAN_THROW_A_FMT(IsADRPRange(Imm) && IsADRPAligned(Imm), "Unscaled offset too large");
|
||||
|
||||
constexpr uint32_t Op = 0b1001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
if (IsADRPRange(Imm) && IsADRPAligned(Imm)) {
|
||||
constexpr uint32_t Op = 0b1001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, Imm);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void adrp(ARMEmitter::Register rd, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::ADRP });
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded adrp(ARMEmitter::Register rd, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::ADRP});
|
||||
constexpr uint32_t Op = 0b1001'0000 << 24;
|
||||
DataProcessing_PCRel_Imm(Op, rd, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void adrp(ARMEmitter::Register rd, BiDirectionalLabel *Label) {
|
||||
[[nodiscard]] BranchEncodeSucceeded adrp(ARMEmitter::Register rd, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
adrp(rd, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
adrp(rd, &Label->Forward);
|
||||
return adrp(rd, &Label->Backward);
|
||||
} else {
|
||||
return adrp(rd, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void LongAddressGen(ARMEmitter::Register rd, BackwardLabel const* Label) {
|
||||
int64_t Imm = reinterpret_cast<int64_t>(Label->Location) - (GetCursorAddress<int64_t>());
|
||||
[[nodiscard]] BranchEncodeSucceeded LongAddressGen(ARMEmitter::Register rd, const BackwardLabel* Label) {
|
||||
const auto SLocation = reinterpret_cast<int64_t>(Label->Location);
|
||||
const auto ULocation = std::bit_cast<uint64_t>(SLocation);
|
||||
|
||||
const int64_t Imm = SLocation - (GetCursorAddress<int64_t>());
|
||||
const auto UImm = std::bit_cast<uint64_t>(Imm);
|
||||
|
||||
if (IsADRRange(Imm)) {
|
||||
// If the range is in ADR range then we can just use ADR.
|
||||
adr(rd, Label);
|
||||
return adr(rd, Label);
|
||||
}
|
||||
else if (IsADRPRange(Imm)) {
|
||||
int64_t ADRPImm = (reinterpret_cast<int64_t>(Label->Location) & ~0xFFFLL)
|
||||
- (GetCursorAddress<int64_t>() & ~0xFFFLL);
|
||||
if (IsADRPRange(Imm)) {
|
||||
const int64_t ADRPImm = (SLocation & ~0xFFFLL) - (GetCursorAddress<int64_t>() & ~0xFFFLL);
|
||||
|
||||
// If the range is in the ADRP range then we can use ADRP.
|
||||
bool NeedsOffset = !IsADRPAligned(reinterpret_cast<uint64_t>(Label->Location));
|
||||
uint64_t AlignedOffset = reinterpret_cast<uint64_t>(Label->Location) & 0xFFFULL;
|
||||
const bool NeedsOffset = !IsADRPAligned(ULocation);
|
||||
const uint64_t AlignedOffset = ULocation & 0xFFFULL;
|
||||
|
||||
// First emit ADRP
|
||||
adrp(rd, ADRPImm >> 12);
|
||||
@@ -102,25 +124,33 @@ public:
|
||||
// Now even an add
|
||||
add(ARMEmitter::Size::i64Bit, rd, rd, AlignedOffset);
|
||||
}
|
||||
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
else {
|
||||
LOGMAN_MSG_A_FMT("Unscaled offset too large");
|
||||
FEX_UNREACHABLE;
|
||||
}
|
||||
|
||||
// Stinky path, we need to load the address as a sequence of movz+movk+movk
|
||||
movz(ARMEmitter::Size::i64Bit, rd, (UImm >> 32) & 0xFFFF, 32);
|
||||
movk(ARMEmitter::Size::i64Bit, rd, (UImm >> 16) & 0xFFFF, 16);
|
||||
movk(ARMEmitter::Size::i64Bit, rd, UImm & 0xFFFF);
|
||||
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
void LongAddressGen(ARMEmitter::Register rd, ForwardLabel* Label) {
|
||||
Label->Insts.emplace_back(SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::LONG_ADDRESS_GEN });
|
||||
// Emit a register index and a nop. These will be backpatched.
|
||||
[[nodiscard]] BranchEncodeSucceeded LongAddressGen(ARMEmitter::Register rd, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::LONG_ADDRESS_GEN});
|
||||
// Emit a register index and two nops. These will be backpatched.
|
||||
dc32(rd.Idx());
|
||||
nop();
|
||||
nop();
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void LongAddressGen(ARMEmitter::Register rd, BiDirectionalLabel *Label) {
|
||||
[[nodiscard]] BranchEncodeSucceeded LongAddressGen(ARMEmitter::Register rd, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
LongAddressGen(rd, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
LongAddressGen(rd, &Label->Forward);
|
||||
return LongAddressGen(rd, &Label->Backward);
|
||||
} else {
|
||||
return LongAddressGen(rd, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,11 +206,7 @@ public:
|
||||
// Logical immediate
|
||||
void and_(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint64_t Imm) {
|
||||
uint32_t n, immr, imms;
|
||||
[[maybe_unused]] const auto IsImm = IsImmLogical(Imm,
|
||||
RegSizeInBits(s),
|
||||
&n,
|
||||
&imms,
|
||||
&immr);
|
||||
const auto IsImm = IsImmLogical(Imm, RegSizeInBits(s), &n, &imms, &immr);
|
||||
LOGMAN_THROW_A_FMT(IsImm, "Couldn't encode immediate to logical op");
|
||||
and_(s, rd, rn, n, immr, imms);
|
||||
}
|
||||
@@ -191,11 +217,7 @@ public:
|
||||
|
||||
void ands(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint64_t Imm) {
|
||||
uint32_t n, immr, imms;
|
||||
[[maybe_unused]] const auto IsImm = IsImmLogical(Imm,
|
||||
RegSizeInBits(s),
|
||||
&n,
|
||||
&imms,
|
||||
&immr);
|
||||
const auto IsImm = IsImmLogical(Imm, RegSizeInBits(s), &n, &imms, &immr);
|
||||
LOGMAN_THROW_A_FMT(IsImm, "Couldn't encode immediate to logical op");
|
||||
ands(s, rd, rn, n, immr, imms);
|
||||
}
|
||||
@@ -206,22 +228,14 @@ public:
|
||||
|
||||
void orr(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint64_t Imm) {
|
||||
uint32_t n, immr, imms;
|
||||
[[maybe_unused]] const auto IsImm = IsImmLogical(Imm,
|
||||
RegSizeInBits(s),
|
||||
&n,
|
||||
&imms,
|
||||
&immr);
|
||||
const auto IsImm = IsImmLogical(Imm, RegSizeInBits(s), &n, &imms, &immr);
|
||||
LOGMAN_THROW_A_FMT(IsImm, "Couldn't encode immediate to logical op");
|
||||
orr(s, rd, rn, n, immr, imms);
|
||||
}
|
||||
|
||||
void eor(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint64_t Imm) {
|
||||
uint32_t n, immr, imms;
|
||||
[[maybe_unused]] const auto IsImm = IsImmLogical(Imm,
|
||||
RegSizeInBits(s),
|
||||
&n,
|
||||
&imms,
|
||||
&immr);
|
||||
const auto IsImm = IsImmLogical(Imm, RegSizeInBits(s), &n, &imms, &immr);
|
||||
LOGMAN_THROW_A_FMT(IsImm, "Couldn't encode immediate to logical op");
|
||||
eor(s, rd, rn, n, immr, imms);
|
||||
}
|
||||
@@ -351,12 +365,12 @@ public:
|
||||
bfi(s, rd, Reg::zr, lsb, width);
|
||||
}
|
||||
void bfxil(ARMEmitter::Size s, Register rd, Register rn, uint32_t lsb, uint32_t width) {
|
||||
[[maybe_unused]] const auto reg_size_bits = RegSizeInBits(s);
|
||||
const auto reg_size_bits = RegSizeInBits(s);
|
||||
const auto lsb_p_width = lsb + width;
|
||||
|
||||
LOGMAN_THROW_A_FMT(width >= 1, "bfxil needs width >= 1");
|
||||
LOGMAN_THROW_A_FMT(lsb_p_width <= reg_size_bits, "bfxil lsb + width ({}) must be <= {}. lsb={}, width={}",
|
||||
lsb_p_width, reg_size_bits, lsb, width);
|
||||
LOGMAN_THROW_A_FMT(lsb_p_width <= reg_size_bits, "bfxil lsb + width ({}) must be <= {}. lsb={}, width={}", lsb_p_width, reg_size_bits,
|
||||
lsb, width);
|
||||
|
||||
bfm(s, rd, rn, lsb, lsb_p_width - 1);
|
||||
}
|
||||
@@ -375,188 +389,142 @@ public:
|
||||
|
||||
// Data processing - 2 source
|
||||
void udiv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0000'10U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0000'10U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void sdiv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0000'11U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0000'11U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
|
||||
void lslv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0010'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0010'00U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void lsrv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0010'01U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0010'01U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void asrv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0010'10U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0010'10U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void rorv(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0010'11U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0010'11U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void crc32b(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0100'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0100'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32h(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0100'01U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0100'01U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32w(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0100'10U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0100'10U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32cb(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0101'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0101'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32ch(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0101'01U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0101'01U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32cw(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0101'10U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0101'10U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i32Bit, rd, rn, rm);
|
||||
}
|
||||
void smax(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0110'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0110'00U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void umax(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0110'01U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0110'01U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void smin(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0110'10U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0110'10U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void umin(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0110'11U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0110'11U << 10);
|
||||
DataProcessing_2Source(Op, s, rd, rn, rm);
|
||||
}
|
||||
void subp(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0000'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0000'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void irg(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0001'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0001'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void gmi(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0001'01U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0001'01U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void pacga(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0011'00U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0011'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32x(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0100'11U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0100'11U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void crc32cx(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) |
|
||||
(0b0101'11U << 10);
|
||||
constexpr uint32_t Op = (0b001'1010'110U << 21) | (0b0101'11U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
void subps(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm) {
|
||||
constexpr uint32_t Op = (0b011'1010'110U << 21) |
|
||||
(0b0000'00U << 10);
|
||||
constexpr uint32_t Op = (0b011'1010'110U << 21) | (0b0000'00U << 10);
|
||||
DataProcessing_2Source(Op, ARMEmitter::Size::i64Bit, rd, rn, rm);
|
||||
}
|
||||
|
||||
// Data processing - 1 source
|
||||
void rbit(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'00U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'00U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void rev16(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'01U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'01U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void rev(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'10U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'10U << 10);
|
||||
DataProcessing_1Source(Op, ARMEmitter::Size::i32Bit, rd, rn);
|
||||
}
|
||||
void rev32(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'10U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'10U << 10);
|
||||
DataProcessing_1Source(Op, ARMEmitter::Size::i64Bit, rd, rn);
|
||||
}
|
||||
void clz(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0001'00U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0001'00U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void cls(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0001'01U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0001'01U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void rev(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'11U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'11U << 10);
|
||||
DataProcessing_1Source(Op, ARMEmitter::Size::i64Bit, rd, rn);
|
||||
}
|
||||
void rev(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0000'10U << 10) |
|
||||
(s == ARMEmitter::Size::i64Bit ? (1U << 10) : 0);
|
||||
uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0000'10U << 10) | (s == ARMEmitter::Size::i64Bit ? (1U << 10) : 0);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void ctz(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0001'10U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0001'10U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void cnt(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0001'11U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0001'11U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
void abs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) |
|
||||
(0b0'0000U << 16) |
|
||||
(0b0010'00U << 10);
|
||||
constexpr uint32_t Op = (0b101'1010'110U << 21) | (0b0'0000U << 16) | (0b0010'00U << 10);
|
||||
DataProcessing_1Source(Op, s, rd, rn);
|
||||
}
|
||||
|
||||
@@ -573,27 +541,33 @@ public:
|
||||
orr(ARMEmitter::Size::i32Bit, rd.R(), ARMEmitter::Reg::zr, rn.R(), ARMEmitter::ShiftType::LSL, 0);
|
||||
}
|
||||
|
||||
void mvn(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void mvn(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL,
|
||||
uint32_t amt = 0) {
|
||||
orn(s, rd, ARMEmitter::Reg::zr, rn, Shift, amt);
|
||||
}
|
||||
|
||||
void and_(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void and_(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b000'1010'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void ands(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void ands(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b110'1010'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void bic(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void bic(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b000'1010'001U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void bics(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void bics(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b110'1010'001U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void orr(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void orr(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b010'1010'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
@@ -601,30 +575,36 @@ public:
|
||||
ands(s, Reg::zr, rn, rm, shift, amt);
|
||||
}
|
||||
|
||||
void orn(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void orn(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b010'1010'001U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void eor(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void eor(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b100'1010'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void eon(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void eon(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
constexpr uint32_t Op = 0b100'1010'001U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
|
||||
// AddSub - shifted register
|
||||
void add(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void add(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
add(ARMEmitter::Size::i64Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void adds(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void adds(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
adds(ARMEmitter::Size::i64Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void cmn(ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
adds(ARMEmitter::Size::i64Bit, ARMEmitter::XReg::zr, rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void sub(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void sub(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
sub(ARMEmitter::Size::i64Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void neg(ARMEmitter::XRegister rd, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
@@ -633,23 +613,27 @@ public:
|
||||
void cmp(ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::rsp, rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void subs(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void subs(ARMEmitter::XRegister rd, ARMEmitter::XRegister rn, ARMEmitter::XRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(ARMEmitter::Size::i64Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void negs(ARMEmitter::XRegister rd, ARMEmitter::XRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(rd, ARMEmitter::XReg::zr, rm, Shift, amt);
|
||||
}
|
||||
|
||||
void add(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void add(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
add(ARMEmitter::Size::i32Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void adds(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void adds(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
adds(ARMEmitter::Size::i32Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void cmn(ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
adds(ARMEmitter::Size::i32Bit, ARMEmitter::WReg::zr, rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void sub(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void sub(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
sub(ARMEmitter::Size::i32Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void neg(ARMEmitter::WRegister rd, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
@@ -658,65 +642,78 @@ public:
|
||||
void cmp(ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(ARMEmitter::Size::i32Bit, ARMEmitter::Reg::rsp, rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void subs(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void subs(ARMEmitter::WRegister rd, ARMEmitter::WRegister rn, ARMEmitter::WRegister rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(ARMEmitter::Size::i32Bit, rd.R(), rn.R(), rm.R(), Shift, amt);
|
||||
}
|
||||
void negs(ARMEmitter::WRegister rd, ARMEmitter::WRegister rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
subs(rd, ARMEmitter::WReg::zr, rm, Shift, amt);
|
||||
}
|
||||
|
||||
void add(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_AA_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
void add(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_A_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
constexpr uint32_t Op = 0b000'1011'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void adds(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_AA_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
void adds(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_A_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
constexpr uint32_t Op = 0b010'1011'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void cmn(ARMEmitter::Size s, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void cmn(ARMEmitter::Size s, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL,
|
||||
uint32_t amt = 0) {
|
||||
adds(s, ARMEmitter::Reg::zr, rn, rm, Shift, amt);
|
||||
}
|
||||
void sub(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_AA_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
void sub(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_A_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
constexpr uint32_t Op = 0b100'1011'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void neg(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void neg(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL,
|
||||
uint32_t amt = 0) {
|
||||
sub(s, rd, ARMEmitter::Reg::zr, rm, Shift, amt);
|
||||
}
|
||||
void cmp(ARMEmitter::Size s, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void cmp(ARMEmitter::Size s, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL,
|
||||
uint32_t amt = 0) {
|
||||
subs(s, ARMEmitter::Reg::zr, rn, rm, Shift, amt);
|
||||
}
|
||||
|
||||
void subs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_AA_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
void subs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
LOGMAN_THROW_A_FMT(Shift != ARMEmitter::ShiftType::ROR, "Doesn't support ROR");
|
||||
constexpr uint32_t Op = 0b110'1011'000U << 21;
|
||||
DataProcessing_Shifted_Reg(Op, s, rd, rn, rm, Shift, amt);
|
||||
}
|
||||
void negs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL, uint32_t amt = 0) {
|
||||
void negs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift = ARMEmitter::ShiftType::LSL,
|
||||
uint32_t amt = 0) {
|
||||
subs(s, rd, ARMEmitter::Reg::zr, rm, Shift, amt);
|
||||
}
|
||||
|
||||
// AddSub - extended register
|
||||
void add(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift = 0) {
|
||||
LOGMAN_THROW_AA_FMT(Shift <= 4, "Shift amount is too large");
|
||||
void add(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option,
|
||||
uint32_t Shift = 0) {
|
||||
LOGMAN_THROW_A_FMT(Shift <= 4, "Shift amount is too large");
|
||||
constexpr uint32_t Op = 0b000'1011'001U << 21;
|
||||
DataProcessing_Extended_Reg(Op, s, rd, rn, rm, Option, Shift);
|
||||
}
|
||||
void adds(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift = 0) {
|
||||
void adds(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option,
|
||||
uint32_t Shift = 0) {
|
||||
constexpr uint32_t Op = 0b010'1011'001U << 21;
|
||||
DataProcessing_Extended_Reg(Op, s, rd, rn, rm, Option, Shift);
|
||||
}
|
||||
void cmn(ARMEmitter::Size s, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift = 0) {
|
||||
adds(s, ARMEmitter::Reg::zr, rn, rm, Option, Shift);
|
||||
}
|
||||
void sub(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift = 0) {
|
||||
void sub(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option,
|
||||
uint32_t Shift = 0) {
|
||||
constexpr uint32_t Op = 0b100'1011'001U << 21;
|
||||
DataProcessing_Extended_Reg(Op, s, rd, rn, rm, Option, Shift);
|
||||
}
|
||||
void subs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift = 0) {
|
||||
void subs(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option,
|
||||
uint32_t Shift = 0) {
|
||||
constexpr uint32_t Op = 0b110'1011'001U << 21;
|
||||
DataProcessing_Extended_Reg(Op, s, rd, rn, rm, Option, Shift);
|
||||
}
|
||||
@@ -751,8 +748,8 @@ public:
|
||||
|
||||
// Rotate right into flags
|
||||
void rmif(XRegister rn, uint32_t shift, uint32_t mask) {
|
||||
LOGMAN_THROW_AA_FMT(shift <= 63, "Shift must be within 0-63. Shift: {}", shift);
|
||||
LOGMAN_THROW_AA_FMT(mask <= 15, "Mask must be within 0-15. Mask: {}", mask);
|
||||
LOGMAN_THROW_A_FMT(shift <= 63, "Shift must be within 0-63. Shift: {}", shift);
|
||||
LOGMAN_THROW_A_FMT(mask <= 15, "Mask must be within 0-15. Mask: {}", mask);
|
||||
|
||||
uint32_t Op = 0b1011'1010'0000'0000'0000'0100'0000'0000;
|
||||
Op |= rn.Idx() << 5;
|
||||
@@ -816,7 +813,8 @@ public:
|
||||
}
|
||||
void cset(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Condition Cond) {
|
||||
constexpr uint32_t Op = 0b0001'1010'100 << 21;
|
||||
ConditionalCompare(Op, 0, 0b01, s, rd, ARMEmitter::Reg::zr, ARMEmitter::Reg::zr, static_cast<ARMEmitter::Condition>(FEXCore::ToUnderlying(Cond) ^ FEXCore::ToUnderlying(ARMEmitter::Condition::CC_NE)));
|
||||
ConditionalCompare(Op, 0, 0b01, s, rd, ARMEmitter::Reg::zr, ARMEmitter::Reg::zr,
|
||||
static_cast<ARMEmitter::Condition>(FEXCore::ToUnderlying(Cond) ^ FEXCore::ToUnderlying(ARMEmitter::Condition::CC_NE)));
|
||||
}
|
||||
void csinc(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::Condition Cond) {
|
||||
constexpr uint32_t Op = 0b0001'1010'100 << 21;
|
||||
@@ -896,13 +894,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr Condition InvertCondition(Condition cond) {
|
||||
// These behave as always, so it makes no sense to allow inverting these.
|
||||
LOGMAN_THROW_AA_FMT(cond != Condition::CC_AL && cond != Condition::CC_NV,
|
||||
"Cannot invert CC_AL or CC_NV");
|
||||
return static_cast<Condition>(FEXCore::ToUnderlying(cond) ^ 1);
|
||||
}
|
||||
|
||||
void and_(ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint32_t n, uint32_t immr, uint32_t imms) {
|
||||
constexpr uint32_t Op = 0b001'0010'00 << 22;
|
||||
DataProcessing_Logical_Imm(Op, s, rd, rn, n, immr, imms);
|
||||
@@ -950,7 +941,7 @@ private:
|
||||
LSL12 = true;
|
||||
Imm >>= 12;
|
||||
}
|
||||
LOGMAN_THROW_AA_FMT(TooLarge == false, "Imm amount too large: 0x{:x}", Imm);
|
||||
LOGMAN_THROW_A_FMT(TooLarge == false, "Imm amount too large: 0x{:x}", Imm);
|
||||
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
@@ -995,7 +986,8 @@ private:
|
||||
}
|
||||
|
||||
// Logical immediate
|
||||
void DataProcessing_Logical_Imm(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint32_t n, uint32_t immr, uint32_t imms) {
|
||||
void DataProcessing_Logical_Imm(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, uint32_t n,
|
||||
uint32_t immr, uint32_t imms) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
@@ -1011,12 +1003,11 @@ private:
|
||||
}
|
||||
|
||||
void xbfiz_helper(bool is_signed, ARMEmitter::Size s, Register rd, Register rn, uint32_t lsb, uint32_t width) {
|
||||
[[maybe_unused]] const auto lsb_p_width = lsb + width;
|
||||
const auto lsb_p_width = lsb + width;
|
||||
const auto reg_size_bits = RegSizeInBits(s);
|
||||
|
||||
LOGMAN_THROW_AA_FMT(lsb_p_width <= reg_size_bits, "lsb + width ({}) must be <= {}. lsb={}, width={}",
|
||||
lsb_p_width, reg_size_bits, lsb, width);
|
||||
LOGMAN_THROW_AA_FMT(width >= 1, "xbfiz width must be >= 1");
|
||||
LOGMAN_THROW_A_FMT(lsb_p_width <= reg_size_bits, "lsb + width ({}) must be <= {}. lsb={}, width={}", lsb_p_width, reg_size_bits, lsb, width);
|
||||
LOGMAN_THROW_A_FMT(width >= 1, "xbfiz width must be >= 1");
|
||||
|
||||
const auto immr = (reg_size_bits - lsb) & (reg_size_bits - 1);
|
||||
const auto imms = width - 1;
|
||||
@@ -1028,12 +1019,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessing_Extract(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, uint32_t Imm) {
|
||||
void DataProcessing_Extract(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm,
|
||||
uint32_t Imm) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
// Current ARMv8 spec hardcodes SF == N for this class of instructions.
|
||||
// Anythign else is undefined behaviour.
|
||||
const uint32_t N = s == ARMEmitter::Size::i64Bit ? (1U << 22) : 0;
|
||||
const uint32_t N = s == ARMEmitter::Size::i64Bit ? (1U << 22) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
|
||||
@@ -1076,10 +1068,11 @@ private:
|
||||
}
|
||||
|
||||
// AddSub - shifted register
|
||||
void DataProcessing_Shifted_Reg(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ShiftType Shift, uint32_t amt) {
|
||||
LOGMAN_THROW_AA_FMT((amt & ~0b11'1111U) == 0, "Shift amount too large");
|
||||
void DataProcessing_Shifted_Reg(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn,
|
||||
ARMEmitter::Register rm, ARMEmitter::ShiftType Shift, uint32_t amt) {
|
||||
LOGMAN_THROW_A_FMT((amt & ~0b11'1111U) == 0, "Shift amount too large");
|
||||
if (s == ARMEmitter::Size::i32Bit) {
|
||||
LOGMAN_THROW_AA_FMT(amt < 32, "Shift amount for 32-bit must be below 32");
|
||||
LOGMAN_THROW_A_FMT(amt < 32, "Shift amount for 32-bit must be below 32");
|
||||
}
|
||||
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
@@ -1097,7 +1090,8 @@ private:
|
||||
}
|
||||
|
||||
// AddSub - extended register
|
||||
void DataProcessing_Extended_Reg(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift) {
|
||||
void DataProcessing_Extended_Reg(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn,
|
||||
ARMEmitter::Register rm, ARMEmitter::ExtendedType Option, uint32_t Shift) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
@@ -1113,7 +1107,8 @@ private:
|
||||
}
|
||||
// Conditional compare - register
|
||||
template<typename T>
|
||||
void ConditionalCompare(uint32_t Op, uint32_t o1, uint32_t o2, uint32_t o3, ARMEmitter::Size s, ARMEmitter::Register rn, T rm, ARMEmitter::StatusFlags flags, ARMEmitter::Condition Cond) {
|
||||
void ConditionalCompare(uint32_t Op, uint32_t o1, uint32_t o2, uint32_t o3, ARMEmitter::Size s, ARMEmitter::Register rn, T rm,
|
||||
ARMEmitter::StatusFlags flags, ARMEmitter::Condition Cond) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
@@ -1131,7 +1126,8 @@ private:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ConditionalCompare(uint32_t Op, uint32_t o1, uint32_t o2, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, T rm, ARMEmitter::Condition Cond) {
|
||||
void ConditionalCompare(uint32_t Op, uint32_t o1, uint32_t o2, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, T rm,
|
||||
ARMEmitter::Condition Cond) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
@@ -1148,7 +1144,8 @@ private:
|
||||
}
|
||||
|
||||
// Data-processing - 3 source
|
||||
void DataProcessing_3Source(uint32_t Op, uint32_t Op0, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn, ARMEmitter::Register rm, ARMEmitter::Register ra) {
|
||||
void DataProcessing_3Source(uint32_t Op, uint32_t Op0, ARMEmitter::Size s, ARMEmitter::Register rd, ARMEmitter::Register rn,
|
||||
ARMEmitter::Register rm, ARMEmitter::Register ra) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
@@ -1170,4 +1167,7 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
}; // struct LoadstoreEmitterOps
|
||||
} // namespace ARMEmitter
|
||||
#endif
|
||||
+2019
-2857
File diff suppressed because it is too large.
Load diff
@@ -3,339 +3,384 @@
|
||||
*
|
||||
* Most of these instructions will use `BackwardLabel`, `ForwardLabel`, or `BiDirectionLabel` to determine where a branch targets.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
#include <CodeEmitter/Emitter.h>
|
||||
namespace ARMEmitter {
|
||||
struct EmitterOps : Emitter {
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Branches, Exception Generating and System instructions
|
||||
public:
|
||||
// Conditional branch immediate
|
||||
///< Branch conditional
|
||||
void b(ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 0, Cond, Imm);
|
||||
}
|
||||
void b(ARMEmitter::Condition Cond, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
public:
|
||||
// Conditional branch immediate
|
||||
///< Branch conditional
|
||||
void b(ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 0, Cond, Imm);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded b(ARMEmitter::Condition Cond, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
if (Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 0, Cond, Imm >> 2);
|
||||
}
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void b(ARMEmitter::Condition Cond, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::BC });
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 0, Cond, 0);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void b(ARMEmitter::Condition Cond, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
b(Cond, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
b(Cond, &Label->Forward);
|
||||
}
|
||||
}
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded b(ARMEmitter::Condition Cond, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::BC});
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 0, Cond, 0);
|
||||
|
||||
///< Branch consistent conditional
|
||||
void bc(ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 1, Cond, Imm);
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded b(ARMEmitter::Condition Cond, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return b(Cond, &Label->Backward);
|
||||
} else {
|
||||
return b(Cond, &Label->Forward);
|
||||
}
|
||||
void bc(ARMEmitter::Condition Cond, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
}
|
||||
|
||||
///< Branch consistent conditional
|
||||
void bc(ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 1, Cond, Imm);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded bc(ARMEmitter::Condition Cond, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
if (Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 1, Cond, Imm >> 2);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void bc(ARMEmitter::Condition Cond, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::BC });
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 1, Cond, 0);
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded bc(ARMEmitter::Condition Cond, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::BC});
|
||||
constexpr uint32_t Op = 0b0101'010 << 25;
|
||||
Branch_Conditional(Op, 0, 1, Cond, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded bc(ARMEmitter::Condition Cond, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return bc(Cond, &Label->Backward);
|
||||
} else {
|
||||
return bc(Cond, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void bc(ARMEmitter::Condition Cond, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
bc(Cond, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
bc(Cond, &Label->Forward);
|
||||
}
|
||||
}
|
||||
// Unconditional branch register
|
||||
void br(ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 | 0b0'000 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
|
||||
// Unconditional branch register
|
||||
void br(ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 |
|
||||
0b0'000 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
void blr(ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 | 0b0'001 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
void blr(ARMEmitter::Register rn) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 |
|
||||
0b0'001 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
void ret(ARMEmitter::Register rn = ARMEmitter::Reg::r30) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 | 0b0'010 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
void ret(ARMEmitter::Register rn = ARMEmitter::Reg::r30) {
|
||||
constexpr uint32_t Op = 0b1101011 << 25 |
|
||||
0b0'010 << 21 | // opc
|
||||
0b1'1111 << 16 | // op2
|
||||
0b0000'00 << 10 | // op3
|
||||
0b0'0000; // op4
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
|
||||
UnconditionalBranch(Op, rn);
|
||||
}
|
||||
// Unconditional branch immediate
|
||||
void b(uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0001'01 << 26;
|
||||
|
||||
// Unconditional branch immediate
|
||||
void b(uint32_t Imm) {
|
||||
UnconditionalBranch(Op, Imm);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded b(const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
if (Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, Imm);
|
||||
}
|
||||
void b(BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
constexpr uint32_t Op = 0b0001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, Imm >> 2);
|
||||
}
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void b(LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::B });
|
||||
constexpr uint32_t Op = 0b0001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, 0);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void b(BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
b(&Label->Backward);
|
||||
}
|
||||
else {
|
||||
b(&Label->Forward);
|
||||
}
|
||||
}
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded b(ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::B});
|
||||
constexpr uint32_t Op = 0b0001'01 << 26;
|
||||
|
||||
void bl(uint32_t Imm) {
|
||||
UnconditionalBranch(Op, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded b(BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return b(&Label->Backward);
|
||||
} else {
|
||||
return b(&Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void bl(uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b1001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, Imm);
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded bl(const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
if (Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b1001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, Imm);
|
||||
}
|
||||
|
||||
void bl(BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
constexpr uint32_t Op = 0b1001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, Imm >> 2);
|
||||
}
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void bl(LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::B });
|
||||
constexpr uint32_t Op = 0b1001'01 << 26;
|
||||
|
||||
UnconditionalBranch(Op, 0);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
void bl(BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
bl(&Label->Backward);
|
||||
}
|
||||
else {
|
||||
bl(&Label->Forward);
|
||||
}
|
||||
}
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded bl(ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::B});
|
||||
constexpr uint32_t Op = 0b1001'01 << 26;
|
||||
|
||||
// Compare and branch
|
||||
void cbz(ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
UnconditionalBranch(Op, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded bl(BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return bl(&Label->Backward);
|
||||
} else {
|
||||
return bl(&Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
// Compare and branch
|
||||
void cbz(ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0011'0100 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, Imm);
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded cbz(ARMEmitter::Size s, ARMEmitter::Register rt, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
|
||||
if (Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0011'0100 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, Imm);
|
||||
}
|
||||
|
||||
void cbz(ARMEmitter::Size s, ARMEmitter::Register rt, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0100 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, Imm >> 2);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void cbz(ARMEmitter::Size s, ARMEmitter::Register rt, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::BC });
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0100 << 24;
|
||||
[[nodiscard]] BranchEncodeSucceeded cbz(ARMEmitter::Size s, ARMEmitter::Register rt, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::BC});
|
||||
|
||||
CompareAndBranch(Op, s, rt, 0);
|
||||
constexpr uint32_t Op = 0b0011'0100 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded cbz(ARMEmitter::Size s, ARMEmitter::Register rt, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return cbz(s, rt, &Label->Backward);
|
||||
} else {
|
||||
return cbz(s, rt, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void cbz(ARMEmitter::Size s, ARMEmitter::Register rt, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
cbz(s, rt, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
cbz(s, rt, &Label->Forward);
|
||||
}
|
||||
}
|
||||
void cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0011'0101 << 24;
|
||||
|
||||
void cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
CompareAndBranch(Op, s, rt, Imm);
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
|
||||
if (Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0011'0101 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, Imm);
|
||||
}
|
||||
|
||||
void cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0101 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, Imm >> 2);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::BC });
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0101 << 24;
|
||||
[[nodiscard]] BranchEncodeSucceeded cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::BC});
|
||||
|
||||
CompareAndBranch(Op, s, rt, 0);
|
||||
constexpr uint32_t Op = 0b0011'0101 << 24;
|
||||
|
||||
CompareAndBranch(Op, s, rt, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return cbnz(s, rt, &Label->Backward);
|
||||
} else {
|
||||
return cbnz(s, rt, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void cbnz(ARMEmitter::Size s, ARMEmitter::Register rt, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
cbnz(s, rt, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
cbnz(s, rt, &Label->Forward);
|
||||
}
|
||||
}
|
||||
// Test and branch immediate
|
||||
void tbz(ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0011'0110 << 24;
|
||||
|
||||
// Test and branch immediate
|
||||
void tbz(ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
TestAndBranch(Op, rt, Bit, Imm);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded tbz(ARMEmitter::Register rt, uint32_t Bit, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
|
||||
if (Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0011'0110 << 24;
|
||||
|
||||
TestAndBranch(Op, rt, Bit, Imm);
|
||||
}
|
||||
void tbz(ARMEmitter::Register rt, uint32_t Bit, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0110 << 24;
|
||||
|
||||
TestAndBranch(Op, rt, Bit, Imm >> 2);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void tbz(ARMEmitter::Register rt, uint32_t Bit, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::TEST_BRANCH });
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0110 << 24;
|
||||
[[nodiscard]] BranchEncodeSucceeded tbz(ARMEmitter::Register rt, uint32_t Bit, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::TEST_BRANCH});
|
||||
|
||||
TestAndBranch(Op, rt, Bit, 0);
|
||||
constexpr uint32_t Op = 0b0011'0110 << 24;
|
||||
|
||||
TestAndBranch(Op, rt, Bit, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded tbz(ARMEmitter::Register rt, uint32_t Bit, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return tbz(rt, Bit, &Label->Backward);
|
||||
} else {
|
||||
return tbz(rt, Bit, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
void tbz(ARMEmitter::Register rt, uint32_t Bit, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
tbz(rt, Bit, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
tbz(rt, Bit, &Label->Forward);
|
||||
}
|
||||
}
|
||||
void tbnz(ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
constexpr uint32_t Op = 0b0011'0111 << 24;
|
||||
|
||||
void tbnz(ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
TestAndBranch(Op, rt, Bit, Imm);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded tbnz(ARMEmitter::Register rt, uint32_t Bit, const BackwardLabel* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
|
||||
if (Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0)) {
|
||||
constexpr uint32_t Op = 0b0011'0111 << 24;
|
||||
|
||||
TestAndBranch(Op, rt, Bit, Imm);
|
||||
}
|
||||
void tbnz(ARMEmitter::Register rt, uint32_t Bit, BackwardLabel const* Label) {
|
||||
int32_t Imm = static_cast<int32_t>(Label->Location - GetCursorAddress<uint8_t*>());
|
||||
LOGMAN_THROW_A_FMT(Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
|
||||
constexpr uint32_t Op = 0b0011'0111 << 24;
|
||||
|
||||
TestAndBranch(Op, rt, Bit, Imm >> 2);
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
template<typename LabelType>
|
||||
requires (std::is_same_v<LabelType, ForwardLabel> || std::is_same_v<LabelType, SingleUseForwardLabel>)
|
||||
void tbnz(ARMEmitter::Register rt, uint32_t Bit, LabelType *Label) {
|
||||
AddLocationToLabel(Label, SingleUseForwardLabel{ .Location = GetCursorAddress<uint8_t*>(), .Type = SingleUseForwardLabel::InstType::TEST_BRANCH });
|
||||
constexpr uint32_t Op = 0b0011'0111 << 24;
|
||||
// Can't encode.
|
||||
return BranchEncodeSucceeded::Failure;
|
||||
}
|
||||
|
||||
TestAndBranch(Op, rt, Bit, 0);
|
||||
}
|
||||
[[nodiscard]] BranchEncodeSucceeded tbnz(ARMEmitter::Register rt, uint32_t Bit, ForwardLabel* Label) {
|
||||
AddLocationToLabel(Label, ForwardLabel::Reference {.Location = GetCursorAddress<uint8_t*>(), .Type = ForwardLabel::InstType::TEST_BRANCH});
|
||||
constexpr uint32_t Op = 0b0011'0111 << 24;
|
||||
|
||||
void tbnz(ARMEmitter::Register rt, uint32_t Bit, BiDirectionalLabel *Label) {
|
||||
if (Label->Backward.Location) {
|
||||
tbnz(rt, Bit, &Label->Backward);
|
||||
}
|
||||
else {
|
||||
tbnz(rt, Bit, &Label->Forward);
|
||||
}
|
||||
TestAndBranch(Op, rt, Bit, 0);
|
||||
|
||||
// Forward label doesn't know if it can encode until Bind.
|
||||
return BranchEncodeSucceeded::Success;
|
||||
}
|
||||
|
||||
[[nodiscard]] BranchEncodeSucceeded tbnz(ARMEmitter::Register rt, uint32_t Bit, BiDirectionalLabel* Label) {
|
||||
if (Label->Backward.Location) {
|
||||
return tbnz(rt, Bit, &Label->Backward);
|
||||
} else {
|
||||
return tbnz(rt, Bit, &Label->Forward);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Conditional branch immediate
|
||||
void Branch_Conditional(uint32_t Op, uint32_t Op1, uint32_t Op0, ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
// Conditional branch immediate
|
||||
void Branch_Conditional(uint32_t Op, uint32_t Op1, uint32_t Op0, ARMEmitter::Condition Cond, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
|
||||
Instr |= Op1 << 24;
|
||||
Instr |= (Imm & 0x7'FFFF) << 5;
|
||||
Instr |= Op0 << 4;
|
||||
Instr |= FEXCore::ToUnderlying(Cond);
|
||||
Instr |= Op1 << 24;
|
||||
Instr |= (Imm & 0x7'FFFF) << 5;
|
||||
Instr |= Op0 << 4;
|
||||
Instr |= FEXCore::ToUnderlying(Cond);
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Unconditional branch register
|
||||
void UnconditionalBranch(uint32_t Op, ARMEmitter::Register rn) {
|
||||
uint32_t Instr = Op;
|
||||
Instr |= Encode_rn(rn);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Unconditional branch register
|
||||
void UnconditionalBranch(uint32_t Op, ARMEmitter::Register rn) {
|
||||
uint32_t Instr = Op;
|
||||
Instr |= Encode_rn(rn);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Unconditional branch - immediate
|
||||
void UnconditionalBranch(uint32_t Op, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
Instr |= Imm & 0x3FF'FFFF;
|
||||
dc32(Instr);
|
||||
}
|
||||
// Unconditional branch - immediate
|
||||
void UnconditionalBranch(uint32_t Op, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
Instr |= Imm & 0x3FF'FFFF;
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Compare and branch
|
||||
void CompareAndBranch(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
// Compare and branch
|
||||
void CompareAndBranch(uint32_t Op, ARMEmitter::Size s, ARMEmitter::Register rt, uint32_t Imm) {
|
||||
const uint32_t SF = s == ARMEmitter::Size::i64Bit ? (1U << 31) : 0;
|
||||
|
||||
uint32_t Instr = Op;
|
||||
uint32_t Instr = Op;
|
||||
|
||||
Instr |= SF;
|
||||
Instr |= (Imm & 0x7'FFFF) << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
Instr |= SF;
|
||||
Instr |= (Imm & 0x7'FFFF) << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Test and branch - immediate
|
||||
void TestAndBranch(uint32_t Op, ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
// Test and branch - immediate
|
||||
void TestAndBranch(uint32_t Op, ARMEmitter::Register rt, uint32_t Bit, uint32_t Imm) {
|
||||
uint32_t Instr = Op;
|
||||
|
||||
Instr |= (Bit >> 5) << 31;
|
||||
Instr |= (Bit & 0b1'1111) << 19;
|
||||
Instr |= (Imm & 0x3FFF) << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
Instr |= (Bit >> 5) << 31;
|
||||
Instr |= (Bit & 0b1'1111) << 19;
|
||||
Instr |= (Imm & 0x3FFF) << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
}; // struct LoadstoreEmitterOps
|
||||
} // namespace ARMEmitter
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ARMEmitter {
|
||||
class Buffer {
|
||||
@@ -21,42 +22,39 @@ public:
|
||||
Size = BaseSize;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires (std::is_trivially_copyable_v<T>)
|
||||
void dcn(const T& Data) {
|
||||
std::memcpy(CurrentOffset, &Data, sizeof(Data));
|
||||
CurrentOffset += sizeof(Data);
|
||||
}
|
||||
void dc8(uint8_t Data) {
|
||||
decltype(Data)* Memory = reinterpret_cast<decltype(Data)*>(CurrentOffset);
|
||||
*Memory = Data;
|
||||
CurrentOffset += sizeof(Data);
|
||||
dcn(Data);
|
||||
}
|
||||
|
||||
void dc16(uint16_t Data) {
|
||||
decltype(Data)* Memory = reinterpret_cast<decltype(Data)*>(CurrentOffset);
|
||||
*Memory = Data;
|
||||
CurrentOffset += sizeof(Data);
|
||||
dcn(Data);
|
||||
}
|
||||
|
||||
void dc32(uint32_t Data) {
|
||||
decltype(Data)* Memory = reinterpret_cast<decltype(Data)*>(CurrentOffset);
|
||||
*Memory = Data;
|
||||
CurrentOffset += sizeof(Data);
|
||||
dcn(Data);
|
||||
}
|
||||
void dc64(uint64_t Data) {
|
||||
dcn(Data);
|
||||
}
|
||||
|
||||
void dc64(uint64_t Data) {
|
||||
decltype(Data)* Memory = reinterpret_cast<decltype(Data)*>(CurrentOffset);
|
||||
*Memory = Data;
|
||||
CurrentOffset += sizeof(Data);
|
||||
}
|
||||
void EmitString(const char* String) {
|
||||
const auto StringLength = strlen(String);
|
||||
memcpy(CurrentOffset, String, StringLength);
|
||||
CurrentOffset += StringLength;
|
||||
}
|
||||
|
||||
void Align() {
|
||||
// Align the buffer to instruction size
|
||||
auto CurrentAlignment = reinterpret_cast<uint64_t>(CurrentOffset) & 0b11;
|
||||
void Align(size_t Size = 4) {
|
||||
// Align the buffer to provided size.
|
||||
auto CurrentAlignment = reinterpret_cast<uint64_t>(CurrentOffset) & (Size - 1);
|
||||
if (!CurrentAlignment) {
|
||||
return;
|
||||
}
|
||||
CurrentOffset += 4 - CurrentAlignment;
|
||||
std::memset(CurrentOffset, 0, Size - CurrentAlignment);
|
||||
CurrentOffset += Size - CurrentAlignment;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -95,10 +93,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void ResetBuffer() {
|
||||
CurrentOffset = BufferBase;
|
||||
}
|
||||
|
||||
uint8_t* BufferBase;
|
||||
uint8_t* CurrentOffset;
|
||||
uint64_t Size;
|
||||
|
||||
+185
-125
@@ -12,6 +12,7 @@
|
||||
#include <CodeEmitter/Registers.h>
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
@@ -86,6 +87,14 @@ constexpr size_t SubRegSizeInBits(SubRegSize size) {
|
||||
return size_t {8} << FEXCore::ToUnderlying(size);
|
||||
}
|
||||
|
||||
// Many floating point operations constrain their element sizes to the
|
||||
// main three float sizes half, single, and double precision. This just
|
||||
// combines all the checks together for brevity.
|
||||
[[nodiscard]]
|
||||
constexpr bool IsStandardFloatSize(SubRegSize size) {
|
||||
return size == SubRegSize::i16Bit || size == SubRegSize::i32Bit || size == SubRegSize::i64Bit;
|
||||
}
|
||||
|
||||
/* This `ScalarRegSize` enum is used for most scalar float
|
||||
* operations.
|
||||
*
|
||||
@@ -302,7 +311,7 @@ class ExtendedMemOperand final {
|
||||
public:
|
||||
ExtendedMemOperand(XRegister rn, XRegister rm = XReg::zr, ExtendedType Option = ExtendedType::LSL_64, uint32_t Shift = 0)
|
||||
: rn {rn}
|
||||
, MetaType {.ExtendedType {
|
||||
, MetaType {.Extended {
|
||||
.Header = {.MemType = TYPE_EXTENDED},
|
||||
.rm = rm,
|
||||
.Option = Option,
|
||||
@@ -331,7 +340,7 @@ public:
|
||||
Register rm;
|
||||
ExtendedType Option;
|
||||
uint32_t Shift;
|
||||
} ExtendedType;
|
||||
} Extended;
|
||||
struct {
|
||||
HeaderStruct Header;
|
||||
IndexType Index;
|
||||
@@ -341,94 +350,89 @@ public:
|
||||
};
|
||||
|
||||
template<uint32_t op0, uint32_t op1, uint32_t CRn, uint32_t CRm, uint32_t op2>
|
||||
constexpr uint32_t GenSystemReg() {
|
||||
return op0 << 19 | op1 << 16 | CRn << 12 | CRm << 8 | op2 << 5;
|
||||
};
|
||||
inline constexpr uint32_t GenSystemReg = op0 << 19 | op1 << 16 | CRn << 12 | CRm << 8 | op2 << 5;
|
||||
|
||||
// This `SystemRegister` enum is used for the mrs/msr instructions.
|
||||
enum class SystemRegister : uint32_t {
|
||||
CTR_EL0 = GenSystemReg<0b11, 0b011, 0b0000, 0b0000, 0b001>(),
|
||||
DCZID_EL0 = GenSystemReg<0b11, 0b011, 0b0000, 0b0000, 0b111>(),
|
||||
TPIDR_EL0 = GenSystemReg<0b11, 0b011, 0b1101, 0b0000, 0b010>(),
|
||||
RNDR = GenSystemReg<0b11, 0b011, 0b0010, 0b0100, 0b000>(),
|
||||
RNDRRS = GenSystemReg<0b11, 0b011, 0b0010, 0b0100, 0b001>(),
|
||||
NZCV = GenSystemReg<0b11, 0b011, 0b0100, 0b0010, 0b000>(),
|
||||
FPCR = GenSystemReg<0b11, 0b011, 0b0100, 0b0100, 0b000>(),
|
||||
TPIDRRO_EL0 = GenSystemReg<0b11, 0b011, 0b1101, 0b0000, 0b011>(),
|
||||
CNTFRQ_EL0 = GenSystemReg<0b11, 0b011, 0b1110, 0b0000, 0b000>(),
|
||||
CNTVCT_EL0 = GenSystemReg<0b11, 0b011, 0b1110, 0b0000, 0b010>(),
|
||||
CTR_EL0 = GenSystemReg<0b11, 0b011, 0b0000, 0b0000, 0b001>,
|
||||
DCZID_EL0 = GenSystemReg<0b11, 0b011, 0b0000, 0b0000, 0b111>,
|
||||
TPIDR_EL0 = GenSystemReg<0b11, 0b011, 0b1101, 0b0000, 0b010>,
|
||||
RNDR = GenSystemReg<0b11, 0b011, 0b0010, 0b0100, 0b000>,
|
||||
RNDRRS = GenSystemReg<0b11, 0b011, 0b0010, 0b0100, 0b001>,
|
||||
NZCV = GenSystemReg<0b11, 0b011, 0b0100, 0b0010, 0b000>,
|
||||
FPCR = GenSystemReg<0b11, 0b011, 0b0100, 0b0100, 0b000>,
|
||||
TPIDRRO_EL0 = GenSystemReg<0b11, 0b011, 0b1101, 0b0000, 0b011>,
|
||||
CNTFRQ_EL0 = GenSystemReg<0b11, 0b011, 0b1110, 0b0000, 0b000>,
|
||||
CNTVCT_EL0 = GenSystemReg<0b11, 0b011, 0b1110, 0b0000, 0b010>,
|
||||
CNTVCTSS_EL0 = GenSystemReg<0b11, 0b011, 0b1110, 0b0000, 0b110>,
|
||||
};
|
||||
|
||||
template<uint32_t op1, uint32_t CRm, uint32_t op2>
|
||||
constexpr uint32_t GenDCReg() {
|
||||
return op1 << 16 | CRm << 8 | op2 << 5;
|
||||
};
|
||||
inline constexpr uint32_t GenDCReg = op1 << 16 | CRm << 8 | op2 << 5;
|
||||
|
||||
// This `DataCacheOperation` enum is used for the dc instruction.
|
||||
enum class DataCacheOperation : uint32_t {
|
||||
IVAC = GenDCReg<0b000, 0b0110, 0b001>(),
|
||||
ISW = GenDCReg<0b000, 0b0110, 0b010>(),
|
||||
CSW = GenDCReg<0b000, 0b1010, 0b010>(),
|
||||
CISW = GenDCReg<0b000, 0b1110, 0b010>(),
|
||||
ZVA = GenDCReg<0b011, 0b0100, 0b001>(),
|
||||
CVAC = GenDCReg<0b011, 0b1010, 0b001>(),
|
||||
CVAU = GenDCReg<0b011, 0b1011, 0b001>(),
|
||||
CIVAC = GenDCReg<0b011, 0b1110, 0b001>(),
|
||||
IVAC = GenDCReg<0b000, 0b0110, 0b001>,
|
||||
ISW = GenDCReg<0b000, 0b0110, 0b010>,
|
||||
CSW = GenDCReg<0b000, 0b1010, 0b010>,
|
||||
CISW = GenDCReg<0b000, 0b1110, 0b010>,
|
||||
ZVA = GenDCReg<0b011, 0b0100, 0b001>,
|
||||
CVAC = GenDCReg<0b011, 0b1010, 0b001>,
|
||||
CVAU = GenDCReg<0b011, 0b1011, 0b001>,
|
||||
CIVAC = GenDCReg<0b011, 0b1110, 0b001>,
|
||||
|
||||
// MTE2
|
||||
IGVAC = GenDCReg<0b000, 0b0110, 0b011>(),
|
||||
IGSW = GenDCReg<0b000, 0b0110, 0b100>(),
|
||||
IGDVAC = GenDCReg<0b000, 0b0110, 0b101>(),
|
||||
IGDSW = GenDCReg<0b000, 0b0110, 0b110>(),
|
||||
CGSW = GenDCReg<0b000, 0b1010, 0b100>(),
|
||||
CGDSW = GenDCReg<0b000, 0b1010, 0b110>(),
|
||||
CIGSW = GenDCReg<0b000, 0b1110, 0b100>(),
|
||||
CIGDSW = GenDCReg<0b000, 0b1110, 0b110>(),
|
||||
IGVAC = GenDCReg<0b000, 0b0110, 0b011>,
|
||||
IGSW = GenDCReg<0b000, 0b0110, 0b100>,
|
||||
IGDVAC = GenDCReg<0b000, 0b0110, 0b101>,
|
||||
IGDSW = GenDCReg<0b000, 0b0110, 0b110>,
|
||||
CGSW = GenDCReg<0b000, 0b1010, 0b100>,
|
||||
CGDSW = GenDCReg<0b000, 0b1010, 0b110>,
|
||||
CIGSW = GenDCReg<0b000, 0b1110, 0b100>,
|
||||
CIGDSW = GenDCReg<0b000, 0b1110, 0b110>,
|
||||
|
||||
// MTE
|
||||
GVA = GenDCReg<0b011, 0b0100, 0b011>(),
|
||||
GZVA = GenDCReg<0b011, 0b0100, 0b100>(),
|
||||
CGVAC = GenDCReg<0b011, 0b1010, 0b011>(),
|
||||
CGDVAC = GenDCReg<0b011, 0b1010, 0b101>(),
|
||||
CGVAP = GenDCReg<0b011, 0b1100, 0b011>(),
|
||||
CGDVAP = GenDCReg<0b011, 0b1100, 0b101>(),
|
||||
CGVADP = GenDCReg<0b011, 0b1101, 0b011>(),
|
||||
CGDVADP = GenDCReg<0b011, 0b1101, 0b101>(),
|
||||
CIGVAC = GenDCReg<0b011, 0b1110, 0b011>(),
|
||||
CIGDVAC = GenDCReg<0b011, 0b1110, 0b101>(),
|
||||
GVA = GenDCReg<0b011, 0b0100, 0b011>,
|
||||
GZVA = GenDCReg<0b011, 0b0100, 0b100>,
|
||||
CGVAC = GenDCReg<0b011, 0b1010, 0b011>,
|
||||
CGDVAC = GenDCReg<0b011, 0b1010, 0b101>,
|
||||
CGVAP = GenDCReg<0b011, 0b1100, 0b011>,
|
||||
CGDVAP = GenDCReg<0b011, 0b1100, 0b101>,
|
||||
CGVADP = GenDCReg<0b011, 0b1101, 0b011>,
|
||||
CGDVADP = GenDCReg<0b011, 0b1101, 0b101>,
|
||||
CIGVAC = GenDCReg<0b011, 0b1110, 0b011>,
|
||||
CIGDVAC = GenDCReg<0b011, 0b1110, 0b101>,
|
||||
|
||||
// DPB
|
||||
CVAP = GenDCReg<0b011, 0b1100, 0b001>(),
|
||||
CVAP = GenDCReg<0b011, 0b1100, 0b001>,
|
||||
|
||||
// DPB2
|
||||
CVADP = GenDCReg<0b011, 0b1101, 0b001>(),
|
||||
CVADP = GenDCReg<0b011, 0b1101, 0b001>,
|
||||
};
|
||||
|
||||
template<uint32_t CRm, uint32_t op2>
|
||||
constexpr uint32_t GenHintBarrierReg() {
|
||||
return CRm << 8 | op2 << 5;
|
||||
}
|
||||
inline constexpr uint32_t GenHintBarrierReg = CRm << 8 | op2 << 5;
|
||||
|
||||
// This `HintRegister` enum is used for the hint instruction.
|
||||
enum class HintRegister : uint32_t {
|
||||
NOP = GenHintBarrierReg<0b0000, 0b000>(),
|
||||
YIELD = GenHintBarrierReg<0b0000, 0b001>(),
|
||||
WFE = GenHintBarrierReg<0b0000, 0b010>(),
|
||||
WFI = GenHintBarrierReg<0b0000, 0b011>(),
|
||||
SEV = GenHintBarrierReg<0b0000, 0b100>(),
|
||||
SEVL = GenHintBarrierReg<0b0000, 0b101>(),
|
||||
DGH = GenHintBarrierReg<0b0000, 0b110>(),
|
||||
CSDB = GenHintBarrierReg<0b0010, 0b100>(),
|
||||
NOP = GenHintBarrierReg<0b0000, 0b000>,
|
||||
YIELD = GenHintBarrierReg<0b0000, 0b001>,
|
||||
WFE = GenHintBarrierReg<0b0000, 0b010>,
|
||||
WFI = GenHintBarrierReg<0b0000, 0b011>,
|
||||
SEV = GenHintBarrierReg<0b0000, 0b100>,
|
||||
SEVL = GenHintBarrierReg<0b0000, 0b101>,
|
||||
DGH = GenHintBarrierReg<0b0000, 0b110>,
|
||||
CSDB = GenHintBarrierReg<0b0010, 0b100>,
|
||||
};
|
||||
|
||||
// This `BarrierRegister` enum is used for the various barrier instructions.
|
||||
enum class BarrierRegister : uint32_t {
|
||||
CLREX = GenHintBarrierReg<0b0000, 0b010>(),
|
||||
TCOMMIT = GenHintBarrierReg<0b0000, 0b011>(),
|
||||
DSB = GenHintBarrierReg<0b0000, 0b100>(),
|
||||
DMB = GenHintBarrierReg<0b0000, 0b101>(),
|
||||
ISB = GenHintBarrierReg<0b0000, 0b110>(),
|
||||
SB = GenHintBarrierReg<0b0000, 0b111>(),
|
||||
CLREX = GenHintBarrierReg<0b0000, 0b010>,
|
||||
TCOMMIT = GenHintBarrierReg<0b0000, 0b011>,
|
||||
DSB = GenHintBarrierReg<0b0000, 0b100>,
|
||||
DMB = GenHintBarrierReg<0b0000, 0b101>,
|
||||
ISB = GenHintBarrierReg<0b0000, 0b110>,
|
||||
SB = GenHintBarrierReg<0b0000, 0b111>,
|
||||
};
|
||||
|
||||
// This `BarrierScope` enum is used for the dsb/dmb instructions.
|
||||
@@ -513,7 +517,7 @@ enum class SVEFMaxMinImm : uint32_t {
|
||||
_1_0,
|
||||
};
|
||||
|
||||
/* This `BackwardLabel` struct used for retaining a location for PC-Relative instructions.
|
||||
/* This `BackwardLabel` struct is used for retaining a location for PC-Relative instructions.
|
||||
* This is specifically a label for a target that is logically `below` an instruction that uses it.
|
||||
* Which means that a branch would jump backwards.
|
||||
*/
|
||||
@@ -521,13 +525,11 @@ struct BackwardLabel {
|
||||
uint8_t* Location {};
|
||||
};
|
||||
|
||||
/* This `SingleUseForwardLabel` struct used for retaining a location for PC-Relative instructions.
|
||||
/* This `ForwardLabel` struct is used for retaining a location for PC-Relative instructions.
|
||||
* This is specifically a label for a target that is logically `above` an instruction that uses it.
|
||||
* Which means that a branch would jump forwards.
|
||||
*
|
||||
* The `ForwardLabel` struct can be bound to multiple instructions, so it needs a vector for each bind instruction type.
|
||||
*/
|
||||
struct SingleUseForwardLabel {
|
||||
struct ForwardLabel {
|
||||
enum class InstType {
|
||||
UNKNOWN,
|
||||
ADR,
|
||||
@@ -538,12 +540,16 @@ struct SingleUseForwardLabel {
|
||||
RELATIVE_LOAD,
|
||||
LONG_ADDRESS_GEN,
|
||||
};
|
||||
uint8_t* Location {};
|
||||
InstType Type = InstType::UNKNOWN;
|
||||
};
|
||||
|
||||
struct ForwardLabel {
|
||||
fextl::vector<SingleUseForwardLabel> Insts {};
|
||||
struct Reference {
|
||||
uint8_t* Location {};
|
||||
InstType Type = InstType::UNKNOWN;
|
||||
};
|
||||
|
||||
// The first element is stored separately to avoid allocations for simple cases
|
||||
Reference FirstInst;
|
||||
|
||||
fextl::vector<Reference> Insts;
|
||||
};
|
||||
|
||||
/* This `BiDirectionalLabel` struct used for retaining a location for PC-Relative instructions.
|
||||
@@ -555,14 +561,12 @@ struct BiDirectionalLabel {
|
||||
ForwardLabel Forward;
|
||||
};
|
||||
|
||||
static inline void AddLocationToLabel(SingleUseForwardLabel* Label, SingleUseForwardLabel&& Location) {
|
||||
LOGMAN_THROW_A_FMT(Label->Type == SingleUseForwardLabel::InstType::UNKNOWN, "Trying to bind a SingleUseForwardLabel to multiple "
|
||||
"locations. Use ForwardLabel instead.");
|
||||
*Label = std::move(Location);
|
||||
}
|
||||
|
||||
static inline void AddLocationToLabel(ForwardLabel* Label, SingleUseForwardLabel&& Location) {
|
||||
Label->Insts.emplace_back(std::move(Location));
|
||||
static inline void AddLocationToLabel(ForwardLabel* Label, ForwardLabel::Reference&& Location) {
|
||||
if (Label->FirstInst.Location == nullptr) {
|
||||
Label->FirstInst = Location;
|
||||
} else {
|
||||
Label->Insts.push_back(Location);
|
||||
}
|
||||
}
|
||||
|
||||
// Some FCMA ASIMD instructions support a rotation argument.
|
||||
@@ -578,6 +582,19 @@ enum class Rotation : uint32_t {
|
||||
template<typename T>
|
||||
concept IsXOrWRegister = std::is_same_v<T, XRegister> || std::is_same_v<T, WRegister>;
|
||||
|
||||
// Concept for contraining some instructions to accept only a QRegister or DRegister.
|
||||
template<typename T>
|
||||
concept IsQOrDRegister = std::is_same_v<T, QRegister> || std::is_same_v<T, DRegister>;
|
||||
|
||||
template<typename T>
|
||||
concept IsLabel = std::is_same_v<T, ARMEmitter::ForwardLabel> || std::is_same_v<T, ARMEmitter::BackwardLabel> ||
|
||||
std::is_same_v<T, ARMEmitter::BiDirectionalLabel> || std::is_same_v<T, ARMEmitter::ForwardLabel::Reference>;
|
||||
|
||||
enum class BranchEncodeSucceeded {
|
||||
Success,
|
||||
Failure,
|
||||
};
|
||||
|
||||
// Whether or not a given set of vector registers are sequential
|
||||
// in increasing order as far as the register file is concerned (modulo its size)
|
||||
//
|
||||
@@ -630,19 +647,25 @@ public:
|
||||
|
||||
// Bind a backward label to an address.
|
||||
// Address that is bound is the current emitter location.
|
||||
void Bind(BackwardLabel* Label) {
|
||||
LOGMAN_THROW_AA_FMT(Label->Location == nullptr, "Trying to bind a label twice");
|
||||
[[nodiscard]] bool Bind(BackwardLabel* Label) {
|
||||
LOGMAN_THROW_A_FMT(Label->Location == nullptr, "Trying to bind a label twice");
|
||||
Label->Location = GetCursorAddress<uint8_t*>();
|
||||
|
||||
// Always binds because it is only storing a location.
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bind(const SingleUseForwardLabel* Label) {
|
||||
[[nodiscard]] bool Bind(const ForwardLabel::Reference* Label) {
|
||||
uint8_t* CurrentAddress = GetCursorAddress<uint8_t*>();
|
||||
// Patch up the instructions
|
||||
switch (Label->Type) {
|
||||
case SingleUseForwardLabel::InstType::ADR: {
|
||||
case ForwardLabel::InstType::ADR: {
|
||||
uint32_t* Instruction = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t Imm = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(Instruction);
|
||||
LOGMAN_THROW_A_FMT(IsADRRange(Imm), "Unscaled offset too large");
|
||||
if (!IsADRRange(Imm)) {
|
||||
// Can't bind.
|
||||
return false;
|
||||
}
|
||||
uint32_t InstMask = 0b11 << 29 | 0b1111'1111'1111'1111'111 << 5;
|
||||
uint32_t Offset = static_cast<uint32_t>(Imm) & 0x3F'FFFF;
|
||||
uint32_t Inst = *Instruction & ~InstMask;
|
||||
@@ -651,10 +674,15 @@ public:
|
||||
*Instruction = Inst;
|
||||
break;
|
||||
}
|
||||
case SingleUseForwardLabel::InstType::ADRP: {
|
||||
case ForwardLabel::InstType::ADRP: {
|
||||
uint32_t* Instruction = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t Imm = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(Instruction);
|
||||
LOGMAN_THROW_A_FMT(IsADRPRange(Imm) && IsADRPAligned(Imm), "Unscaled offset too large");
|
||||
|
||||
if (!(IsADRPRange(Imm) && IsADRPAligned(Imm))) {
|
||||
// Can't bind.
|
||||
return false;
|
||||
}
|
||||
|
||||
Imm >>= 12;
|
||||
uint32_t InstMask = 0b11 << 29 | 0b1111'1111'1111'1111'111 << 5;
|
||||
uint32_t Offset = static_cast<uint32_t>(Imm) & 0x3F'FFFF;
|
||||
@@ -664,11 +692,13 @@ public:
|
||||
*Instruction = Inst;
|
||||
break;
|
||||
}
|
||||
|
||||
case SingleUseForwardLabel::InstType::B: {
|
||||
case ForwardLabel::InstType::B: {
|
||||
uint32_t* Instruction = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t Imm = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(Instruction);
|
||||
LOGMAN_THROW_A_FMT(Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
if (!(Imm >= -134217728 && Imm <= 134217724 && ((Imm & 0b11) == 0))) {
|
||||
// Can't bind.
|
||||
return false;
|
||||
}
|
||||
Imm >>= 2;
|
||||
uint32_t InstMask = 0x3FF'FFFF;
|
||||
uint32_t Offset = static_cast<uint32_t>(Imm) & InstMask;
|
||||
@@ -678,11 +708,13 @@ public:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SingleUseForwardLabel::InstType::TEST_BRANCH: {
|
||||
case ForwardLabel::InstType::TEST_BRANCH: {
|
||||
uint32_t* Instruction = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t Imm = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(Instruction);
|
||||
LOGMAN_THROW_A_FMT(Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
if (!(Imm >= -32768 && Imm <= 32764 && ((Imm & 0b11) == 0))) {
|
||||
// Can't bind.
|
||||
return false;
|
||||
}
|
||||
Imm >>= 2;
|
||||
uint32_t InstMask = 0x3FFF;
|
||||
uint32_t Offset = static_cast<uint32_t>(Imm) & InstMask;
|
||||
@@ -692,11 +724,14 @@ public:
|
||||
|
||||
break;
|
||||
}
|
||||
case SingleUseForwardLabel::InstType::BC:
|
||||
case SingleUseForwardLabel::InstType::RELATIVE_LOAD: {
|
||||
case ForwardLabel::InstType::BC:
|
||||
case ForwardLabel::InstType::RELATIVE_LOAD: {
|
||||
uint32_t* Instruction = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t Imm = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(Instruction);
|
||||
LOGMAN_THROW_A_FMT(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0), "Unscaled offset too large");
|
||||
if (!(Imm >= -1048576 && Imm <= 1048575 && ((Imm & 0b11) == 0))) {
|
||||
// Can't bind.
|
||||
return false;
|
||||
}
|
||||
Imm >>= 2;
|
||||
uint32_t InstMask = 0x7'FFFF;
|
||||
uint32_t Offset = static_cast<uint32_t>(Imm) & InstMask;
|
||||
@@ -705,39 +740,45 @@ public:
|
||||
*Instruction = Inst;
|
||||
break;
|
||||
}
|
||||
case SingleUseForwardLabel::InstType::LONG_ADDRESS_GEN: {
|
||||
uint32_t* Instructions = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
int64_t ImmInstOne = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(&Instructions[0]);
|
||||
int64_t ImmInstTwo = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(&Instructions[1]);
|
||||
auto OriginalOffset = GetCursorOffset();
|
||||
case ForwardLabel::InstType::LONG_ADDRESS_GEN: {
|
||||
const auto* Instructions = reinterpret_cast<uint32_t*>(Label->Location);
|
||||
const auto ImmInstOne = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(&Instructions[0]);
|
||||
const auto ImmInstTwo = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(&Instructions[1]);
|
||||
const auto ImmInstThree = reinterpret_cast<int64_t>(CurrentAddress) - reinterpret_cast<int64_t>(&Instructions[2]);
|
||||
const auto OriginalOffset = GetCursorOffset();
|
||||
|
||||
auto InstOffset = GetCursorOffsetFromAddress(Instructions);
|
||||
const auto InstOffset = GetCursorOffsetFromAddress(Instructions);
|
||||
SetCursorOffset(InstOffset);
|
||||
|
||||
// We encoded the destination register in to the first instruction space.
|
||||
// Read it back.
|
||||
ARMEmitter::Register DestReg(Instructions[0]);
|
||||
|
||||
if (IsADRRange(ImmInstTwo)) {
|
||||
// If within ADR range from the second instruction, then we can emit NOP+ADR
|
||||
if (IsADRRange(ImmInstThree)) {
|
||||
// If within ADR range from the third instruction, then we can emit NOP+NOP+ADR
|
||||
nop();
|
||||
adr(DestReg, static_cast<uint32_t>(ImmInstTwo) & 0x7FFF);
|
||||
} else if (IsADRPRange(ImmInstOne)) {
|
||||
nop();
|
||||
adr(DestReg, static_cast<uint32_t>(ImmInstThree) & 0x7FFF);
|
||||
} else if (IsADRPRange(ImmInstTwo)) {
|
||||
|
||||
// If within ADRP range from the first instruction, then we are /definitely/ in range for the second instruction.
|
||||
// First check if we are in non-offset range for second instruction.
|
||||
if (IsADRPAligned(reinterpret_cast<uint64_t>(CurrentAddress))) {
|
||||
// We can emit nop + adrp
|
||||
// We can emit nop + nop + adrp
|
||||
nop();
|
||||
nop();
|
||||
adrp(DestReg, static_cast<uint32_t>(ImmInstThree >> 12) & 0x7FFF);
|
||||
} else {
|
||||
// Not aligned, need nop + adrp + add
|
||||
nop();
|
||||
adrp(DestReg, static_cast<uint32_t>(ImmInstTwo >> 12) & 0x7FFF);
|
||||
} else {
|
||||
// Not aligned, need adrp + add
|
||||
adrp(DestReg, static_cast<uint32_t>(ImmInstOne >> 12) & 0x7FFF);
|
||||
add(ARMEmitter::Size::i64Bit, DestReg, DestReg, ImmInstOne & 0xFFF);
|
||||
add(ARMEmitter::Size::i64Bit, DestReg, DestReg, ImmInstTwo & 0xFFF);
|
||||
}
|
||||
} else {
|
||||
LOGMAN_MSG_A_FMT("Unscaled offset is too large");
|
||||
FEX_UNREACHABLE;
|
||||
// Stinky path, we need to emit a movz+movk+movk sequence.
|
||||
movz(ARMEmitter::Size::i64Bit, DestReg, uint32_t(ImmInstOne >> 32) & 0x7FFF, 32);
|
||||
movk(ARMEmitter::Size::i64Bit, DestReg, uint32_t(ImmInstOne >> 16) & 0xFFFF, 16);
|
||||
movk(ARMEmitter::Size::i64Bit, DestReg, uint32_t(ImmInstOne) & 0xFFFF);
|
||||
}
|
||||
|
||||
SetCursorOffset(OriginalOffset);
|
||||
@@ -745,33 +786,52 @@ public:
|
||||
}
|
||||
default: LOGMAN_MSG_A_FMT("Unexpected inst type in label fixup");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bind a forward label to a location.
|
||||
// This walks all the instructions in the label's vector.
|
||||
// Then backpatching all instructions that have used the label.
|
||||
template<bool WarnAboutEmpty = false>
|
||||
void Bind(ForwardLabel* Label) {
|
||||
if constexpr (WarnAboutEmpty) {
|
||||
LOGMAN_THROW_A_FMT(Label->Insts.empty() == false, "Binding forward label that didn't have any instructions using it");
|
||||
[[nodiscard]] bool Bind(ForwardLabel* Label) {
|
||||
bool Bound = true;
|
||||
if (Label->FirstInst.Location) {
|
||||
Bound &= Bind(&Label->FirstInst);
|
||||
}
|
||||
for (auto& Inst : Label->Insts) {
|
||||
Bind(&Inst);
|
||||
Bound &= Bind(&Inst);
|
||||
}
|
||||
|
||||
return Bound;
|
||||
}
|
||||
|
||||
// Bind a bidirectional location to a location.
|
||||
// Binds both forwards and backwards depending on how the label was used.
|
||||
void Bind(BiDirectionalLabel* Label) {
|
||||
[[nodiscard]] bool Bind(BiDirectionalLabel* Label) {
|
||||
bool Bound = true;
|
||||
if (!Label->Backward.Location) {
|
||||
Bind(&Label->Backward);
|
||||
Bound &= Bind(&Label->Backward);
|
||||
}
|
||||
Bind<false>(&Label->Forward);
|
||||
Bound &= Bind(&Label->Forward);
|
||||
|
||||
return Bound;
|
||||
}
|
||||
|
||||
static constexpr Condition InvertCondition(Condition cond) {
|
||||
// These behave as always, so it makes no sense to allow inverting these.
|
||||
LOGMAN_THROW_A_FMT(cond != Condition::CC_AL && cond != Condition::CC_NV, "Cannot invert CC_AL or CC_NV");
|
||||
return static_cast<Condition>(FEXCore::ToUnderlying(cond) ^ 1);
|
||||
}
|
||||
|
||||
#include <CodeEmitter/VixlUtils.inl>
|
||||
|
||||
public:
|
||||
|
||||
// This symbol is used to allow external tooling (IDEs, clang-format, ...) to process the included files individually:
|
||||
// If defined, the files will inject member functions into this class.
|
||||
// If not, the files will wrap the member functions in a class so that tooling will process them properly.
|
||||
#define INCLUDED_BY_EMITTER
|
||||
|
||||
// TODO: Implement SME when it matters.
|
||||
#include <CodeEmitter/ALUOps.inl>
|
||||
#include <CodeEmitter/BranchOps.inl>
|
||||
@@ -781,7 +841,9 @@ public:
|
||||
#include <CodeEmitter/ASIMDOps.inl>
|
||||
#include <CodeEmitter/SVEOps.inl>
|
||||
|
||||
private:
|
||||
#undef INCLUDED_BY_EMITTER
|
||||
|
||||
protected:
|
||||
template<typename T>
|
||||
uint32_t Encode_ra(T Reg) const {
|
||||
return Reg.Idx() << 10;
|
||||
@@ -793,7 +855,6 @@ private:
|
||||
uint32_t Encode_rt2(T Reg) const {
|
||||
return Reg.Idx() << 10;
|
||||
}
|
||||
template<>
|
||||
uint32_t Encode_rt2(uint32_t Reg) const {
|
||||
return Reg << 10;
|
||||
}
|
||||
@@ -829,7 +890,6 @@ private:
|
||||
uint32_t Encode_rt(T Reg) const {
|
||||
return Reg.Idx();
|
||||
}
|
||||
template<>
|
||||
uint32_t Encode_rt(Prefetch Reg) const {
|
||||
return FEXCore::ToUnderlying(Reg);
|
||||
}
|
||||
|
||||
+1143
-1000
File diff suppressed because it is too large.
Load diff
@@ -30,9 +30,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(Register) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<Register>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<Register>, "Needs to be standard");
|
||||
static_assert(sizeof(Register) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<Register>);
|
||||
static_assert(std::is_standard_layout_v<Register>);
|
||||
|
||||
/* 32-bit GPR register class.
|
||||
* This class will imply a 32-bit register size being used.
|
||||
@@ -58,9 +58,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(Register) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<Register>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<Register>, "Needs to be standard");
|
||||
static_assert(sizeof(WRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<WRegister>);
|
||||
static_assert(std::is_standard_layout_v<WRegister>);
|
||||
|
||||
/* 64-bit GPR register class.
|
||||
* This class will imply a 64-bit register size being used.
|
||||
@@ -86,9 +86,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(Register) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<Register>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<Register>, "Needs to be standard");
|
||||
static_assert(sizeof(XRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<XRegister>);
|
||||
static_assert(std::is_standard_layout_v<XRegister>);
|
||||
|
||||
inline constexpr WRegister Register::W() const {
|
||||
return WRegister {Index};
|
||||
@@ -283,9 +283,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(VRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<VRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<VRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(VRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<VRegister>);
|
||||
static_assert(std::is_standard_layout_v<VRegister>);
|
||||
|
||||
/* 8-bit ASIMD register class
|
||||
* This class implies 8-bit scalar register.
|
||||
@@ -315,9 +315,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(BRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<BRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<BRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(BRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<BRegister>);
|
||||
static_assert(std::is_standard_layout_v<BRegister>);
|
||||
|
||||
/* 16-bit ASIMD register class
|
||||
* This class implies 16-bit scalar register.
|
||||
@@ -347,9 +347,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(HRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<HRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<HRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(HRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<HRegister>);
|
||||
static_assert(std::is_standard_layout_v<HRegister>);
|
||||
|
||||
/* 32-bit ASIMD register class
|
||||
* This class implies 32-bit scalar register.
|
||||
@@ -379,9 +379,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(SRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<SRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<SRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(SRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<SRegister>);
|
||||
static_assert(std::is_standard_layout_v<SRegister>);
|
||||
|
||||
/* 64-bit ASIMD register class
|
||||
* This class doesn't imply Vector or Scalar.
|
||||
@@ -412,9 +412,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(DRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<DRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<DRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(DRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<DRegister>);
|
||||
static_assert(std::is_standard_layout_v<DRegister>);
|
||||
|
||||
/* 128-bit ASIMD register class
|
||||
* This class doesn't imply Vector or Scalar.
|
||||
@@ -445,9 +445,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(QRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<QRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<QRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(QRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<QRegister>);
|
||||
static_assert(std::is_standard_layout_v<QRegister>);
|
||||
|
||||
/* Unsized SVE register class.
|
||||
* This class explicitly implies the instruction will operate using SVE.
|
||||
@@ -474,9 +474,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(ZRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<ZRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<ZRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(ZRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<ZRegister>);
|
||||
static_assert(std::is_standard_layout_v<ZRegister>);
|
||||
|
||||
// VRegister
|
||||
inline constexpr BRegister VRegister::B() const {
|
||||
@@ -919,9 +919,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(PRegister) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<PRegister>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<PRegister>, "Needs to be standard");
|
||||
static_assert(sizeof(PRegister) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<PRegister>);
|
||||
static_assert(std::is_standard_layout_v<PRegister>);
|
||||
|
||||
// Unsized predicate register for SVE with zeroing semantics.
|
||||
class PRegisterZero {
|
||||
@@ -947,9 +947,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(PRegisterZero) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<PRegisterZero>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<PRegisterZero>, "Needs to be standard");
|
||||
static_assert(sizeof(PRegisterZero) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<PRegisterZero>);
|
||||
static_assert(std::is_standard_layout_v<PRegisterZero>);
|
||||
|
||||
// Unsized predicate register for SVE with merging semantics.
|
||||
class PRegisterMerge {
|
||||
@@ -975,9 +975,9 @@ public:
|
||||
private:
|
||||
uint32_t Index;
|
||||
};
|
||||
static_assert(sizeof(PRegisterZero) == sizeof(uint32_t), "Needs to be uint32_t");
|
||||
static_assert(std::is_trivial_v<PRegisterZero>, "Needs to be trivial");
|
||||
static_assert(std::is_standard_layout_v<PRegisterZero>, "Needs to be standard");
|
||||
static_assert(sizeof(PRegisterMerge) == sizeof(uint32_t));
|
||||
static_assert(std::is_trivially_copyable_v<PRegisterMerge>);
|
||||
static_assert(std::is_standard_layout_v<PRegisterMerge>);
|
||||
|
||||
// PRegister
|
||||
inline constexpr PRegisterZero PRegister::Zeroing() const {
|
||||
|
||||
+526
-678
File diff suppressed because it is too large.
Load diff
@@ -16,28 +16,34 @@
|
||||
* Exceptions to this rule will have asserts in the emitter implementation when misused.
|
||||
*
|
||||
*/
|
||||
public:
|
||||
// Advanced SIMD scalar copy
|
||||
void dup(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Index) {
|
||||
constexpr uint32_t Op = 0b0101'1110'0000'0000'0000'01 << 10;
|
||||
|
||||
#pragma once
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
#include <CodeEmitter/Emitter.h>
|
||||
namespace ARMEmitter {
|
||||
struct EmitterOps : Emitter {
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Advanced SIMD scalar copy
|
||||
void dup(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Index) {
|
||||
const uint32_t SizeImm = FEXCore::ToUnderlying(size);
|
||||
const uint32_t IndexShift = SizeImm + 1;
|
||||
const uint32_t ElementSize = 1U << SizeImm;
|
||||
const uint32_t MaxIndex = 128U / (ElementSize * 8);
|
||||
|
||||
LOGMAN_THROW_AA_FMT(Index < MaxIndex, "Index too large. Index={}, Max Index: {}", Index, MaxIndex);
|
||||
LOGMAN_THROW_A_FMT(Index < MaxIndex, "Index too large. Index={}, Max Index: {}", Index, MaxIndex);
|
||||
|
||||
const uint32_t imm5 = (Index << IndexShift) | ElementSize;
|
||||
|
||||
ASIMDScalarCopy(Op, 1, imm5, 0b0000, rd, rn);
|
||||
ASIMDScalarCopy(1, 1, imm5, 0b0000, rd, rn);
|
||||
}
|
||||
|
||||
void mov(ARMEmitter::ScalarRegSize size, ARMEmitter::VRegister rd, ARMEmitter::VRegister rn, uint32_t Index) {
|
||||
void mov(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Index) {
|
||||
dup(size, rd, rn, Index);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar three same FP16
|
||||
// Advanced SIMD scalar three same FP16
|
||||
void fmulx(HRegister rd, HRegister rn, HRegister rm) {
|
||||
ASIMDScalarThreeSameFP16(0, 0, 0b011, rm, rn, rd);
|
||||
}
|
||||
@@ -66,7 +72,7 @@ public:
|
||||
ASIMDScalarThreeSameFP16(1, 1, 0b101, rm, rn, rd);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar two-register miscellaneous FP16
|
||||
// Advanced SIMD scalar two-register miscellaneous FP16
|
||||
void fcvtns(HRegister rd, HRegister rn) {
|
||||
ASIMDScalarTwoRegMiscFP16(0, 0, 0b11010, rn, rd);
|
||||
}
|
||||
@@ -128,9 +134,17 @@ public:
|
||||
ASIMDScalarTwoRegMiscFP16(1, 1, 0b11101, rn, rd);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar three same extra
|
||||
// XXX:
|
||||
// Advanced SIMD scalar two-register miscellaneous
|
||||
// Advanced SIMD scalar three same extra
|
||||
void sqrdmlah(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i32Bit, "Only supports 16/32-bit");
|
||||
ASIMDScalarThreeSameExtra(1, size, 0b0000, rm, rn, rd);
|
||||
}
|
||||
void sqrdmlsh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i32Bit, "Only supports 16/32-bit");
|
||||
ASIMDScalarThreeSameExtra(1, size, 0b0001, rm, rn, rd);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar two-register miscellaneous
|
||||
void suqadd(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b00011, rd, rn);
|
||||
}
|
||||
@@ -140,67 +154,55 @@ public:
|
||||
|
||||
///< Comparison against 0.0
|
||||
void cmgt(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b01000, rd, rn);
|
||||
}
|
||||
///< Comparison against 0.0
|
||||
void cmeq(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b01001, rd, rn);
|
||||
}
|
||||
|
||||
///< Comparison against 0.0
|
||||
void cmlt(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b01010, rd, rn);
|
||||
}
|
||||
void abs(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b01011, rd, rn);
|
||||
}
|
||||
///< size is destination size.
|
||||
void sqxtn(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
ASIMDScalar2RegMisc(0, 0, size, 0b10100, rd, rn);
|
||||
}
|
||||
|
||||
void fcvtns(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 0, ConvertedSize, 0b11010, rd, rn);
|
||||
}
|
||||
void fcvtms(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 0, ConvertedSize, 0b11011, rd, rn);
|
||||
}
|
||||
void fcvtas(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 0, ConvertedSize, 0b11100, rd, rn);
|
||||
}
|
||||
void scvtf(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 0, ConvertedSize, 0b11101, rd, rn);
|
||||
}
|
||||
@@ -249,70 +251,58 @@ public:
|
||||
}
|
||||
///< Comparison against 0.0
|
||||
void cmge(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 1, size, 0b01000, rd, rn);
|
||||
}
|
||||
///< Comparison against 0.0
|
||||
void cmle(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 1, size, 0b01001, rd, rn);
|
||||
}
|
||||
void neg(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMDScalar2RegMisc(0, 1, size, 0b01011, rd, rn);
|
||||
}
|
||||
///< size is destination.
|
||||
void sqxtun(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
ASIMDScalar2RegMisc(0, 1, size, 0b10010, rd, rn);
|
||||
}
|
||||
///< size is destination.
|
||||
void uqxtn(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "64-bit destination not supported");
|
||||
ASIMDScalar2RegMisc(0, 1, size, 0b10100, rd, rn);
|
||||
}
|
||||
///< size is destination.
|
||||
void fcvtxn(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMDScalar2RegMisc(0, 1, ScalarRegSize::i16Bit, 0b10110, rd, rn);
|
||||
}
|
||||
void fcvtnu(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 1, ConvertedSize, 0b11010, rd, rn);
|
||||
}
|
||||
void fcvtmu(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 1, ConvertedSize, 0b11011, rd, rn);
|
||||
}
|
||||
void fcvtau(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 1, ConvertedSize, 0b11100, rd, rn);
|
||||
}
|
||||
void ucvtf(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(0, 1, ConvertedSize, 0b11101, rd, rn);
|
||||
}
|
||||
@@ -366,73 +356,55 @@ public:
|
||||
}
|
||||
|
||||
void fmaxnmp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(1, 1, ConvertedSize, 0b01100, rd, rn);
|
||||
}
|
||||
void faddp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(1, 1, ConvertedSize, 0b01101, rd, rn);
|
||||
}
|
||||
void fmaxp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMDScalar2RegMisc(1, 1, ConvertedSize, 0b01111, rd, rn);
|
||||
}
|
||||
void fminnmp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMDScalar2RegMisc(1, 1, size, 0b01100, rd, rn);
|
||||
}
|
||||
void fminp(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMDScalar2RegMisc(1, 1, size, 0b01111, rd, rn);
|
||||
}
|
||||
// Advanced SIMD scalar three different
|
||||
// Advanced SIMD scalar three different
|
||||
///< size is destination.
|
||||
void sqdmlal(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i32Bit :
|
||||
ScalarRegSize::i16Bit;
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i32Bit : ScalarRegSize::i16Bit;
|
||||
ASIMD3RegDifferent(0, ConvertedSize, 0b1001, rd, rn, rm);
|
||||
}
|
||||
///< size is destination.
|
||||
void sqdmlsl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i32Bit :
|
||||
ScalarRegSize::i16Bit;
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i32Bit : ScalarRegSize::i16Bit;
|
||||
ASIMD3RegDifferent(0, ConvertedSize, 0b1011, rd, rn, rm);
|
||||
}
|
||||
|
||||
///< size is destination.
|
||||
void sqdmull(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i32Bit :
|
||||
ScalarRegSize::i16Bit;
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i32Bit : ScalarRegSize::i16Bit;
|
||||
ASIMD3RegDifferent(0, ConvertedSize, 0b1101, rd, rn, rm);
|
||||
}
|
||||
// Advanced SIMD scalar three same
|
||||
// Advanced SIMD scalar three same
|
||||
void sqadd(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
ASIMD3RegSame(0, size, 0b00001, rd, rn, rm);
|
||||
}
|
||||
@@ -440,71 +412,62 @@ public:
|
||||
ASIMD3RegSame(0, size, 0b00101, rd, rn, rm);
|
||||
}
|
||||
void cmgt(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b00110, rd, rn, rm);
|
||||
}
|
||||
void cmge(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b00111, rd, rn, rm);
|
||||
}
|
||||
void sshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b01000, rd, rn, rm);
|
||||
}
|
||||
void sqshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
ASIMD3RegSame(0, size, 0b01001, rd, rn, rm);
|
||||
}
|
||||
void srshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b01010, rd, rn, rm);
|
||||
}
|
||||
void sqrshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
ASIMD3RegSame(0, size, 0b01011, rd, rn, rm);
|
||||
}
|
||||
void add(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b10000, rd, rn, rm);
|
||||
}
|
||||
void cmtst(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(0, size, 0b10001, rd, rn, rm);
|
||||
}
|
||||
void sqdmulh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i32Bit || size == ScalarRegSize::i16Bit, "Invalid size");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i32Bit || size == ScalarRegSize::i16Bit, "Invalid size");
|
||||
ASIMD3RegSame(0, size, 0b10110, rd, rn, rm);
|
||||
}
|
||||
void fmulx(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMD3RegSame(0, ConvertedSize, 0b11011, rd, rn, rm);
|
||||
}
|
||||
void fcmeq(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMD3RegSame(0, ConvertedSize, 0b11100, rd, rn, rm);
|
||||
}
|
||||
void frecps(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMD3RegSame(0, ConvertedSize, 0b11111, rd, rn, rm);
|
||||
}
|
||||
void frsqrts(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMD3RegSame(0, size, 0b11111, rd, rn, rm);
|
||||
}
|
||||
void uqadd(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
@@ -514,75 +477,69 @@ public:
|
||||
ASIMD3RegSame(1, size, 0b00101, rd, rn, rm);
|
||||
}
|
||||
void cmhi(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b00110, rd, rn, rm);
|
||||
}
|
||||
void cmhs(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b00111, rd, rn, rm);
|
||||
}
|
||||
void ushl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b01000, rd, rn, rm);
|
||||
}
|
||||
void uqshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
ASIMD3RegSame(1, size, 0b01001, rd, rn, rm);
|
||||
}
|
||||
void urshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b01010, rd, rn, rm);
|
||||
}
|
||||
void uqrshl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
ASIMD3RegSame(1, size, 0b01011, rd, rn, rm);
|
||||
}
|
||||
void sub(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b10000, rd, rn, rm);
|
||||
}
|
||||
void cmeq(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit, "Only supports 64-bit");
|
||||
ASIMD3RegSame(1, size, 0b10001, rd, rn, rm);
|
||||
}
|
||||
void sqrdmulh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i32Bit || size == ScalarRegSize::i16Bit, "Invalid size");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i32Bit || size == ScalarRegSize::i16Bit, "Invalid size");
|
||||
ASIMD3RegSame(1, size, 0b10110, rd, rn, rm);
|
||||
}
|
||||
void fcmge(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMD3RegSame(1, ConvertedSize, 0b11100, rd, rn, rm);
|
||||
}
|
||||
void facge(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
|
||||
const ScalarRegSize ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ?
|
||||
ScalarRegSize::i16Bit :
|
||||
ScalarRegSize::i8Bit;
|
||||
const ScalarRegSize ConvertedSize = size == ScalarRegSize::i64Bit ? ScalarRegSize::i16Bit : ScalarRegSize::i8Bit;
|
||||
|
||||
ASIMD3RegSame(1, ConvertedSize, 0b11101, rd, rn, rm);
|
||||
}
|
||||
void fabd(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMD3RegSame(1, size, 0b11010, rd, rn, rm);
|
||||
}
|
||||
void fcmgt(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMD3RegSame(1, size, 0b11100, rd, rn, rm);
|
||||
}
|
||||
void facgt(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for float convert");
|
||||
ASIMD3RegSame(1, size, 0b11101, rd, rn, rm);
|
||||
}
|
||||
// Advanced SIMD scalar shift by immediate
|
||||
// Advanced SIMD scalar shift by immediate
|
||||
void sshr(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -592,8 +549,8 @@ public:
|
||||
ASIMDScalarShiftByImm(0, immh, immb, 0b00000, rd, rn);
|
||||
}
|
||||
void ssra(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -603,8 +560,8 @@ public:
|
||||
ASIMDScalarShiftByImm(0, immh, immb, 0b00010, rd, rn);
|
||||
}
|
||||
void srshr(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -614,8 +571,8 @@ public:
|
||||
ASIMDScalarShiftByImm(0, immh, immb, 0b00100, rd, rn);
|
||||
}
|
||||
void srsra(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -625,8 +582,8 @@ public:
|
||||
ASIMDScalarShiftByImm(0, immh, immb, 0b00110, rd, rn);
|
||||
}
|
||||
void shl(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
// Shift encoded a bit weirdly.
|
||||
// shift = immh:immb - elementsize but immh is /also/ used for element size.
|
||||
const uint32_t immh = 1 << FEXCore::ToUnderlying(size) | (Shift >> 3);
|
||||
@@ -644,7 +601,7 @@ public:
|
||||
///< size is destination
|
||||
void sqshrn(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrn");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrn");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -655,7 +612,7 @@ public:
|
||||
}
|
||||
void sqrshrn(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrn");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrn");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -666,8 +623,8 @@ public:
|
||||
}
|
||||
// TODO: SCVTF, FCVTZS
|
||||
void ushr(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -677,8 +634,8 @@ public:
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b00000, rd, rn);
|
||||
}
|
||||
void usra(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -688,8 +645,8 @@ public:
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b00010, rd, rn);
|
||||
}
|
||||
void urshr(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -699,8 +656,8 @@ public:
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b00100, rd, rn);
|
||||
}
|
||||
void ursra(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -710,8 +667,8 @@ public:
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b00110, rd, rn);
|
||||
}
|
||||
void sri(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -721,8 +678,8 @@ public:
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b01000, rd, rn);
|
||||
}
|
||||
void sli(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_AA_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < 64, "Invalid shift for sshr");
|
||||
LOGMAN_THROW_A_FMT(size == ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sshr");
|
||||
// Shift encoded a bit weirdly.
|
||||
// shift = immh:immb - elementsize but immh is /also/ used for element size.
|
||||
const uint32_t immh = 1 << FEXCore::ToUnderlying(size) | (Shift >> 3);
|
||||
@@ -748,7 +705,7 @@ public:
|
||||
///< size is destination.
|
||||
void sqshrun(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrun");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqshrun");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -760,7 +717,7 @@ public:
|
||||
///< size is destination.
|
||||
void sqrshrun(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -772,7 +729,7 @@ public:
|
||||
///< size is destination.
|
||||
void uqshrn(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -784,7 +741,7 @@ public:
|
||||
///< size is destination.
|
||||
void uqrshrn(ScalarRegSize size, VRegister rd, VRegister rn, uint32_t Shift) {
|
||||
LOGMAN_THROW_A_FMT(Shift > 0 && Shift < ScalarRegSizeInBits(size), "Invalid shift for sshr");
|
||||
LOGMAN_THROW_AA_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
LOGMAN_THROW_A_FMT(size != ARMEmitter::ScalarRegSize::i64Bit, "Invalid size selected for sqrshrun");
|
||||
const size_t SubregSizeInBits = ScalarRegSizeInBits(size);
|
||||
// Shift encoded in immh:immb, but inverted with 128-bit source
|
||||
// shift = (esize * 2) - immh:immb
|
||||
@@ -793,11 +750,52 @@ public:
|
||||
const uint32_t immb = InvertedShift & 0b111;
|
||||
ASIMDScalarShiftByImm(1, immh, immb, 0b10011, rd, rn);
|
||||
}
|
||||
|
||||
// TODO: UCVTF, FCVTZU
|
||||
// Advanced SIMD scalar x indexed element
|
||||
// XXX:
|
||||
//
|
||||
// Floating-point data-processing (1 source)
|
||||
|
||||
// Advanced SIMD scalar x indexed element
|
||||
void sqdmlal(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(0, size, 0b0011, rm, rn, rd, index);
|
||||
}
|
||||
void sqdmlsl(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(0, size, 0b0111, rm, rn, rd, index);
|
||||
}
|
||||
void sqdmull(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(0, size, 0b1011, rm, rn, rd, index);
|
||||
}
|
||||
void sqdmulh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(0, size, 0b1100, rm, rn, rd, index);
|
||||
}
|
||||
void sqrdmulh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(0, size, 0b1101, rm, rn, rd, index);
|
||||
}
|
||||
void fmla(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
ASIMDScalarXIndexedElement(0, size, 0b0001, rm, rn, rd, index);
|
||||
}
|
||||
void fmls(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
ASIMDScalarXIndexedElement(0, size, 0b0101, rm, rn, rd, index);
|
||||
}
|
||||
void fmul(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
ASIMDScalarXIndexedElement(0, size, 0b1001, rm, rn, rd, index);
|
||||
}
|
||||
void sqrdmlah(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(1, size, 0b1101, rm, rn, rd, index);
|
||||
}
|
||||
void sqrdmlsh(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i64Bit, "Scalar size must not be 64-bit");
|
||||
ASIMDScalarXIndexedElement(1, size, 0b1111, rm, rn, rd, index);
|
||||
}
|
||||
void fmulx(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, uint32_t index) {
|
||||
ASIMDScalarXIndexedElement(1, size, 0b1001, rm, rn, rd, index);
|
||||
}
|
||||
|
||||
// Floating-point data-processing (1 source)
|
||||
void fmov(ScalarRegSize size, VRegister rd, VRegister rn) {
|
||||
Float1Source(size, 0, 0, 0b000000, rd, rn);
|
||||
}
|
||||
@@ -991,14 +989,14 @@ public:
|
||||
Float1Source(0, 0, 0b11, 0b001111, rd.V(), rn.V());
|
||||
}
|
||||
|
||||
// Floating-point compare
|
||||
// Floating-point compare
|
||||
void fcmp(ScalarRegSize Size, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(Size != ScalarRegSize::i8Bit, "8-bit destination not supported");
|
||||
LOGMAN_THROW_A_FMT(Size != ScalarRegSize::i8Bit, "8-bit destination not supported");
|
||||
|
||||
const auto ConvertedSize =
|
||||
Size == ARMEmitter::ScalarRegSize::i64Bit ? 0b01 :
|
||||
Size == ARMEmitter::ScalarRegSize::i32Bit ? 0b00 :
|
||||
Size == ARMEmitter::ScalarRegSize::i16Bit ? 0b11 : 0;
|
||||
const auto ConvertedSize = Size == ARMEmitter::ScalarRegSize::i64Bit ? 0b01 :
|
||||
Size == ARMEmitter::ScalarRegSize::i32Bit ? 0b00 :
|
||||
Size == ARMEmitter::ScalarRegSize::i16Bit ? 0b11 :
|
||||
0;
|
||||
|
||||
FloatCompare(0, 0, ConvertedSize, 0b00, 0b00000, rn, rm);
|
||||
}
|
||||
@@ -1051,7 +1049,7 @@ public:
|
||||
FloatCompare(0, 0, 0b11, 0b00, 0b11000, rn.V(), VReg::v0);
|
||||
}
|
||||
|
||||
// Floating-point immediate
|
||||
// Floating-point immediate
|
||||
void fmov(ARMEmitter::ScalarRegSize size, ARMEmitter::VRegister rd, float Value) {
|
||||
uint32_t M = 0;
|
||||
uint32_t S = 0;
|
||||
@@ -1061,16 +1059,13 @@ public:
|
||||
if (size == ARMEmitter::ScalarRegSize::i16Bit) {
|
||||
LOGMAN_MSG_A_FMT("Unsupported");
|
||||
FEX_UNREACHABLE;
|
||||
}
|
||||
else if (size == ARMEmitter::ScalarRegSize::i32Bit) {
|
||||
} else if (size == ARMEmitter::ScalarRegSize::i32Bit) {
|
||||
ptype = 0b00;
|
||||
imm8 = FP32ToImm8(Value);
|
||||
}
|
||||
else if (size == ARMEmitter::ScalarRegSize::i64Bit) {
|
||||
} else if (size == ARMEmitter::ScalarRegSize::i64Bit) {
|
||||
ptype = 0b01;
|
||||
imm8 = FP64ToImm8(Value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
FEX_UNREACHABLE;
|
||||
}
|
||||
|
||||
@@ -1090,7 +1085,7 @@ public:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Floating-point conditional compare
|
||||
// Floating-point conditional compare
|
||||
void fccmp(SRegister rn, SRegister rm, StatusFlags flags, Condition Cond) {
|
||||
FloatConditionalCompare(0, 0, 0b00, 0b0, rn.V(), rm.V(), flags, Cond);
|
||||
}
|
||||
@@ -1110,7 +1105,7 @@ public:
|
||||
FloatConditionalCompare(0, 0, 0b11, 0b1, rn.V(), rm.V(), flags, Cond);
|
||||
}
|
||||
|
||||
// Floating-point data-processing (2 source)
|
||||
// Floating-point data-processing (2 source)
|
||||
void fmul(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm) {
|
||||
Float2Source(size, 0, 0, 0b0000, rd, rn, rm);
|
||||
}
|
||||
@@ -1225,11 +1220,10 @@ public:
|
||||
|
||||
// Floating-point conditional select
|
||||
void fcsel(ScalarRegSize size, VRegister rd, VRegister rn, VRegister rm, Condition Cond) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit,
|
||||
"Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
const uint32_t ConvertedSize = size == ScalarRegSize::i64Bit ? 0b01 : size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
FloatConditionalSelect(0, 0, ConvertedSize, rd, rn, rm, Cond);
|
||||
}
|
||||
@@ -1244,7 +1238,7 @@ public:
|
||||
FloatConditionalSelect(0, 0, 0b11, rd.V(), rn.V(), rm.V(), Cond);
|
||||
}
|
||||
|
||||
// Floating-point data-processing (3 source)
|
||||
// Floating-point data-processing (3 source)
|
||||
void fmadd(SRegister rd, SRegister rn, SRegister rm, SRegister ra) {
|
||||
Float3Source(0, 0, 0b00, 0, 0, rd.V(), rn.V(), rm.V(), ra.V());
|
||||
}
|
||||
@@ -1285,11 +1279,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// Advanced SIMD scalar copy
|
||||
void ASIMDScalarCopy(uint32_t Op, uint32_t Q, uint32_t imm5, uint32_t imm4, ARMEmitter::VRegister rd, ARMEmitter::VRegister rn) {
|
||||
uint32_t Instr = Op;
|
||||
|
||||
// Advanced SIMD scalar copy
|
||||
void ASIMDScalarCopy(uint32_t Q, uint32_t b28, uint32_t imm5, uint32_t imm4, VRegister rd, VRegister rn) {
|
||||
uint32_t Instr = 0b0000'1110'0000'0000'0000'01U << 10;
|
||||
Instr |= Q << 30;
|
||||
Instr |= b28 << 28;
|
||||
Instr |= imm5 << 16;
|
||||
Instr |= imm4 << 11;
|
||||
Instr |= Encode_rn(rn);
|
||||
@@ -1297,7 +1291,7 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar three same FP16
|
||||
// Advanced SIMD scalar three same FP16
|
||||
void ASIMDScalarThreeSameFP16(uint32_t U, uint32_t a, uint32_t opcode, HRegister rm, HRegister rn, HRegister rd) {
|
||||
uint32_t Instr = 0b0101'1110'0100'0000'0000'0100'0000'0000;
|
||||
|
||||
@@ -1309,7 +1303,7 @@ private:
|
||||
Instr |= rd.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
// Advanced SIMD scalar two-register miscellaneous FP16
|
||||
// Advanced SIMD scalar two-register miscellaneous FP16
|
||||
void ASIMDScalarTwoRegMiscFP16(uint32_t U, uint32_t a, uint32_t opcode, HRegister rn, HRegister rd) {
|
||||
uint32_t Instr = 0b0101'1110'0111'1000'0000'1000'0000'0000;
|
||||
|
||||
@@ -1321,9 +1315,19 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar three same extra
|
||||
// XXX:
|
||||
// Advanced SIMD scalar two-register miscellaneous
|
||||
// Advanced SIMD scalar three same extra
|
||||
void ASIMDScalarThreeSameExtra(uint32_t U, ScalarRegSize size, uint32_t opcode, VRegister rm, VRegister rn, VRegister rd) {
|
||||
uint32_t Instr = 0b0101'1110'0000'0000'1000'0100'0000'0000;
|
||||
Instr |= U << 29;
|
||||
Instr |= FEXCore::ToUnderlying(size) << 22;
|
||||
Instr |= rm.Idx() << 16;
|
||||
Instr |= opcode << 11;
|
||||
Instr |= rn.Idx() << 5;
|
||||
Instr |= rd.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar two-register miscellaneous
|
||||
void ASIMDScalar2RegMisc(uint32_t b20, uint32_t U, ScalarRegSize size, uint32_t opcode, VRegister rd, VRegister rn) {
|
||||
uint32_t Instr = 0b0101'1110'0010'0000'0000'1000'0000'0000;
|
||||
|
||||
@@ -1336,9 +1340,7 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Advanced SIMD scalar pairwise
|
||||
// XXX:
|
||||
// Advanced SIMD scalar three different
|
||||
// Advanced SIMD scalar three different
|
||||
void ASIMD3RegDifferent(uint32_t U, ScalarRegSize size, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0101'1110'0010'0000'0000'0000'0000'0000;
|
||||
|
||||
@@ -1350,7 +1352,7 @@ private:
|
||||
Instr |= Encode_rd(rd);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Advanced SIMD scalar three same
|
||||
// Advanced SIMD scalar three same
|
||||
void ASIMD3RegSame(uint32_t U, ScalarRegSize size, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0101'1110'0010'0000'0000'0100'0000'0000;
|
||||
|
||||
@@ -1362,7 +1364,7 @@ private:
|
||||
Instr |= Encode_rd(rd);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Advanced SIMD scalar shift by immediate
|
||||
// Advanced SIMD scalar shift by immediate
|
||||
void ASIMDScalarShiftByImm(uint32_t U, uint32_t immh, uint32_t immb, uint32_t opcode, VRegister rd, VRegister rn) {
|
||||
uint32_t Instr = 0b0101'1111'0000'0000'0000'0100'0000'0000;
|
||||
|
||||
@@ -1374,9 +1376,51 @@ private:
|
||||
Instr |= Encode_rd(rd);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Advanced SIMD scalar x indexed element
|
||||
// XXX:
|
||||
// Floating-point data-processing (1 source)
|
||||
|
||||
// Advanced SIMD scalar x indexed element
|
||||
void ASIMDScalarXIndexedElement(uint32_t U, ScalarRegSize size, uint32_t opcode, VRegister rm, VRegister rn, VRegister rd, uint32_t index) {
|
||||
LOGMAN_THROW_A_FMT(size != ScalarRegSize::i8Bit, "Scalar size must not be 8-bit");
|
||||
|
||||
const auto invalid_bound = 16U >> FEXCore::ToUnderlying(size);
|
||||
LOGMAN_THROW_A_FMT(index < invalid_bound, "Index ({}) must be within [0-{}]", index, invalid_bound - 1);
|
||||
|
||||
uint32_t Instr = 0b0101'1111'0000'0000'0000'0000'0000'0000;
|
||||
|
||||
// FMUL/FMLA/FMLS indexed variants deal with size differently.
|
||||
if (opcode == 0b0001 || opcode == 0b0101 || opcode == 0b1001) {
|
||||
// Unlike other instructions in the group, 16-bit is encoded as zero
|
||||
// and 32/64-bit are encoded with the top bit always set to one.
|
||||
if (size != ScalarRegSize::i16Bit) {
|
||||
Instr |= (0b10 | (FEXCore::ToUnderlying(size) & 1)) << 22;
|
||||
}
|
||||
} else {
|
||||
Instr |= FEXCore::ToUnderlying(size) << 22;
|
||||
}
|
||||
|
||||
uint32_t H = 0;
|
||||
uint32_t LM = 0;
|
||||
if (size == ScalarRegSize::i16Bit) {
|
||||
LOGMAN_THROW_A_FMT(rm <= VReg::v15, "rm ({}) must be within [v0-v15]", rm.Idx());
|
||||
H = (index >> 2) & 1;
|
||||
LM = index & 0b11;
|
||||
} else if (size == ScalarRegSize::i32Bit) {
|
||||
H = (index >> 1) & 1;
|
||||
LM = (index & 0b01) << 1;
|
||||
} else {
|
||||
H = index & 1;
|
||||
}
|
||||
|
||||
Instr |= U << 29;
|
||||
Instr |= LM << 20;
|
||||
Instr |= rm.Idx() << 16;
|
||||
Instr |= opcode << 12;
|
||||
Instr |= H << 11;
|
||||
Instr |= rn.Idx() << 5;
|
||||
Instr |= rd.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Floating-point data-processing (1 source)
|
||||
void Float1Source(uint32_t M, uint32_t S, uint32_t ptype, uint32_t opcode, VRegister rd, VRegister rn) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0100'0000'0000'0000;
|
||||
|
||||
@@ -1390,16 +1434,15 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
void Float1Source(ScalarRegSize size, uint32_t M, uint32_t S, uint32_t opcode, VRegister rd, VRegister rn) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit,
|
||||
"Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
const uint32_t ConvertedSize = size == ScalarRegSize::i64Bit ? 0b01 : size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
Float1Source(M, S, ConvertedSize, opcode, rd, rn);
|
||||
}
|
||||
|
||||
// Floating-point compare
|
||||
// Floating-point compare
|
||||
void FloatCompare(uint32_t M, uint32_t S, uint32_t ftype, uint32_t op, uint32_t opcode2, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0010'0000'0000'0000;
|
||||
|
||||
@@ -1413,9 +1456,9 @@ private:
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
// Floating-point immediate
|
||||
// XXX:
|
||||
// Floating-point conditional compare
|
||||
// Floating-point immediate
|
||||
// XXX:
|
||||
// Floating-point conditional compare
|
||||
void FloatConditionalCompare(uint32_t M, uint32_t S, uint32_t ptype, uint32_t op, VRegister rn, VRegister rm, StatusFlags flags, Condition Cond) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0000'0100'0000'0000;
|
||||
|
||||
@@ -1430,7 +1473,7 @@ private:
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
// Floating-point data-processing (2 source)
|
||||
// Floating-point data-processing (2 source)
|
||||
|
||||
void Float2Source(uint32_t M, uint32_t S, uint32_t ptype, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0000'1000'0000'0000;
|
||||
@@ -1447,16 +1490,15 @@ private:
|
||||
}
|
||||
|
||||
void Float2Source(ScalarRegSize size, uint32_t M, uint32_t S, uint32_t opcode, VRegister rd, VRegister rn, VRegister rm) {
|
||||
LOGMAN_THROW_AA_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit, "Invalid size selected for {}", __func__);
|
||||
LOGMAN_THROW_A_FMT(size == ScalarRegSize::i16Bit || size == ScalarRegSize::i64Bit || size == ScalarRegSize::i32Bit,
|
||||
"Invalid size selected for {}", __func__);
|
||||
|
||||
const uint32_t ConvertedSize =
|
||||
size == ScalarRegSize::i64Bit ? 0b01 :
|
||||
size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
const uint32_t ConvertedSize = size == ScalarRegSize::i64Bit ? 0b01 : size == ScalarRegSize::i32Bit ? 0b00 : 0b11;
|
||||
|
||||
Float2Source(M, S, ConvertedSize, opcode, rd, rn, rm);
|
||||
}
|
||||
|
||||
// Floating-point conditional select
|
||||
// Floating-point conditional select
|
||||
void FloatConditionalSelect(uint32_t M, uint32_t S, uint32_t ptype, VRegister rd, VRegister rn, VRegister rm, Condition Cond) {
|
||||
uint32_t Instr = 0b0001'1110'0010'0000'0000'1100'0000'0000;
|
||||
|
||||
@@ -1470,7 +1512,7 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Floating-point data-processing (3 source)
|
||||
// Floating-point data-processing (3 source)
|
||||
void Float3Source(uint32_t M, uint32_t S, uint32_t ptype, uint32_t o1, uint32_t o0, VRegister rd, VRegister rn, VRegister rm, VRegister ra) {
|
||||
uint32_t Instr = 0b0001'1111'0000'0000'0000'0000'0000'0000;
|
||||
|
||||
@@ -1485,3 +1527,8 @@ private:
|
||||
Instr |= Encode_rd(rd);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
}; // struct LoadstoreEmitterOps
|
||||
} // namespace ARMEmitter
|
||||
#endif
|
||||
@@ -4,173 +4,191 @@
|
||||
* This is mostly a mashup of various instruction types.
|
||||
* Nothing follows an explicit pattern since they are mostly different.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
#include <CodeEmitter/Emitter.h>
|
||||
namespace ARMEmitter {
|
||||
struct EmitterOps : Emitter {
|
||||
#endif
|
||||
|
||||
public:
|
||||
// System with result
|
||||
// TODO: SYSL
|
||||
// System Instruction
|
||||
// TODO: AT
|
||||
// TODO: CFP
|
||||
// TODO: CPP
|
||||
void dc(ARMEmitter::DataCacheOperation DCOp, ARMEmitter::Register rt) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0000'1000'0111 << 12;
|
||||
SystemInstruction(Op, 0, FEXCore::ToUnderlying(DCOp), rt);
|
||||
}
|
||||
// TODO: DVP
|
||||
// TODO: IC
|
||||
// TODO: TLBI
|
||||
// Reserved
|
||||
void udf(uint32_t Imm) {
|
||||
LOGMAN_THROW_A_FMT(Imm < 0x1'0000, "Immediate needs to be 16-bit");
|
||||
dc32(Imm);
|
||||
}
|
||||
|
||||
// Exception generation
|
||||
void svc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b01, Imm);
|
||||
}
|
||||
void hvc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b10, Imm);
|
||||
}
|
||||
void smc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b11, Imm);
|
||||
}
|
||||
void brk(uint32_t Imm) {
|
||||
ExceptionGeneration(0b001, 0b000, 0b00, Imm);
|
||||
}
|
||||
void hlt(uint32_t Imm) {
|
||||
ExceptionGeneration(0b010, 0b000, 0b00, Imm);
|
||||
}
|
||||
void tcancel(uint32_t Imm) {
|
||||
ExceptionGeneration(0b011, 0b000, 0b00, Imm);
|
||||
}
|
||||
void dcps1(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b01, Imm);
|
||||
}
|
||||
void dcps2(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b10, Imm);
|
||||
}
|
||||
void dcps3(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b11, Imm);
|
||||
}
|
||||
// System instructions with register argument
|
||||
void wfet(ARMEmitter::Register rt) {
|
||||
SystemInstructionWithReg(0b0000, 0b000, rt);
|
||||
}
|
||||
void wfit(ARMEmitter::Register rt) {
|
||||
SystemInstructionWithReg(0b0000, 0b001, rt);
|
||||
}
|
||||
// System with result
|
||||
// TODO: SYSL
|
||||
// System Instruction
|
||||
// TODO: AT
|
||||
// TODO: CFP
|
||||
// TODO: CPP
|
||||
void dc(ARMEmitter::DataCacheOperation DCOp, ARMEmitter::Register rt) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0000'1000'0111 << 12;
|
||||
SystemInstruction(Op, 0, FEXCore::ToUnderlying(DCOp), rt);
|
||||
}
|
||||
// TODO: DVP
|
||||
// TODO: IC
|
||||
// TODO: TLBI
|
||||
|
||||
// Hints
|
||||
void nop() {
|
||||
Hint(ARMEmitter::HintRegister::NOP);
|
||||
}
|
||||
void yield() {
|
||||
Hint(ARMEmitter::HintRegister::YIELD);
|
||||
}
|
||||
void wfe() {
|
||||
Hint(ARMEmitter::HintRegister::WFE);
|
||||
}
|
||||
void wfi() {
|
||||
Hint(ARMEmitter::HintRegister::WFI);
|
||||
}
|
||||
void sev() {
|
||||
Hint(ARMEmitter::HintRegister::SEV);
|
||||
}
|
||||
void sevl() {
|
||||
Hint(ARMEmitter::HintRegister::SEVL);
|
||||
}
|
||||
void dgh() {
|
||||
Hint(ARMEmitter::HintRegister::DGH);
|
||||
}
|
||||
void csdb() {
|
||||
Hint(ARMEmitter::HintRegister::CSDB);
|
||||
}
|
||||
// Exception generation
|
||||
void svc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b01, Imm);
|
||||
}
|
||||
void hvc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b10, Imm);
|
||||
}
|
||||
void smc(uint32_t Imm) {
|
||||
ExceptionGeneration(0b000, 0b000, 0b11, Imm);
|
||||
}
|
||||
void brk(uint32_t Imm) {
|
||||
ExceptionGeneration(0b001, 0b000, 0b00, Imm);
|
||||
}
|
||||
void hlt(uint32_t Imm) {
|
||||
ExceptionGeneration(0b010, 0b000, 0b00, Imm);
|
||||
}
|
||||
void tcancel(uint32_t Imm) {
|
||||
ExceptionGeneration(0b011, 0b000, 0b00, Imm);
|
||||
}
|
||||
void dcps1(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b01, Imm);
|
||||
}
|
||||
void dcps2(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b10, Imm);
|
||||
}
|
||||
void dcps3(uint32_t Imm) {
|
||||
ExceptionGeneration(0b101, 0b000, 0b11, Imm);
|
||||
}
|
||||
// System instructions with register argument
|
||||
void wfet(ARMEmitter::Register rt) {
|
||||
SystemInstructionWithReg(0b0000, 0b000, rt);
|
||||
}
|
||||
void wfit(ARMEmitter::Register rt) {
|
||||
SystemInstructionWithReg(0b0000, 0b001, rt);
|
||||
}
|
||||
|
||||
// Barriers
|
||||
void clrex(uint32_t imm = 15) {
|
||||
LOGMAN_THROW_AA_FMT(imm < 16, "Immediate out of range");
|
||||
Barrier(ARMEmitter::BarrierRegister::CLREX, imm);
|
||||
}
|
||||
void dsb(ARMEmitter::BarrierScope Scope) {
|
||||
Barrier(ARMEmitter::BarrierRegister::DSB, FEXCore::ToUnderlying(Scope));
|
||||
}
|
||||
void dmb(ARMEmitter::BarrierScope Scope) {
|
||||
Barrier(ARMEmitter::BarrierRegister::DMB, FEXCore::ToUnderlying(Scope));
|
||||
}
|
||||
void isb() {
|
||||
Barrier(ARMEmitter::BarrierRegister::ISB, FEXCore::ToUnderlying(ARMEmitter::BarrierScope::SY));
|
||||
}
|
||||
void sb() {
|
||||
Barrier(ARMEmitter::BarrierRegister::SB, 0);
|
||||
}
|
||||
void tcommit() {
|
||||
Barrier(ARMEmitter::BarrierRegister::TCOMMIT, 0);
|
||||
}
|
||||
// Hints
|
||||
void nop() {
|
||||
Hint(ARMEmitter::HintRegister::NOP);
|
||||
}
|
||||
void yield() {
|
||||
Hint(ARMEmitter::HintRegister::YIELD);
|
||||
}
|
||||
void wfe() {
|
||||
Hint(ARMEmitter::HintRegister::WFE);
|
||||
}
|
||||
void wfi() {
|
||||
Hint(ARMEmitter::HintRegister::WFI);
|
||||
}
|
||||
void sev() {
|
||||
Hint(ARMEmitter::HintRegister::SEV);
|
||||
}
|
||||
void sevl() {
|
||||
Hint(ARMEmitter::HintRegister::SEVL);
|
||||
}
|
||||
void dgh() {
|
||||
Hint(ARMEmitter::HintRegister::DGH);
|
||||
}
|
||||
void csdb() {
|
||||
Hint(ARMEmitter::HintRegister::CSDB);
|
||||
}
|
||||
|
||||
// System register move
|
||||
void msr(ARMEmitter::SystemRegister reg, ARMEmitter::Register rt) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0001 << 20;
|
||||
SystemRegisterMove(Op, rt, reg);
|
||||
}
|
||||
// Barriers
|
||||
void clrex(uint32_t imm = 15) {
|
||||
LOGMAN_THROW_A_FMT(imm < 16, "Immediate out of range");
|
||||
Barrier(ARMEmitter::BarrierRegister::CLREX, imm);
|
||||
}
|
||||
void dsb(ARMEmitter::BarrierScope Scope) {
|
||||
Barrier(ARMEmitter::BarrierRegister::DSB, FEXCore::ToUnderlying(Scope));
|
||||
}
|
||||
void dmb(ARMEmitter::BarrierScope Scope) {
|
||||
Barrier(ARMEmitter::BarrierRegister::DMB, FEXCore::ToUnderlying(Scope));
|
||||
}
|
||||
void isb() {
|
||||
Barrier(ARMEmitter::BarrierRegister::ISB, FEXCore::ToUnderlying(ARMEmitter::BarrierScope::SY));
|
||||
}
|
||||
void sb() {
|
||||
Barrier(ARMEmitter::BarrierRegister::SB, 0);
|
||||
}
|
||||
void tcommit() {
|
||||
Barrier(ARMEmitter::BarrierRegister::TCOMMIT, 0);
|
||||
}
|
||||
|
||||
void mrs(ARMEmitter::Register rd, ARMEmitter::SystemRegister reg) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0011 << 20;
|
||||
SystemRegisterMove(Op, rd, reg);
|
||||
}
|
||||
// System register move
|
||||
void msr(ARMEmitter::SystemRegister reg, ARMEmitter::Register rt) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0001 << 20;
|
||||
SystemRegisterMove(Op, rt, reg);
|
||||
}
|
||||
|
||||
void mrs(ARMEmitter::Register rd, ARMEmitter::SystemRegister reg) {
|
||||
constexpr uint32_t Op = 0b1101'0101'0011 << 20;
|
||||
SystemRegisterMove(Op, rd, reg);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Exception Generation
|
||||
void ExceptionGeneration(uint32_t opc, uint32_t op2, uint32_t LL, uint32_t Imm) {
|
||||
LOGMAN_THROW_AA_FMT((Imm & 0xFFFF'0000) == 0, "Imm amount too large");
|
||||
// Exception Generation
|
||||
void ExceptionGeneration(uint32_t opc, uint32_t op2, uint32_t LL, uint32_t Imm) {
|
||||
LOGMAN_THROW_A_FMT((Imm & 0xFFFF'0000) == 0, "Imm amount too large");
|
||||
|
||||
uint32_t Instr = 0b1101'0100 << 24;
|
||||
uint32_t Instr = 0b1101'0100 << 24;
|
||||
|
||||
Instr |= opc << 21;
|
||||
Instr |= Imm << 5;
|
||||
Instr |= op2 << 2;
|
||||
Instr |= LL;
|
||||
Instr |= opc << 21;
|
||||
Instr |= Imm << 5;
|
||||
Instr |= op2 << 2;
|
||||
Instr |= LL;
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// System instructions with register argument
|
||||
void SystemInstructionWithReg(uint32_t CRm, uint32_t op2, ARMEmitter::Register rt) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0001 << 12;
|
||||
// System instructions with register argument
|
||||
void SystemInstructionWithReg(uint32_t CRm, uint32_t op2, ARMEmitter::Register rt) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0001 << 12;
|
||||
|
||||
Instr |= CRm << 8;
|
||||
Instr |= op2 << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
Instr |= CRm << 8;
|
||||
Instr |= op2 << 5;
|
||||
Instr |= Encode_rt(rt);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Hints
|
||||
void Hint(ARMEmitter::HintRegister Reg) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0010'0000'0001'1111U;
|
||||
Instr |= FEXCore::ToUnderlying(Reg);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Barriers
|
||||
void Barrier(ARMEmitter::BarrierRegister Reg, uint32_t CRm) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0011'0000'0001'1111U;
|
||||
Instr |= CRm << 8;
|
||||
Instr |= FEXCore::ToUnderlying(Reg);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Hints
|
||||
void Hint(ARMEmitter::HintRegister Reg) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0010'0000'0001'1111U;
|
||||
Instr |= FEXCore::ToUnderlying(Reg);
|
||||
dc32(Instr);
|
||||
}
|
||||
// Barriers
|
||||
void Barrier(ARMEmitter::BarrierRegister Reg, uint32_t CRm) {
|
||||
uint32_t Instr = 0b1101'0101'0000'0011'0011'0000'0001'1111U;
|
||||
Instr |= CRm << 8;
|
||||
Instr |= FEXCore::ToUnderlying(Reg);
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// System Instruction
|
||||
void SystemInstruction(uint32_t Op, uint32_t L, uint32_t SubOp, ARMEmitter::Register rt) {
|
||||
uint32_t Instr = Op;
|
||||
// System Instruction
|
||||
void SystemInstruction(uint32_t Op, uint32_t L, uint32_t SubOp, ARMEmitter::Register rt) {
|
||||
uint32_t Instr = Op;
|
||||
|
||||
Instr |= L << 21;
|
||||
Instr |= SubOp;
|
||||
Instr |= Encode_rt(rt);
|
||||
Instr |= L << 21;
|
||||
Instr |= SubOp;
|
||||
Instr |= Encode_rt(rt);
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// System register move
|
||||
void SystemRegisterMove(uint32_t Op, ARMEmitter::Register rt, ARMEmitter::SystemRegister reg) {
|
||||
uint32_t Instr = Op;
|
||||
// System register move
|
||||
void SystemRegisterMove(uint32_t Op, ARMEmitter::Register rt, ARMEmitter::SystemRegister reg) {
|
||||
uint32_t Instr = Op;
|
||||
|
||||
Instr |= FEXCore::ToUnderlying(reg);
|
||||
Instr |= Encode_rt(rt);
|
||||
Instr |= FEXCore::ToUnderlying(reg);
|
||||
Instr |= Encode_rt(rt);
|
||||
|
||||
dc32(Instr);
|
||||
}
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
#ifndef INCLUDED_BY_EMITTER
|
||||
}; // struct LoadstoreEmitterOps
|
||||
} // namespace ARMEmitter
|
||||
#endif
|
||||
@@ -34,21 +34,15 @@
|
||||
// by the corresponding fields in the logical instruction.
|
||||
// If it can not be encoded, the function returns false, and the values pointed
|
||||
// to by n, imm_s and imm_r are undefined.
|
||||
static bool IsImmLogical(uint64_t value,
|
||||
unsigned width,
|
||||
unsigned* n = nullptr,
|
||||
unsigned* imm_s = nullptr,
|
||||
unsigned* imm_r = nullptr) {
|
||||
static bool IsImmLogical(uint64_t value, unsigned width, unsigned* n = nullptr, unsigned* imm_s = nullptr, unsigned* imm_r = nullptr) {
|
||||
[[maybe_unused]] constexpr auto kBRegSize = 8;
|
||||
[[maybe_unused]] constexpr auto kHRegSize = 16;
|
||||
[[maybe_unused]] constexpr auto kSRegSize = 32;
|
||||
[[maybe_unused]] constexpr auto kDRegSize = 64;
|
||||
|
||||
constexpr auto kWRegSize = 32;
|
||||
constexpr auto kXRegSize = 64;
|
||||
|
||||
LOGMAN_THROW_A_FMT((width == kBRegSize) || (width == kHRegSize) ||
|
||||
(width == kSRegSize) || (width == kDRegSize), "Unexpected imm size");
|
||||
LOGMAN_THROW_A_FMT((width == kBRegSize) || (width == kHRegSize) || (width == kSRegSize) || (width == kDRegSize), "Unexpected imm size");
|
||||
|
||||
bool negate = false;
|
||||
|
||||
@@ -134,8 +128,8 @@ static bool IsImmLogical(uint64_t value,
|
||||
// Compute the repeat distance d, and set up a bitmask covering the basic
|
||||
// unit of repetition (i.e. a word with the bottom d bits set). Also, in all
|
||||
// of these cases the N bit of the output will be zero.
|
||||
clz_a = CountLeadingZeros(a, kXRegSize);
|
||||
int clz_c = CountLeadingZeros(c, kXRegSize);
|
||||
clz_a = std::countl_zero(a);
|
||||
int clz_c = std::countl_zero(c);
|
||||
d = clz_a - clz_c;
|
||||
mask = ((UINT64_C(1) << d) - 1);
|
||||
out_n = 0;
|
||||
@@ -156,7 +150,7 @@ static bool IsImmLogical(uint64_t value,
|
||||
// of set bits in our word, meaning that we have the trivial case of
|
||||
// d == 64 and only one 'repetition'. Set up all the same variables as in
|
||||
// the general case above, and set the N bit in the output.
|
||||
clz_a = CountLeadingZeros(a, kXRegSize);
|
||||
clz_a = std::countl_zero(a);
|
||||
d = 64;
|
||||
mask = ~UINT64_C(0);
|
||||
out_n = 1;
|
||||
@@ -164,7 +158,7 @@ static bool IsImmLogical(uint64_t value,
|
||||
}
|
||||
|
||||
// If the repeat period d is not a power of two, it can't be encoded.
|
||||
if (!IsPowerOf2(d)) {
|
||||
if (!std::has_single_bit(uint32_t(d))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -182,14 +176,9 @@ static bool IsImmLogical(uint64_t value,
|
||||
// (1 + 2^d + 2^(2d) + ...), i.e. 0x0001000100010001 or similar. These can
|
||||
// be derived using a table lookup on CLZ(d).
|
||||
static const uint64_t multipliers[] = {
|
||||
0x0000000000000001UL,
|
||||
0x0000000100000001UL,
|
||||
0x0001000100010001UL,
|
||||
0x0101010101010101UL,
|
||||
0x1111111111111111UL,
|
||||
0x5555555555555555UL,
|
||||
0x0000000000000001UL, 0x0000000100000001UL, 0x0001000100010001UL, 0x0101010101010101UL, 0x1111111111111111UL, 0x5555555555555555UL,
|
||||
};
|
||||
uint64_t multiplier = multipliers[CountLeadingZeros(d, kXRegSize) - 57];
|
||||
uint64_t multiplier = multipliers[std::countl_zero(uint64_t(d)) - 57];
|
||||
uint64_t candidate = (b - a) * multiplier;
|
||||
|
||||
if (value != candidate) {
|
||||
@@ -204,7 +193,7 @@ static bool IsImmLogical(uint64_t value,
|
||||
// Count the set bits in our basic stretch. The special case of clz(0) == -1
|
||||
// makes the answer come out right for stretches that reach the very top of
|
||||
// the word (e.g. numbers like 0xffffc00000000000).
|
||||
int clz_b = (b == 0) ? -1 : CountLeadingZeros(b, kXRegSize);
|
||||
int clz_b = (b == 0) ? -1 : std::countl_zero(b);
|
||||
int s = clz_a - clz_b;
|
||||
|
||||
// Decide how many bits to rotate right by, to put the low bit of that basic
|
||||
@@ -234,9 +223,13 @@ static bool IsImmLogical(uint64_t value,
|
||||
// 11110s 2 UInt(s)
|
||||
//
|
||||
// So we 'or' (2 * -d) with our computed s to form imms.
|
||||
if ((n != NULL) || (imm_s != NULL) || (imm_r != NULL)) {
|
||||
if (n != nullptr) {
|
||||
*n = out_n;
|
||||
}
|
||||
if (imm_s != nullptr) {
|
||||
*imm_s = ((2 * -d) | (s - 1)) & 0x3f;
|
||||
}
|
||||
if (imm_r != nullptr) {
|
||||
*imm_r = r;
|
||||
}
|
||||
|
||||
@@ -244,7 +237,9 @@ static bool IsImmLogical(uint64_t value,
|
||||
}
|
||||
|
||||
static inline bool IsIntN(unsigned n, int64_t x) {
|
||||
if (n == 64) return true;
|
||||
if (n == 64) {
|
||||
return true;
|
||||
}
|
||||
int64_t limit = INT64_C(1) << (n - 1);
|
||||
return (-limit <= x) && (x < limit);
|
||||
}
|
||||
@@ -271,11 +266,15 @@ V(57) V(58) V(59) V(60) V(61) V(62) V(63)
|
||||
|
||||
// clang-format on
|
||||
|
||||
#define DECLARE_IS_INT_N(N) \
|
||||
static inline bool IsInt##N(int64_t x) { return IsIntN(N, x); }
|
||||
#define DECLARE_IS_INT_N(N) \
|
||||
static inline bool IsInt##N(int64_t x) { \
|
||||
return IsIntN(N, x); \
|
||||
}
|
||||
|
||||
#define DECLARE_IS_UINT_N(N) \
|
||||
static inline bool IsUint##N(int64_t x) { return IsUintN(N, x); }
|
||||
#define DECLARE_IS_UINT_N(N) \
|
||||
static inline bool IsUint##N(int64_t x) { \
|
||||
return IsUintN(N, x); \
|
||||
}
|
||||
|
||||
INT_1_TO_63_LIST(DECLARE_IS_INT_N)
|
||||
INT_1_TO_63_LIST(DECLARE_IS_UINT_N)
|
||||
@@ -285,14 +284,9 @@ INT_1_TO_63_LIST(DECLARE_IS_UINT_N)
|
||||
|
||||
private:
|
||||
|
||||
template <typename V>
|
||||
static inline bool IsPowerOf2(V value) {
|
||||
return (value != 0) && ((value & (value - 1)) == 0);
|
||||
}
|
||||
|
||||
// Some compilers dislike negating unsigned integers,
|
||||
// so we provide an equivalent.
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
static inline T UnsignedNegate(T value) {
|
||||
static_assert(std::is_unsigned<T>::value);
|
||||
return ~value + 1;
|
||||
@@ -302,50 +296,4 @@ static inline uint64_t LowestSetBit(uint64_t value) {
|
||||
return value & UnsignedNegate(value);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static inline int CountLeadingZeros(V value, int width = (sizeof(V) * 8)) {
|
||||
#if COMPILER_HAS_BUILTIN_CLZ
|
||||
if (width == 32) {
|
||||
return (value == 0) ? 32 : __builtin_clz(static_cast<unsigned>(value));
|
||||
} else if (width == 64) {
|
||||
return (value == 0) ? 64 : __builtin_clzll(value);
|
||||
}
|
||||
#endif
|
||||
return CountLeadingZerosFallBack(value, width);
|
||||
}
|
||||
|
||||
static inline int CountLeadingZerosFallBack(uint64_t value, int width) {
|
||||
LOGMAN_THROW_A_FMT(IsPowerOf2(width) && (width <= 64), "Invalid width");
|
||||
if (value == 0) {
|
||||
return width;
|
||||
}
|
||||
int count = 0;
|
||||
value = value << (64 - width);
|
||||
if ((value & UINT64_C(0xffffffff00000000)) == 0) {
|
||||
count += 32;
|
||||
value = value << 32;
|
||||
}
|
||||
if ((value & UINT64_C(0xffff000000000000)) == 0) {
|
||||
count += 16;
|
||||
value = value << 16;
|
||||
}
|
||||
if ((value & UINT64_C(0xff00000000000000)) == 0) {
|
||||
count += 8;
|
||||
value = value << 8;
|
||||
}
|
||||
if ((value & UINT64_C(0xf000000000000000)) == 0) {
|
||||
count += 4;
|
||||
value = value << 4;
|
||||
}
|
||||
if ((value & UINT64_C(0xc000000000000000)) == 0) {
|
||||
count += 2;
|
||||
value = value << 2;
|
||||
}
|
||||
if ((value & UINT64_C(0x8000000000000000)) == 0) {
|
||||
count += 1;
|
||||
}
|
||||
count += (value == 0);
|
||||
return count;
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -4,7 +4,8 @@ file(GLOB GEN_CONFIG_SOURCES CONFIGURE_DEPENDS *.json.in)
|
||||
# Any application configuration json file gets installed
|
||||
foreach(CONFIG_SRC ${CONFIG_SOURCES})
|
||||
install(FILES ${CONFIG_SRC}
|
||||
DESTINATION ${DATA_DIRECTORY}/AppConfig/)
|
||||
DESTINATION ${DATA_DIRECTORY}/AppConfig/
|
||||
COMPONENT Runtime)
|
||||
endforeach()
|
||||
|
||||
# Any configuration file json file that needs to be generated
|
||||
@@ -14,12 +15,10 @@ foreach(GEN_CONFIG_SRC ${GEN_CONFIG_SOURCES})
|
||||
get_filename_component(CONFIG_NAME ${GEN_CONFIG_SRC} NAME_WLE)
|
||||
|
||||
# Configure it
|
||||
configure_file(
|
||||
${GEN_CONFIG_SRC}
|
||||
${CMAKE_BINARY_DIR}/Data/AppConfig/${CONFIG_NAME})
|
||||
configure_file(${GEN_CONFIG_SRC} ${CMAKE_BINARY_DIR}/Data/AppConfig/${CONFIG_NAME})
|
||||
|
||||
# Then install the configured json
|
||||
install(
|
||||
FILES ${CMAKE_BINARY_DIR}/Data/AppConfig/${CONFIG_NAME}
|
||||
DESTINATION ${DATA_DIRECTORY}/AppConfig/)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/Data/AppConfig/${CONFIG_NAME}
|
||||
DESTINATION ${DATA_DIRECTORY}/AppConfig/
|
||||
COMPONENT Runtime)
|
||||
endforeach()
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(Zycore QUIET CONFIG)
|
||||
|
||||
if (Zycore_CONSIDERED_CONFIGS)
|
||||
find_package_handle_standard_args(Zycore CONFIG_MODE)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(Zycore QUIET IMPORTED_TARGET zycore)
|
||||
find_package_handle_standard_args(Zycore
|
||||
REQUIRED_VARS zycore_LINK_LIBRARIES
|
||||
VERSION_VAR zycore_VERSION)
|
||||
|
||||
if (TARGET PkgConfig::zycore)
|
||||
add_library(Zycore::Zycore ALIAS PkgConfig::zycore)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(Zydis QUIET CONFIG)
|
||||
|
||||
if (Zydis_CONSIDERED_CONFIGS)
|
||||
find_package_handle_standard_args(Zydis CONFIG_MODE)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(Zydis QUIET IMPORTED_TARGET zydis)
|
||||
find_package_handle_standard_args(Zydis
|
||||
REQUIRED_VARS zydis_LINK_LIBRARIES
|
||||
VERSION_VAR zydis_VERSION)
|
||||
|
||||
if (TARGET PkgConfig::zydis)
|
||||
add_library(Zydis::Zydis ALIAS PkgConfig::zydis)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(xxhash QUIET IMPORTED_TARGET xxhash libxxhash)
|
||||
find_package_handle_standard_args(xxhash
|
||||
REQUIRED_VARS xxhash_LINK_LIBRARIES
|
||||
VERSION_VAR xxhash_VERSION
|
||||
)
|
||||
|
||||
if (xxhash_FOUND AND NOT TARGET xxHash::xxhash)
|
||||
if (TARGET PkgConfig::xxhash)
|
||||
add_library(xxHash::xxhash ALIAS PkgConfig::xxhash)
|
||||
else()
|
||||
add_library(xxHash::xxhash ALIAS xxhash)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,15 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# This applies some common linker options that reduce code size and linking time in Release mode. Namely:
|
||||
# --gc-sections: Linktime garbage collection, discards unused sections from the final output
|
||||
# --strip-all : Similar to running `strip`, discards the symbol table from the final output
|
||||
# --as-needed : Only includes libraries that are actually needed in the final output.
|
||||
|
||||
macro(LinkerGC target)
|
||||
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
|
||||
target_link_options(${target} PRIVATE
|
||||
"LINKER:--gc-sections"
|
||||
"LINKER:--strip-all"
|
||||
"LINKER:--as-needed")
|
||||
endif()
|
||||
endmacro()
|
||||
File renamed without changes.
@@ -1,6 +1,6 @@
|
||||
# This is a reference AArch64 cross compile script
|
||||
# Pass in to cmake when building:
|
||||
# eg: cmake -DCMAKE_TOOLCHAIN_FILE=../CMakeToolchains/AArch64.cmake ..
|
||||
# eg: cmake --toolchain ../Data/CMake/toolchain_aarch64.cmake ..
|
||||
if (NOT DEFINED ENV{SYSROOT})
|
||||
message(FATAL_ERROR "Need to have SYSROOT environment variable set")
|
||||
endif()
|
||||
@@ -4,12 +4,13 @@ set(CMAKE_RC_COMPILER ${MINGW_TRIPLE}-windres)
|
||||
set(CMAKE_C_COMPILER ${MINGW_TRIPLE}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${MINGW_TRIPLE}-clang++)
|
||||
set(CMAKE_DLLTOOL ${MINGW_TRIPLE}-dlltool)
|
||||
set(CMAKE_AR ${MINGW_TRIPLE}-ar)
|
||||
|
||||
# Compile everything as static to avoid requiring the MinGW runtime libraries, force page aligned sections so that
|
||||
# debug symbols work correctly, and disable loop alignment to workaround an LLVM bug
|
||||
# (https://github.com/llvm/llvm-project/issues/47432)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-static -static-libgcc -static-libstdc++ -Wl,--file-alignment=4096,/mllvm:-align-loops=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -static-libgcc -static-libstdc++ -Wl,--file-alignment=4096,/mllvm:-align-loops=1")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-static -Wl,--file-alignment=4096,/mllvm:-align-loops=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -Wl,--file-alignment=4096,/mllvm:-align-loops=1")
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
|
||||
set(CMAKE_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,31 @@
|
||||
# --- Stage 1: Builder ---
|
||||
FROM ubuntu:22.04 as builder
|
||||
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get update
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt install -y cmake \
|
||||
clang-13 llvm-13 nasm ninja-build pkg-config \
|
||||
libcap-dev libglfw3-dev libepoxy-dev python3-dev libsdl2-dev \
|
||||
python3 linux-headers-generic \
|
||||
git qtbase5-dev qtdeclarative5-dev lld
|
||||
|
||||
RUN git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git
|
||||
WORKDIR /FEX
|
||||
RUN mkdir build
|
||||
|
||||
ARG CC=clang-13
|
||||
ARG CXX=clang++-13
|
||||
RUN cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTING=False -DENABLE_ASSERTIONS=False -G Ninja .
|
||||
RUN ninja
|
||||
|
||||
WORKDIR /FEX/build
|
||||
|
||||
# --- Stage 2: Runner ---
|
||||
FROM builder as runner
|
||||
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get update
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt install -y \
|
||||
libcap-dev libglfw3-dev libepoxy-dev
|
||||
|
||||
COPY --from=builder /FEX/Bin/* /usr/bin/
|
||||
|
||||
WORKDIR /
|
||||
+7
-135
@@ -9,25 +9,6 @@
|
||||
"@PREFIX_LIB@/libGL.so.1.7.0"
|
||||
]
|
||||
},
|
||||
"GLESv2": {
|
||||
"Library": "libGLESv2-guest.so",
|
||||
"Depends": [
|
||||
"X11"
|
||||
],
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libGLESv2.so",
|
||||
"@PREFIX_LIB@/libGLESv2.so.2",
|
||||
"@PREFIX_LIB@/libGLESv2.so.2.0.0"
|
||||
]
|
||||
},
|
||||
"X11": {
|
||||
"Library": "libX11-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libX11.so",
|
||||
"@PREFIX_LIB@/libX11.so.6",
|
||||
"@PREFIX_LIB@/libX11.so.6.4.0"
|
||||
]
|
||||
},
|
||||
"Vulkan": {
|
||||
"Library": "libvulkan-guest.so",
|
||||
"Overlay": [
|
||||
@@ -36,89 +17,6 @@
|
||||
"@HOME@/.local/share/Steam/ubuntu12_32/steam-runtime/pinned_libs_64/libvulkan.so.1"
|
||||
]
|
||||
},
|
||||
"xcb": {
|
||||
"Depends": [
|
||||
"X11"
|
||||
],
|
||||
"Library": "libxcb-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb.so",
|
||||
"@PREFIX_LIB@/libxcb.so.1",
|
||||
"@PREFIX_LIB@/libxcb.so.1.1.0"
|
||||
]
|
||||
},
|
||||
"xcb-dri2": {
|
||||
"Library": "libxcb-dri2-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-dri2.so",
|
||||
"@PREFIX_LIB@/libxcb-dri2.so.0",
|
||||
"@PREFIX_LIB@/libxcb-dri2.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-dri3": {
|
||||
"Library": "libxcb-dri3-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-dri3.so",
|
||||
"@PREFIX_LIB@/libxcb-dri3.so.0",
|
||||
"@PREFIX_LIB@/libxcb-dri3.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-xfixes": {
|
||||
"Library": "libxcb-xfixes-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-xfixes.so",
|
||||
"@PREFIX_LIB@/libxcb-xfixes.so.0",
|
||||
"@PREFIX_LIB@/libxcb-xfixes.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-shm": {
|
||||
"Library": "libxcb-shm-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-shm.so",
|
||||
"@PREFIX_LIB@/libxcb-shm.so.0",
|
||||
"@PREFIX_LIB@/libxcb-shm.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-sync": {
|
||||
"Library": "libxcb-sync-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-sync.so",
|
||||
"@PREFIX_LIB@/libxcb-sync.so.1",
|
||||
"@PREFIX_LIB@/libxcb-sync.so.1.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-randr": {
|
||||
"Library": "libxcb-randr-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-randr.so",
|
||||
"@PREFIX_LIB@/libxcb-randr.so.0",
|
||||
"@PREFIX_LIB@/libxcb-randr.so.0.1.0"
|
||||
]
|
||||
},
|
||||
"xcb-present": {
|
||||
"Library": "libxcb-present-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-present.so",
|
||||
"@PREFIX_LIB@/libxcb-present.so.0",
|
||||
"@PREFIX_LIB@/libxcb-present.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xcb-glx": {
|
||||
"Library": "libxcb-glx-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxcb-glx.so",
|
||||
"@PREFIX_LIB@/libxcb-glx.so.0",
|
||||
"@PREFIX_LIB@/libxcb-glx.so.0.0.0"
|
||||
]
|
||||
},
|
||||
"xshmfence": {
|
||||
"Library": "libxshmfence-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libxshmfence.so",
|
||||
"@PREFIX_LIB@/libxshmfence.so.1",
|
||||
"@PREFIX_LIB@/libxshmfence.so.1.0.0"
|
||||
]
|
||||
},
|
||||
"drm": {
|
||||
"Library": "libdrm-guest.so",
|
||||
"Overlay": [
|
||||
@@ -141,38 +39,6 @@
|
||||
"@PREFIX_LIB@/libfex_thunk_test.so"
|
||||
]
|
||||
},
|
||||
"Xrender": {
|
||||
"Library": "libXrender-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libXrender.so",
|
||||
"@PREFIX_LIB@/libXrender.so.1",
|
||||
"@PREFIX_LIB@/libXrender.so.1.3.0"
|
||||
]
|
||||
},
|
||||
"Xext": {
|
||||
"Library": "libXext-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libXext.so",
|
||||
"@PREFIX_LIB@/libXext.so.6",
|
||||
"@PREFIX_LIB@/libXext.so.6.4.0"
|
||||
]
|
||||
},
|
||||
"Xfixes": {
|
||||
"Library": "libXfixes-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libXfixes.so",
|
||||
"@PREFIX_LIB@/libXfixes.so.3",
|
||||
"@PREFIX_LIB@/libXfixes.so.3.1.0"
|
||||
]
|
||||
},
|
||||
"OpenCL": {
|
||||
"Library" : "libOpenCL-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libOpenCL.so",
|
||||
"@PREFIX_LIB@/libOpenCL.so.1",
|
||||
"@PREFIX_LIB@/libOpenCL.so.1.0.0"
|
||||
]
|
||||
},
|
||||
"WaylandClient": {
|
||||
"Library" : "libwayland-client-guest.so",
|
||||
"Overlay": [
|
||||
@@ -181,6 +47,12 @@
|
||||
"@PREFIX_LIB@/libwayland-client.so.0.20.0"
|
||||
]
|
||||
},
|
||||
"":{}
|
||||
"cuda": {
|
||||
"Library" : "libcuda-guest.so",
|
||||
"Overlay": [
|
||||
"@PREFIX_LIB@/libcuda.so",
|
||||
"@PREFIX_LIB@/libcuda.so.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,21 @@ function(GenBinFmt Name)
|
||||
get_filename_component(FMT_NAME ${Name} NAME_WE)
|
||||
|
||||
# Configure it
|
||||
configure_file(
|
||||
${Name}
|
||||
${CMAKE_BINARY_DIR}/Data/binfmts/${FMT_NAME})
|
||||
configure_file(${Name} ${CMAKE_BINARY_DIR}/Data/binfmts/${FMT_NAME})
|
||||
|
||||
# Then install the configured binfmt
|
||||
install(
|
||||
FILES ${CMAKE_BINARY_DIR}/Data/binfmts/${FMT_NAME}
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/binfmts/)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/Data/binfmts/${FMT_NAME}
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/binfmts/
|
||||
COMPONENT Runtime)
|
||||
endfunction()
|
||||
|
||||
if (NOT USE_LEGACY_BINFMTMISC)
|
||||
configure_file(FEX-x86.conf.in ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86.conf)
|
||||
configure_file(FEX-x86_64.conf.in ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86_64.conf)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86.conf ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86_64.conf
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/binfmt.d/)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86.conf ${CMAKE_BINARY_DIR}/Data/binfmts/FEX-x86_64.conf
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/binfmt.d/
|
||||
COMPONENT Runtime)
|
||||
else()
|
||||
GenBinFmt(FEX-x86.in)
|
||||
GenBinFmt(FEX-x86_64.in)
|
||||
|
||||
@@ -1 +1 @@
|
||||
:FEX-x86:M:0:\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff:@CMAKE_INSTALL_PREFIX@/bin/FEXInterpreter:POCF
|
||||
:FEX-x86:M:0:\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff:@CMAKE_INSTALL_PREFIX@/bin/FEX:POCF
|
||||
@@ -1,5 +1,5 @@
|
||||
package fex
|
||||
interpreter @CMAKE_INSTALL_PREFIX@/bin/FEXInterpreter
|
||||
interpreter @CMAKE_INSTALL_PREFIX@/bin/FEX
|
||||
magic \x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00
|
||||
offset 0
|
||||
mask \xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff
|
||||
|
||||
@@ -1 +1 @@
|
||||
:FEX-x86_64:M:0:\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff:@CMAKE_INSTALL_PREFIX@/bin/FEXInterpreter:POCF
|
||||
:FEX-x86_64:M:0:\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff:@CMAKE_INSTALL_PREFIX@/bin/FEX:POCF
|
||||
@@ -1,5 +1,5 @@
|
||||
package fex
|
||||
interpreter @CMAKE_INSTALL_PREFIX@/bin/FEXInterpreter
|
||||
interpreter @CMAKE_INSTALL_PREFIX@/bin/FEX
|
||||
magic \x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00
|
||||
offset 0
|
||||
mask \xff\xff\xff\xff\xff\xfe\xfe\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
let
|
||||
pkgsCross32 = pkgs.pkgsCross.gnu32;
|
||||
pkgsCross64 = pkgs.pkgsCross.gnu64;
|
||||
|
||||
gcc32 = pkgs.writeText "toolchain_nix_gcc_x86_32.txt" ''
|
||||
set(CMAKE_SYSTEM_PROCESSOR i686)
|
||||
set(CMAKE_C_COMPILER ${pkgsCross32.buildPackages.gcc}/bin/i686-unknown-linux-gnu-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${pkgsCross32.buildPackages.gcc}/bin/i686-unknown-linux-gnu-g++)
|
||||
'';
|
||||
|
||||
gcc64 = pkgs.writeText "toolchain_nix_gcc_x86_64.txt" ''
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
set(CMAKE_C_COMPILER ${pkgsCross64.buildPackages.gcc}/bin/x86_64-unknown-linux-gnu-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${pkgsCross64.buildPackages.gcc}/bin/x86_64-unknown-linux-gnu-g++)
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgsCross64.buildPackages.clang
|
||||
pkgsCross32.buildPackages.clang
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
if [[ $- == *i* ]]; then
|
||||
echo "toolchain32: ${gcc32}"
|
||||
echo "toolchain64: ${gcc64}"
|
||||
echo ""
|
||||
echo "Use \$FEX_CMAKE_TOOLCHAINS to configure CMake."
|
||||
fi
|
||||
'';
|
||||
|
||||
FEX_CMAKE_TOOLCHAINS = "-DX86_32_TOOLCHAIN_FILE=${gcc32} -DX86_64_TOOLCHAIN_FILE=${gcc64}";
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
let
|
||||
pkgsCross32 = pkgs.pkgsCross.gnu32;
|
||||
pkgsCross64 = pkgs.pkgsCross.gnu64;
|
||||
|
||||
devRootFS = pkgs.buildEnv {
|
||||
name = "fex-dev-rootfs";
|
||||
paths = [
|
||||
pkgsCross64.stdenv.cc.libc_dev
|
||||
pkgsCross32.stdenv.cc.libc_dev
|
||||
pkgsCross64.stdenv.cc.cc
|
||||
pkgsCross32.stdenv.cc.cc
|
||||
|
||||
pkgs.alsa-lib.dev
|
||||
pkgs.libdrm.dev
|
||||
pkgs.libGL.dev
|
||||
pkgs.wayland.dev
|
||||
pkgs.xorg.libX11.dev
|
||||
pkgs.xorg.libxcb.dev
|
||||
pkgs.xorg.libXrandr.dev
|
||||
pkgs.xorg.libXrender.dev
|
||||
pkgs.xorg.xorgproto
|
||||
];
|
||||
ignoreCollisions = true;
|
||||
pathsToLink = [
|
||||
"/include"
|
||||
"/lib"
|
||||
];
|
||||
|
||||
postBuild = ''
|
||||
mkdir -p $out/usr
|
||||
ln -s $out/include $out/usr/
|
||||
'';
|
||||
};
|
||||
|
||||
toolchain32 = pkgs.writeText "toolchain_nix_x86_32.txt" ''
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_SYSTEM_PROCESSOR i686)
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
set(CMAKE_C_COMPILER ${pkgsCross32.buildPackages.clang}/bin/i686-unknown-linux-gnu-clang)
|
||||
set(CMAKE_CXX_COMPILER ${pkgsCross32.buildPackages.clang}/bin/i686-unknown-linux-gnu-clang++)
|
||||
set(CLANG_FLAGS "-nodefaultlibs -nostartfiles -lstdc++ -target i686-linux-gnu -msse2 -mfpmath=sse --sysroot=${devRootFS} -iwithsysroot/include")
|
||||
set(CMAKE_C_FLAGS "''${CMAKE_C_FLAGS} ''${CLANG_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "''${CMAKE_CXX_FLAGS} ''${CLANG_FLAGS}")
|
||||
'';
|
||||
|
||||
toolchain64 = pkgs.writeText "toolchain_nix_x86_64.txt" ''
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
set(CMAKE_C_COMPILER ${pkgsCross64.buildPackages.clang}/bin/x86_64-unknown-linux-gnu-clang)
|
||||
set(CMAKE_CXX_COMPILER ${pkgsCross64.buildPackages.clang}/bin/x86_64-unknown-linux-gnu-clang++)
|
||||
set(CLANG_FLAGS "-nodefaultlibs -nostartfiles -lstdc++ -target x86_64-linux-gnu --sysroot=${devRootFS} -iwithsysroot/usr/include")
|
||||
set(CMAKE_C_FLAGS "''${CMAKE_C_FLAGS} ''${CLANG_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "''${CMAKE_CXX_FLAGS} ''${CLANG_FLAGS}")
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgsCross64.buildPackages.clang
|
||||
pkgsCross32.buildPackages.clang
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
if [[ $- == *i* ]]; then
|
||||
echo "Set up dev RootFS at ${devRootFS}"
|
||||
echo "toolchain32: ${toolchain32}"
|
||||
echo "toolchain64: ${toolchain64}"
|
||||
echo ""
|
||||
echo "Use \$FEX_CMAKE_TOOLCHAINS to configure CMake."
|
||||
fi
|
||||
'';
|
||||
|
||||
FEX_CMAKE_TOOLCHAINS = "-DX86_32_TOOLCHAIN_FILE=${toolchain32} -DX86_64_TOOLCHAIN_FILE=${toolchain64} -DX86_DEV_ROOTFS=${devRootFS}";
|
||||
ROOTFS = "${devRootFS}";
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
let
|
||||
toolchain = pkgs.fetchzip {
|
||||
url = "https://github.com/bylaws/llvm-mingw/releases/download/20250920/llvm-mingw-20250920-ucrt-ubuntu-22.04-aarch64.tar.xz";
|
||||
sha256 = "sha256-LaojKjC8KzY+soW5u6eoDoXE3qtYk9Ejr7M3enTqRAE=";
|
||||
};
|
||||
|
||||
cmakeToolchainFile = pkgs.substitute {
|
||||
# Use absolute paths that are discoverable outside of the nix shell
|
||||
src = ../../CMake/toolchain_mingw.cmake;
|
||||
substitutions = ["--replace-fail" "\${MINGW_TRIPLE}-" "${toolchain}/bin/\${MINGW_TRIPLE}-"];
|
||||
};
|
||||
|
||||
mesonCrossFile = pkgs.writeText "crossfile_llvm_mingw.txt" ''
|
||||
[binaries]
|
||||
ar = '${toolchain}/bin/arm64ec-w64-mingw32-ar'
|
||||
c = '${toolchain}/bin/arm64ec-w64-mingw32-gcc'
|
||||
cpp = '${toolchain}/bin/arm64ec-w64-mingw32-g++'
|
||||
ld = '${toolchain}/bin/arm64ec-w64-mingw32-ld'
|
||||
windres = '${toolchain}/bin/arm64ec-w64-mingw32-windres'
|
||||
strip = '${toolchain}/bin/strip'
|
||||
widl = '${toolchain}/bin/arm64ec-w64-mingw32-widl'
|
||||
pkgconfig = 'aarch64-linux-gnu-pkg-config'
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = [
|
||||
toolchain
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
if [[ $- == *i* ]]; then
|
||||
echo "llvm-mingw set up at ${toolchain}."
|
||||
echo ""
|
||||
echo "To configure DXVK/vkd3d-proton: meson setup \$FEX_MESON_CROSSFILE"
|
||||
echo ""
|
||||
echo "To configure 32-bit FEX build: cmake \$FEX_CMAKE_TOOLCHAIN_WOW64"
|
||||
echo "To configure 64-bit FEX build: cmake \$FEX_CMAKE_TOOLCHAIN_ARM64EC"
|
||||
fi
|
||||
'';
|
||||
|
||||
# E.g. cmake $FEX_CMAKE_TOOLCHAIN_ARM64EC -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LTO=False -DBUILD_TESTING=False
|
||||
FEX_CMAKE_TOOLCHAIN_ARM64EC = "--toolchain ${cmakeToolchainFile} -DMINGW_TRIPLE=arm64ec-w64-mingw32 -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows";
|
||||
FEX_CMAKE_TOOLCHAIN_WOW64 = "--toolchain ${cmakeToolchainFile} -DMINGW_TRIPLE=aarch64-w64-mingw32 -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows";
|
||||
FEX_MESON_CROSSFILE = "--cross-file ${mesonCrossFile}";
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash WineOnArm/shell.nix
|
||||
|
||||
# Helper script to configure CMake for building FEX as library for emulation
|
||||
# of 32-bit applications in Wine/Proton.
|
||||
# The required cross-toolchains will be set up and managed by nix.
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Expected CMake argument list"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f CMakeCache.txt ]
|
||||
then
|
||||
echo "Expected empty build folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -o xtrace
|
||||
cmake $FEX_CMAKE_TOOLCHAIN_WOW64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LTO=False -DBUILD_TESTING=False $@
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash WineOnArm/shell.nix
|
||||
|
||||
# Helper script to configure CMake for building FEX as library for emulation
|
||||
# of 64-bit applications in Wine/Proton
|
||||
# Nix is used to install and manage the required cross-toolchains.
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Expected CMake argument list"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f CMakeCache.txt ]
|
||||
then
|
||||
echo "Expected empty build folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -o xtrace
|
||||
cmake $FEX_CMAKE_TOOLCHAIN_ARM64EC -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LTO=False -DBUILD_TESTING=False $@
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash FEXLinuxTests/shell.nix
|
||||
|
||||
# Helper script to configure CMake for building FEXLinuxTests.
|
||||
# Nix is used to install and manage the required cross-toolchains.
|
||||
|
||||
if [ ! -f CMakeCache.txt ]
|
||||
then
|
||||
echo "Must be run from a pre-configured CMake build folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove previous build to ensure the new toolchain is applied
|
||||
rm -rf unittests/FEXLinuxTests
|
||||
|
||||
set -o xtrace
|
||||
cmake . $FEX_CMAKE_TOOLCHAINS -DBUILD_TESTING=ON -DBUILD_FEX_LINUX_TESTS=ON
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
# Helper script to configure CMake for library forwarding in FEX.
|
||||
# Nix is used to install and manage the required cross-toolchains.
|
||||
|
||||
if [ ! -f CMakeCache.txt ]
|
||||
then
|
||||
echo "Must be run from a pre-configured CMake build folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove previous build to ensure the new toolchain is applied
|
||||
rm -rf guest-libs guest-libs-32 Guest Guest_32
|
||||
|
||||
# Set clang executable path manually since the one from the nix store
|
||||
# will be picked up otherwise
|
||||
CLANG_EXEC_PATH=""
|
||||
if ! grep -q CLANG_EXEC_PATH CMakeCache.txt
|
||||
then
|
||||
CLANG_EXEC_PATH="-DCLANG_EXEC_PATH=`which clang`"
|
||||
fi
|
||||
|
||||
nix-shell `dirname -- "$0"`/LibraryForwarding/shell.nix \
|
||||
--run "set -o xtrace; cmake . \$FEX_CMAKE_TOOLCHAINS -DBUILD_THUNKS=ON $CLANG_EXEC_PATH; set +o xtrace"
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
# --- Stage 1: Builder ---
|
||||
FROM ubuntu:20.04 as builder
|
||||
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get update
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt install -y cmake \
|
||||
clang-10 llvm-10 nasm ninja-build pkg-config \
|
||||
libcap-dev libglfw3-dev libepoxy-dev python3-dev libsdl2-dev \
|
||||
python3 linux-headers-generic \
|
||||
git
|
||||
|
||||
RUN git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git
|
||||
|
||||
CMD [ "mkdir /opt/FEX/build" ]
|
||||
|
||||
WORKDIR /opt/FEX/build
|
||||
|
||||
ARG CC=clang-10
|
||||
ARG CXX=clang++-10
|
||||
RUN cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release
|
||||
RUN ninja
|
||||
|
||||
# --- Stage 2: Runner ---
|
||||
FROM ubuntu:20.04
|
||||
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get update
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt install -y \
|
||||
libcap-dev libglfw3-dev libepoxy-dev
|
||||
|
||||
COPY --from=builder /opt/FEX/build/Bin/* /usr/bin/
|
||||
|
||||
WORKDIR /root
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
DisableFormat: true
|
||||
Vendored
+1
-1
Submodule External/Catch2 updated: 8ac8190e49...b3fb4b9fea.
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
|
||||
add_library(softfloat_3e STATIC
|
||||
# F80 support
|
||||
src/extF80_add.c
|
||||
src/extF80_div.c
|
||||
src/extF80_sub.c
|
||||
src/extF80_mul.c
|
||||
src/extF80_rem.c
|
||||
src/extF80_sqrt.c
|
||||
src/extF80_le.c
|
||||
src/extF80_to_i32.c
|
||||
src/extF80_to_i64.c
|
||||
src/extF80_to_ui64.c
|
||||
src/extF80_to_f32.c
|
||||
src/extF80_to_f64.c
|
||||
src/i32_to_extF80.c
|
||||
src/ui64_to_extF80.c
|
||||
src/extF80_to_f128.c
|
||||
src/f128_to_extF80.c
|
||||
|
||||
# F128 support
|
||||
src/f128_add.c
|
||||
src/f128_div.c
|
||||
src/f128_eq.c
|
||||
src/f128_eq_signaling.c
|
||||
src/f128_isSignalingNaN.c
|
||||
src/f128_le.c
|
||||
src/f128_le_quiet.c
|
||||
src/f128_lt.c
|
||||
src/f128_lt_quiet.c
|
||||
src/f128_mulAdd.c
|
||||
src/f128_mul.c
|
||||
src/f128_rem.c
|
||||
src/f128_sqrt.c
|
||||
src/f128_sub.c
|
||||
src/f128_to_f16.c
|
||||
src/f128_to_f32.c
|
||||
src/f128_to_f64.c
|
||||
src/f128_to_i32.c
|
||||
src/f128_to_i64.c
|
||||
src/f128_to_ui32.c
|
||||
src/f128_to_ui64.c
|
||||
src/s_addMagsF128.c
|
||||
src/s_subMagsF128.c
|
||||
src/s_normRoundPackToF128.c
|
||||
src/s_roundPackToF128.c
|
||||
src/s_propagateNaNF128UI.c
|
||||
|
||||
# Conversion
|
||||
src/f32_to_f128.c
|
||||
src/i32_to_f128.c
|
||||
|
||||
src/s_roundToUI64.c
|
||||
src/s_f128UIToCommonNaN.c
|
||||
src/s_commonNaNToF128UI.c
|
||||
src/s_normSubnormalF128Sig.c
|
||||
src/s_roundToI32.c
|
||||
src/s_roundToI64.c
|
||||
src/s_roundPackToF32.c
|
||||
src/s_addMagsExtF80.c
|
||||
src/s_extF80UIToCommonNaN.c
|
||||
src/s_commonNaNToF32UI.c
|
||||
src/s_commonNaNToF64UI.c
|
||||
src/s_roundPackToF64.c
|
||||
src/s_propagateNaNExtF80UI.c
|
||||
src/s_roundPackToExtF80.c
|
||||
src/s_normSubnormalExtF80Sig.c
|
||||
src/s_subMagsExtF80.c
|
||||
src/s_shiftRightJam128.c
|
||||
src/s_shiftRightJam128Extra.c
|
||||
src/s_normRoundPackToExtF80.c
|
||||
src/s_approxRecip_1Ks.c
|
||||
src/s_approxRecipSqrt32_1.c
|
||||
src/s_approxRecipSqrt_1Ks.c
|
||||
src/softfloat_raiseFlags.c
|
||||
src/f64_to_extF80.c
|
||||
src/s_commonNaNToExtF80UI.c
|
||||
src/s_normSubnormalF64Sig.c
|
||||
src/s_f64UIToCommonNaN.c
|
||||
src/extF80_roundToInt.c
|
||||
src/extF80_eq.c
|
||||
src/extF80_lt.c
|
||||
src/f32_to_extF80.c
|
||||
src/s_normSubnormalF32Sig.c
|
||||
src/s_f32UIToCommonNaN.c)
|
||||
|
||||
if (ARCHITECTURE_arm64 AND HAS_CLANG_PRESERVE_ALL)
|
||||
list(APPEND DEFINES "-DFEXCORE_PRESERVE_ALL_ATTR=__attribute__((preserve_all));-DFEXCORE_HAS_PRESERVE_ALL_ATTR=1")
|
||||
else()
|
||||
list(APPEND DEFINES "-DFEXCORE_PRESERVE_ALL_ATTR=;-DFEXCORE_HAS_PRESERVE_ALL_ATTR=0")
|
||||
endif()
|
||||
|
||||
list(APPEND DEFINES "-DSOFTFLOAT_BUILTIN_CLZ=1;-DINLINE=static inline;-DINLINE_LEVEL=4;-DSOFTFLOAT_FAST_INT64=1;-DSOFTFLOAT_FAST_DIV32TO16=1;-DSOFTFLOAT_FAST_DIV64TO32=1")
|
||||
|
||||
target_include_directories(softfloat_3e PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
target_include_directories(softfloat_3e PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/SoftFloat-3e/)
|
||||
target_compile_definitions(softfloat_3e PUBLIC ${DEFINES})
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+30
-22
@@ -149,7 +149,7 @@ float64_t f32_to_f64( float32_t );
|
||||
#ifdef SOFTFLOAT_FAST_INT64
|
||||
FEXCORE_PRESERVE_ALL_ATTR
|
||||
extFloat80_t f32_to_extF80( struct softfloat_state *, float32_t );
|
||||
float128_t f32_to_f128( float32_t );
|
||||
float128_t f32_to_f128( struct softfloat_state *, float32_t );
|
||||
#endif
|
||||
void f32_to_extF80M( float32_t, extFloat80_t * );
|
||||
void f32_to_f128M( float32_t, float128_t * );
|
||||
@@ -243,13 +243,17 @@ FEXCORE_PRESERVE_ALL_ATTR
|
||||
extFloat80_t extF80_sqrt( struct softfloat_state *, extFloat80_t );
|
||||
FEXCORE_PRESERVE_ALL_ATTR
|
||||
bool extF80_eq( struct softfloat_state *, extFloat80_t, extFloat80_t );
|
||||
bool extF80_le( extFloat80_t, extFloat80_t );
|
||||
bool extF80_le( struct softfloat_state *, extFloat80_t, extFloat80_t );
|
||||
FEXCORE_PRESERVE_ALL_ATTR
|
||||
bool extF80_lt( struct softfloat_state *, extFloat80_t, extFloat80_t );
|
||||
bool extF80_eq_signaling( extFloat80_t, extFloat80_t );
|
||||
bool extF80_le_quiet( extFloat80_t, extFloat80_t );
|
||||
bool extF80_lt_quiet( extFloat80_t, extFloat80_t );
|
||||
bool extF80_isSignalingNaN( extFloat80_t );
|
||||
static inline extFloat80_t extF80_complement_sign(extFloat80_t a) {
|
||||
a.signExp ^= 1ULL << 15;
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool );
|
||||
uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool );
|
||||
@@ -284,34 +288,38 @@ bool extF80M_isSignalingNaN( const extFloat80_t * );
|
||||
| 128-bit (quadruple-precision) floating-point operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifdef SOFTFLOAT_FAST_INT64
|
||||
uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool );
|
||||
uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool );
|
||||
int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool );
|
||||
int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool );
|
||||
uint_fast32_t f128_to_ui32( struct softfloat_state *, float128_t, uint_fast8_t, bool );
|
||||
uint_fast64_t f128_to_ui64( struct softfloat_state *, float128_t, uint_fast8_t, bool );
|
||||
int_fast32_t f128_to_i32( struct softfloat_state *, float128_t, uint_fast8_t, bool );
|
||||
int_fast64_t f128_to_i64( struct softfloat_state *, float128_t, uint_fast8_t, bool );
|
||||
uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool );
|
||||
uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool );
|
||||
int_fast32_t f128_to_i32_r_minMag( float128_t, bool );
|
||||
int_fast64_t f128_to_i64_r_minMag( float128_t, bool );
|
||||
float16_t f128_to_f16( float128_t );
|
||||
float32_t f128_to_f32( float128_t );
|
||||
float64_t f128_to_f64( float128_t );
|
||||
float16_t f128_to_f16( struct softfloat_state *, float128_t );
|
||||
float32_t f128_to_f32( struct softfloat_state *, float128_t );
|
||||
float64_t f128_to_f64( struct softfloat_state *, float128_t );
|
||||
FEXCORE_PRESERVE_ALL_ATTR
|
||||
extFloat80_t f128_to_extF80( struct softfloat_state *, float128_t );
|
||||
float128_t f128_roundToInt( float128_t, uint_fast8_t, bool );
|
||||
float128_t f128_add( float128_t, float128_t );
|
||||
float128_t f128_sub( float128_t, float128_t );
|
||||
float128_t f128_mul( float128_t, float128_t );
|
||||
float128_t f128_mulAdd( float128_t, float128_t, float128_t );
|
||||
float128_t f128_div( float128_t, float128_t );
|
||||
float128_t f128_rem( float128_t, float128_t );
|
||||
float128_t f128_sqrt( float128_t );
|
||||
bool f128_eq( float128_t, float128_t );
|
||||
bool f128_le( float128_t, float128_t );
|
||||
bool f128_lt( float128_t, float128_t );
|
||||
bool f128_eq_signaling( float128_t, float128_t );
|
||||
bool f128_le_quiet( float128_t, float128_t );
|
||||
bool f128_lt_quiet( float128_t, float128_t );
|
||||
float128_t f128_add( struct softfloat_state *, float128_t, float128_t );
|
||||
float128_t f128_sub( struct softfloat_state *, float128_t, float128_t );
|
||||
float128_t f128_mul( struct softfloat_state *, float128_t, float128_t );
|
||||
float128_t f128_mulAdd( struct softfloat_state *, float128_t, float128_t, float128_t );
|
||||
float128_t f128_div( struct softfloat_state *, float128_t, float128_t );
|
||||
float128_t f128_rem( struct softfloat_state *, float128_t, float128_t );
|
||||
float128_t f128_sqrt( struct softfloat_state *, float128_t );
|
||||
bool f128_eq( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_le( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_lt( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_eq_signaling( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_le_quiet( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_lt_quiet( struct softfloat_state *, float128_t, float128_t );
|
||||
bool f128_isSignalingNaN( float128_t );
|
||||
static inline float128_t f128_complement_sign(float128_t a) {
|
||||
a.v[1] ^= 1ULL << 63;
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool );
|
||||
uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool );
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+73
@@ -0,0 +1,73 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool extF80_le( struct softfloat_state *state, extFloat80_t a, extFloat80_t b )
|
||||
{
|
||||
union { struct extFloat80M s; extFloat80_t f; } uA;
|
||||
uint_fast16_t uiA64;
|
||||
uint_fast64_t uiA0;
|
||||
union { struct extFloat80M s; extFloat80_t f; } uB;
|
||||
uint_fast16_t uiB64;
|
||||
uint_fast64_t uiB0;
|
||||
bool signA, signB;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.s.signExp;
|
||||
uiA0 = uA.s.signif;
|
||||
uB.f = b;
|
||||
uiB64 = uB.s.signExp;
|
||||
uiB0 = uB.s.signif;
|
||||
if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
return false;
|
||||
}
|
||||
signA = signExtF80UI64( uiA64 );
|
||||
signB = signExtF80UI64( uiB64 );
|
||||
return
|
||||
(signA != signB)
|
||||
? signA || ! (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0)
|
||||
: ((uiA64 == uiB64) && (uiA0 == uiB0))
|
||||
|| (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));
|
||||
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
float128_t f128_add( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
bool signA;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signB;
|
||||
#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2)
|
||||
float128_t
|
||||
(*magsFuncPtr)(
|
||||
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );
|
||||
#endif
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
signA = signF128UI64( uiA64 );
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
signB = signF128UI64( uiB64 );
|
||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||
if ( signA == signB ) {
|
||||
return softfloat_addMagsF128( state, uiA64, uiA0, uiB64, uiB0, signA );
|
||||
} else {
|
||||
return softfloat_subMagsF128( state, uiA64, uiA0, uiB64, uiB0, signA );
|
||||
}
|
||||
#else
|
||||
magsFuncPtr =
|
||||
(signA == signB) ? softfloat_addMagsF128 : softfloat_subMagsF128;
|
||||
return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Vendored
+199
@@ -0,0 +1,199 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
float128_t f128_div( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
bool signA;
|
||||
int_fast32_t expA;
|
||||
struct uint128 sigA;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signB;
|
||||
int_fast32_t expB;
|
||||
struct uint128 sigB;
|
||||
bool signZ;
|
||||
struct exp32_sig128 normExpSig;
|
||||
int_fast32_t expZ;
|
||||
struct uint128 rem;
|
||||
uint_fast32_t recip32;
|
||||
int ix;
|
||||
uint_fast64_t q64;
|
||||
uint_fast32_t q;
|
||||
struct uint128 term;
|
||||
uint_fast32_t qs[3];
|
||||
uint_fast64_t sigZExtra;
|
||||
struct uint128 sigZ, uiZ;
|
||||
union ui128_f128 uZ;
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
signA = signF128UI64( uiA64 );
|
||||
expA = expF128UI64( uiA64 );
|
||||
sigA.v64 = fracF128UI64( uiA64 );
|
||||
sigA.v0 = uiA0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
signB = signF128UI64( uiB64 );
|
||||
expB = expF128UI64( uiB64 );
|
||||
sigB.v64 = fracF128UI64( uiB64 );
|
||||
sigB.v0 = uiB0;
|
||||
signZ = signA ^ signB;
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
if ( expA == 0x7FFF ) {
|
||||
if ( sigA.v64 | sigA.v0 ) goto propagateNaN;
|
||||
if ( expB == 0x7FFF ) {
|
||||
if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
|
||||
goto invalid;
|
||||
}
|
||||
goto infinity;
|
||||
}
|
||||
if ( expB == 0x7FFF ) {
|
||||
if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
|
||||
goto zero;
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
if ( ! expB ) {
|
||||
if ( ! (sigB.v64 | sigB.v0) ) {
|
||||
if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid;
|
||||
softfloat_raiseFlags( state, softfloat_flag_infinite );
|
||||
goto infinity;
|
||||
}
|
||||
normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );
|
||||
expB = normExpSig.exp;
|
||||
sigB = normExpSig.sig;
|
||||
}
|
||||
if ( ! expA ) {
|
||||
if ( ! (sigA.v64 | sigA.v0) ) goto zero;
|
||||
normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );
|
||||
expA = normExpSig.exp;
|
||||
sigA = normExpSig.sig;
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
expZ = expA - expB + 0x3FFE;
|
||||
sigA.v64 |= UINT64_C( 0x0001000000000000 );
|
||||
sigB.v64 |= UINT64_C( 0x0001000000000000 );
|
||||
rem = sigA;
|
||||
if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) {
|
||||
--expZ;
|
||||
rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 );
|
||||
}
|
||||
recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );
|
||||
ix = 3;
|
||||
for (;;) {
|
||||
q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;
|
||||
q = (q64 + 0x80000000)>>32;
|
||||
--ix;
|
||||
if ( ix < 0 ) break;
|
||||
rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
|
||||
term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
|
||||
rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
|
||||
if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
|
||||
--q;
|
||||
rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
|
||||
}
|
||||
qs[ix] = q;
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
if ( ((q + 1) & 7) < 2 ) {
|
||||
rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
|
||||
term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
|
||||
rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
|
||||
if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
|
||||
--q;
|
||||
rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
|
||||
} else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) {
|
||||
++q;
|
||||
rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
|
||||
}
|
||||
if ( rem.v64 | rem.v0 ) q |= 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
sigZExtra = (uint64_t) ((uint_fast64_t) q<<60);
|
||||
term = softfloat_shortShiftLeft128( 0, qs[1], 54 );
|
||||
sigZ =
|
||||
softfloat_add128(
|
||||
(uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4),
|
||||
term.v64, term.v0
|
||||
);
|
||||
return
|
||||
softfloat_roundPackToF128( state, signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
propagateNaN:
|
||||
uiZ = softfloat_propagateNaNF128UI( state, uiA64, uiA0, uiB64, uiB0 );
|
||||
goto uiZ;
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
invalid:
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
uiZ.v64 = defaultNaNF128UI64;
|
||||
uiZ.v0 = defaultNaNF128UI0;
|
||||
goto uiZ;
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
infinity:
|
||||
uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );
|
||||
goto uiZ0;
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
zero:
|
||||
uiZ.v64 = packToF128UI64( signZ, 0, 0 );
|
||||
uiZ0:
|
||||
uiZ.v0 = 0;
|
||||
uiZ:
|
||||
uZ.ui = uiZ;
|
||||
return uZ.f;
|
||||
|
||||
}
|
||||
|
||||
Vendored
+73
@@ -0,0 +1,73 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_eq( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
if (
|
||||
softfloat_isSigNaNF128UI( uiA64, uiA0 )
|
||||
|| softfloat_isSigNaNF128UI( uiB64, uiB0 )
|
||||
) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return
|
||||
(uiA0 == uiB0)
|
||||
&& ( (uiA64 == uiB64)
|
||||
|| (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_eq_signaling( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
return false;
|
||||
}
|
||||
return
|
||||
(uiA0 == uiB0)
|
||||
&& ( (uiA64 == uiB64)
|
||||
|| (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_isSignalingNaN( float128_t a )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
|
||||
uA.f = a;
|
||||
return softfloat_isSigNaNF128UI( uA.ui.v64, uA.ui.v0 );
|
||||
|
||||
}
|
||||
|
||||
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_le( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signA, signB;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
return false;
|
||||
}
|
||||
signA = signF128UI64( uiA64 );
|
||||
signB = signF128UI64( uiB64 );
|
||||
return
|
||||
(signA != signB)
|
||||
? signA
|
||||
|| ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
|
||||
| uiA0 | uiB0)
|
||||
: ((uiA64 == uiB64) && (uiA0 == uiB0))
|
||||
|| (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));
|
||||
|
||||
}
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_le_quiet( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signA, signB;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
if (
|
||||
softfloat_isSigNaNF128UI( uiA64, uiA0 )
|
||||
|| softfloat_isSigNaNF128UI( uiB64, uiB0 )
|
||||
) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
signA = signF128UI64( uiA64 );
|
||||
signB = signF128UI64( uiB64 );
|
||||
return
|
||||
(signA != signB)
|
||||
? signA
|
||||
|| ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
|
||||
| uiA0 | uiB0)
|
||||
: ((uiA64 == uiB64) && (uiA0 == uiB0))
|
||||
|| (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));
|
||||
|
||||
}
|
||||
|
||||
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_lt( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signA, signB;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
return false;
|
||||
}
|
||||
signA = signF128UI64( uiA64 );
|
||||
signB = signF128UI64( uiB64 );
|
||||
return
|
||||
(signA != signB)
|
||||
? signA
|
||||
&& (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
|
||||
| uiA0 | uiB0)
|
||||
: ((uiA64 != uiB64) || (uiA0 != uiB0))
|
||||
&& (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));
|
||||
|
||||
}
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||
Package, Release 3e, by John R. Hauser.
|
||||
|
||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions, and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "specialize.h"
|
||||
#include "softfloat.h"
|
||||
|
||||
bool f128_lt_quiet( struct softfloat_state *state, float128_t a, float128_t b )
|
||||
{
|
||||
union ui128_f128 uA;
|
||||
uint_fast64_t uiA64, uiA0;
|
||||
union ui128_f128 uB;
|
||||
uint_fast64_t uiB64, uiB0;
|
||||
bool signA, signB;
|
||||
|
||||
uA.f = a;
|
||||
uiA64 = uA.ui.v64;
|
||||
uiA0 = uA.ui.v0;
|
||||
uB.f = b;
|
||||
uiB64 = uB.ui.v64;
|
||||
uiB0 = uB.ui.v0;
|
||||
if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
|
||||
if (
|
||||
softfloat_isSigNaNF128UI( uiA64, uiA0 )
|
||||
|| softfloat_isSigNaNF128UI( uiB64, uiB0 )
|
||||
) {
|
||||
softfloat_raiseFlags( state, softfloat_flag_invalid );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
signA = signF128UI64( uiA64 );
|
||||
signB = signF128UI64( uiB64 );
|
||||
return
|
||||
(signA != signB)
|
||||
? signA
|
||||
&& (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
|
||||
| uiA0 | uiB0)
|
||||
: ((uiA64 != uiB64) || (uiA0 != uiB0))
|
||||
&& (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));
|
||||
|
||||
}
|
||||
|
||||
Loaded 100 of 1953 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user