mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-28 13:16:24 +02:00
Compare commits
996 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
29a02f4787 | ||
![]() |
e2f9d84b64 | ||
![]() |
0cc94fdf37 | ||
![]() |
74a9b94227 | ||
![]() |
d3208a4c44 | ||
![]() |
5d136980a3 | ||
![]() |
572ad1eac5 | ||
![]() |
6bb2af0091 | ||
![]() |
534a194ed9 | ||
![]() |
331805791e | ||
![]() |
6773406bb6 | ||
![]() |
6226eadf55 | ||
![]() |
b1cde5fd97 | ||
![]() |
39944b2063 | ||
![]() |
973c6ba5df | ||
![]() |
6803c91da8 | ||
![]() |
557c2a50b2 | ||
![]() |
77a797f154 | ||
![]() |
faf9e3cdd7 | ||
![]() |
7bc80ed4fe | ||
![]() |
a1d44ec496 | ||
![]() |
bab3beb0ac | ||
![]() |
aa9e74339b | ||
![]() |
908273d848 | ||
![]() |
b51ad11574 | ||
![]() |
ea027d65a7 | ||
![]() |
d03ae9c164 | ||
![]() |
90e9492f6c | ||
![]() |
512120db04 | ||
![]() |
90582e9e93 | ||
![]() |
b97fae08b5 | ||
![]() |
eed6ef632d | ||
![]() |
0409c15903 | ||
![]() |
c58272ac20 | ||
![]() |
9d83dfd19c | ||
![]() |
ce31a47934 | ||
![]() |
d31d1f91cf | ||
![]() |
ef02194a77 | ||
![]() |
a16764d191 | ||
![]() |
5108ab790f | ||
![]() |
71dc71fee8 | ||
![]() |
c95bf748b2 | ||
![]() |
b5e9acc50b | ||
![]() |
e3fba4e32f | ||
![]() |
efa25d471e | ||
![]() |
b37aa61e47 | ||
![]() |
8feeb977b7 | ||
![]() |
b761a2c86d | ||
![]() |
693837dca7 | ||
![]() |
70abff072b | ||
![]() |
1e861b99a9 | ||
![]() |
13e404bde0 | ||
![]() |
04561a0cd3 | ||
![]() |
0652d7e740 | ||
![]() |
f2aea4fb22 | ||
![]() |
3950e8adff | ||
![]() |
0e84f2b1f0 | ||
![]() |
051c794cc4 | ||
![]() |
053a9cb549 | ||
![]() |
d688fed7d2 | ||
![]() |
8f5102aa2a | ||
![]() |
379e9ab622 | ||
![]() |
af2575b40e | ||
![]() |
361d0c5632 | ||
![]() |
417df486b1 | ||
![]() |
813d05bdf7 | ||
![]() |
3429361a5d | ||
![]() |
92b2947f04 | ||
![]() |
4c281062ba | ||
![]() |
84686d50cd | ||
![]() |
81412c7dd5 | ||
![]() |
960421a7c1 | ||
![]() |
9233fe86b0 | ||
![]() |
1156307ef9 | ||
![]() |
a32a87e0c9 | ||
![]() |
7157565665 | ||
![]() |
6873303864 | ||
![]() |
cd72ba0075 | ||
![]() |
be6919d931 | ||
![]() |
cf0185da17 | ||
![]() |
1d923ba7b0 | ||
![]() |
f14d65b543 | ||
![]() |
fd9f161476 | ||
![]() |
ae070c76d7 | ||
![]() |
2aa072fbfa | ||
![]() |
1c411082db | ||
![]() |
be7285f7fc | ||
![]() |
6f59a14ec6 | ||
![]() |
d85ec0eff5 | ||
![]() |
02ad827a94 | ||
![]() |
6e7220eb28 | ||
![]() |
7a3a21b0c0 | ||
![]() |
92440afcd7 | ||
![]() |
df3b5b4bd8 | ||
![]() |
11cc80f7fc | ||
![]() |
f6c1e97110 | ||
![]() |
e18e27fbc5 | ||
![]() |
f1eb911d25 | ||
![]() |
e1c0b3acab | ||
![]() |
1d4928e859 | ||
![]() |
28b8dc14c7 | ||
![]() |
21971a2be7 | ||
![]() |
321bdecbc2 | ||
![]() |
6904d6a461 | ||
![]() |
d8e3ab3974 | ||
![]() |
9b429afbb4 | ||
![]() |
b71a4cb745 | ||
![]() |
844b1d8b9a | ||
![]() |
c4ea0e0df2 | ||
![]() |
0ae536a757 | ||
![]() |
4c9e8f8e5c | ||
![]() |
e33dc6f096 | ||
![]() |
3a79b442b0 | ||
![]() |
244c0505d9 | ||
![]() |
e0181d3410 | ||
![]() |
4c7c5ea323 | ||
![]() |
4a6d9c2b3f | ||
![]() |
2c8afa7e6e | ||
![]() |
d98ed30450 | ||
![]() |
7c89e87deb | ||
![]() |
60992e2545 | ||
![]() |
adae465b08 | ||
![]() |
6602693477 | ||
![]() |
b76e223cc3 | ||
![]() |
2ea9e945ab | ||
![]() |
a84cc62508 | ||
![]() |
343de5171c | ||
![]() |
5d8451b41a | ||
![]() |
dfdbb23f0d | ||
![]() |
1e6b2ea9ca | ||
![]() |
5bf656cb25 | ||
![]() |
a6ce065f79 | ||
![]() |
c9e120f8f2 | ||
![]() |
cb486ad66d | ||
![]() |
463b5d403c | ||
![]() |
2cbc83e89b | ||
![]() |
8ad5c73f4c | ||
![]() |
d7754aeee1 | ||
![]() |
4ef2836df1 | ||
![]() |
e7d3f39c1b | ||
![]() |
2f064064ca | ||
![]() |
86c2f261af | ||
![]() |
497627d09e | ||
![]() |
4ced04948a | ||
![]() |
02d459a9bd | ||
![]() |
52fae771ad | ||
![]() |
e685168675 | ||
![]() |
e250d83e2a | ||
![]() |
d27b4a7615 | ||
![]() |
d4bf7d3c2b | ||
![]() |
c067f85fa3 | ||
![]() |
1a705418c5 | ||
![]() |
8ca06b69ac | ||
![]() |
8e666ab19f | ||
![]() |
c229d458e7 | ||
![]() |
f09ca0f57f | ||
![]() |
f2c5cf8a60 | ||
![]() |
9742a78c06 | ||
![]() |
cb33e2c13f | ||
![]() |
f77fe4a6b2 | ||
![]() |
a35d907445 | ||
![]() |
d730b095a4 | ||
![]() |
17f3540ac9 | ||
![]() |
097adacb3a | ||
![]() |
078909169d | ||
![]() |
95fdc0ca24 | ||
![]() |
fae60f64a7 | ||
![]() |
24c90a8fde | ||
![]() |
fa5840927a | ||
![]() |
57118e00fb | ||
![]() |
11ea020092 | ||
![]() |
80ab0f96b9 | ||
![]() |
70f3dae146 | ||
![]() |
4590ffce65 | ||
![]() |
350b1fc013 | ||
![]() |
eb075af06f | ||
![]() |
d857106c28 | ||
![]() |
7664f8cde9 | ||
![]() |
ddc00cf2d8 | ||
![]() |
05b4bd8c61 | ||
![]() |
20111a651c | ||
![]() |
659e580f4d | ||
![]() |
e6339ac950 | ||
![]() |
6b402847d2 | ||
![]() |
3b06f4cb78 | ||
![]() |
cdf60eecc0 | ||
![]() |
1219f329c1 | ||
![]() |
d5527f87cb | ||
![]() |
fc75dbc8b8 | ||
![]() |
04361b864a | ||
![]() |
7271e7050d | ||
![]() |
1ca4484148 | ||
![]() |
056f56bc70 | ||
![]() |
bda699f68e | ||
![]() |
0db85d0aa9 | ||
![]() |
44632e5d8b | ||
![]() |
551d2c1134 | ||
![]() |
25cc9b24b4 | ||
![]() |
638c616ab7 | ||
![]() |
109f0fc659 | ||
![]() |
dfcb8a7fc0 | ||
![]() |
d87d3235e9 | ||
![]() |
f3a9cecf72 | ||
![]() |
97a1bbdd74 | ||
![]() |
e379fad5da | ||
![]() |
c76f32a4ee | ||
![]() |
7bdf013ba6 | ||
![]() |
e07130ecc3 | ||
![]() |
dd02c8e25d | ||
![]() |
bed3835718 | ||
![]() |
2b06826922 | ||
![]() |
a23c6bf547 | ||
![]() |
27cdf876a2 | ||
![]() |
b0c0e8f7ad | ||
![]() |
2317c06364 | ||
![]() |
c12a59ecd6 | ||
![]() |
57c22a1f32 | ||
![]() |
f7976753fd | ||
![]() |
b45a65fbdc | ||
![]() |
c410474d83 | ||
![]() |
ffdc419417 | ||
![]() |
da3f4e1d3a | ||
![]() |
69d79322bb | ||
![]() |
c3af1dbf1a | ||
![]() |
10ac381525 | ||
![]() |
e104ee6be3 | ||
![]() |
e65d1ec6c9 | ||
![]() |
534f92506b | ||
![]() |
10d20c1ae3 | ||
![]() |
e294a79975 | ||
![]() |
ec06a86899 | ||
![]() |
2e4de17472 | ||
![]() |
9227cbe5a7 | ||
![]() |
332bcdfaf1 | ||
![]() |
1c8276197f | ||
![]() |
a3596ba858 | ||
![]() |
3ffcc72117 | ||
![]() |
fe1617ffea | ||
![]() |
eb6b0e9adc | ||
![]() |
9631bdfe16 | ||
![]() |
2a84656ffc | ||
![]() |
6c6580ddcc | ||
![]() |
c47448628c | ||
![]() |
d0ac83b493 | ||
![]() |
e0ddbe55c0 | ||
![]() |
4a4078865f | ||
![]() |
3f59bade94 | ||
![]() |
c2ed0fd5fd | ||
![]() |
de16d8fa3e | ||
![]() |
9b1fb3a27b | ||
![]() |
b9150a0092 | ||
![]() |
c1002d4826 | ||
![]() |
b1de7696ee | ||
![]() |
f91cd05260 | ||
![]() |
920933bc9f | ||
![]() |
52b0b45d34 | ||
![]() |
12f0dbcc70 | ||
![]() |
719be560ec | ||
![]() |
18238736be | ||
![]() |
5d9e4ad7a4 | ||
![]() |
adba775f0c | ||
![]() |
2ffaeb2803 | ||
![]() |
b16b844760 | ||
![]() |
bc07bc482d | ||
![]() |
61975ca44d | ||
![]() |
66054dd225 | ||
![]() |
b1f61e5143 | ||
![]() |
0d7d0e8092 | ||
![]() |
aa2178dbe5 | ||
![]() |
f92d09711b | ||
![]() |
45ee8cd0e8 | ||
![]() |
395bbd144a | ||
![]() |
744d813b87 | ||
![]() |
7d59ada798 | ||
![]() |
a4b5304935 | ||
![]() |
0965ee905d | ||
![]() |
855161b23b | ||
![]() |
6b55d158b7 | ||
![]() |
91f73a4891 | ||
![]() |
883d4d863a | ||
![]() |
ca5de909a1 | ||
![]() |
5172567b08 | ||
![]() |
6fe4cee7c0 | ||
![]() |
8623452abc | ||
![]() |
17e8ae1d9a | ||
![]() |
7591b07fce | ||
![]() |
89b4389ed2 | ||
![]() |
d9ee729199 | ||
![]() |
ba0cd13cff | ||
![]() |
501b199e24 | ||
![]() |
8aecccadb8 | ||
![]() |
e23d610f49 | ||
![]() |
f6822f7358 | ||
![]() |
d3f84a1305 | ||
![]() |
06d34a5992 | ||
![]() |
e8e1dc6619 | ||
![]() |
c5603d4c36 | ||
![]() |
05b56730d6 | ||
![]() |
43f7b000ca | ||
![]() |
ad89cf39b6 | ||
![]() |
96c33a0b92 | ||
![]() |
e0db55df46 | ||
![]() |
30fef8e96e | ||
![]() |
9cb5f5689b | ||
![]() |
a205ec374b | ||
![]() |
aab9b58542 | ||
![]() |
daa648dc40 | ||
![]() |
1024aa8757 | ||
![]() |
13388e972a | ||
![]() |
1eb78872d8 | ||
![]() |
fe9fe2a10f | ||
![]() |
6ab899f621 | ||
![]() |
faacec9801 | ||
![]() |
55fdb3f6b2 | ||
![]() |
1129ab0e8c | ||
![]() |
b6b391b2cf | ||
![]() |
f3cf03495d | ||
![]() |
7bce8206d5 | ||
![]() |
efa0cc7554 | ||
![]() |
1c0813d09d | ||
![]() |
8bec09d7ff | ||
![]() |
e4b4e94b56 | ||
![]() |
764c9e9d4e | ||
![]() |
05e991db87 | ||
![]() |
2cd876b1cb | ||
![]() |
93a298523f | ||
![]() |
253cbb2810 | ||
![]() |
9c226dcc7a | ||
![]() |
30a534edcd | ||
![]() |
1d88771d1b | ||
![]() |
4e8157688e | ||
![]() |
5085af0050 | ||
![]() |
2c8edaf89e | ||
![]() |
aa8ba8b503 | ||
![]() |
a4211fec33 | ||
![]() |
54b233dd78 | ||
![]() |
d1da937fce | ||
![]() |
4a8f98126f | ||
![]() |
e55629a908 | ||
![]() |
c638a7daf8 | ||
![]() |
5e5e180fea | ||
![]() |
131fe71205 | ||
![]() |
6af388c623 | ||
![]() |
45cec4e7cf | ||
![]() |
479b38f035 | ||
![]() |
3ecc7819cc | ||
![]() |
4b1d94ccd8 | ||
![]() |
4ae9f1c0d2 | ||
![]() |
717851985e | ||
![]() |
bd08a111a8 | ||
![]() |
1972a47f39 | ||
![]() |
222ceb818b | ||
![]() |
b0fcc5bee1 | ||
![]() |
820e8f7375 | ||
![]() |
e8a7d5b0b7 | ||
![]() |
fafb99c702 | ||
![]() |
df9e6e4812 | ||
![]() |
566f3d079a | ||
![]() |
d7707d4176 | ||
![]() |
7a9b62884a | ||
![]() |
de9faf183a | ||
![]() |
0bf7c5dfa2 | ||
![]() |
11bc32d98e | ||
![]() |
063430ea16 | ||
![]() |
65f08caaa3 | ||
![]() |
f225b18c05 | ||
![]() |
d8549f687b | ||
![]() |
5ab50680b4 | ||
![]() |
a0edc5c2b0 | ||
![]() |
158ea7b4d6 | ||
![]() |
8bc3de8303 | ||
![]() |
c812106611 | ||
![]() |
11e4d8f970 | ||
![]() |
774edb7b29 | ||
![]() |
55536f5d78 | ||
![]() |
b2eecd28ce | ||
![]() |
fe43c32e60 | ||
![]() |
8117e160c2 | ||
![]() |
bf713a80d6 | ||
![]() |
b38b5a1e70 | ||
![]() |
2d7700949c | ||
![]() |
ea2287af03 | ||
![]() |
37af8c70aa | ||
![]() |
50cee3fd19 | ||
![]() |
a46aacf2e2 | ||
![]() |
ad9d6588e8 | ||
![]() |
38ef65aae0 | ||
![]() |
9f94aa1c79 | ||
![]() |
2c9a26c11c | ||
![]() |
a4a15a4c80 | ||
![]() |
cc3b95eee1 | ||
![]() |
2ab806f759 | ||
![]() |
6d75410bd2 | ||
![]() |
196b2eaf66 | ||
![]() |
82fe519766 | ||
![]() |
ff05e03cc8 | ||
![]() |
e18c6d90c4 | ||
![]() |
9075a3960b | ||
![]() |
3cf54987d2 | ||
![]() |
9c12f52805 | ||
![]() |
059fc83d4d | ||
![]() |
04ce7fb764 | ||
![]() |
359852b5c0 | ||
![]() |
796674d9cf | ||
![]() |
4efe24a3bc | ||
![]() |
1a42d1396c | ||
![]() |
11f29361eb | ||
![]() |
71d8cfd232 | ||
![]() |
023bd5f00f | ||
![]() |
0ed7fd14ba | ||
![]() |
a624fe64b9 | ||
![]() |
e02ef52069 | ||
![]() |
707c9ef748 | ||
![]() |
2acc43e968 | ||
![]() |
191e158289 | ||
![]() |
a469f3d710 | ||
![]() |
1b3656bca9 | ||
![]() |
502ce98b3a | ||
![]() |
7085bafa60 | ||
![]() |
9d28af935d | ||
![]() |
cdf4016c25 | ||
![]() |
082c718f5d | ||
![]() |
31de0bf8c6 | ||
![]() |
f3942968f9 | ||
![]() |
ac838aa81d | ||
![]() |
0f857400b6 | ||
![]() |
95f9e548ca | ||
![]() |
a5dbcb75d0 | ||
![]() |
aa0cb50c5d | ||
![]() |
ae90db2040 | ||
![]() |
46a5cafaa8 | ||
![]() |
2853f5b426 | ||
![]() |
45125c16cf | ||
![]() |
9f3eac7f26 | ||
![]() |
70b767ef60 | ||
![]() |
3c2f283ec7 | ||
![]() |
3e12865f51 | ||
![]() |
ed2590a8ac | ||
![]() |
9cb3b40ffc | ||
![]() |
c7db948fb3 | ||
![]() |
9e1a13b2ee | ||
![]() |
d95f724d17 | ||
![]() |
e859bd5aa2 | ||
![]() |
ccef0b49eb | ||
![]() |
7f5a356c3d | ||
![]() |
ae92fbf539 | ||
![]() |
56d373a011 | ||
![]() |
742083ae3d | ||
![]() |
5fad450027 | ||
![]() |
929a16dd26 | ||
![]() |
4e47c86f90 | ||
![]() |
15d1528774 | ||
![]() |
3cdaaa0b69 | ||
![]() |
5f023ca49b | ||
![]() |
eae6dba610 | ||
![]() |
94b65aec02 | ||
![]() |
beab133c8d | ||
![]() |
f1fd5c9366 | ||
![]() |
5396327ac1 | ||
![]() |
3f12727ef8 | ||
![]() |
8bfcebebf1 | ||
![]() |
e3f20abd23 | ||
![]() |
0c36bcd7d4 | ||
![]() |
050b9a0da4 | ||
![]() |
a1291f1061 | ||
![]() |
f15aa8fba0 | ||
![]() |
250acab7a7 | ||
![]() |
93539e7d45 | ||
![]() |
69e0b79bd9 | ||
![]() |
5eba42fa06 | ||
![]() |
58c1ab7989 | ||
![]() |
2d1a4c3ce5 | ||
![]() |
e6b393e420 | ||
![]() |
fe661dc750 | ||
![]() |
ac401034d7 | ||
![]() |
1712d69dcd | ||
![]() |
f2aa6b3a5b | ||
![]() |
68bbb29be6 | ||
![]() |
76ec047eb7 | ||
![]() |
1ae349efb1 | ||
![]() |
5099548856 | ||
![]() |
a97fd4beb1 | ||
![]() |
97188556d8 | ||
![]() |
e0567c5ce9 | ||
![]() |
be3bd0bcb5 | ||
![]() |
3b5f6170d1 | ||
![]() |
9b6afa0ea2 | ||
![]() |
3541e282ea | ||
![]() |
1ce37ec317 | ||
![]() |
c06f16c5e6 | ||
![]() |
7829fd8ee7 | ||
![]() |
33079422fe | ||
![]() |
f81cb093fc | ||
![]() |
dc0c7a2912 | ||
![]() |
1fbee5a584 | ||
![]() |
c140e9b23c | ||
![]() |
9c8055440e | ||
![]() |
c03cd50fa3 | ||
![]() |
069f630776 | ||
![]() |
13d411e4de | ||
![]() |
9f53b07491 | ||
![]() |
cd8113dadf | ||
![]() |
9089c4ffe5 | ||
![]() |
fe9d8d05bd | ||
![]() |
880a8ae748 | ||
![]() |
11531dacb6 | ||
![]() |
3974739ed3 | ||
![]() |
440a3447fb | ||
![]() |
65374ed6cb | ||
![]() |
789d6ab959 | ||
![]() |
182db31343 | ||
![]() |
ea296b134d | ||
![]() |
bf584442b2 | ||
![]() |
cb7c294dbf | ||
![]() |
eaf1e7efd2 | ||
![]() |
471e7ed2e4 | ||
![]() |
ad3e80b383 | ||
![]() |
ed64a63094 | ||
![]() |
8df7ba2d56 | ||
![]() |
e743d78115 | ||
![]() |
04ba762710 | ||
![]() |
f42b2ed59d | ||
![]() |
d135385cab | ||
![]() |
b360f4e721 | ||
![]() |
a1c0c70ec2 | ||
![]() |
290ac405ac | ||
![]() |
bbd64fd5f0 | ||
![]() |
09446fd80e | ||
![]() |
4f014a89cf | ||
![]() |
6482e566ab | ||
![]() |
7fcd9b792e | ||
![]() |
e676fd8b17 | ||
![]() |
dd16e3cee1 | ||
![]() |
31e5f74e05 | ||
![]() |
f2f099bddb | ||
![]() |
2616dc57fb | ||
![]() |
0cdf7cfe21 | ||
![]() |
2ecf999569 | ||
![]() |
b612fc5155 | ||
![]() |
25eb545409 | ||
![]() |
52269964b6 | ||
![]() |
ccdddac8fc | ||
![]() |
1bc30bf3ba | ||
![]() |
4868fface8 | ||
![]() |
6fca4492d0 | ||
![]() |
ade2f256e0 | ||
![]() |
580b150c9a | ||
![]() |
e6bad52945 | ||
![]() |
beda3206e0 | ||
![]() |
2f93a0f706 | ||
![]() |
80f44d9547 | ||
![]() |
b08e5db6d8 | ||
![]() |
6a291d4116 | ||
![]() |
6fc827fe67 | ||
![]() |
6cd4866d76 | ||
![]() |
4d7ca5c0f0 | ||
![]() |
a375faecc1 | ||
![]() |
1728b0f20c | ||
![]() |
5aa071c59b | ||
![]() |
1018c9db8b | ||
![]() |
01ccd18726 | ||
![]() |
abfbc6f4bc | ||
![]() |
6a4bc02d7a | ||
![]() |
814c0526d2 | ||
![]() |
a5a4ef38e6 | ||
![]() |
c17e3bfcdf | ||
![]() |
017f46f318 | ||
![]() |
fd4d801bfd | ||
![]() |
f1dee50275 | ||
![]() |
c2ae49eb47 | ||
![]() |
47c71966d0 | ||
![]() |
f9e8f4bc29 | ||
![]() |
7694c8c046 | ||
![]() |
0dd789e8a5 | ||
![]() |
4e0aafd005 | ||
![]() |
c5091f499e | ||
![]() |
41c8fd8194 | ||
![]() |
d4a7ee25ea | ||
![]() |
3141c560fb | ||
![]() |
de341b285b | ||
![]() |
cc95e80ee9 | ||
![]() |
d75ce52bd4 | ||
![]() |
4a4ea557de | ||
![]() |
33f42adb11 | ||
![]() |
918ec1bde3 | ||
![]() |
cca429d46a | ||
![]() |
845c86f545 | ||
![]() |
27993b789f | ||
![]() |
bdd890cf6f | ||
![]() |
c5574b41a1 | ||
![]() |
292e27f0da | ||
![]() |
606e149bd3 | ||
![]() |
a8c3407d11 | ||
![]() |
daa8168985 | ||
![]() |
f580521e99 | ||
![]() |
2226521f6c | ||
![]() |
384416953d | ||
![]() |
1343fabe41 | ||
![]() |
1e52af5e29 | ||
![]() |
672f5df0f9 | ||
![]() |
804d9c1efe | ||
![]() |
9270b35648 | ||
![]() |
5a6d01db3c | ||
![]() |
ef9c1416ec | ||
![]() |
5efa7d5dfa | ||
![]() |
a82569d615 | ||
![]() |
ed5832ca73 | ||
![]() |
574aa9ff9c | ||
![]() |
8a29428de2 | ||
![]() |
f4272b05fa | ||
![]() |
d8265f7772 | ||
![]() |
259526430c | ||
![]() |
b5fafb6394 | ||
![]() |
323c356d9c | ||
![]() |
30b22ce6ba | ||
![]() |
9acecc9eb2 | ||
![]() |
4193a37a91 | ||
![]() |
c4cc657b89 | ||
![]() |
9726b0feb0 | ||
![]() |
159ff828a1 | ||
![]() |
6fa2bfc736 | ||
![]() |
2c24df0247 | ||
![]() |
13efc3e544 | ||
![]() |
845dd9a8db | ||
![]() |
b661bdd997 | ||
![]() |
cc84041270 | ||
![]() |
987ab9be41 | ||
![]() |
8a2bc3957a | ||
![]() |
850df38f1e | ||
![]() |
c8d598d5ac | ||
![]() |
3e5b2bda38 | ||
![]() |
9bb50fc6dd | ||
![]() |
e956864697 | ||
![]() |
f43442f774 | ||
![]() |
88d11d3d8d | ||
![]() |
391f57bdd2 | ||
![]() |
fd2b5a7fc1 | ||
![]() |
37c165e9fc | ||
![]() |
003a6d322b | ||
![]() |
978d2c132b | ||
![]() |
5d63706cea | ||
![]() |
732aafd3bb | ||
![]() |
3fa714bb72 | ||
![]() |
7c01633f13 | ||
![]() |
27c5cba10b | ||
![]() |
3525d5ecd4 | ||
![]() |
6286501550 | ||
![]() |
61ae427a4d | ||
![]() |
19d2883a35 | ||
![]() |
617c03119f | ||
![]() |
e43d899e1d | ||
![]() |
0cd09ea0c5 | ||
![]() |
4135d74e4d | ||
![]() |
bd29f658b1 | ||
![]() |
df150f0788 | ||
![]() |
e50198b37d | ||
![]() |
f426945fec | ||
![]() |
172869bfba | ||
![]() |
b6f88514f9 | ||
![]() |
e92f52e56c | ||
![]() |
318498eab0 | ||
![]() |
a5cde8e006 | ||
![]() |
d0a344d632 | ||
![]() |
ca66298817 | ||
![]() |
9ae1c4380d | ||
![]() |
c88518bce2 | ||
![]() |
a3888ed7cf | ||
![]() |
7cbbd02973 | ||
![]() |
b2e1e553e4 | ||
![]() |
699e1962b1 | ||
![]() |
e486b902b1 | ||
![]() |
0ab5b41c4b | ||
![]() |
d10a478cce | ||
![]() |
ec1020b165 | ||
![]() |
4082ebad1a | ||
![]() |
da8ea06074 | ||
![]() |
7f9dccb293 | ||
![]() |
8e4a77aba0 | ||
![]() |
8fd8a776c9 | ||
![]() |
eec92c242c | ||
![]() |
42a739d34c | ||
![]() |
f362bef43d | ||
![]() |
f5ce539de9 | ||
![]() |
4f699afe7a | ||
![]() |
6caab1aa37 | ||
![]() |
9baaa2b8f8 | ||
![]() |
7f376b4f45 | ||
![]() |
32cdccde12 | ||
![]() |
cbd851d00e | ||
![]() |
f463ea1c5d | ||
![]() |
1dd69912b1 | ||
![]() |
1fbb0d8e7d | ||
![]() |
9ee3f1ff36 | ||
![]() |
d052d74ac4 | ||
![]() |
df91c4c57a | ||
![]() |
2aaaa7872f | ||
![]() |
b5999583d6 | ||
![]() |
8b3a945b5f | ||
![]() |
09107b67ff | ||
![]() |
12b264af44 | ||
![]() |
0c21b07f19 | ||
![]() |
18625cf775 | ||
![]() |
77a9246825 | ||
![]() |
709eeda94a | ||
![]() |
7d54424048 | ||
![]() |
664c63c6a8 | ||
![]() |
153d1ef06b | ||
![]() |
e1e4e5d2d5 | ||
![]() |
44ee4190e6 | ||
![]() |
9408452f93 | ||
![]() |
38833ff60a | ||
![]() |
1faa72f22f | ||
![]() |
56e45ae648 | ||
![]() |
07074272ca | ||
![]() |
9eb273a0f7 | ||
![]() |
ccddaa77d1 | ||
![]() |
01c2e67334 | ||
![]() |
4c646721d6 | ||
![]() |
d3bc3a1081 | ||
![]() |
c69881a0a2 | ||
![]() |
1bc0159139 | ||
![]() |
0733b7d0a1 | ||
![]() |
9df1366fa1 | ||
![]() |
c73b5bdf46 | ||
![]() |
9754d247b5 | ||
![]() |
267e9f6350 | ||
![]() |
d7b3dd12d1 | ||
![]() |
c9b2a6b1f1 | ||
![]() |
17233d30da | ||
![]() |
2bf48f57d2 | ||
![]() |
412d4065b8 | ||
![]() |
e6644626fc | ||
![]() |
0bacdb8765 | ||
![]() |
0ca4d6e921 | ||
![]() |
f0aa7eedf6 | ||
![]() |
41acc4b1f3 | ||
![]() |
7aede70ba9 | ||
![]() |
a0a4f78cff | ||
![]() |
16a60fdf12 | ||
![]() |
4d7350fc6e | ||
![]() |
b05eab21a2 | ||
![]() |
ff667a5c84 | ||
![]() |
2f540dc88c | ||
![]() |
3cb996bf5c | ||
![]() |
852823104f | ||
![]() |
3094df54dd | ||
![]() |
278fe9d4f0 | ||
![]() |
a560d2efdb | ||
![]() |
a270dc721c | ||
![]() |
23b0b22400 | ||
![]() |
3dfbf55611 | ||
![]() |
cb355f504d | ||
![]() |
b5483d8fe0 | ||
![]() |
8259f790d7 | ||
![]() |
1ea345faa7 | ||
![]() |
5913ceda40 | ||
![]() |
decd37ce6d | ||
![]() |
67ec10feea | ||
![]() |
4c7cb54ec6 | ||
![]() |
f898a5ecf4 | ||
![]() |
2fac0f4db1 | ||
![]() |
0f18df982f | ||
![]() |
d9fe0da345 | ||
![]() |
1f0fa525a3 | ||
![]() |
e15a207656 | ||
![]() |
77ef82d92a | ||
![]() |
ba199f4325 | ||
![]() |
4171913baf | ||
![]() |
5b36a9cf9f | ||
![]() |
a460eda195 | ||
![]() |
c77c1acd08 | ||
![]() |
d68295e57d | ||
![]() |
bb3d95722e | ||
![]() |
2fa3a7bfa1 | ||
![]() |
381921390a | ||
![]() |
221524d879 | ||
![]() |
9cddf3b66b | ||
![]() |
0adaa4cb96 | ||
![]() |
ff6628149d | ||
![]() |
8db5a7e98b | ||
![]() |
8e00cb5232 | ||
![]() |
362f62cd39 | ||
![]() |
2cd54d0da0 | ||
![]() |
b97b8ca8f5 | ||
![]() |
d7d4225e0d | ||
![]() |
a9e0fac9dc | ||
![]() |
1b9656e960 | ||
![]() |
8994e7476c | ||
![]() |
b3944a18b7 | ||
![]() |
18c957f90b | ||
![]() |
1a005f96e7 | ||
![]() |
072cd2824a | ||
![]() |
9da97bc911 | ||
![]() |
39252b7267 | ||
![]() |
ec11bf2af9 | ||
![]() |
8ae72c1a00 | ||
![]() |
06abba25c1 | ||
![]() |
de00a71690 | ||
![]() |
315a1819c0 | ||
![]() |
4ffb8aef12 | ||
![]() |
290a6ad5de | ||
![]() |
eda4f4349b | ||
![]() |
5fbcb1f3a7 | ||
![]() |
d00754477e | ||
![]() |
0bc1eddaeb | ||
![]() |
baad1e313f | ||
![]() |
a1e6d11dcb | ||
![]() |
3d168a8bfa | ||
![]() |
000c1756de | ||
![]() |
1d0152b961 | ||
![]() |
07690e4527 | ||
![]() |
08b7257be5 | ||
![]() |
17483aad24 | ||
![]() |
6b5cb151c3 | ||
![]() |
3680df6092 | ||
![]() |
facc12a94a | ||
![]() |
8e55e6d6d7 | ||
![]() |
346dfe9542 | ||
![]() |
8a2b56cae6 | ||
![]() |
baf179efdb | ||
![]() |
2a72fb2088 | ||
![]() |
0caeab2270 | ||
![]() |
f72d2c1b2b | ||
![]() |
a18cecbc30 | ||
![]() |
2e6794e69b | ||
![]() |
7e16fccfc1 | ||
![]() |
a81212bbf1 | ||
![]() |
e8d3ad4d8b | ||
![]() |
3b6731a351 | ||
![]() |
e653848a2c | ||
![]() |
5534001152 | ||
![]() |
e05875a079 | ||
![]() |
49eeb26b6f | ||
![]() |
f8d63f9a2f | ||
![]() |
e2b7738465 | ||
![]() |
1d42c29335 | ||
![]() |
c2de5cc700 | ||
![]() |
aaaf60b7a4 | ||
![]() |
150e06e0de | ||
![]() |
c0a4d95c5d | ||
![]() |
c3831428e0 | ||
![]() |
fda79efed4 | ||
![]() |
8444e4dca0 | ||
![]() |
008d908c5a | ||
![]() |
722953211d | ||
![]() |
df5002bdbf | ||
![]() |
f4b757c584 | ||
![]() |
25d69079cb | ||
![]() |
2e1ede5348 | ||
![]() |
52f42d450f | ||
![]() |
11416e2167 | ||
![]() |
e5d076a1b2 | ||
![]() |
d394dd769a | ||
![]() |
6de3afc43d | ||
![]() |
9b90e81817 | ||
![]() |
1e53a17041 | ||
![]() |
0c23104792 | ||
![]() |
1ed2aea029 | ||
![]() |
34caa03385 | ||
![]() |
104701e80d | ||
![]() |
cef88febb2 | ||
![]() |
5fccfb76b9 | ||
![]() |
4cb5946be4 | ||
![]() |
e1dfb48e23 | ||
![]() |
6d8738c048 | ||
![]() |
abfcfcaf0f | ||
![]() |
d404a8b05b | ||
![]() |
42cbe24bb1 | ||
![]() |
79ba9d1258 | ||
![]() |
826ffd4a04 | ||
![]() |
7369079459 | ||
![]() |
a506d81989 | ||
![]() |
15c20920b3 | ||
![]() |
285ee276b6 | ||
![]() |
617b81e209 | ||
![]() |
eb6ce7bcb3 | ||
![]() |
69f75f2df1 | ||
![]() |
10c8d73b60 | ||
![]() |
e01a30016e | ||
![]() |
e26625dfd5 | ||
![]() |
9c82d98ec4 | ||
![]() |
4aae82bad1 | ||
![]() |
299be822c4 | ||
![]() |
b17e4f79fb | ||
![]() |
a7b58df3fe | ||
![]() |
8c2d6192ba | ||
![]() |
2a23000fed | ||
![]() |
ab7d0a2e6d | ||
![]() |
bd2681b2f9 | ||
![]() |
640d7f9e77 | ||
![]() |
02e8278438 | ||
![]() |
6acd86c890 | ||
![]() |
708256ce96 | ||
![]() |
5bf50836e1 | ||
![]() |
730ba44043 | ||
![]() |
36c374cc7a | ||
![]() |
75f714488e | ||
![]() |
4831965404 | ||
![]() |
47b8145809 | ||
![]() |
20cc21add6 | ||
![]() |
683baec1af | ||
![]() |
f4957d2a09 | ||
![]() |
3e1182af22 | ||
![]() |
6664ed1b11 | ||
![]() |
0c88b9eff7 | ||
![]() |
8a064bcd7e | ||
![]() |
5ff962be37 | ||
![]() |
d9c8b7d937 | ||
![]() |
feeeafe8fe | ||
![]() |
04f014c777 | ||
![]() |
4a677deb50 | ||
![]() |
1c07bf3dd0 | ||
![]() |
4c83794254 | ||
![]() |
6911e288bc | ||
![]() |
67ab54e2bb | ||
![]() |
139c195eb7 | ||
![]() |
9305d171e7 | ||
![]() |
fb4ab5ea08 | ||
![]() |
d7e17abade | ||
![]() |
bdb92224f9 | ||
![]() |
b21740c931 | ||
![]() |
4f06c343a4 | ||
![]() |
6c6f18509b | ||
![]() |
70b7c4c1c3 | ||
![]() |
7764a74a6d | ||
![]() |
5de2c4f292 | ||
![]() |
5845787325 | ||
![]() |
9c94db1130 | ||
![]() |
1c3347c95a | ||
![]() |
b70580bc9f | ||
![]() |
4926df42a4 | ||
![]() |
7038a902c3 | ||
![]() |
6be8838043 | ||
![]() |
033ea86c1b | ||
![]() |
dfb4854d19 | ||
![]() |
a09d314817 | ||
![]() |
75035b3231 | ||
![]() |
9a1bdaae16 | ||
![]() |
c2f6d5d029 | ||
![]() |
4f160b35f6 | ||
![]() |
5fa74574ba | ||
![]() |
a647050ed4 | ||
![]() |
8686bea63f | ||
![]() |
d280fbdf37 | ||
![]() |
7d88dfa00d | ||
![]() |
570c7cfaa2 | ||
![]() |
281be7ca62 | ||
![]() |
c69904afc6 | ||
![]() |
26375766b4 | ||
![]() |
a01a06cd3f | ||
![]() |
7618ef134d | ||
![]() |
a2cd3c2799 | ||
![]() |
eefeb65d9a | ||
![]() |
e30ee32eee | ||
![]() |
59277a9301 | ||
![]() |
2d0d73b617 | ||
![]() |
59277e49c5 | ||
![]() |
8e8ad0f37e | ||
![]() |
b883de5d67 | ||
![]() |
1040ec4e53 | ||
![]() |
4d1ebaf9ba | ||
![]() |
dc3267f152 | ||
![]() |
f76a97c976 | ||
![]() |
0f3c7f920b | ||
![]() |
9ae89d55ca | ||
![]() |
dde62f44c7 | ||
![]() |
decc93bcdc | ||
![]() |
8b75ce1d98 | ||
![]() |
509f6d738c | ||
![]() |
f3efada444 | ||
![]() |
b20613661c | ||
![]() |
2facad4be3 | ||
![]() |
741eba2798 | ||
![]() |
59b3ff7802 | ||
![]() |
c0cc3c4188 | ||
![]() |
6ca57dd016 | ||
![]() |
af1ed1c227 | ||
![]() |
bf5c44df38 | ||
![]() |
01aa8a6a29 | ||
![]() |
430073817c | ||
![]() |
045f9a39bb | ||
![]() |
235083ad75 | ||
![]() |
a13cf098b4 | ||
![]() |
1800ecc1b4 | ||
![]() |
280b94fc0c | ||
![]() |
0faf3f5709 | ||
![]() |
4ee1dff497 | ||
![]() |
b2a35ecf6c | ||
![]() |
5f6d9eef6b | ||
![]() |
40a488799e | ||
![]() |
f9f037a951 | ||
![]() |
456f1ec739 | ||
![]() |
df9450d2ad | ||
![]() |
a989d28e03 | ||
![]() |
cb31d79164 | ||
![]() |
290e7c5ec8 |
1527 changed files with 82949 additions and 41732 deletions
|
@ -16,6 +16,17 @@ tab_width = 4
|
||||||
# New line preferences
|
# New line preferences
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:silent
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||||
|
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
|
||||||
# Markdown, JSON, YAML, props and csproj files
|
# Markdown, JSON, YAML, props and csproj files
|
||||||
[*.{md,json,yml,props,csproj}]
|
[*.{md,json,yml,props,csproj}]
|
||||||
|
@ -106,7 +117,7 @@ csharp_style_conditional_delegate_call = true:suggestion
|
||||||
csharp_prefer_static_local_function = true:suggestion
|
csharp_prefer_static_local_function = true:suggestion
|
||||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
|
||||||
csharp_style_prefer_readonly_struct = true
|
csharp_style_prefer_readonly_struct = true
|
||||||
csharp_style_prefer_method_group_conversion = true
|
csharp_style_prefer_method_group_conversion = true:silent
|
||||||
|
|
||||||
# Code-block preferences
|
# Code-block preferences
|
||||||
csharp_prefer_braces = true:silent
|
csharp_prefer_braces = true:silent
|
||||||
|
@ -177,9 +188,9 @@ csharp_preserve_single_line_statements = false
|
||||||
|
|
||||||
# Naming rules
|
# Naming rules
|
||||||
|
|
||||||
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = suggestion
|
||||||
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
|
||||||
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase
|
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = IPascalCase
|
||||||
|
|
||||||
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||||
|
@ -236,28 +247,22 @@ dotnet_naming_style.IPascalCase.required_suffix =
|
||||||
dotnet_naming_style.IPascalCase.word_separator =
|
dotnet_naming_style.IPascalCase.word_separator =
|
||||||
dotnet_naming_style.IPascalCase.capitalization = pascal_case
|
dotnet_naming_style.IPascalCase.capitalization = pascal_case
|
||||||
|
|
||||||
# TODO:
|
# Other settings
|
||||||
# .NET 8 migration (new warnings are caused by the NET 8 C# compiler and analyzer)
|
csharp_style_prefer_top_level_statements = true:suggestion
|
||||||
# The following info messages might need to be fixed in the source code instead of hiding the actual message
|
csharp_style_prefer_primary_constructors = false:suggestion
|
||||||
# Without the following lines, dotnet format would fail
|
csharp_prefer_system_threading_lock = true:suggestion
|
||||||
# Disable "Collection initialization can be simplified"
|
|
||||||
|
|
||||||
|
# Analyzers
|
||||||
|
dotnet_diagnostic.CA1069.severity = none # CA1069: Enums values should not be duplicated
|
||||||
|
# Disable Collection initialization can be simplified
|
||||||
dotnet_diagnostic.IDE0028.severity = none
|
dotnet_diagnostic.IDE0028.severity = none
|
||||||
dotnet_diagnostic.IDE0300.severity = none
|
dotnet_diagnostic.IDE0300.severity = none
|
||||||
dotnet_diagnostic.IDE0301.severity = none
|
dotnet_diagnostic.IDE0301.severity = none
|
||||||
dotnet_diagnostic.IDE0302.severity = none
|
dotnet_diagnostic.IDE0302.severity = none
|
||||||
dotnet_diagnostic.IDE0305.severity = none
|
dotnet_diagnostic.IDE0305.severity = none
|
||||||
# Disable "'new' expression can be simplified"
|
dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
|
||||||
dotnet_diagnostic.IDE0090.severity = none
|
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
|
||||||
# Disable "Use primary constructor"
|
|
||||||
dotnet_diagnostic.IDE0290.severity = none
|
|
||||||
# Disable "Member '' does not access instance data and can be marked as static"
|
|
||||||
dotnet_diagnostic.CA1822.severity = none
|
|
||||||
# Disable "Change type of field '' from '' to '' for improved performance"
|
|
||||||
dotnet_diagnostic.CA1859.severity = none
|
|
||||||
# Disable "Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array"
|
|
||||||
dotnet_diagnostic.CA1861.severity = none
|
|
||||||
# Disable "Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'"
|
|
||||||
dotnet_diagnostic.CA1862.severity = none
|
|
||||||
|
|
||||||
[src/Ryujinx/UI/ViewModels/**.cs]
|
[src/Ryujinx/UI/ViewModels/**.cs]
|
||||||
# Disable "mark members as static" rule for ViewModels
|
# Disable "mark members as static" rule for ViewModels
|
||||||
|
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -22,7 +22,7 @@ body:
|
||||||
id: log
|
id: log
|
||||||
attributes:
|
attributes:
|
||||||
label: Log file
|
label: Log file
|
||||||
description: A log file will help our developers to better diagnose and fix the issue.
|
description: "A log file will help our developers to better diagnose and fix the issue. UPLOAD THE FILE. DO NOT COPY AND PASTE THE FILE'S CONTENT."
|
||||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
40
.github/dependabot.yml
vendored
40
.github/dependabot.yml
vendored
|
@ -1,40 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
labels:
|
|
||||||
- "infra"
|
|
||||||
reviewers:
|
|
||||||
- TSRBerry
|
|
||||||
commit-message:
|
|
||||||
prefix: "ci"
|
|
||||||
|
|
||||||
- package-ecosystem: nuget
|
|
||||||
directory: /
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
labels:
|
|
||||||
- "infra"
|
|
||||||
reviewers:
|
|
||||||
- TSRBerry
|
|
||||||
commit-message:
|
|
||||||
prefix: nuget
|
|
||||||
groups:
|
|
||||||
Avalonia:
|
|
||||||
patterns:
|
|
||||||
- "*Avalonia*"
|
|
||||||
Silk.NET:
|
|
||||||
patterns:
|
|
||||||
- "Silk.NET*"
|
|
||||||
OpenTK:
|
|
||||||
patterns:
|
|
||||||
- "OpenTK*"
|
|
||||||
SixLabors:
|
|
||||||
patterns:
|
|
||||||
- "SixLabors*"
|
|
||||||
NUnit:
|
|
||||||
patterns:
|
|
||||||
- "NUnit*"
|
|
14
.github/labeler.yml
vendored
14
.github/labeler.yml
vendored
|
@ -18,6 +18,10 @@ gpu:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
||||||
|
|
||||||
|
'graphics-backend:metal':
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
|
||||||
|
|
||||||
gui:
|
gui:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
||||||
|
@ -32,4 +36,12 @@ kernel:
|
||||||
|
|
||||||
infra:
|
infra:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props']
|
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props', 'src/Ryujinx.BuildValidationTasks/**']
|
||||||
|
|
||||||
|
documentation:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: 'docs/**'
|
||||||
|
|
||||||
|
ldn:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: 'src/Ryujinx.HLE/HOS/Services/Ldn/**'
|
||||||
|
|
63
.github/workflows/build.yml
vendored
63
.github/workflows/build.yml
vendored
|
@ -7,6 +7,7 @@ env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2.0"
|
RYUJINX_BASE_VERSION: "1.2.0"
|
||||||
|
RELEASE: 0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
@ -18,6 +19,7 @@ jobs:
|
||||||
configuration: [Debug, Release]
|
configuration: [Debug, Release]
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
- { name: osx-x64, os: macos-13, zip_os_name: osx_x64 }
|
- { name: osx-x64, os: macos-13, zip_os_name: osx_x64 }
|
||||||
|
@ -60,19 +62,45 @@ jobs:
|
||||||
if: matrix.platform.name != 'linux-arm64'
|
if: matrix.platform.name != 'linux-arm64'
|
||||||
|
|
||||||
- name: Publish Ryujinx
|
- name: Publish Ryujinx
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
- name: Publish Ryujinx.Headless.SDL2
|
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||||
|
|
||||||
- name: Set executable bit
|
- name: Set executable bit
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||||
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
|
|
||||||
|
- name: Build AppImage
|
||||||
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
|
||||||
|
sudo apt install -y zsync desktop-file-utils appstream
|
||||||
|
|
||||||
|
mkdir -p tools
|
||||||
|
export PATH="$PATH:$(readlink -f tools)"
|
||||||
|
|
||||||
|
# Setup appimagetool
|
||||||
|
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
chmod +x tools/appimagetool
|
||||||
|
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
|
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
|
ARCH_NAME=x64
|
||||||
|
export ARCH=x86_64
|
||||||
|
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
|
ARCH_NAME=arm64
|
||||||
|
export ARCH=aarch64
|
||||||
|
else
|
||||||
|
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
|
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
@ -80,12 +108,12 @@ jobs:
|
||||||
path: publish
|
path: publish
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
- name: Upload Ryujinx (AppImage) artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
with:
|
with:
|
||||||
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
||||||
path: publish_sdl2_headless
|
path: publish_appimage
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
name: macOS Universal (${{ matrix.configuration }})
|
name: macOS Universal (${{ matrix.configuration }})
|
||||||
|
@ -102,11 +130,11 @@ jobs:
|
||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Setup LLVM 14
|
- name: Setup LLVM 17
|
||||||
run: |
|
run: |
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 14
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install rcodesign
|
- name: Install rcodesign
|
||||||
run: |
|
run: |
|
||||||
|
@ -132,20 +160,9 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
path: "publish/*.tar.gz"
|
path: "publish/*.tar.gz"
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
|
||||||
path: "publish_headless/*.tar.gz"
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
|
|
249
.github/workflows/canary.yml
vendored
Normal file
249
.github/workflows/canary.yml
vendored
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
name: Canary release job
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs: {}
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/**'
|
||||||
|
- 'docs/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- '*.yml'
|
||||||
|
- '*.json'
|
||||||
|
- '*.config'
|
||||||
|
- '*.md'
|
||||||
|
|
||||||
|
concurrency: release
|
||||||
|
|
||||||
|
env:
|
||||||
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
RYUJINX_BASE_VERSION: "1.3"
|
||||||
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
||||||
|
RELEASE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Release for ${{ matrix.platform.name }}
|
||||||
|
runs-on: ${{ matrix.platform.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Overwrite csc problem matcher
|
||||||
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Configure for release
|
||||||
|
run: |
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Create output dir
|
||||||
|
run: "mkdir release_output"
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: |
|
||||||
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
|
|
||||||
|
- name: Packing Windows builds
|
||||||
|
if: matrix.platform.os == 'windows-latest'
|
||||||
|
run: |
|
||||||
|
pushd publish
|
||||||
|
rm libarmeilleure-jitsupport.dylib
|
||||||
|
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
|
popd
|
||||||
|
|
||||||
|
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
|
||||||
|
|
||||||
|
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Packing Linux builds
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
pushd publish
|
||||||
|
rm libarmeilleure-jitsupport.dylib
|
||||||
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
|
popd
|
||||||
|
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Build AppImage (Linux)
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
|
||||||
|
sudo apt install -y zsync desktop-file-utils appstream
|
||||||
|
|
||||||
|
mkdir -p tools
|
||||||
|
export PATH="$PATH:$(readlink -f tools)"
|
||||||
|
|
||||||
|
# Setup appimagetool
|
||||||
|
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
chmod +x tools/appimagetool
|
||||||
|
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
|
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
|
ARCH_NAME=x64
|
||||||
|
export ARCH=x86_64
|
||||||
|
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
|
ARCH_NAME=arm64
|
||||||
|
export ARCH=aarch64
|
||||||
|
else
|
||||||
|
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
|
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
pushd publish_appimage
|
||||||
|
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
|
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
|
popd
|
||||||
|
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
macos_release:
|
||||||
|
name: Release MacOS universal
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Setup LLVM 17
|
||||||
|
run: |
|
||||||
|
wget https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x llvm.sh
|
||||||
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install rcodesign
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
|
||||||
|
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
|
||||||
|
rm apple-codesign.tar.gz
|
||||||
|
mv rcodesign $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Configure for release
|
||||||
|
run: |
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Publish macOS Ryujinx
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
|
||||||
|
|
||||||
|
create_gitlab_release:
|
||||||
|
name: Create GitLab Release
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs:
|
||||||
|
- macos_release
|
||||||
|
- release
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create tag
|
||||||
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}"
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=CreateReleaseFromGenericPackageFiles "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|main|Canary ${{ steps.version_info.outputs.build_version }}|**Full Changelog:** [${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
|
||||||
|
|
||||||
|
- name: Send notification webhook
|
||||||
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||||
|
|
||||||
|
- name: Notify update server of new builds
|
||||||
|
run: |
|
||||||
|
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
51
.github/workflows/checks.yml
vendored
51
.github/workflows/checks.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Perform checks
|
name: Build PR
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -20,55 +20,6 @@ concurrency:
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
global-json-file: global.json
|
|
||||||
|
|
||||||
- name: Overwrite csc problem matcher
|
|
||||||
run: echo "::add-matcher::.github/csc.json"
|
|
||||||
|
|
||||||
- run: dotnet restore
|
|
||||||
|
|
||||||
- name: Print dotnet format version
|
|
||||||
run: dotnet format --version
|
|
||||||
|
|
||||||
- name: Run dotnet format whitespace
|
|
||||||
run: |
|
|
||||||
dotnet format whitespace --verify-no-changes --report ./whitespace-report.json -v d
|
|
||||||
|
|
||||||
# For some unknown reason this step sometimes fails with exit code 139 (segfault?),
|
|
||||||
# so in that case we'll try again (3 tries max).
|
|
||||||
- name: Run dotnet format style
|
|
||||||
uses: TSRBerry/unstable-commands@v1
|
|
||||||
with:
|
|
||||||
commands: dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d
|
|
||||||
timeout-minutes: 5
|
|
||||||
retry-codes: 139
|
|
||||||
|
|
||||||
# For some unknown reason this step sometimes fails with exit code 139 (segfault?),
|
|
||||||
# so in that case we'll try again (3 tries max).
|
|
||||||
- name: Run dotnet format analyzers
|
|
||||||
uses: TSRBerry/unstable-commands@v1
|
|
||||||
with:
|
|
||||||
commands: dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d
|
|
||||||
timeout-minutes: 5
|
|
||||||
retry-codes: 139
|
|
||||||
|
|
||||||
- name: Upload report
|
|
||||||
if: failure()
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: dotnet-format
|
|
||||||
path: ./*-report.json
|
|
||||||
|
|
||||||
pr_build:
|
pr_build:
|
||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
needs: format
|
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
224
.github/workflows/debug_release.yml
vendored
Normal file
224
.github/workflows/debug_release.yml
vendored
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
name: Release job (Debug)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs: {}
|
||||||
|
|
||||||
|
concurrency: release
|
||||||
|
|
||||||
|
env:
|
||||||
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
RYUJINX_BASE_VERSION: "1.3"
|
||||||
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
|
RELEASE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Release for ${{ matrix.platform.name }}
|
||||||
|
runs-on: ${{ matrix.platform.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Overwrite csc problem matcher
|
||||||
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Configure for release
|
||||||
|
run: |
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Create output dir
|
||||||
|
run: "mkdir release_output"
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: |
|
||||||
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
|
|
||||||
|
- name: Packing Windows builds
|
||||||
|
if: matrix.platform.os == 'windows-latest'
|
||||||
|
run: |
|
||||||
|
pushd publish
|
||||||
|
rm libarmeilleure-jitsupport.dylib
|
||||||
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
|
popd
|
||||||
|
|
||||||
|
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
|
||||||
|
|
||||||
|
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Packing Linux builds
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
pushd publish
|
||||||
|
rm libarmeilleure-jitsupport.dylib
|
||||||
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
|
popd
|
||||||
|
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Build AppImage (Linux)
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
|
|
||||||
|
sudo apt install -y zsync desktop-file-utils appstream
|
||||||
|
|
||||||
|
mkdir -p tools
|
||||||
|
export PATH="$PATH:$(readlink -f tools)"
|
||||||
|
|
||||||
|
# Setup appimagetool
|
||||||
|
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
chmod +x tools/appimagetool
|
||||||
|
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
|
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
|
ARCH_NAME=x64
|
||||||
|
export ARCH=x86_64
|
||||||
|
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
|
ARCH_NAME=arm64
|
||||||
|
export ARCH=aarch64
|
||||||
|
else
|
||||||
|
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
|
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
pushd publish_appimage
|
||||||
|
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
|
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
|
popd
|
||||||
|
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
macos_release:
|
||||||
|
name: Release MacOS universal
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Setup LLVM 17
|
||||||
|
run: |
|
||||||
|
wget https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x llvm.sh
|
||||||
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install rcodesign
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
|
||||||
|
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
|
||||||
|
rm apple-codesign.tar.gz
|
||||||
|
mv rcodesign $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Configure for release
|
||||||
|
run: |
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Publish macOS Ryujinx
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
|
||||||
|
|
||||||
|
create_gitlab_release:
|
||||||
|
name: Create GitLab Release
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs:
|
||||||
|
- macos_release
|
||||||
|
- release
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|test|THIS IS NOT INTENDED FOR END USER USAGE"
|
14
.github/workflows/nightly_pr_comment.yml
vendored
14
.github/workflows/nightly_pr_comment.yml
vendored
|
@ -2,7 +2,7 @@ name: Comment PR artifacts links
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_run:
|
||||||
workflows: ['Perform checks']
|
workflows: ['Build PR']
|
||||||
types: [completed]
|
types: [completed]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -38,20 +38,16 @@ jobs:
|
||||||
return core.error(`No artifacts found`);
|
return core.error(`No artifacts found`);
|
||||||
}
|
}
|
||||||
let body = `Download the artifacts for this pull request:\n`;
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less (SDL2)</summary>\n`;
|
|
||||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||||
for (const art of artifacts) {
|
for (const art of artifacts) {
|
||||||
if(art.name.includes('Debug')) {
|
const url = `https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip`;
|
||||||
hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
if (art.name.includes('Debug')) {
|
||||||
} else if(art.name.includes('sdl2-ryujinx-headless')) {
|
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||||
hidden_headless_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
|
||||||
} else {
|
} else {
|
||||||
body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
body += `\n* [${art.name}](${url})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hidden_headless_artifacts += `\n</details>`;
|
|
||||||
hidden_debug_artifacts += `\n</details>`;
|
hidden_debug_artifacts += `\n</details>`;
|
||||||
body += hidden_headless_artifacts;
|
|
||||||
body += hidden_debug_artifacts;
|
body += hidden_debug_artifacts;
|
||||||
|
|
||||||
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||||
|
|
218
.github/workflows/release.yml
vendored
218
.github/workflows/release.yml
vendored
|
@ -3,57 +3,17 @@ name: Release job
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs: {}
|
inputs: {}
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
paths-ignore:
|
|
||||||
- '.github/**'
|
|
||||||
- '*.yml'
|
|
||||||
- '*.json'
|
|
||||||
- '*.config'
|
|
||||||
- '*.md'
|
|
||||||
|
|
||||||
concurrency: release
|
concurrency: release
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.3"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "master"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
RELEASE: 1
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tag:
|
|
||||||
name: Create tag
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Get version info
|
|
||||||
id: version_info
|
|
||||||
run: |
|
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Create tag
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
github.rest.git.createRef({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
|
||||||
sha: context.sha
|
|
||||||
})
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
uses: ncipollo/release-action@v1
|
|
||||||
with:
|
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
|
||||||
omitBodyDuringUpdate: true
|
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
|
||||||
token: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Release for ${{ matrix.platform.name }}
|
name: Release for ${{ matrix.platform.name }}
|
||||||
runs-on: ${{ matrix.platform.os }}
|
runs-on: ${{ matrix.platform.os }}
|
||||||
|
@ -61,6 +21,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
steps:
|
steps:
|
||||||
|
@ -77,6 +38,7 @@ jobs:
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
@ -85,8 +47,6 @@ jobs:
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
|
||||||
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
@ -95,55 +55,91 @@ jobs:
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
|
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_ava
|
pushd publish
|
||||||
cp publish/Ryujinx.exe publish/Ryujinx.Ava.exe
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
|
||||||
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
|
||||||
popd
|
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_ava
|
pushd publish
|
||||||
cp publish/Ryujinx publish/Ryujinx.Ava
|
rm libarmeilleure-jitsupport.dylib
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava publish/Ryujinx
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
|
||||||
tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Build AppImage (Linux)
|
||||||
uses: ncipollo/release-action@v1
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
with:
|
run: |
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
|
||||||
omitBodyDuringUpdate: true
|
sudo apt install -y zsync desktop-file-utils appstream
|
||||||
allowUpdates: true
|
|
||||||
replacesArtifacts: true
|
mkdir -p tools
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
export PATH="$PATH:$(readlink -f tools)"
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
|
||||||
token: ${{ secrets.RELEASE_TOKEN }}
|
# Setup appimagetool
|
||||||
|
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
chmod +x tools/appimagetool
|
||||||
|
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
|
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
|
ARCH_NAME=x64
|
||||||
|
export ARCH=x86_64
|
||||||
|
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
|
ARCH_NAME=arm64
|
||||||
|
export ARCH=aarch64
|
||||||
|
else
|
||||||
|
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
|
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
|
||||||
|
pushd publish_appimage
|
||||||
|
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
|
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
|
popd
|
||||||
|
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -151,11 +147,21 @@ jobs:
|
||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Setup LLVM 15
|
- name: Setup LLVM 17
|
||||||
run: |
|
run: |
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 15
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
|
- name: Install GitLabCli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install rcodesign
|
- name: Install rcodesign
|
||||||
run: |
|
run: |
|
||||||
|
@ -172,6 +178,7 @@ jobs:
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Configure for release
|
- name: Configure for release
|
||||||
|
@ -179,28 +186,49 @@ jobs:
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
|
||||||
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx
|
- name: Publish macOS Ryujinx
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
create_gitlab_release:
|
||||||
|
name: Create GitLab Release
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs:
|
||||||
|
- macos_release
|
||||||
|
- release
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Install GitLabCli
|
||||||
uses: ncipollo/release-action@v1
|
run: |
|
||||||
with:
|
mkdir -p $HOME/.bin
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
||||||
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
chmod +x gli
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
mv gli $HOME/.bin/
|
||||||
omitBodyDuringUpdate: true
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
allowUpdates: true
|
env:
|
||||||
replacesArtifacts: true
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
- name: Create release
|
||||||
token: ${{ secrets.RELEASE_TOKEN }}
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|${{ steps.version_info.outputs.build_version }}|msd:${{ steps.version_info.outputs.build_version }}"
|
||||||
|
|
||||||
|
- name: Send notification webhook
|
||||||
|
run: |
|
||||||
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||||
|
|
||||||
|
- name: Notify update server of new builds
|
||||||
|
run: |
|
||||||
|
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
||||||
|
|
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -16,6 +16,8 @@ x64/
|
||||||
build/
|
build/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
|
AppDir/
|
||||||
|
publish_appimage/
|
||||||
|
|
||||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||||
!packages/*/build/
|
!packages/*/build/
|
||||||
|
@ -173,3 +175,10 @@ PublishProfiles/
|
||||||
|
|
||||||
# Glade backup files
|
# Glade backup files
|
||||||
*.glade~
|
*.glade~
|
||||||
|
|
||||||
|
# Ignore MacOS Attribute Files
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Ignore distribution build files
|
||||||
|
distribution/macos/temp/
|
||||||
|
distribution/macos/output/
|
||||||
|
|
18
BuildAndPushLibraries.sh
Normal file
18
BuildAndPushLibraries.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
function pub {
|
||||||
|
dotnet publish -c release
|
||||||
|
}
|
||||||
|
|
||||||
|
function package {
|
||||||
|
cd src/$1
|
||||||
|
pub
|
||||||
|
mv bin/Release/$1.1.0.0.nupkg ../../pkgs/$1.1.0.0.nupkg
|
||||||
|
cd ../../
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf pkgs
|
||||||
|
mkdir pkgs
|
||||||
|
|
||||||
|
package ARMeilleure
|
||||||
|
package Ryujinx.Memory
|
||||||
|
|
||||||
|
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs
|
254
CHANGELOG.md
Normal file
254
CHANGELOG.md
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
# Ryujinx Changelog
|
||||||
|
|
||||||
|
All updates to this Ryujinx branch will be documented in this file.
|
||||||
|
|
||||||
|
## [1.3.2](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.2>) - 2025-06-09
|
||||||
|
|
||||||
|
## [1.3.1](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.1>) - 2025-04-23
|
||||||
|
|
||||||
|
## [1.2.86](<https://github.com/Ryubing/Stable-Releases/releases/tag/1.2.86>) - 2025-03-13
|
||||||
|
|
||||||
|
## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16
|
||||||
|
|
||||||
|
## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22
|
||||||
|
|
||||||
|
## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19
|
||||||
|
|
||||||
|
## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19
|
||||||
|
A list of notable changes can be found on the release linked in the version number above.
|
||||||
|
|
||||||
|
Additionally, 1.2.74 & 75 were fixes for uploading Windows build artifacts.
|
||||||
|
|
||||||
|
1.2.76 fixes a rare crash on startup.
|
||||||
|
|
||||||
|
## [1.2.72](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.72>) - 2024-11-03
|
||||||
|
PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://github.com/GreemDev/Ryujinx/pull/164>), [#139](<https://github.com/GreemDev/Ryujinx/pull/139>)
|
||||||
|
### HLE:
|
||||||
|
- Add DebugMouse HID device.
|
||||||
|
- Fixes "Clock Tower Rewind" crashing while loading.
|
||||||
|
### Audio:
|
||||||
|
- Fix index bounds check in GetCoefficientAtIndex.
|
||||||
|
- Fixes crashing in Super Mario Party Jamboree.
|
||||||
|
### misc:
|
||||||
|
- Update macOS distribution .icns.
|
||||||
|
|
||||||
|
## [1.2.69](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.69>) - 2024-11-01
|
||||||
|
### Infra:
|
||||||
|
- Compile the native libraries into the Ryujinx executable.
|
||||||
|
- Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only)
|
||||||
|
### Misc:
|
||||||
|
- Remove custom themes in config.
|
||||||
|
- This is a leftover from the GTK UI, as Avalonia does not have custom themes.
|
||||||
|
- Replace "" with `string.Empty`.
|
||||||
|
- Code cleanups & simplifications.
|
||||||
|
|
||||||
|
## [1.2.67](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.67>) - 2024-11-01
|
||||||
|
PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github.com/GreemDev/Ryujinx/pull/135>)
|
||||||
|
|
||||||
|
### GUI:
|
||||||
|
- Set UseFloatingWatermark to false when watermark is empty
|
||||||
|
- Should prevent the text prompt box from having weird jumpy behavior.
|
||||||
|
### GPU:
|
||||||
|
- Increase the amount of VRAM cache available for textures based on selected DRAM amount.
|
||||||
|
### Misc:
|
||||||
|
- Fix homebrew loading.
|
||||||
|
|
||||||
|
|
||||||
|
## [1.2.64](https://github.com/GreemDev/Ryujinx/releases/tag/1.2.64) - 2024-10-30
|
||||||
|
PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com/GreemDev/Ryujinx/pull/96), [#97](https://github.com/GreemDev/Ryujinx/pull/97), [#101](https://github.com/GreemDev/Ryujinx/pull/101), [#103](https://github.com/GreemDev/Ryujinx/pull/103)
|
||||||
|
### GUI:
|
||||||
|
- Option to show classic-style title bar. Requires restart of emulator to take effect.
|
||||||
|
- This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place.
|
||||||
|
### i18n:
|
||||||
|
- it_IT:
|
||||||
|
- Add missing Italian strings.
|
||||||
|
- pt_BR:
|
||||||
|
- Add missing Brazilian Portuguese strings.
|
||||||
|
- fr_FR:
|
||||||
|
- Fix some French strings.
|
||||||
|
### MISC:
|
||||||
|
- Higher-res logo.
|
||||||
|
|
||||||
|
## 1.2.59 - 2024-10-27
|
||||||
|
|
||||||
|
PRs [#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)
|
||||||
|
### i18n:
|
||||||
|
- fr_FR:
|
||||||
|
- Add missing translations for new features & fix a couple wrong ones.
|
||||||
|
- Fix Ignore Missing Services / Ignore Applet tooltip.
|
||||||
|
|
||||||
|
## 1.2.57 - 2024-10-27
|
||||||
|
PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com/GreemDev/Ryujinx/pull/42)
|
||||||
|
### GUI:
|
||||||
|
- Automatically remove invalid DLC & updates as part of autoload.
|
||||||
|
- Added Thai translation for Ignore Applet hover tooltip.
|
||||||
|
### INPUT:
|
||||||
|
- When using multiple gamepads, when reconnecting they will no longer be mixed up between players.
|
||||||
|
|
||||||
|
## 1.2.50 - 2024-10-25
|
||||||
|
### GUI:
|
||||||
|
- Fix crash when using "delete all" button in mod manager.
|
||||||
|
### Updater:
|
||||||
|
- Remove Avalonia migration code.
|
||||||
|
### MISC:
|
||||||
|
- Replace references to IntPtr/UIntPtr to nint/nuint.
|
||||||
|
|
||||||
|
## 1.2.45 - 2024-10-25
|
||||||
|
### GUI:
|
||||||
|
- Added program icon to windows other than the main.
|
||||||
|
- Reference translations added in the last version.
|
||||||
|
- Shader compile counter is now translated.
|
||||||
|
### RPC:
|
||||||
|
- Added SONIC X SHADOW GENERATIONS asset image.
|
||||||
|
### MISC:
|
||||||
|
- Code cleanup.
|
||||||
|
|
||||||
|
## 1.2.44 - 2024-10-25
|
||||||
|
PR [#59](https://github.com/GreemDev/Ryujinx/pull/59)
|
||||||
|
### GUI:
|
||||||
|
- Add descriptions for "ignoring applet" translated into other languages.
|
||||||
|
|
||||||
|
NOTE: The translation isn't referenced in the code yet, it will be in the next update. These are just the translations.
|
||||||
|
|
||||||
|
## Hotfix: 1.2.43 - 2024-10-24
|
||||||
|
### GUI:
|
||||||
|
- Do not enable Ignore Applet by default when upgrading config version.
|
||||||
|
|
||||||
|
## 1.2.42 - 2024-10-24
|
||||||
|
Sources:
|
||||||
|
|
||||||
|
Init function: https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9
|
||||||
|
|
||||||
|
Shader counter: https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357
|
||||||
|
|
||||||
|
Thanks MutantAura :D
|
||||||
|
### GUI:
|
||||||
|
- Implement shader compile counter (currently not translated, will change, need to pull changes.)
|
||||||
|
- Remove graphics backend / GPU name event logic in favor of a single init function.
|
||||||
|
|
||||||
|
## 1.2.41 - 2024-10-24
|
||||||
|
PR [#54](https://github.com/GreemDev/Ryujinx/pull/54)
|
||||||
|
|
||||||
|
Thanks Whitescatz!
|
||||||
|
### i18n:
|
||||||
|
- th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar.
|
||||||
|
|
||||||
|
## 1.2.40 - 2024-10-23
|
||||||
|
PR [#40](https://github.com/GreemDev/Ryujinx/pull/40)
|
||||||
|
|
||||||
|
Thanks Вова С!
|
||||||
|
### GUI:
|
||||||
|
- Add option to ignore controller applet upon start.
|
||||||
|
|
||||||
|
*This option is under the hacks section for a reason; it ignores intended behavior. Use with caution.
|
||||||
|
|
||||||
|
## 1.2.39 - 2024-10-23
|
||||||
|
### MISC:
|
||||||
|
- Null-coalesce autoloaddirs on config load.
|
||||||
|
- Should prevent crashing on config loads in some circumstances.
|
||||||
|
|
||||||
|
## 1.2.38 - 2024-10-23
|
||||||
|
PR [#51](https://github.com/GreemDev/Ryujinx/pull/51)
|
||||||
|
### i18n:
|
||||||
|
- zh_CH (Simplified Chinese): Add some missing translations.
|
||||||
|
|
||||||
|
## 1.2.37 - 2024-10-23
|
||||||
|
PR [#37](https://github.com/GreemDev/Ryujinx/pull/37)
|
||||||
|
|
||||||
|
Thanks Last Breath!
|
||||||
|
### GUI:
|
||||||
|
- Set the default controller to the Pro Controller.
|
||||||
|
|
||||||
|
## 1.2.36 - 2024-10-21
|
||||||
|
PR [#30](https://github.com/GreemDev/Ryujinx/pull/30)
|
||||||
|
### GUI:
|
||||||
|
- Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file.
|
||||||
|
|
||||||
|
## 1.2.35 - 2024-10-21
|
||||||
|
PR [#32](https://github.com/GreemDev/Ryujinx/pull/32)
|
||||||
|
### GUI:
|
||||||
|
- Replace "expand DRAM" option with a DRAM size dropdown.
|
||||||
|
- Allows for using mods which require a ridiculous amount of memory to allocate from.
|
||||||
|
|
||||||
|
## 1.2.34 - 2024-10-21
|
||||||
|
PR [#29](https://github.com/GreemDev/Ryujinx/pull/29)
|
||||||
|
### GUI:
|
||||||
|
- Fix duplicate controller names when 2 controllers of the same type are connected.
|
||||||
|
### INPUT:
|
||||||
|
- Fix invert x, y, and rotate when mapping physical left stick to logical right stick and vice versa.
|
||||||
|
|
||||||
|
## 1.2.32-1.2.33 - 2024-10-21
|
||||||
|
### i18n:
|
||||||
|
- fr_FR: Added missing strings and general improvements.
|
||||||
|
- Improve French translation clarity & add missing translations by Nebroc351, helped by Fredy27 in the Discord.
|
||||||
|
|
||||||
|
## 1.2.31 - 2024-10-21
|
||||||
|
### GUI:
|
||||||
|
- Revert maximized = fullscreen change.
|
||||||
|
- Fixes fullscreen not hiding the Windows taskbar.
|
||||||
|
|
||||||
|
## 1.2.30 - 2024-10-19
|
||||||
|
### GUI:
|
||||||
|
- Reload game list on locale change.
|
||||||
|
- Add keybinds to useful things (namely opening Amiibo scan window (Ctrl + A) and the scan button (Enter)).
|
||||||
|
- Reset RPC state when AppHost stops.
|
||||||
|
|
||||||
|
### MISC:
|
||||||
|
- XML & code cleanups.
|
||||||
|
|
||||||
|
## 1.2.29 - 2024-10-19
|
||||||
|
### GUI:
|
||||||
|
- Remove references to ryujinx.org in the localization files.
|
||||||
|
- Switch from downloading amiibo.ryujinx.org to just referencing a file in the repo & images in the repo, under assets/amiibo.
|
||||||
|
|
||||||
|
This fork is now entirely independent of the existing Ryujinx infrastructure, and as such the Amiibo features will continue to work in my version when they break in the mainline version.
|
||||||
|
|
||||||
|
## 1.2.28 - 2024-10-17
|
||||||
|
### GUI:
|
||||||
|
- Fix dialog popups doubling the window controls and laying text over the menu bar.
|
||||||
|
|
||||||
|
## 1.2.26 - 2024-10-17
|
||||||
|
### I18n:
|
||||||
|
Added Low-power PPTC mode strings to the translation files.
|
||||||
|
### GUI:
|
||||||
|
- Remove OS-provided title bar and put the Ryujinx logo next to "File" in the menu bar.
|
||||||
|
- What was in the title bar, Ryujinx version & current game information, is still visible by hovering the Ryujinx icon.
|
||||||
|
- Added icons to many actions in dropdown menus.
|
||||||
|
### RPC:
|
||||||
|
- Added Kirby and the Forgotten Land, Elder Scrolls V Skyrim, and Hyrule Warriors: Age of Calamity to the RPC assets.
|
||||||
|
|
||||||
|
## 1.2.25 - 2024-10-14
|
||||||
|
### CPU:
|
||||||
|
- Add low-power PPTC mode.
|
||||||
|
- Specifically, this setting causes the core count to get reduced by two-thirds, for lower-power but still fast loading if desired, and for unstable CPUs.
|
||||||
|
|
||||||
|
## 1.2.24 - 2024-10-14
|
||||||
|
### SDL:
|
||||||
|
- Move Mouse & MouseDriver to Input project, instead of Headless.
|
||||||
|
|
||||||
|
## 1.2.22 - 2024-10-12
|
||||||
|
### GUI/RPC:
|
||||||
|
- Added RDR, Luigi's Mansion 2 HD & 3 asset images.
|
||||||
|
### MISC:
|
||||||
|
- Minor code cleanups & improvements.
|
||||||
|
- Removed duplicate executable in the release bundle (leftovers from GTK & Avalonia dual releases).
|
||||||
|
- Removed Avalonia test release bundle, which was kept in Ryujinx for the OG Avalonia testers. That doesn't apply to this fork, so it's removed.
|
||||||
|
|
||||||
|
## 1.2.21 - 2024-10-11
|
||||||
|
### GUI/RPC:
|
||||||
|
- Add game version string when hovering large image asset.
|
||||||
|
- Add version information about this fork to the Ryujinx logo (big when in main menu, small when in game) when hovering.
|
||||||
|
|
||||||
|
## 1.2.20 - 2024-10-11
|
||||||
|
### MISC:
|
||||||
|
- Code cleanups & remove references to Ryujinx Patreon & Twitter.
|
||||||
|
### GUI:
|
||||||
|
- Add more Discord presence assets.
|
||||||
|
|
||||||
|
## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11
|
||||||
|
### GUI/INFRA/MISC:
|
||||||
|
- Remove GTK UI.
|
||||||
|
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)).
|
||||||
|
- Changed executable icon to rainbow logo.
|
||||||
|
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
|
||||||
|
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.
|
23
COMPILING.md
Normal file
23
COMPILING.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
## Compilation
|
||||||
|
|
||||||
|
Building the project is for users that want to contribute code only.
|
||||||
|
If you wish to build the emulator yourself, follow these steps:
|
||||||
|
|
||||||
|
### Step 1
|
||||||
|
|
||||||
|
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0).
|
||||||
|
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
||||||
|
|
||||||
|
### Step 2
|
||||||
|
|
||||||
|
Either use `git clone https://github.com/Ryubing/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
||||||
|
|
||||||
|
### Step 3
|
||||||
|
|
||||||
|
To build Ryujinx, open a command prompt inside the project directory.
|
||||||
|
You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`.
|
||||||
|
Then type the following command: `dotnet build -c Release -o build`
|
||||||
|
the built files will be found in the newly created build directory.
|
||||||
|
|
||||||
|
Ryujinx system files are stored in the `Ryujinx` folder.
|
||||||
|
This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
|
@ -12,24 +12,15 @@ Please read the entire document before continuing as it can potentially save eve
|
||||||
|
|
||||||
We always welcome bug reports, feature proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible.
|
We always welcome bug reports, feature proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible.
|
||||||
|
|
||||||
### Identify Where to Report
|
|
||||||
|
|
||||||
The Ryujinx codebase is distributed across multiple repositories in the [Ryujinx organization](https://github.com/Ryujinx). Depending on the feedback you might want to file the issue on a different repo. Here are a few common repos:
|
|
||||||
|
|
||||||
* [Ryujinx/Ryujinx](https://github.com/Ryujinx/Ryujinx) Ryujinx core project files.
|
|
||||||
* [Ryujinx/Ryujinx-Games-List](https://github.com/Ryujinx/Ryujinx-Games-List) Ryujinx game compatibility list.
|
|
||||||
* [Ryujinx/Ryujinx-Website](https://github.com/Ryujinx/Ryujinx-Website) Ryujinx website source code.
|
|
||||||
* [Ryujinx/Ryujinx-Ldn-Website](https://github.com/Ryujinx/Ryujinx-Ldn-Website) Ryujinx LDN website source code.
|
|
||||||
|
|
||||||
### Finding Existing Issues
|
### Finding Existing Issues
|
||||||
|
|
||||||
Before filing a new issue, please search our [open issues](https://github.com/Ryujinx/Ryujinx/issues) to check if it already exists.
|
Before filing a new issue, please search our [open issues](https://github.com/Ryubing/Ryujinx/issues) to check if it already exists.
|
||||||
|
|
||||||
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
|
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
|
||||||
|
|
||||||
### Writing a Good Feature Request
|
### Writing a Good Feature Request
|
||||||
|
|
||||||
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
|
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
|
||||||
|
|
||||||
### Writing a Good Bug Report
|
### Writing a Good Bug Report
|
||||||
|
|
||||||
|
@ -43,13 +34,13 @@ Ideally, a bug report should contain the following information:
|
||||||
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
|
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
|
||||||
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
|
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
|
||||||
|
|
||||||
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
|
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
|
||||||
|
|
||||||
## Contributing Changes
|
## Contributing Changes
|
||||||
|
|
||||||
Project maintainers will merge changes that both improve the project and meet our standards for code quality.
|
Project maintainers will merge changes that both improve the project and meet our standards for code quality.
|
||||||
|
|
||||||
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryujinx/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
|
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryubing/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
|
||||||
|
|
||||||
### DOs and DON'Ts
|
### DOs and DON'Ts
|
||||||
|
|
||||||
|
@ -83,23 +74,23 @@ We use and recommend the following workflow:
|
||||||
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
|
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
|
||||||
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
|
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
|
||||||
4. Make and commit your changes to your branch.
|
4. Make and commit your changes to your branch.
|
||||||
- [Build Instructions](https://github.com/Ryujinx/Ryujinx#building) explains how to build and test.
|
- [Build Instructions](https://github.com/Ryubing/Ryujinx/blob/master/COMPILING.md) explains how to build and test.
|
||||||
- Commit messages should be clear statements of action and intent.
|
- Commit messages should be clear statements of action and intent.
|
||||||
6. Build the repository with your changes.
|
6. Build the repository with your changes.
|
||||||
- Make sure that the builds are clean.
|
- Make sure that the builds are clean.
|
||||||
- Make sure that `dotnet format` has been run and any corrections tested and committed.
|
- Make sure that `dotnet format` has been run and any corrections tested and committed.
|
||||||
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
|
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
|
||||||
- State in the description what issue or improvement your change is addressing.
|
- State in the description what issue or improvement your change is addressing.
|
||||||
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryujinx/Ryujinx/actions) to check for outstanding errors.
|
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryubing/Ryujinx/actions) to check for outstanding errors.
|
||||||
8. Wait for feedback or approval of your changes from the [core development team](https://github.com/orgs/Ryujinx/teams/developers)
|
8. Wait for feedback or approval of your changes from the core development team
|
||||||
- Details about the pull request [review procedure](docs/workflow/ci/pr-guide.md).
|
- Details about the pull request [review procedure](docs/workflow/pr-guide.md).
|
||||||
9. When the team members have signed off, and all checks are green, your PR will be merged.
|
9. When the team members have signed off, and all checks are green, your PR will be merged.
|
||||||
- The next official build will automatically include your change.
|
- The next official build will automatically include your change.
|
||||||
- You can delete the branch you used for making the change.
|
- You can delete the branch you used for making the change.
|
||||||
|
|
||||||
### Good First Issues
|
### Good First Issues
|
||||||
|
|
||||||
The team marks the most straightforward issues as [good first issues](https://github.com/Ryujinx/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
|
The team marks the most straightforward issues as [good first issues](https://github.com/Ryubing/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
|
||||||
|
|
||||||
### Commit Messages
|
### Commit Messages
|
||||||
|
|
||||||
|
@ -122,7 +113,7 @@ Also do your best to factor commits appropriately, not too large with unrelated
|
||||||
|
|
||||||
### PR - CI Process
|
### PR - CI Process
|
||||||
|
|
||||||
The [Ryujinx continuous integration](https://github.com/Ryujinx/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
|
The [Ryujinx continuous integration](https://github.com/Ryubing/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
|
||||||
|
|
||||||
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
|
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
|
||||||
* `dotnet format` has not been run on the PR and has outstanding stylistic issues.
|
* `dotnet format` has not been run on the PR and has outstanding stylistic issues.
|
||||||
|
@ -143,5 +134,5 @@ Ryujinx uses some implementations and frameworks from other projects. The follow
|
||||||
|
|
||||||
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
|
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
|
||||||
- The license of the file is left in-tact.
|
- The license of the file is left in-tact.
|
||||||
- The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryujinx/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.
|
- The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryubing/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.
|
||||||
|
|
||||||
|
|
6
Directory.Build.props
Normal file
6
Directory.Build.props
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -3,23 +3,29 @@
|
||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="11.0.10" />
|
<PackageVersion Include="Avalonia" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.13" />
|
||||||
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.18" />
|
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.19" />
|
||||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.18" />
|
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.19" />
|
||||||
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||||
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.4.0" />
|
||||||
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||||
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="Concentus" Version="2.2.0" />
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||||
|
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||||
<PackageVersion Include="LibHac" Version="0.19.0" />
|
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.0.1" />
|
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||||
|
@ -30,21 +36,27 @@
|
||||||
<PackageVersion Include="OpenTK.Graphics" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Graphics" Version="4.8.2" />
|
||||||
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
|
||||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
||||||
|
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
|
||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
|
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
|
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
|
||||||
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
|
||||||
|
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
|
||||||
<PackageVersion Include="SkiaSharp" Version="2.88.7" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
||||||
<PackageVersion Include="System.Management" Version="8.0.0" />
|
<PackageVersion Include="System.Management" Version="9.0.2" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
137
README.md
137
README.md
|
@ -1,98 +1,66 @@
|
||||||
<h1 align="center">
|
<table align="center">
|
||||||
<br>
|
<tr>
|
||||||
<a href="https://ryujinx.org/"><img src="https://raw.githubusercontent.com/Ryujinx/Ryujinx/master/distribution/misc/Logo.svg" alt="Ryujinx" width="150"></a>
|
<td align="center" width="25%">
|
||||||
<br>
|
<img src="https://raw.githubusercontent.com/Ryubing/Assets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
|
||||||
<b>Ryujinx</b>
|
</td>
|
||||||
<br>
|
<td align="center" width="75%">
|
||||||
<sub><sup><b>(REE-YOU-JINX)</b></sup></sub>
|
|
||||||
<br>
|
# Ryujinx
|
||||||
</h1>
|
|
||||||
|
[](https://update.ryujinx.app/latest/stable)
|
||||||
|
[](https://update.ryujinx.app/latest/canary)
|
||||||
|
<br>
|
||||||
|
<a href="https://discord.gg/PEuzjrFXUA">
|
||||||
|
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
||||||
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
||||||
It was written from scratch and development on the project began in September 2017.
|
It was written from scratch and development on the project began in September 2017.
|
||||||
Ryujinx is available on Github under the <a href="https://github.com/Ryujinx/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
|
Ryujinx is available on a self-managed GitLab instance under the <a href="https://git.ryujinx.app/ryubing/ryujinx/-/blob/master/LICENSE.txt?ref_type=heads" target="_blank">MIT license</a>.
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
On October 1st 2024, Ryujinx was discontinued as the creator was forced to abandon the project.
|
||||||
|
<br>
|
||||||
|
This fork is intended to be a QoL uplift for existing Ryujinx users.
|
||||||
|
<br>
|
||||||
|
This is not a Ryujinx revival project. This is not a Phoenix project.
|
||||||
|
<br>
|
||||||
|
Guides and documentation can be found on the <a href="https://git.ryujinx.app/groups/ryubing/-/wikis/home">Wiki tab</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/Ryujinx/Ryujinx/actions/workflows/release.yml">
|
<img src="https://git.ryujinx.app/ryubing/ryujinx/-/raw/master/docs/shell.png?ref_type=heads&inline=false" alt="Ryujinx example">
|
||||||
<img src="https://github.com/Ryujinx/Ryujinx/actions/workflows/release.yml/badge.svg"
|
|
||||||
alt="">
|
|
||||||
</a>
|
|
||||||
<a href="https://crwd.in/ryujinx">
|
|
||||||
<img src="https://badges.crowdin.net/ryujinx/localized.svg"
|
|
||||||
alt="">
|
|
||||||
</a>
|
|
||||||
<a href="https://discord.com/invite/VkQYXAZ">
|
|
||||||
<img src="https://img.shields.io/discord/410208534861447168?color=5865F2&label=Ryujinx&logo=discord&logoColor=white"
|
|
||||||
alt="Discord">
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<img src="https://raw.githubusercontent.com/Ryujinx/Ryujinx-Website/master/public/assets/images/shell.png">
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
As of May 2024, Ryujinx has been tested on approximately 4,300 titles;
|
|
||||||
over 4,100 boot past menus and into gameplay, with roughly 3,550 of those being considered playable.
|
|
||||||
|
|
||||||
You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
|
|
||||||
|
|
||||||
Anyone is free to submit a new game test or update an existing game test entry;
|
|
||||||
simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue.
|
|
||||||
Use the search function to see if a game has been tested already!
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To run this emulator, your PC must be equipped with at least 8GiB of RAM;
|
To run this emulator, your PC must be equipped with at least 8GiB of RAM;
|
||||||
failing to meet this requirement may result in a poor gameplay experience or unexpected crashes.
|
failing to meet this requirement may result in a poor gameplay experience or unexpected crashes.
|
||||||
|
|
||||||
See our [Setup & Configuration Guide](https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide) on how to set up the emulator.
|
|
||||||
|
|
||||||
For our Local Wireless (LDN) builds, see our [Multiplayer: Local Play/Local Wireless Guide
|
|
||||||
](https://github.com/Ryujinx/Ryujinx/wiki/Multiplayer-(LDN-Local-Wireless)-Guide).
|
|
||||||
|
|
||||||
Avalonia UI comes with translations for various languages. See [Crowdin](https://crwd.in/ryujinx) for more information.
|
|
||||||
|
|
||||||
## Latest build
|
## Latest build
|
||||||
|
|
||||||
These builds are compiled automatically for each commit on the master branch.
|
Stable builds are made every so often, based on the `master` branch, that then gets put into the releases you know and love.
|
||||||
While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken**.
|
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
||||||
|
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
|
||||||
|
|
||||||
If you want to see details on updates to the emulator, you can visit our [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog).
|
You can find the stable releases [here](https://git.ryujinx.app/ryubing/ryujinx/-/releases).
|
||||||
|
|
||||||
The latest automatic build for Windows, macOS, and Linux can be found on the [Official Website](https://ryujinx.org/download).
|
Canary builds are compiled automatically for each commit on the `master` branch.
|
||||||
|
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
||||||
|
These canary builds are only recommended for experienced users.
|
||||||
|
|
||||||
|
You can find the canary releases [here](https://git.ryujinx.app/ryubing/canary/-/releases).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
If you are planning to contribute or just want to learn more about this project please read through our [documentation](docs/README.md).
|
If you are planning to contribute or just want to learn more about this project please read through our [documentation](docs/README.md).
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
If you wish to build the emulator yourself, follow these steps:
|
|
||||||
|
|
||||||
### Step 1
|
|
||||||
|
|
||||||
Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0).
|
|
||||||
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
|
||||||
|
|
||||||
### Step 2
|
|
||||||
|
|
||||||
Either use `git clone https://github.com/Ryujinx/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
|
||||||
|
|
||||||
### Step 3
|
|
||||||
|
|
||||||
To build Ryujinx, open a command prompt inside the project directory.
|
|
||||||
You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`.
|
|
||||||
Then type the following command: `dotnet build -c Release -o build`
|
|
||||||
the built files will be found in the newly created build directory.
|
|
||||||
|
|
||||||
Ryujinx system files are stored in the `Ryujinx` folder.
|
|
||||||
This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Audio**
|
- **Audio**
|
||||||
|
@ -120,7 +88,7 @@ This folder is located in the user folder, which can be accessed by clicking `Op
|
||||||
|
|
||||||
- **Input**
|
- **Input**
|
||||||
|
|
||||||
We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers.
|
We currently have support for keyboard, mouse, touch input, Joy-Con input support, and nearly all controllers.
|
||||||
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
||||||
In all scenarios, you can set up everything inside the input configuration menu.
|
In all scenarios, you can set up everything inside the input configuration menu.
|
||||||
|
|
||||||
|
@ -133,28 +101,7 @@ This folder is located in the user folder, which can be accessed by clicking `Op
|
||||||
- **Configuration**
|
- **Configuration**
|
||||||
|
|
||||||
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
||||||
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
||||||
|
|
||||||
## Contact
|
|
||||||
|
|
||||||
If you have contributions, suggestions, need emulator support or just want to get in touch with the team, join our [Discord server](https://discord.com/invite/Ryujinx).
|
|
||||||
You may also review our [FAQ](https://github.com/Ryujinx/Ryujinx/wiki/Frequently-Asked-Questions).
|
|
||||||
|
|
||||||
## Donations
|
|
||||||
|
|
||||||
If you'd like to support the project financially, Ryujinx has an active Patreon campaign.
|
|
||||||
|
|
||||||
<a href="https://www.patreon.com/ryujinx">
|
|
||||||
<img src="https://images.squarespace-cdn.com/content/v1/560c1d39e4b0b4fae0c9cf2a/1567548955044-WVD994WZP76EWF15T0L3/Patreon+Button.png?format=500w" width="150">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
All developers working on the project do so in their free time, but the project has several expenses:
|
|
||||||
* Hackable Nintendo Switch consoles to reverse-engineer the hardware
|
|
||||||
* Additional computer hardware for testing purposes (e.g. GPUs to diagnose graphical bugs, etc.)
|
|
||||||
* Licenses for various software development tools (e.g. Jetbrains, IDA)
|
|
||||||
* Web hosting and infrastructure maintenance (e.g. LDN servers)
|
|
||||||
|
|
||||||
All funds received through Patreon are considered a donation to support the project. Patrons receive early access to progress reports and exclusive access to developer interviews.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -164,7 +111,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
- [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system.
|
- [LibHac](https://git.ryujinx.app/ryubing/libhac) is used for our file-system.
|
||||||
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
|
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
|
||||||
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
|
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
|
||||||
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.
|
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.
|
29
Ryujinx.sln
29
Ryujinx.sln
|
@ -29,12 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec", "s
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "src\Ryujinx.Audio\Ryujinx.Audio.csproj", "{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "src\Ryujinx.Audio\Ryujinx.Audio.csproj", "{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
.editorconfig = .editorconfig
|
|
||||||
Directory.Packages.props = Directory.Packages.props
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Memory", "src\Ryujinx.Tests.Memory\Ryujinx.Tests.Memory.csproj", "{D1CC5322-7325-4F6B-9625-194B30BE1296}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Memory", "src\Ryujinx.Tests.Memory\Ryujinx.Tests.Memory.csproj", "{D1CC5322-7325-4F6B-9625-194B30BE1296}"
|
||||||
|
@ -63,14 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
||||||
|
@ -87,6 +77,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
.editorconfig = .editorconfig
|
||||||
|
.github\workflows\build.yml = .github\workflows\build.yml
|
||||||
|
.github\workflows\canary.yml = .github\workflows\canary.yml
|
||||||
|
Directory.Packages.props = Directory.Packages.props
|
||||||
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
|
nuget.config = nuget.config
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -201,10 +203,6 @@ Global
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -249,6 +247,9 @@ Global
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseExplicitType</s:String>
|
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseExplicitType</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String>
|
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GL/@EntryIndexedValue">GL</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDL/@EntryIndexedValue">SDL</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDL/@EntryIndexedValue">OS</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></Policy></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></Policy></s:String>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=amiibo/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ASET/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ASET/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Astc/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Astc/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Luma/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Luma/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
25026
assets/locales.json
Normal file
25026
assets/locales.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@ if [ -z "$RYUJINX_BIN" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
COMMAND="env DOTNET_EnableAlternateStackCheck=1"
|
COMMAND="env LANG=C.UTF-8 DOTNET_EnableAlternateStackCheck=1"
|
||||||
|
|
||||||
if command -v gamemoderun > /dev/null 2>&1; then
|
if command -v gamemoderun > /dev/null 2>&1; then
|
||||||
COMMAND="$COMMAND gamemoderun"
|
COMMAND="$COMMAND gamemoderun"
|
||||||
|
|
3
distribution/linux/appimage/AppRun
Executable file
3
distribution/linux/appimage/AppRun
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
CURRENTDIR="$(readlink -f "$(dirname "$0")")"
|
||||||
|
exec "$CURRENTDIR"/usr/bin/Ryujinx.sh "$@"
|
33
distribution/linux/appimage/build-appimage.sh
Executable file
33
distribution/linux/appimage/build-appimage.sh
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOTDIR="$(readlink -f "$(dirname "$0")")"/../../../
|
||||||
|
cd "$ROOTDIR"
|
||||||
|
|
||||||
|
BUILDDIR=${BUILDDIR:-publish}
|
||||||
|
OUTDIR=${OUTDIR:-publish_appimage}
|
||||||
|
UFLAG=${UFLAG:-"gh-releases-zsync|Ryubing|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||||
|
|
||||||
|
rm -rf AppDir
|
||||||
|
mkdir -p AppDir/usr/bin
|
||||||
|
|
||||||
|
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||||
|
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||||
|
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
||||||
|
|
||||||
|
|
||||||
|
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||||
|
|
||||||
|
# Ensure necessary bins are set as executable
|
||||||
|
chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
|
||||||
|
|
||||||
|
mkdir -p "$OUTDIR"
|
||||||
|
|
||||||
|
appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
|
||||||
|
-u "$UFLAG" \
|
||||||
|
AppDir "$OUTDIR"/Ryujinx.AppImage
|
||||||
|
|
||||||
|
# Move zsync file needed for delta updates
|
||||||
|
if [ "$RELEASE" = "1" ]; then
|
||||||
|
mv ./*.AppImage.zsync "$OUTDIR"
|
||||||
|
fi
|
|
@ -40,11 +40,11 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.1</string>
|
<string>1.2</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.1.0</string>
|
<string>1.2.0</string>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
|
|
Binary file not shown.
|
@ -19,7 +19,7 @@ if platform.system() == "Darwin":
|
||||||
else:
|
else:
|
||||||
OTOOL = shutil.which("llvm-otool")
|
OTOOL = shutil.which("llvm-otool")
|
||||||
if OTOOL is None:
|
if OTOOL is None:
|
||||||
for llvm_ver in [15, 14, 13]:
|
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||||
otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
|
otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
|
||||||
if otool_path is not None:
|
if otool_path is not None:
|
||||||
OTOOL = otool_path
|
OTOOL = otool_path
|
||||||
|
@ -562,9 +562,11 @@ search_path = [
|
||||||
|
|
||||||
|
|
||||||
for path in content_directory.rglob("**/*.dylib"):
|
for path in content_directory.rglob("**/*.dylib"):
|
||||||
|
if not path.name.startswith("._"):
|
||||||
current_search_path = [path.parent]
|
current_search_path = [path.parent]
|
||||||
current_search_path.extend(search_path)
|
current_search_path.extend(search_path)
|
||||||
|
|
||||||
|
print(f"Fixing path '{path}' using search path of '{current_search_path}' for context of '{content_directory}'.")
|
||||||
fixup_dylib(
|
fixup_dylib(
|
||||||
path,
|
path,
|
||||||
get_path_related_to_target_exec(content_directory, path),
|
get_path_related_to_target_exec(content_directory, path),
|
||||||
|
@ -573,6 +575,7 @@ for path in content_directory.rglob("**/*.dylib"):
|
||||||
)
|
)
|
||||||
|
|
||||||
for path in content_directory.rglob("**/*.so"):
|
for path in content_directory.rglob("**/*.so"):
|
||||||
|
if not path.name.startswith("._"):
|
||||||
current_search_path = [path.parent]
|
current_search_path = [path.parent]
|
||||||
current_search_path.extend(search_path)
|
current_search_path.extend(search_path)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ else:
|
||||||
LIPO = shutil.which("llvm-lipo")
|
LIPO = shutil.which("llvm-lipo")
|
||||||
|
|
||||||
if LIPO is None:
|
if LIPO is None:
|
||||||
for llvm_ver in [15, 14, 13]:
|
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||||
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
|
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
|
||||||
if lipo_path is not None:
|
if lipo_path is not None:
|
||||||
LIPO = lipo_path
|
LIPO = lipo_path
|
||||||
|
|
|
@ -30,21 +30,32 @@ cp -r "$PUBLISH_DIRECTORY/THIRDPARTY.md" "$APP_BUNDLE_DIRECTORY/Contents/Resourc
|
||||||
echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
|
echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
|
||||||
|
|
||||||
# Fixup libraries and executable
|
# Fixup libraries and executable
|
||||||
|
echo "Running bundle fix up python script"
|
||||||
python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx
|
python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx
|
||||||
|
|
||||||
# Now sign it
|
# Now sign it
|
||||||
|
echo "Starting signing process"
|
||||||
if ! [ -x "$(command -v codesign)" ];
|
if ! [ -x "$(command -v codesign)" ];
|
||||||
then
|
then
|
||||||
if ! [ -x "$(command -v rcodesign)" ];
|
if ! [ -x "$(command -v rcodesign)" ];
|
||||||
then
|
then
|
||||||
echo "Cannot find rcodesign on your system, please install rcodesign."
|
echo "Cannot find rcodesign on your system, please install rcodesign and ensure it is in your search path."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# cargo install apple-codesign
|
echo "Using rcodesign for ad-hoc signing"
|
||||||
echo "Usign rcodesign for ad-hoc signing"
|
|
||||||
|
echo "Resigning all frameworks dylib files as ad-hoc"
|
||||||
|
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec rcodesign sign {} \;
|
||||||
|
|
||||||
|
echo "Signing app bundle as ad-hoc"
|
||||||
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY"
|
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY"
|
||||||
else
|
else
|
||||||
echo "Usign codesign for ad-hoc signing"
|
echo "Using codesign for ad-hoc signing"
|
||||||
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$APP_BUNDLE_DIRECTORY"
|
|
||||||
|
echo "Resigning all frameworks dylib files as ad-hoc"
|
||||||
|
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
|
||||||
|
|
||||||
|
echo "Signing app bundle as ad-hoc"
|
||||||
|
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY"
|
||||||
fi
|
fi
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$#" -lt 7 ]; then
|
if [ "$#" -lt 8 ]; then
|
||||||
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <EXTRA_ARGS>"
|
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <CANARY>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -18,10 +18,23 @@ ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
|
||||||
VERSION=$5
|
VERSION=$5
|
||||||
SOURCE_REVISION_ID=$6
|
SOURCE_REVISION_ID=$6
|
||||||
CONFIGURATION=$7
|
CONFIGURATION=$7
|
||||||
EXTRA_ARGS=$8
|
CANARY=$8
|
||||||
|
|
||||||
if [ "$VERSION" == "1.1.0" ];
|
if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
then
|
echo "Clearing xattr on all dot undercsore files"
|
||||||
|
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
|
||||||
|
for f; do
|
||||||
|
dir=$(dirname "$f")
|
||||||
|
base=$(basename "$f")
|
||||||
|
orig="$dir/${base#._}"
|
||||||
|
[ -f "$orig" ] && xattr -c "$orig" || true
|
||||||
|
done
|
||||||
|
' sh {} +
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CANARY" == "1" ]; then
|
||||||
|
RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
|
||||||
|
elif [ "$VERSION" == "1.1.0" ]; then
|
||||||
RELEASE_TAR_FILE_NAME=ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar
|
RELEASE_TAR_FILE_NAME=ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar
|
||||||
else
|
else
|
||||||
RELEASE_TAR_FILE_NAME=ryujinx-$VERSION-macos_universal.app.tar
|
RELEASE_TAR_FILE_NAME=ryujinx-$VERSION-macos_universal.app.tar
|
||||||
|
@ -61,16 +74,16 @@ mkdir -p "$OUTPUT_DIRECTORY"
|
||||||
cp -R "$ARM64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE"
|
cp -R "$ARM64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE"
|
||||||
rm "$UNIVERSAL_APP_BUNDLE/$EXECUTABLE_SUB_PATH"
|
rm "$UNIVERSAL_APP_BUNDLE/$EXECUTABLE_SUB_PATH"
|
||||||
|
|
||||||
# Make it libraries universal
|
# Make its libraries universal
|
||||||
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_BUNDLE" "$X64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE" "**/*.dylib"
|
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_BUNDLE" "$X64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE" "**/*.dylib"
|
||||||
|
|
||||||
if ! [ -x "$(command -v lipo)" ];
|
if ! [ -x "$(command -v lipo)" ];
|
||||||
then
|
then
|
||||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||||
then
|
then
|
||||||
LIPO=llvm-lipo
|
LIPO=llvm-lipo
|
||||||
else
|
else
|
||||||
LIPO=llvm-lipo-14
|
LIPO=llvm-lipo-17
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
LIPO=lipo
|
LIPO=lipo
|
||||||
|
@ -99,7 +112,7 @@ then
|
||||||
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$UNIVERSAL_APP_BUNDLE"
|
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$UNIVERSAL_APP_BUNDLE"
|
||||||
else
|
else
|
||||||
echo "Using codesign for ad-hoc signing"
|
echo "Using codesign for ad-hoc signing"
|
||||||
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$UNIVERSAL_APP_BUNDLE"
|
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$UNIVERSAL_APP_BUNDLE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Creating archive"
|
echo "Creating archive"
|
||||||
|
@ -109,12 +122,6 @@ python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "
|
||||||
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
||||||
rm "$RELEASE_TAR_FILE_NAME"
|
rm "$RELEASE_TAR_FILE_NAME"
|
||||||
|
|
||||||
# Create legacy update package for Avalonia to not left behind old testers.
|
|
||||||
if [ "$VERSION" != "1.1.0" ];
|
|
||||||
then
|
|
||||||
cp $RELEASE_TAR_FILE_NAME.gz test-ava-ryujinx-$VERSION-macos_universal.app.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
echo "Done"
|
echo "Done"
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$#" -lt 7 ]; then
|
if [ "$#" -lt 8 ]; then
|
||||||
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <EXTRA_ARGS>"
|
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <CANARY>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -18,13 +18,26 @@ ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
|
||||||
VERSION=$5
|
VERSION=$5
|
||||||
SOURCE_REVISION_ID=$6
|
SOURCE_REVISION_ID=$6
|
||||||
CONFIGURATION=$7
|
CONFIGURATION=$7
|
||||||
EXTRA_ARGS=$8
|
CANARY=$8
|
||||||
|
|
||||||
if [ "$VERSION" == "1.1.0" ];
|
if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
then
|
echo "Clearing xattr on all dot undercsore files"
|
||||||
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
|
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
|
||||||
|
for f; do
|
||||||
|
dir=$(dirname "$f")
|
||||||
|
base=$(basename "$f")
|
||||||
|
orig="$dir/${base#._}"
|
||||||
|
[ -f "$orig" ] && xattr -c "$orig" || true
|
||||||
|
done
|
||||||
|
' sh {} +
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CANARY" == "1" ]; then
|
||||||
|
RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
|
||||||
|
elif [ "$VERSION" == "1.1.0" ]; then
|
||||||
|
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
|
||||||
else
|
else
|
||||||
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar
|
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$VERSION-macos_universal.tar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
||||||
|
@ -56,16 +69,16 @@ mkdir -p "$OUTPUT_DIRECTORY"
|
||||||
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
|
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
|
||||||
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
|
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
|
||||||
|
|
||||||
# Make it libraries universal
|
# Make its libraries universal
|
||||||
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
|
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
|
||||||
|
|
||||||
if ! [ -x "$(command -v lipo)" ];
|
if ! [ -x "$(command -v lipo)" ];
|
||||||
then
|
then
|
||||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||||
then
|
then
|
||||||
LIPO=llvm-lipo
|
LIPO=llvm-lipo
|
||||||
else
|
else
|
||||||
LIPO=llvm-lipo-14
|
LIPO=llvm-lipo-17
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
LIPO=lipo
|
LIPO=lipo
|
||||||
|
@ -95,7 +108,7 @@ else
|
||||||
echo "Using codesign for ad-hoc signing"
|
echo "Using codesign for ad-hoc signing"
|
||||||
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
||||||
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
||||||
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE"
|
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$FILE"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
<string>Copyright © 2018 - 2025 Ryujinx Team and Contributors.</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
@ -17,7 +17,7 @@ error_handler() {
|
||||||
set the button_pressed to the button returned of the result
|
set the button_pressed to the button returned of the result
|
||||||
|
|
||||||
if the button_pressed is \"Open Download Page\" then
|
if the button_pressed is \"Open Download Page\" then
|
||||||
open location \"https://ryujinx.org/download\"
|
open location \"https://ryujinx.app/download\"
|
||||||
end if
|
end if
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 MiB |
3452
docs/compatibility.csv
Normal file
3452
docs/compatibility.csv
Normal file
File diff suppressed because it is too large
Load diff
BIN
docs/shell.png
Normal file
BIN
docs/shell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 MiB |
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
## Contributing Rules
|
## Contributing Rules
|
||||||
|
|
||||||
All contributions to Ryujinx/Ryujinx repository are made via pull requests (PRs) rather than through direct commits. The pull requests are reviewed and merged by the maintainers after a review and at least two approvals from the core development team.
|
All contributions to GreemDev/Ryujinx repository are made via pull requests (PRs) rather than through direct commits. The pull requests are reviewed and merged by the maintainers after a review and at least two approvals from the core development team.
|
||||||
|
|
||||||
To merge pull requests, you must have write permissions in the repository.
|
To merge pull requests, you must have write permissions in the repository.
|
||||||
|
|
||||||
## Quick Code Review Rules
|
## Quick Code Review Rules
|
||||||
|
|
||||||
* Do not mix unrelated changes in one pull request. For example, a code style change should never be mixed with a bug fix.
|
* Do not mix unrelated changes in one pull request. For example, a code style change should never be mixed with a bug fix.
|
||||||
* All changes should follow the existing code style. You can read more about our code style at [docs/coding-guidelines](../coding-guidelines/coding-style.md).
|
* All changes should follow the existing code style. You can read more about our code style at [docs/coding-style](../coding-guidelines/coding-style.md).
|
||||||
* Adding external dependencies is to be avoided unless not doing so would introduce _significant_ complexity. Any dependency addition should be justified and discussed before merge.
|
* Adding external dependencies is to be avoided unless not doing so would introduce _significant_ complexity. Any dependency addition should be justified and discussed before merge.
|
||||||
* Use Draft pull requests for changes you are still working on but want early CI loop feedback. When you think your changes are ready for review, [change the status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request) of your pull request.
|
* Use Draft pull requests for changes you are still working on but want early CI loop feedback. When you think your changes are ready for review, [change the status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request) of your pull request.
|
||||||
* Rebase your changes when required or directly requested. Changes should always be commited on top of the upstream branch, not the other way around.
|
* Rebase your changes when required or directly requested. Changes should always be commited on top of the upstream branch, not the other way around.
|
||||||
|
@ -18,13 +18,13 @@ To merge pull requests, you must have write permissions in the repository.
|
||||||
|
|
||||||
## Pull Request Ownership
|
## Pull Request Ownership
|
||||||
|
|
||||||
Every pull request will have automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
|
Every pull request will automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
|
||||||
|
|
||||||
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
|
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
|
||||||
|
|
||||||
## Pull Request Builds
|
## Pull Request Builds
|
||||||
|
|
||||||
When submitting a PR to the `Ryujinx/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
|
When submitting a PR to the `Ryubing/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
|
||||||
|
|
||||||
## Review Turnaround Times
|
## Review Turnaround Times
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ Anyone with write access can merge a pull request manually when the following co
|
||||||
|
|
||||||
* The PR has been approved by two reviewers and any other objections are addressed.
|
* The PR has been approved by two reviewers and any other objections are addressed.
|
||||||
* You can request follow up reviews from the original reviewers if they requested changes.
|
* You can request follow up reviews from the original reviewers if they requested changes.
|
||||||
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of your PR.
|
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of your PR.
|
||||||
|
|
||||||
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.
|
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.100",
|
"version": "9.0.100",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
nuget.config
18
nuget.config
|
@ -1,7 +1,25 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<clear />
|
<clear />
|
||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
|
||||||
|
<!--<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />-->
|
||||||
|
<add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
|
<packageSourceMapping>
|
||||||
|
<!-- key value for <packageSource> should match key values from <packageSources> element -->
|
||||||
|
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
|
||||||
|
<packageSource key="nuget.org">
|
||||||
|
<package pattern="*" />
|
||||||
|
</packageSource>
|
||||||
|
<packageSource key="Ryujinx.UpdateClient">
|
||||||
|
<package pattern="Ryujinx.UpdateClient" />
|
||||||
|
<package pattern="Ryujinx.Systems.Update.Common" />
|
||||||
|
</packageSource>
|
||||||
|
<!--<packageSource key="LibHacAlpha">
|
||||||
|
<package pattern="Ryujinx.LibHac" />
|
||||||
|
</packageSource>-->
|
||||||
|
</packageSourceMapping>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
|
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
public static void RunPass(ControlFlowGraph cfg)
|
public static void RunPass(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
var constants = new Dictionary<ulong, Operand>();
|
Dictionary<ulong, Operand> constants = new();
|
||||||
|
|
||||||
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
||||||
{
|
{
|
||||||
// If the constant has many uses, we also force a new constant mov to be added, in order
|
// If the constant has many uses, we also force a new constant mov to be added, in order
|
||||||
// to avoid overflow of the counts field (that is limited to 16 bits).
|
// to avoid overflow of the counts field (that is limited to 16 bits).
|
||||||
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
|
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
|
||||||
{
|
{
|
||||||
constant = Local(source.Type);
|
constant = Local(source.Type);
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
private static bool IsMemoryLoadOrStore(Instruction inst)
|
private static bool IsMemoryLoadOrStore(Instruction inst)
|
||||||
{
|
{
|
||||||
return inst == Instruction.Load || inst == Instruction.Store;
|
return inst is Instruction.Load or Instruction.Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ConstTooLong(Operand constOp, OperandType accessType)
|
private static bool ConstTooLong(Operand constOp, OperandType accessType)
|
||||||
|
|
|
@ -123,7 +123,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
public void Cset(Operand rd, ArmCondition condition)
|
public void Cset(Operand rd, ArmCondition condition)
|
||||||
{
|
{
|
||||||
var zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
|
Operand zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
|
||||||
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,6 +774,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
instI |= 1 << 22; // sh flag
|
instI |= 1 << 22; // sh flag
|
||||||
imm >>= 12;
|
imm >>= 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
|
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
||||||
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
||||||
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
||||||
if (value == 0 || value == ulong.MaxValue)
|
if (value is 0 or ulong.MaxValue)
|
||||||
{
|
{
|
||||||
immN = 0;
|
immN = 0;
|
||||||
immS = 0;
|
immS = 0;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.CodeGen.RegisterAllocators;
|
using ARMeilleure.CodeGen.RegisterAllocators;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -14,7 +15,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
private const int CbnzInstLength = 4;
|
private const int CbnzInstLength = 4;
|
||||||
private const int LdrLitInstLength = 4;
|
private const int LdrLitInstLength = 4;
|
||||||
|
|
||||||
private readonly Stream _stream;
|
private readonly RecyclableMemoryStream _stream;
|
||||||
|
|
||||||
public int StreamOffset => (int)_stream.Length;
|
public int StreamOffset => (int)_stream.Length;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
{
|
{
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
Symbol = symbol;
|
Symbol = symbol;
|
||||||
LdrOffsets = new List<(Operand, int)>();
|
LdrOffsets = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
long target = _stream.Position;
|
long target = _stream.Position;
|
||||||
|
|
||||||
if (_pendingBranches.TryGetValue(block, out var list))
|
if (_pendingBranches.TryGetValue(block, out List<(ArmCondition Condition, long BranchPos)> list))
|
||||||
{
|
{
|
||||||
foreach ((ArmCondition condition, long branchPos) in list)
|
foreach ((ArmCondition condition, long branchPos) in list)
|
||||||
{
|
{
|
||||||
|
@ -119,7 +120,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!_pendingBranches.TryGetValue(target, out var list))
|
if (!_pendingBranches.TryGetValue(target, out List<(ArmCondition Condition, long BranchPos)> list))
|
||||||
{
|
{
|
||||||
list = new List<(ArmCondition, long)>();
|
list = new List<(ArmCondition, long)>();
|
||||||
_pendingBranches.Add(target, list);
|
_pendingBranches.Add(target, list);
|
||||||
|
@ -266,7 +267,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
relocInfo = new RelocInfo(Array.Empty<RelocEntry>());
|
relocInfo = new RelocInfo([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (code, relocInfo);
|
return (code, relocInfo);
|
||||||
|
|
|
@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
// The only blocks which can have 0 successors are exit blocks.
|
// The only blocks which can have 0 successors are exit blocks.
|
||||||
Operation last = block.Operations.Last;
|
Operation last = block.Operations.Last;
|
||||||
|
|
||||||
Debug.Assert(last.Instruction == Instruction.Tailcall ||
|
Debug.Assert(last.Instruction is Instruction.Tailcall or
|
||||||
last.Instruction == Instruction.Return);
|
Instruction.Return);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -322,7 +322,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
|
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
|
||||||
Debug.Assert(dest.Type != source.Type);
|
Debug.Assert(dest.Type != source.Type);
|
||||||
Debug.Assert(source.Type != OperandType.V128);
|
Debug.Assert(source.Type != OperandType.V128);
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
|
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
|
||||||
Debug.Assert(dest.Type != source.Type);
|
Debug.Assert(dest.Type != source.Type);
|
||||||
Debug.Assert(source.Type.IsInteger());
|
Debug.Assert(source.Type.IsInteger());
|
||||||
|
|
||||||
|
@ -1079,7 +1079,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
private static UnwindInfo WritePrologue(CodeGenContext context)
|
private static UnwindInfo WritePrologue(CodeGenContext context)
|
||||||
{
|
{
|
||||||
List<UnwindPushEntry> pushEntries = new();
|
List<UnwindPushEntry> pushEntries = [];
|
||||||
|
|
||||||
Operand rsp = Register(SpRegister);
|
Operand rsp = Register(SpRegister);
|
||||||
|
|
||||||
|
@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
private static bool IsLoadOrStore(Operation operation)
|
private static bool IsLoadOrStore(Operation operation)
|
||||||
{
|
{
|
||||||
return operation.Instruction == Instruction.Load || operation.Instruction == Instruction.Store;
|
return operation.Instruction is Instruction.Load or Instruction.Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperandType GetMemOpValueType(Operation operation)
|
private static OperandType GetMemOpValueType(Operation operation)
|
||||||
|
@ -1499,6 +1499,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memOp.Index != default)
|
if (memOp.Index != default)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1553,7 +1554,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
private static void EnsureSameReg(Operand op1, Operand op2)
|
private static void EnsureSameReg(Operand op1, Operand op2)
|
||||||
{
|
{
|
||||||
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
|
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
|
||||||
Debug.Assert(op1.Kind == op2.Kind);
|
Debug.Assert(op1.Kind == op2.Kind);
|
||||||
Debug.Assert(op1.Value == op2.Value);
|
Debug.Assert(op1.Value == op2.Value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,7 +509,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(instruction, rd, rn);
|
context.Assembler.WriteInstruction(instruction, rd, rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateScalarTernary(
|
private static void GenerateScalarTernary(
|
||||||
|
|
|
@ -127,21 +127,22 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
#region macOS
|
#region macOS
|
||||||
|
|
||||||
[LibraryImport("libSystem.dylib", SetLastError = true)]
|
[LibraryImport("libSystem.dylib", SetLastError = true)]
|
||||||
private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
|
private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, nint newValue, ulong newValueSize);
|
||||||
|
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
private static bool CheckSysctlName(string name)
|
private static bool CheckSysctlName(string name)
|
||||||
{
|
{
|
||||||
ulong size = sizeof(int);
|
ulong size = sizeof(int);
|
||||||
if (sysctlbyname(name, out int val, ref size, IntPtr.Zero, 0) == 0 && size == sizeof(int))
|
if (sysctlbyname(name, out int val, ref size, nint.Zero, 0) == 0 && size == sizeof(int))
|
||||||
{
|
{
|
||||||
return val != 0;
|
return val != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string[] _sysctlNames = new string[]
|
private static readonly string[] _sysctlNames =
|
||||||
{
|
[
|
||||||
"hw.optional.floatingpoint",
|
"hw.optional.floatingpoint",
|
||||||
"hw.optional.AdvSIMD",
|
"hw.optional.AdvSIMD",
|
||||||
"hw.optional.arm.FEAT_FP16",
|
"hw.optional.arm.FEAT_FP16",
|
||||||
|
@ -150,8 +151,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
"hw.optional.arm.FEAT_LSE",
|
"hw.optional.arm.FEAT_LSE",
|
||||||
"hw.optional.armv8_crc32",
|
"hw.optional.armv8_crc32",
|
||||||
"hw.optional.arm.FEAT_SHA1",
|
"hw.optional.arm.FEAT_SHA1",
|
||||||
"hw.optional.arm.FEAT_SHA256",
|
"hw.optional.arm.FEAT_SHA256"
|
||||||
};
|
];
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum MacOsFeatureFlags
|
public enum MacOsFeatureFlags
|
||||||
|
|
|
@ -261,10 +261,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
List<Operand> sources = new()
|
List<Operand> sources =
|
||||||
{
|
[
|
||||||
operation.GetSource(0),
|
operation.GetSource(0)
|
||||||
};
|
];
|
||||||
|
|
||||||
int argsCount = operation.SourcesCount - 1;
|
int argsCount = operation.SourcesCount - 1;
|
||||||
|
|
||||||
|
@ -365,10 +365,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Operation node,
|
Operation node,
|
||||||
Operation operation)
|
Operation operation)
|
||||||
{
|
{
|
||||||
List<Operand> sources = new()
|
List<Operand> sources =
|
||||||
{
|
[
|
||||||
operation.GetSource(0),
|
operation.GetSource(0)
|
||||||
};
|
];
|
||||||
|
|
||||||
int argsCount = operation.SourcesCount - 1;
|
int argsCount = operation.SourcesCount - 1;
|
||||||
|
|
||||||
|
@ -468,8 +468,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
// Update the sources and destinations with split 64-bit halfs of the whole 128-bit values.
|
// Update the sources and destinations with split 64-bit halfs of the whole 128-bit values.
|
||||||
// We also need a additional registers that will be used to store temporary information.
|
// We also need a additional registers that will be used to store temporary information.
|
||||||
operation.SetDestinations(new[] { actualLow, actualHigh, Local(OperandType.I64), Local(OperandType.I64) });
|
operation.SetDestinations([actualLow, actualHigh, Local(OperandType.I64), Local(OperandType.I64)]);
|
||||||
operation.SetSources(new[] { address, expectedLow, expectedHigh, desiredLow, desiredHigh });
|
operation.SetSources([address, expectedLow, expectedHigh, desiredLow, desiredHigh]);
|
||||||
|
|
||||||
// Add some dummy uses of the input operands, as the CAS operation will be a loop,
|
// Add some dummy uses of the input operands, as the CAS operation will be a loop,
|
||||||
// so they can't be used as destination operand.
|
// so they can't be used as destination operand.
|
||||||
|
@ -486,7 +486,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We need a additional register where the store result will be written to.
|
// We need a additional register where the store result will be written to.
|
||||||
node.SetDestinations(new[] { node.Destination, Local(OperandType.I32) });
|
node.SetDestinations([node.Destination, Local(OperandType.I32)]);
|
||||||
|
|
||||||
// Add some dummy uses of the input operands, as the CAS operation will be a loop,
|
// Add some dummy uses of the input operands, as the CAS operation will be a loop,
|
||||||
// so they can't be used as destination operand.
|
// so they can't be used as destination operand.
|
||||||
|
@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
{
|
{
|
||||||
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
|
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
|
||||||
|
|
||||||
return info.Type == IntrinsicType.ScalarBinaryRd ||
|
return info.Type is IntrinsicType.ScalarBinaryRd or
|
||||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
IntrinsicType.ScalarTernaryFPRdByElem or
|
||||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
IntrinsicType.ScalarTernaryShlRd or
|
||||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
IntrinsicType.ScalarTernaryShrRd or
|
||||||
info.Type == IntrinsicType.Vector128BinaryRd ||
|
IntrinsicType.Vector128BinaryRd or
|
||||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
IntrinsicType.VectorBinaryRd or
|
||||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
IntrinsicType.VectorInsertByElem or
|
||||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
IntrinsicType.VectorTernaryRd or
|
||||||
info.Type == IntrinsicType.VectorTernaryRdBitwise ||
|
IntrinsicType.VectorTernaryRdBitwise or
|
||||||
info.Type == IntrinsicType.VectorTernaryFPRdByElem ||
|
IntrinsicType.VectorTernaryFPRdByElem or
|
||||||
info.Type == IntrinsicType.VectorTernaryRdByElem ||
|
IntrinsicType.VectorTernaryRdByElem or
|
||||||
info.Type == IntrinsicType.VectorTernaryShlRd ||
|
IntrinsicType.VectorTernaryShlRd or
|
||||||
info.Type == IntrinsicType.VectorTernaryShrRd;
|
IntrinsicType.VectorTernaryShrRd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool HasConstSrc1(Operation node, ulong value)
|
private static bool HasConstSrc1(Operation node, ulong value)
|
||||||
|
@ -847,9 +847,9 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var compType = (Comparison)comp.AsInt32();
|
Comparison compType = (Comparison)comp.AsInt32();
|
||||||
|
|
||||||
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
return compType is Comparison.Equal or Comparison.NotEqual;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -871,9 +871,9 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
|
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
|
||||||
|
|
||||||
// Those have integer inputs that don't support consts.
|
// Those have integer inputs that don't support consts.
|
||||||
return info.Type != IntrinsicType.ScalarFPConvGpr &&
|
return info.Type is not IntrinsicType.ScalarFPConvGpr and
|
||||||
info.Type != IntrinsicType.ScalarFPConvFixedGpr &&
|
not IntrinsicType.ScalarFPConvFixedGpr and
|
||||||
info.Type != IntrinsicType.SetRegister;
|
not IntrinsicType.SetRegister;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.CodeGen.Unwinding;
|
using ARMeilleure.CodeGen.Unwinding;
|
||||||
using ARMeilleure.Translation.Cache;
|
using ARMeilleure.Translation.Cache;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen
|
namespace ARMeilleure.CodeGen
|
||||||
|
@ -58,7 +57,7 @@ namespace ARMeilleure.CodeGen
|
||||||
/// <typeparam name="T">Type of delegate</typeparam>
|
/// <typeparam name="T">Type of delegate</typeparam>
|
||||||
/// <param name="codePointer">Pointer to the function code in memory</param>
|
/// <param name="codePointer">Pointer to the function code in memory</param>
|
||||||
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
|
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
|
||||||
public T MapWithPointer<T>(out IntPtr codePointer)
|
public T MapWithPointer<T>(out nint codePointer)
|
||||||
{
|
{
|
||||||
codePointer = JitCache.Map(this);
|
codePointer = JitCache.Map(this);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ARMeilleure.CodeGen.Linking
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an empty <see cref="RelocInfo"/>.
|
/// Gets an empty <see cref="RelocInfo"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static RelocInfo Empty { get; } = new RelocInfo(null);
|
public static RelocInfo Empty { get; } = new(null);
|
||||||
|
|
||||||
private readonly RelocEntry[] _entries;
|
private readonly RelocEntry[] _entries;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x + y);
|
EvaluateBinaryI64(operation, (x, y) => x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.BitwiseAnd:
|
case Instruction.BitwiseAnd:
|
||||||
|
@ -48,6 +49,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x & y);
|
EvaluateBinaryI64(operation, (x, y) => x & y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.BitwiseExclusiveOr:
|
case Instruction.BitwiseExclusiveOr:
|
||||||
|
@ -59,6 +61,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x ^ y);
|
EvaluateBinaryI64(operation, (x, y) => x ^ y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.BitwiseNot:
|
case Instruction.BitwiseNot:
|
||||||
|
@ -70,6 +73,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => ~x);
|
EvaluateUnaryI64(operation, (x) => ~x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.BitwiseOr:
|
case Instruction.BitwiseOr:
|
||||||
|
@ -81,6 +85,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x | y);
|
EvaluateBinaryI64(operation, (x, y) => x | y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ConvertI64ToI32:
|
case Instruction.ConvertI64ToI32:
|
||||||
|
@ -88,6 +93,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI32(operation, (x) => x);
|
EvaluateUnaryI32(operation, (x) => x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Compare:
|
case Instruction.Compare:
|
||||||
|
@ -129,6 +135,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Copy:
|
case Instruction.Copy:
|
||||||
|
@ -140,6 +147,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => x);
|
EvaluateUnaryI64(operation, (x) => x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Divide:
|
case Instruction.Divide:
|
||||||
|
@ -151,6 +159,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
|
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.DivideUI:
|
case Instruction.DivideUI:
|
||||||
|
@ -162,6 +171,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
|
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Multiply:
|
case Instruction.Multiply:
|
||||||
|
@ -173,6 +183,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x * y);
|
EvaluateBinaryI64(operation, (x, y) => x * y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Negate:
|
case Instruction.Negate:
|
||||||
|
@ -184,6 +195,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => -x);
|
EvaluateUnaryI64(operation, (x) => -x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ShiftLeft:
|
case Instruction.ShiftLeft:
|
||||||
|
@ -195,6 +207,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x << (int)y);
|
EvaluateBinaryI64(operation, (x, y) => x << (int)y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ShiftRightSI:
|
case Instruction.ShiftRightSI:
|
||||||
|
@ -206,6 +219,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
|
EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ShiftRightUI:
|
case Instruction.ShiftRightUI:
|
||||||
|
@ -217,6 +231,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
|
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.SignExtend16:
|
case Instruction.SignExtend16:
|
||||||
|
@ -228,6 +243,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (short)x);
|
EvaluateUnaryI64(operation, (x) => (short)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.SignExtend32:
|
case Instruction.SignExtend32:
|
||||||
|
@ -239,6 +255,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (int)x);
|
EvaluateUnaryI64(operation, (x) => (int)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.SignExtend8:
|
case Instruction.SignExtend8:
|
||||||
|
@ -250,6 +267,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (sbyte)x);
|
EvaluateUnaryI64(operation, (x) => (sbyte)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ZeroExtend16:
|
case Instruction.ZeroExtend16:
|
||||||
|
@ -261,6 +279,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (ushort)x);
|
EvaluateUnaryI64(operation, (x) => (ushort)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ZeroExtend32:
|
case Instruction.ZeroExtend32:
|
||||||
|
@ -272,6 +291,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (uint)x);
|
EvaluateUnaryI64(operation, (x) => (uint)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ZeroExtend8:
|
case Instruction.ZeroExtend8:
|
||||||
|
@ -283,6 +303,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateUnaryI64(operation, (x) => (byte)x);
|
EvaluateUnaryI64(operation, (x) => (byte)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Subtract:
|
case Instruction.Subtract:
|
||||||
|
@ -294,6 +315,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
{
|
{
|
||||||
EvaluateBinaryI64(operation, (x, y) => x - y);
|
EvaluateBinaryI64(operation, (x, y) => x - y);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||||
|
|
||||||
private static bool HasSideEffects(Operation node)
|
private static bool HasSideEffects(Operation node)
|
||||||
{
|
{
|
||||||
return node.Instruction == Instruction.Call
|
return node.Instruction is Instruction.Call
|
||||||
|| node.Instruction == Instruction.Tailcall
|
or Instruction.Tailcall
|
||||||
|| node.Instruction == Instruction.CompareAndSwap
|
or Instruction.CompareAndSwap
|
||||||
|| node.Instruction == Instruction.CompareAndSwap16
|
or Instruction.CompareAndSwap16
|
||||||
|| node.Instruction == Instruction.CompareAndSwap8;
|
or Instruction.CompareAndSwap8;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsPropagableCompare(Operation operation)
|
private static bool IsPropagableCompare(Operation operation)
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
public ParallelCopy()
|
public ParallelCopy()
|
||||||
{
|
{
|
||||||
_copies = new List<Copy>();
|
_copies = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCopy(Register dest, Register source, OperandType type)
|
public void AddCopy(Register dest, Register source, OperandType type)
|
||||||
|
@ -218,7 +218,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
public Operation[] Sequence()
|
public Operation[] Sequence()
|
||||||
{
|
{
|
||||||
List<Operation> sequence = new();
|
List<Operation> sequence = [];
|
||||||
|
|
||||||
if (_spillQueue != null)
|
if (_spillQueue != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
{
|
{
|
||||||
NumberLocals(cfg, regMasks.RegistersCount);
|
NumberLocals(cfg, regMasks.RegistersCount);
|
||||||
|
|
||||||
var context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
|
AllocationContext context = new(stackAlloc, regMasks, _intervals.Count);
|
||||||
|
|
||||||
BuildIntervals(cfg, context);
|
BuildIntervals(cfg, context);
|
||||||
|
|
||||||
|
@ -799,8 +799,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
private void NumberLocals(ControlFlowGraph cfg, int registersCount)
|
private void NumberLocals(ControlFlowGraph cfg, int registersCount)
|
||||||
{
|
{
|
||||||
_operationNodes = new List<(IntrusiveList<Operation>, Operation)>();
|
_operationNodes = [];
|
||||||
_intervals = new List<LiveInterval>();
|
_intervals = [];
|
||||||
|
|
||||||
for (int index = 0; index < registersCount; index++)
|
for (int index = 0; index < registersCount; index++)
|
||||||
{
|
{
|
||||||
|
@ -839,7 +839,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
{
|
{
|
||||||
dest.NumberLocal(_intervals.Count);
|
dest.NumberLocal(_intervals.Count);
|
||||||
|
|
||||||
LiveInterval interval = new LiveInterval(dest);
|
LiveInterval interval = new(dest);
|
||||||
_intervals.Add(interval);
|
_intervals.Add(interval);
|
||||||
|
|
||||||
SetVisited(dest);
|
SetVisited(dest);
|
||||||
|
@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
// If this is a copy (or copy-like operation), set the copy source interval as well.
|
// If this is a copy (or copy-like operation), set the copy source interval as well.
|
||||||
// This is used for register preferencing later on, which allows the copy to be eliminated
|
// This is used for register preferencing later on, which allows the copy to be eliminated
|
||||||
// in some cases.
|
// in some cases.
|
||||||
if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32)
|
if (node.Instruction is Instruction.Copy or Instruction.ZeroExtend32)
|
||||||
{
|
{
|
||||||
Operand source = node.GetSource(0);
|
Operand source = node.GetSource(0);
|
||||||
|
|
||||||
|
@ -980,7 +980,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
_blockLiveIn = blkLiveIn;
|
_blockLiveIn = blkLiveIn;
|
||||||
|
|
||||||
_blockEdges = new HashSet<int>();
|
_blockEdges = [];
|
||||||
|
|
||||||
// Compute lifetime intervals.
|
// Compute lifetime intervals.
|
||||||
int operationPos = _operationsCount;
|
int operationPos = _operationsCount;
|
||||||
|
@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
private static bool IsLocalOrRegister(OperandKind kind)
|
private static bool IsLocalOrRegister(OperandKind kind)
|
||||||
{
|
{
|
||||||
return kind == OperandKind.LocalVariable ||
|
return kind is OperandKind.LocalVariable or
|
||||||
kind == OperandKind.Register;
|
OperandKind.Register;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,7 +387,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return HashCode.Combine((IntPtr)_data);
|
return HashCode.Combine((nint)_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -15,12 +15,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
{
|
{
|
||||||
if (_count + 1 > _capacity)
|
if (_count + 1 > _capacity)
|
||||||
{
|
{
|
||||||
var oldSpan = Span;
|
Span<LiveInterval> oldSpan = Span;
|
||||||
|
|
||||||
_capacity = Math.Max(4, _capacity * 2);
|
_capacity = Math.Max(4, _capacity * 2);
|
||||||
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
|
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
|
||||||
|
|
||||||
var newSpan = Span;
|
Span<LiveInterval> newSpan = Span;
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return HashCode.Combine((IntPtr)_data);
|
return HashCode.Combine((nint)_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -16,12 +16,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
{
|
{
|
||||||
if (Count + 1 > _capacity)
|
if (Count + 1 > _capacity)
|
||||||
{
|
{
|
||||||
var oldSpan = Span;
|
Span<int> oldSpan = Span;
|
||||||
|
|
||||||
_capacity = Math.Max(4, _capacity * 2);
|
_capacity = Math.Max(4, _capacity * 2);
|
||||||
_items = Allocators.Default.Allocate<int>((uint)_capacity);
|
_items = Allocators.Default.Allocate<int>((uint)_capacity);
|
||||||
|
|
||||||
var newSpan = Span;
|
Span<int> newSpan = Span;
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -74,9 +75,9 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
_labels = new Dictionary<Operand, long>();
|
_labels = new Dictionary<Operand, long>();
|
||||||
_jumps = new List<Jump>();
|
_jumps = [];
|
||||||
|
|
||||||
_relocs = relocatable ? new List<Reloc>() : null;
|
_relocs = relocatable ? [] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MarkLabel(Operand label)
|
public void MarkLabel(Operand label)
|
||||||
|
@ -1324,8 +1325,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
public (byte[], RelocInfo) GetCode()
|
public (byte[], RelocInfo) GetCode()
|
||||||
{
|
{
|
||||||
var jumps = CollectionsMarshal.AsSpan(_jumps);
|
Span<Jump> jumps = CollectionsMarshal.AsSpan(_jumps);
|
||||||
var relocs = CollectionsMarshal.AsSpan(_relocs);
|
Span<Reloc> relocs = CollectionsMarshal.AsSpan(_relocs);
|
||||||
|
|
||||||
// Write jump relative offsets.
|
// Write jump relative offsets.
|
||||||
bool modified;
|
bool modified;
|
||||||
|
@ -1410,15 +1411,15 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
// Write the code, ignoring the dummy bytes after jumps, into a new stream.
|
// Write the code, ignoring the dummy bytes after jumps, into a new stream.
|
||||||
_stream.Seek(0, SeekOrigin.Begin);
|
_stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
using var codeStream = MemoryStreamManager.Shared.GetStream();
|
using RecyclableMemoryStream codeStream = MemoryStreamManager.Shared.GetStream();
|
||||||
var assembler = new Assembler(codeStream, HasRelocs);
|
Assembler assembler = new(codeStream, HasRelocs);
|
||||||
|
|
||||||
bool hasRelocs = HasRelocs;
|
bool hasRelocs = HasRelocs;
|
||||||
int relocIndex = 0;
|
int relocIndex = 0;
|
||||||
int relocOffset = 0;
|
int relocOffset = 0;
|
||||||
var relocEntries = hasRelocs
|
RelocEntry[] relocEntries = hasRelocs
|
||||||
? new RelocEntry[relocs.Length]
|
? new RelocEntry[relocs.Length]
|
||||||
: Array.Empty<RelocEntry>();
|
: [];
|
||||||
|
|
||||||
for (int i = 0; i < jumps.Length; i++)
|
for (int i = 0; i < jumps.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -1469,15 +1470,15 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
_stream.CopyTo(codeStream);
|
_stream.CopyTo(codeStream);
|
||||||
|
|
||||||
var code = codeStream.ToArray();
|
byte[] code = codeStream.ToArray();
|
||||||
var relocInfo = new RelocInfo(relocEntries);
|
RelocInfo relocInfo = new(relocEntries);
|
||||||
|
|
||||||
return (code, relocInfo);
|
return (code, relocInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool Is64Bits(OperandType type)
|
private static bool Is64Bits(OperandType type)
|
||||||
{
|
{
|
||||||
return type == OperandType.I64 || type == OperandType.FP64;
|
return type is OperandType.I64 or OperandType.FP64;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsImm8(ulong immediate, OperandType type)
|
private static bool IsImm8(ulong immediate, OperandType type)
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
private const int BadOp = 0;
|
private const int BadOp = 0;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
|
||||||
private enum InstructionFlags
|
private enum InstructionFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using ARMeilleure.CodeGen.RegisterAllocators;
|
using ARMeilleure.CodeGen.RegisterAllocators;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
@ -8,7 +9,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
class CodeGenContext
|
class CodeGenContext
|
||||||
{
|
{
|
||||||
private readonly Stream _stream;
|
private readonly RecyclableMemoryStream _stream;
|
||||||
private readonly Operand[] _blockLabels;
|
private readonly Operand[] _blockLabels;
|
||||||
|
|
||||||
public int StreamOffset => (int)_stream.Length;
|
public int StreamOffset => (int)_stream.Length;
|
||||||
|
|
|
@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
// The only blocks which can have 0 successors are exit blocks.
|
// The only blocks which can have 0 successors are exit blocks.
|
||||||
Operation last = block.Operations.Last;
|
Operation last = block.Operations.Last;
|
||||||
|
|
||||||
Debug.Assert(last.Instruction == Instruction.Tailcall ||
|
Debug.Assert(last.Instruction is Instruction.Tailcall or
|
||||||
last.Instruction == Instruction.Return);
|
Instruction.Return);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
|
Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
|
||||||
|
|
||||||
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
|
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
|
||||||
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory);
|
Debug.Assert(src3.Kind is OperandKind.Register or OperandKind.Memory);
|
||||||
|
|
||||||
EnsureSameType(dest, src1, src2, src3);
|
EnsureSameType(dest, src1, src2, src3);
|
||||||
Debug.Assert(dest.Type == OperandType.V128);
|
Debug.Assert(dest.Type == OperandType.V128);
|
||||||
|
@ -623,7 +623,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
@ -661,7 +661,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
|
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
|
||||||
|
|
||||||
if (dest.Type == OperandType.FP32)
|
if (dest.Type == OperandType.FP32)
|
||||||
{
|
{
|
||||||
|
@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
|
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
|
||||||
Debug.Assert(op1.Kind == op2.Kind);
|
Debug.Assert(op1.Kind == op2.Kind);
|
||||||
Debug.Assert(op1.Value == op2.Value);
|
Debug.Assert(op1.Value == op2.Value);
|
||||||
}
|
}
|
||||||
|
@ -1748,7 +1748,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
private static UnwindInfo WritePrologue(CodeGenContext context)
|
private static UnwindInfo WritePrologue(CodeGenContext context)
|
||||||
{
|
{
|
||||||
List<UnwindPushEntry> pushEntries = new();
|
List<UnwindPushEntry> pushEntries = [];
|
||||||
|
|
||||||
Operand rsp = Register(X86Register.Rsp);
|
Operand rsp = Register(X86Register.Rsp);
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<byte> asmGetXcr0 = new byte[]
|
ReadOnlySpan<byte> asmGetXcr0 =
|
||||||
{
|
[
|
||||||
0x31, 0xc9, // xor ecx, ecx
|
0x31, 0xc9, // xor ecx, ecx
|
||||||
0xf, 0x01, 0xd0, // xgetbv
|
0xf, 0x01, 0xd0, // xgetbv
|
||||||
0xc3, // ret
|
0xc3 // ret
|
||||||
};
|
];
|
||||||
|
|
||||||
using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);
|
using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
|
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
|
||||||
|
|
||||||
var fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
|
GetXcr0 fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
|
||||||
|
|
||||||
return fGetXcr0();
|
return fGetXcr0();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
|
PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ConvertToFPUI:
|
case Instruction.ConvertToFPUI:
|
||||||
|
@ -81,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
|
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Negate:
|
case Instruction.Negate:
|
||||||
|
@ -88,6 +90,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
GenerateNegate(block.Operations, node);
|
GenerateNegate(block.Operations, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Return:
|
case Instruction.Return:
|
||||||
|
@ -99,6 +102,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
|
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Tailcall:
|
case Instruction.Tailcall:
|
||||||
|
@ -110,6 +114,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
|
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.VectorInsert8:
|
case Instruction.VectorInsert8:
|
||||||
|
@ -117,6 +122,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
GenerateVectorInsert8(block.Operations, node);
|
GenerateVectorInsert8(block.Operations, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Extended:
|
case Instruction.Extended:
|
||||||
|
@ -124,14 +130,15 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
int stackOffset = stackAlloc.Allocate(OperandType.I32);
|
int stackOffset = stackAlloc.Allocate(OperandType.I32);
|
||||||
|
|
||||||
node.SetSources(new Operand[] { Const(stackOffset), node.GetSource(0) });
|
node.SetSources([Const(stackOffset), node.GetSource(0)]);
|
||||||
}
|
}
|
||||||
else if (node.Intrinsic == Intrinsic.X86Stmxcsr)
|
else if (node.Intrinsic == Intrinsic.X86Stmxcsr)
|
||||||
{
|
{
|
||||||
int stackOffset = stackAlloc.Allocate(OperandType.I32);
|
int stackOffset = stackAlloc.Allocate(OperandType.I32);
|
||||||
|
|
||||||
node.SetSources(new Operand[] { Const(stackOffset) });
|
node.SetSources([Const(stackOffset)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,8 +260,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
|
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
|
||||||
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
|
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
|
||||||
|
|
||||||
operation.SetDestinations(new Operand[] { rdx, rax });
|
operation.SetDestinations([rdx, rax]);
|
||||||
operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx });
|
operation.SetSources([operation.GetSource(0), rdx, rax, rcx, rbx]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -274,7 +281,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
|
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
|
||||||
|
|
||||||
node.SetSources(new Operand[] { node.GetSource(0), rax, temp });
|
node.SetSources([node.GetSource(0), rax, temp]);
|
||||||
|
|
||||||
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
||||||
|
|
||||||
|
@ -303,7 +310,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
||||||
|
|
||||||
node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) });
|
node.SetSources([rdx, rax, node.GetSource(1)]);
|
||||||
node.Destination = rax;
|
node.Destination = rax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,9 +319,9 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
case Instruction.Extended:
|
case Instruction.Extended:
|
||||||
{
|
{
|
||||||
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
|
bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
|
||||||
node.Intrinsic == Intrinsic.X86Blendvps ||
|
Intrinsic.X86Blendvps or
|
||||||
node.Intrinsic == Intrinsic.X86Pblendvb;
|
Intrinsic.X86Pblendvb;
|
||||||
|
|
||||||
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
|
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
|
||||||
// SHA256RNDS2 always has an implied XMM0 as a last operand.
|
// SHA256RNDS2 always has an implied XMM0 as a last operand.
|
||||||
|
@ -348,7 +355,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
|
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
|
||||||
|
|
||||||
node.SetDestinations(new Operand[] { rdx, rax });
|
node.SetDestinations([rdx, rax]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -513,8 +520,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Operand dest = node.Destination;
|
Operand dest = node.Destination;
|
||||||
Operand source = node.GetSource(0);
|
Operand source = node.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type == OperandType.FP32 ||
|
Debug.Assert(dest.Type is OperandType.FP32 or
|
||||||
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
|
OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
|
||||||
|
|
||||||
Operation currentNode = node;
|
Operation currentNode = node;
|
||||||
|
|
||||||
|
@ -759,9 +766,9 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
var compType = (Comparison)comp.AsInt32();
|
Comparison compType = (Comparison)comp.AsInt32();
|
||||||
|
|
||||||
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
return compType is Comparison.Equal or Comparison.NotEqual;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
Operand dest = node.Destination;
|
Operand dest = node.Destination;
|
||||||
|
|
||||||
List<Operand> sources = new()
|
List<Operand> sources =
|
||||||
{
|
[
|
||||||
node.GetSource(0),
|
node.GetSource(0)
|
||||||
};
|
];
|
||||||
|
|
||||||
int argsCount = node.SourcesCount - 1;
|
int argsCount = node.SourcesCount - 1;
|
||||||
|
|
||||||
|
@ -117,10 +117,10 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
|
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
|
||||||
{
|
{
|
||||||
List<Operand> sources = new()
|
List<Operand> sources =
|
||||||
{
|
[
|
||||||
node.GetSource(0),
|
node.GetSource(0)
|
||||||
};
|
];
|
||||||
|
|
||||||
int argsCount = node.SourcesCount - 1;
|
int argsCount = node.SourcesCount - 1;
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
nodes.AddBefore(node, retCopyOp);
|
nodes.AddBefore(node, retCopyOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
node.SetSources(Array.Empty<Operand>());
|
node.SetSources([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
public static void RunPass(ControlFlowGraph cfg)
|
public static void RunPass(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
var constants = new Dictionary<ulong, Operand>();
|
Dictionary<ulong, Operand> constants = new();
|
||||||
|
|
||||||
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
|
||||||
{
|
{
|
||||||
// If the constant has many uses, we also force a new constant mov to be added, in order
|
// If the constant has many uses, we also force a new constant mov to be added, in order
|
||||||
// to avoid overflow of the counts field (that is limited to 16 bits).
|
// to avoid overflow of the counts field (that is limited to 16 bits).
|
||||||
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
|
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
|
||||||
{
|
{
|
||||||
constant = Local(source.Type);
|
constant = Local(source.Type);
|
||||||
|
|
||||||
|
@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
private static bool IsMemoryLoadOrStore(Instruction inst)
|
private static bool IsMemoryLoadOrStore(Instruction inst)
|
||||||
{
|
{
|
||||||
return inst == Instruction.Load ||
|
return inst is Instruction.Load or
|
||||||
inst == Instruction.Load16 ||
|
Instruction.Load16 or
|
||||||
inst == Instruction.Load8 ||
|
Instruction.Load8 or
|
||||||
inst == Instruction.Store ||
|
Instruction.Store or
|
||||||
inst == Instruction.Store16 ||
|
Instruction.Store16 or
|
||||||
inst == Instruction.Store8;
|
Instruction.Store8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
|
||||||
enum X86Register
|
enum X86Register
|
||||||
{
|
{
|
||||||
Invalid = -1,
|
Invalid = -1,
|
||||||
|
|
|
@ -1,252 +0,0 @@
|
||||||
using ARMeilleure.Diagnostics;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a table of guest address to a value.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TEntry">Type of the value</typeparam>
|
|
||||||
public unsafe class AddressTable<TEntry> : IDisposable where TEntry : unmanaged
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a level in an <see cref="AddressTable{TEntry}"/>.
|
|
||||||
/// </summary>
|
|
||||||
public readonly struct Level
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the index of the <see cref="Level"/> in the guest address.
|
|
||||||
/// </summary>
|
|
||||||
public int Index { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the length of the <see cref="Level"/> in the guest address.
|
|
||||||
/// </summary>
|
|
||||||
public int Length { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the mask which masks the bits used by the <see cref="Level"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ulong Mask => ((1ul << Length) - 1) << Index;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Level"/> structure with the specified
|
|
||||||
/// <paramref name="index"/> and <paramref name="length"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index">Index of the <see cref="Level"/></param>
|
|
||||||
/// <param name="length">Length of the <see cref="Level"/></param>
|
|
||||||
public Level(int index, int length)
|
|
||||||
{
|
|
||||||
(Index, Length) = (index, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the value of the <see cref="Level"/> from the specified guest <paramref name="address"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">Guest address</param>
|
|
||||||
/// <returns>Value of the <see cref="Level"/> from the specified guest <paramref name="address"/></returns>
|
|
||||||
public int GetValue(ulong address)
|
|
||||||
{
|
|
||||||
return (int)((address & Mask) >> Index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _disposed;
|
|
||||||
private TEntry** _table;
|
|
||||||
private readonly List<IntPtr> _pages;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the bits used by the <see cref="Levels"/> of the <see cref="AddressTable{TEntry}"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public ulong Mask { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="Level"/>s used by the <see cref="AddressTable{TEntry}"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public Level[] Levels { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the default fill value of newly created leaf pages.
|
|
||||||
/// </summary>
|
|
||||||
public TEntry Fill { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the base address of the <see cref="EntryTable{TEntry}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
|
||||||
public IntPtr Base
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
||||||
|
|
||||||
lock (_pages)
|
|
||||||
{
|
|
||||||
return (IntPtr)GetRootPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new instance of the <see cref="AddressTable{TEntry}"/> class with the specified list of
|
|
||||||
/// <see cref="Level"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="levels"/> is null</exception>
|
|
||||||
/// <exception cref="ArgumentException">Length of <paramref name="levels"/> is less than 2</exception>
|
|
||||||
public AddressTable(Level[] levels)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(levels);
|
|
||||||
|
|
||||||
if (levels.Length < 2)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Table must be at least 2 levels deep.", nameof(levels));
|
|
||||||
}
|
|
||||||
|
|
||||||
_pages = new List<IntPtr>(capacity: 16);
|
|
||||||
|
|
||||||
Levels = levels;
|
|
||||||
Mask = 0;
|
|
||||||
|
|
||||||
foreach (var level in Levels)
|
|
||||||
{
|
|
||||||
Mask |= level.Mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if the specified <paramref name="address"/> is in the range of the
|
|
||||||
/// <see cref="AddressTable{TEntry}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">Guest address</param>
|
|
||||||
/// <returns><see langword="true"/> if is valid; otherwise <see langword="false"/></returns>
|
|
||||||
public bool IsValid(ulong address)
|
|
||||||
{
|
|
||||||
return (address & ~Mask) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a reference to the value at the specified guest <paramref name="address"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">Guest address</param>
|
|
||||||
/// <returns>Reference to the value at the specified guest <paramref name="address"/></returns>
|
|
||||||
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
|
||||||
/// <exception cref="ArgumentException"><paramref name="address"/> is not mapped</exception>
|
|
||||||
public ref TEntry GetValue(ulong address)
|
|
||||||
{
|
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
||||||
|
|
||||||
if (!IsValid(address))
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"Address 0x{address:X} is not mapped onto the table.", nameof(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_pages)
|
|
||||||
{
|
|
||||||
return ref GetPage(address)[Levels[^1].GetValue(address)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the leaf page for the specified guest <paramref name="address"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">Guest address</param>
|
|
||||||
/// <returns>Leaf page for the specified guest <paramref name="address"/></returns>
|
|
||||||
private TEntry* GetPage(ulong address)
|
|
||||||
{
|
|
||||||
TEntry** page = GetRootPage();
|
|
||||||
|
|
||||||
for (int i = 0; i < Levels.Length - 1; i++)
|
|
||||||
{
|
|
||||||
ref Level level = ref Levels[i];
|
|
||||||
ref TEntry* nextPage = ref page[level.GetValue(address)];
|
|
||||||
|
|
||||||
if (nextPage == null)
|
|
||||||
{
|
|
||||||
ref Level nextLevel = ref Levels[i + 1];
|
|
||||||
|
|
||||||
nextPage = i == Levels.Length - 2 ?
|
|
||||||
(TEntry*)Allocate(1 << nextLevel.Length, Fill, leaf: true) :
|
|
||||||
(TEntry*)Allocate(1 << nextLevel.Length, IntPtr.Zero, leaf: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
page = (TEntry**)nextPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TEntry*)page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lazily initialize and get the root page of the <see cref="AddressTable{TEntry}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Root page of the <see cref="AddressTable{TEntry}"/></returns>
|
|
||||||
private TEntry** GetRootPage()
|
|
||||||
{
|
|
||||||
if (_table == null)
|
|
||||||
{
|
|
||||||
_table = (TEntry**)Allocate(1 << Levels[0].Length, fill: IntPtr.Zero, leaf: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allocates a block of memory of the specified type and length.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">Type of elements</typeparam>
|
|
||||||
/// <param name="length">Number of elements</param>
|
|
||||||
/// <param name="fill">Fill value</param>
|
|
||||||
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword="false"/></param>
|
|
||||||
/// <returns>Allocated block</returns>
|
|
||||||
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
|
||||||
{
|
|
||||||
var size = sizeof(T) * length;
|
|
||||||
var page = (IntPtr)NativeAllocator.Instance.Allocate((uint)size);
|
|
||||||
var span = new Span<T>((void*)page, length);
|
|
||||||
|
|
||||||
span.Fill(fill);
|
|
||||||
|
|
||||||
_pages.Add(page);
|
|
||||||
|
|
||||||
TranslatorEventSource.Log.AddressTableAllocated(size, leaf);
|
|
||||||
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases all resources used by the <see cref="AddressTable{TEntry}"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases all unmanaged and optionally managed resources used by the <see cref="AddressTable{TEntry}"/>
|
|
||||||
/// instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resouces</param>
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (!_disposed)
|
|
||||||
{
|
|
||||||
foreach (var page in _pages)
|
|
||||||
{
|
|
||||||
Marshal.FreeHGlobal(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
_disposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Frees resources used by the <see cref="AddressTable{TEntry}"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
~AddressTable()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
44
src/ARMeilleure/Common/AddressTableLevel.cs
Normal file
44
src/ARMeilleure/Common/AddressTableLevel.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
namespace ARMeilleure.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a level in an <see cref="IAddressTable{TEntry}"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct AddressTableLevel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the <see cref="Level"/> in the guest address.
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the length of the <see cref="AddressTableLevel"/> in the guest address.
|
||||||
|
/// </summary>
|
||||||
|
public int Length { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the mask which masks the bits used by the <see cref="AddressTableLevel"/>.
|
||||||
|
/// </summary>
|
||||||
|
public ulong Mask => ((1ul << Length) - 1) << Index;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AddressTableLevel"/> structure with the specified
|
||||||
|
/// <paramref name="index"/> and <paramref name="length"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Index of the <see cref="AddressTableLevel"/></param>
|
||||||
|
/// <param name="length">Length of the <see cref="AddressTableLevel"/></param>
|
||||||
|
public AddressTableLevel(int index, int length)
|
||||||
|
{
|
||||||
|
(Index, Length) = (index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the <see cref="AddressTableLevel"/> from the specified guest <paramref name="address"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Guest address</param>
|
||||||
|
/// <returns>Value of the <see cref="AddressTableLevel"/> from the specified guest <paramref name="address"/></returns>
|
||||||
|
public long GetValue(ulong address)
|
||||||
|
{
|
||||||
|
return (long)((address & Mask) >> Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
src/ARMeilleure/Common/AddressTablePresets.cs
Normal file
69
src/ARMeilleure/Common/AddressTablePresets.cs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
namespace ARMeilleure.Common
|
||||||
|
{
|
||||||
|
public static class AddressTablePresets
|
||||||
|
{
|
||||||
|
private static readonly AddressTableLevel[] _levels64Bit =
|
||||||
|
[
|
||||||
|
new(31, 17),
|
||||||
|
new(23, 8),
|
||||||
|
new(15, 8),
|
||||||
|
new( 7, 8),
|
||||||
|
new( 2, 5)
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly AddressTableLevel[] _levels32Bit =
|
||||||
|
[
|
||||||
|
new(31, 17),
|
||||||
|
new(23, 8),
|
||||||
|
new(15, 8),
|
||||||
|
new( 7, 8),
|
||||||
|
new( 1, 6)
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly AddressTableLevel[] _levels64BitSparseTiny =
|
||||||
|
[
|
||||||
|
new( 11, 28),
|
||||||
|
new( 2, 9)
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly AddressTableLevel[] _levels32BitSparseTiny =
|
||||||
|
[
|
||||||
|
new( 10, 22),
|
||||||
|
new( 1, 9)
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly AddressTableLevel[] _levels64BitSparseGiant =
|
||||||
|
[
|
||||||
|
new( 38, 1),
|
||||||
|
new( 2, 36)
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly AddressTableLevel[] _levels32BitSparseGiant =
|
||||||
|
[
|
||||||
|
new( 31, 1),
|
||||||
|
new( 1, 30)
|
||||||
|
];
|
||||||
|
|
||||||
|
//high power will run worse on DDR3 systems and some DDR4 systems due to the higher ram utilization
|
||||||
|
//low power will never run worse than non-sparse, but for most systems it won't be necessary
|
||||||
|
//high power is always used, but I've left low power in here for future reference
|
||||||
|
public static AddressTableLevel[] GetArmPreset(bool for64Bits, bool sparse, bool lowPower = false)
|
||||||
|
{
|
||||||
|
if (sparse)
|
||||||
|
{
|
||||||
|
if (lowPower)
|
||||||
|
{
|
||||||
|
return for64Bits ? _levels64BitSparseTiny : _levels32BitSparseTiny;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return for64Bits ? _levels64BitSparseGiant : _levels32BitSparseGiant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return for64Bits ? _levels64Bit : _levels32Bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
|
|
||||||
namespace ARMeilleure.Common
|
namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
unsafe abstract class Allocator : IDisposable
|
public unsafe abstract class Allocator : IDisposable
|
||||||
{
|
{
|
||||||
public T* Allocate<T>(ulong count = 1) where T : unmanaged
|
public T* Allocate<T>(ulong count = 1) where T : unmanaged
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ARMeilleure.Common
|
||||||
private List<PageInfo> _pages;
|
private List<PageInfo> _pages;
|
||||||
private readonly ulong _pageSize;
|
private readonly ulong _pageSize;
|
||||||
private readonly uint _pageCount;
|
private readonly uint _pageCount;
|
||||||
private readonly List<IntPtr> _extras;
|
private readonly List<nint> _extras;
|
||||||
|
|
||||||
public ArenaAllocator(uint pageSize, uint pageCount)
|
public ArenaAllocator(uint pageSize, uint pageCount)
|
||||||
{
|
{
|
||||||
|
@ -31,11 +31,11 @@ namespace ARMeilleure.Common
|
||||||
_pageIndex = -1;
|
_pageIndex = -1;
|
||||||
|
|
||||||
_page = null;
|
_page = null;
|
||||||
_pages = new List<PageInfo>();
|
_pages = [];
|
||||||
_pageSize = pageSize;
|
_pageSize = pageSize;
|
||||||
_pageCount = pageCount;
|
_pageCount = pageCount;
|
||||||
|
|
||||||
_extras = new List<IntPtr>();
|
_extras = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<T> AllocateSpan<T>(ulong count) where T : unmanaged
|
public Span<T> AllocateSpan<T>(ulong count) where T : unmanaged
|
||||||
|
@ -64,7 +64,7 @@ namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
void* extra = NativeAllocator.Instance.Allocate(size);
|
void* extra = NativeAllocator.Instance.Allocate(size);
|
||||||
|
|
||||||
_extras.Add((IntPtr)extra);
|
_extras.Add((nint)extra);
|
||||||
|
|
||||||
return extra;
|
return extra;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
_page = new PageInfo
|
_page = new PageInfo
|
||||||
{
|
{
|
||||||
Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize),
|
Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize)
|
||||||
};
|
};
|
||||||
|
|
||||||
_pages.Add(_page);
|
_pages.Add(_page);
|
||||||
|
@ -114,7 +114,7 @@ namespace ARMeilleure.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free extra blocks that are not page-sized
|
// Free extra blocks that are not page-sized
|
||||||
foreach (IntPtr ptr in _extras)
|
foreach (nint ptr in _extras)
|
||||||
{
|
{
|
||||||
NativeAllocator.Instance.Free((void*)ptr);
|
NativeAllocator.Instance.Free((void*)ptr);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ namespace ARMeilleure.Common
|
||||||
NativeAllocator.Instance.Free(info.Pointer);
|
NativeAllocator.Instance.Free(info.Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (IntPtr ptr in _extras)
|
foreach (nint ptr in _extras)
|
||||||
{
|
{
|
||||||
NativeAllocator.Instance.Free((void*)ptr);
|
NativeAllocator.Instance.Free((void*)ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,13 +129,13 @@ namespace ARMeilleure.Common
|
||||||
|
|
||||||
if (count > _count)
|
if (count > _count)
|
||||||
{
|
{
|
||||||
var oldMask = _masks;
|
long* oldMask = _masks;
|
||||||
var oldSpan = new Span<long>(_masks, _count);
|
Span<long> oldSpan = new(_masks, _count);
|
||||||
|
|
||||||
_masks = _allocator.Allocate<long>((uint)count);
|
_masks = _allocator.Allocate<long>((uint)count);
|
||||||
_count = count;
|
_count = count;
|
||||||
|
|
||||||
var newSpan = new Span<long>(_masks, _count);
|
Span<long> newSpan = new(_masks, _count);
|
||||||
|
|
||||||
oldSpan.CopyTo(newSpan);
|
oldSpan.CopyTo(newSpan);
|
||||||
newSpan[oldSpan.Length..].Clear();
|
newSpan[oldSpan.Length..].Clear();
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
static class BitUtils
|
static class BitUtils
|
||||||
{
|
{
|
||||||
private static ReadOnlySpan<sbyte> HbsNibbleLut => new sbyte[] { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
|
private static ReadOnlySpan<sbyte> HbsNibbleLut => [-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3];
|
||||||
|
|
||||||
public static long FillWithOnes(int bits)
|
public static long FillWithOnes(int bits)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace ARMeilleure.Common
|
||||||
private int _freeHint;
|
private int _freeHint;
|
||||||
private readonly int _pageCapacity; // Number of entries per page.
|
private readonly int _pageCapacity; // Number of entries per page.
|
||||||
private readonly int _pageLogCapacity;
|
private readonly int _pageLogCapacity;
|
||||||
private readonly Dictionary<int, IntPtr> _pages;
|
private readonly Dictionary<int, nint> _pages;
|
||||||
private readonly BitMap _allocated;
|
private readonly BitMap _allocated;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -41,7 +41,7 @@ namespace ARMeilleure.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
_allocated = new BitMap(NativeAllocator.Instance);
|
_allocated = new BitMap(NativeAllocator.Instance);
|
||||||
_pages = new Dictionary<int, IntPtr>();
|
_pages = new Dictionary<int, nint>();
|
||||||
_pageLogCapacity = BitOperations.Log2((uint)(pageSize / sizeof(TEntry)));
|
_pageLogCapacity = BitOperations.Log2((uint)(pageSize / sizeof(TEntry)));
|
||||||
_pageCapacity = 1 << _pageLogCapacity;
|
_pageCapacity = 1 << _pageLogCapacity;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace ARMeilleure.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = _freeHint++;
|
int index = _freeHint++;
|
||||||
var page = GetPage(index);
|
Span<TEntry> page = GetPage(index);
|
||||||
|
|
||||||
_allocated.Set(index);
|
_allocated.Set(index);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ namespace ARMeilleure.Common
|
||||||
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
|
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
var page = GetPage(index);
|
Span<TEntry> page = GetPage(index);
|
||||||
|
|
||||||
return ref GetValue(page, index);
|
return ref GetValue(page, index);
|
||||||
}
|
}
|
||||||
|
@ -136,11 +136,11 @@ namespace ARMeilleure.Common
|
||||||
/// <returns>Page for the specified <see cref="index"/></returns>
|
/// <returns>Page for the specified <see cref="index"/></returns>
|
||||||
private unsafe Span<TEntry> GetPage(int index)
|
private unsafe Span<TEntry> GetPage(int index)
|
||||||
{
|
{
|
||||||
var pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
|
int pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
|
||||||
|
|
||||||
if (!_pages.TryGetValue(pageIndex, out IntPtr page))
|
if (!_pages.TryGetValue(pageIndex, out nint page))
|
||||||
{
|
{
|
||||||
page = (IntPtr)NativeAllocator.Instance.Allocate((uint)sizeof(TEntry) * (uint)_pageCapacity);
|
page = (nint)NativeAllocator.Instance.Allocate((uint)sizeof(TEntry) * (uint)_pageCapacity);
|
||||||
|
|
||||||
_pages.Add(pageIndex, page);
|
_pages.Add(pageIndex, page);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
_allocated.Dispose();
|
_allocated.Dispose();
|
||||||
|
|
||||||
foreach (var page in _pages.Values)
|
foreach (IntPtr page in _pages.Values)
|
||||||
{
|
{
|
||||||
NativeAllocator.Instance.Free((void*)page);
|
NativeAllocator.Instance.Free((void*)page);
|
||||||
}
|
}
|
||||||
|
|
51
src/ARMeilleure/Common/IAddressTable.cs
Normal file
51
src/ARMeilleure/Common/IAddressTable.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Common
|
||||||
|
{
|
||||||
|
public interface IAddressTable<TEntry> : IDisposable where TEntry : unmanaged
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True if the address table's bottom level is sparsely mapped.
|
||||||
|
/// This also ensures the second bottom level is filled with a dummy page rather than 0.
|
||||||
|
/// </summary>
|
||||||
|
bool Sparse { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the bits used by the <see cref="Levels"/> of the <see cref="IAddressTable{TEntry}"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
ulong Mask { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="AddressTableLevel"/>s used by the <see cref="IAddressTable{TEntry}"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
AddressTableLevel[] Levels { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default fill value of newly created leaf pages.
|
||||||
|
/// </summary>
|
||||||
|
TEntry Fill { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the base address of the <see cref="EntryTable{TEntry}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
||||||
|
nint Base { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the specified <paramref name="address"/> is in the range of the
|
||||||
|
/// <see cref="IAddressTable{TEntry}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Guest address</param>
|
||||||
|
/// <returns><see langword="true"/> if is valid; otherwise <see langword="false"/></returns>
|
||||||
|
bool IsValid(ulong address);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a reference to the value at the specified guest <paramref name="address"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Guest address</param>
|
||||||
|
/// <returns>Reference to the value at the specified guest <paramref name="address"/></returns>
|
||||||
|
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="address"/> is not mapped</exception>
|
||||||
|
ref TEntry GetValue(ulong address);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,13 +3,13 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ARMeilleure.Common
|
namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
unsafe sealed class NativeAllocator : Allocator
|
public unsafe sealed class NativeAllocator : Allocator
|
||||||
{
|
{
|
||||||
public static NativeAllocator Instance { get; } = new();
|
public static NativeAllocator Instance { get; } = new();
|
||||||
|
|
||||||
public override void* Allocate(ulong size)
|
public override void* Allocate(ulong size)
|
||||||
{
|
{
|
||||||
void* result = (void*)Marshal.AllocHGlobal((IntPtr)size);
|
void* result = (void*)Marshal.AllocHGlobal((nint)size);
|
||||||
|
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ namespace ARMeilleure.Common
|
||||||
|
|
||||||
public override void Free(void* block)
|
public override void Free(void* block)
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal((IntPtr)block);
|
Marshal.FreeHGlobal((nint)block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public Block()
|
public Block()
|
||||||
{
|
{
|
||||||
OpCodes = new List<OpCode>();
|
OpCodes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block(ulong address) : this()
|
public Block(ulong address) : this()
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
|
public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
|
||||||
{
|
{
|
||||||
List<Block> blocks = new();
|
List<Block> blocks = [];
|
||||||
|
|
||||||
Queue<Block> workQueue = new();
|
Queue<Block> workQueue = new();
|
||||||
|
|
||||||
|
@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare and branch instructions are always conditional.
|
// Compare and branch instructions are always conditional.
|
||||||
if (opCode.Instruction.Name == InstName.Cbz ||
|
if (opCode.Instruction.Name is InstName.Cbz or
|
||||||
opCode.Instruction.Name == InstName.Cbnz)
|
InstName.Cbnz)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -274,9 +274,10 @@ namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
if (opCode is OpCodeT32)
|
if (opCode is OpCodeT32)
|
||||||
{
|
{
|
||||||
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq &&
|
return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
|
||||||
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn;
|
not InstName.Cmp and not InstName.Cmn;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +285,7 @@ namespace ARMeilleure.Decoders
|
||||||
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
|
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
|
||||||
// a write back to PC (wback == true && Rn == 15), however the later may
|
// a write back to PC (wback == true && Rn == 15), however the later may
|
||||||
// be "undefined" depending on the CPU, so compilers should not produce that.
|
// be "undefined" depending on the CPU, so compilers should not produce that.
|
||||||
if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult)
|
if (opCode is IOpCode32Mem or IOpCode32MemMult)
|
||||||
{
|
{
|
||||||
int rt, rn;
|
int rt, rn;
|
||||||
|
|
||||||
|
@ -326,15 +327,15 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit branch instructions.
|
// Explicit branch instructions.
|
||||||
return opCode is IOpCode32BImm ||
|
return opCode is IOpCode32BImm or
|
||||||
opCode is IOpCode32BReg;
|
IOpCode32BReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsCall(OpCode opCode)
|
private static bool IsCall(OpCode opCode)
|
||||||
{
|
{
|
||||||
return opCode.Instruction.Name == InstName.Bl ||
|
return opCode.Instruction.Name is InstName.Bl or
|
||||||
opCode.Instruction.Name == InstName.Blr ||
|
InstName.Blr or
|
||||||
opCode.Instruction.Name == InstName.Blx;
|
InstName.Blx;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsException(OpCode opCode)
|
private static bool IsException(OpCode opCode)
|
||||||
|
@ -344,9 +345,9 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
private static bool IsTrap(OpCode opCode)
|
private static bool IsTrap(OpCode opCode)
|
||||||
{
|
{
|
||||||
return opCode.Instruction.Name == InstName.Brk ||
|
return opCode.Instruction.Name is InstName.Brk or
|
||||||
opCode.Instruction.Name == InstName.Trap ||
|
InstName.Trap or
|
||||||
opCode.Instruction.Name == InstName.Und;
|
InstName.Und;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)
|
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using ARMeilleure.Common;
|
using ARMeilleure.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
|
@ -149,7 +150,7 @@ namespace ARMeilleure.Decoders
|
||||||
return (((long)opCode << 45) >> 48) & ~3;
|
return (((long)opCode << 45) >> 48) & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool VectorArgumentsInvalid(bool q, params int[] args)
|
public static bool VectorArgumentsInvalid(bool q, params ReadOnlySpan<int> args)
|
||||||
{
|
{
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
|
@ -161,6 +162,7 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
||||||
{
|
{
|
||||||
var opc = (opCode >> 16) & 0xf;
|
int opc = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
if ((opc & 0b1) == 1)
|
if ((opc & 0b1) == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace ARMeilleure.Decoders
|
||||||
Instruction = InstDescriptor.Undefined;
|
Instruction = InstDescriptor.Undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q = ((opCode >> 21) & 0x1) != 0;
|
Q = ((opCode >> 21) & 0x1) != 0;
|
||||||
|
|
||||||
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
||||||
|
|
|
@ -5,12 +5,12 @@ namespace ARMeilleure.Decoders
|
||||||
class OpCode32SimdMemPair : OpCode32, IOpCode32Simd
|
class OpCode32SimdMemPair : OpCode32, IOpCode32Simd
|
||||||
{
|
{
|
||||||
private static readonly int[] _regsMap =
|
private static readonly int[] _regsMap =
|
||||||
{
|
[
|
||||||
1, 1, 4, 2,
|
1, 1, 4, 2,
|
||||||
1, 1, 3, 1,
|
1, 1, 3, 1,
|
||||||
1, 1, 2, 1,
|
1, 1, 2, 1,
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1
|
||||||
};
|
];
|
||||||
|
|
||||||
public int Vd { get; }
|
public int Vd { get; }
|
||||||
public int Rn { get; }
|
public int Rn { get; }
|
||||||
|
@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
|
||||||
Rn = (opCode >> 16) & 0xf;
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
WBack = Rm != RegisterAlias.Aarch32Pc;
|
WBack = Rm != RegisterAlias.Aarch32Pc;
|
||||||
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
|
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
|
||||||
|
|
||||||
Regs = _regsMap[(opCode >> 8) & 0xf];
|
Regs = _regsMap[(opCode >> 8) & 0xf];
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
|
||||||
Rn = (opCode >> 16) & 0xf;
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
WBack = Rm != RegisterAlias.Aarch32Pc;
|
WBack = Rm != RegisterAlias.Aarch32Pc;
|
||||||
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
|
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace ARMeilleure.Decoders
|
||||||
Op = (opCode >> 20) & 0x1;
|
Op = (opCode >> 20) & 0x1;
|
||||||
U = ((opCode >> 23) & 1) != 0;
|
U = ((opCode >> 23) & 1) != 0;
|
||||||
|
|
||||||
var opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
|
int opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
|
||||||
|
|
||||||
if ((opc & 0b01000) == 0b01000)
|
if ((opc & 0b01000) == 0b01000)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
else if (DataOp == DataOp.Logical)
|
else if (DataOp == DataOp.Logical)
|
||||||
{
|
{
|
||||||
var bm = DecoderHelper.DecodeBitMask(opCode, true);
|
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, true);
|
||||||
|
|
||||||
if (bm.IsUndefined)
|
if (bm.IsUndefined)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
{
|
{
|
||||||
var bm = DecoderHelper.DecodeBitMask(opCode, false);
|
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, false);
|
||||||
|
|
||||||
if (bm.IsUndefined)
|
if (bm.IsUndefined)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
|
||||||
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
|
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
|
||||||
|
|
||||||
PostIdx = type == MemOp.PostIndexed;
|
PostIdx = type == MemOp.PostIndexed;
|
||||||
Unscaled = type == MemOp.Unscaled ||
|
Unscaled = type is MemOp.Unscaled or
|
||||||
type == MemOp.Unprivileged;
|
MemOp.Unprivileged;
|
||||||
|
|
||||||
// Unscaled and Unprivileged doesn't write back,
|
// Unscaled and Unprivileged doesn't write back,
|
||||||
// but they do use the 9-bits Signed Immediate.
|
// but they do use the 9-bits Signed Immediate.
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
{
|
{
|
||||||
List<Condition> conds = new();
|
List<Condition> conds = [];
|
||||||
|
|
||||||
int cond = (opCode >> 4) & 0xf;
|
int cond = (opCode >> 4) & 0xf;
|
||||||
int mask = opCode & 0xf;
|
int mask = opCode & 0xf;
|
||||||
|
|
|
@ -29,9 +29,9 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly List<InstInfo> _allInstA32 = new();
|
private static readonly List<InstInfo> _allInstA32 = [];
|
||||||
private static readonly List<InstInfo> _allInstT32 = new();
|
private static readonly List<InstInfo> _allInstT32 = [];
|
||||||
private static readonly List<InstInfo> _allInstA64 = new();
|
private static readonly List<InstInfo> _allInstA64 = [];
|
||||||
|
|
||||||
private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][];
|
private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][];
|
||||||
private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][];
|
private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][];
|
||||||
|
@ -1330,7 +1330,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
for (int index = 0; index < temp.Length; index++)
|
for (int index = 0; index < temp.Length; index++)
|
||||||
{
|
{
|
||||||
temp[index] = new List<InstInfo>();
|
temp[index] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (InstInfo inst in allInsts)
|
foreach (InstInfo inst in allInsts)
|
||||||
|
@ -1381,6 +1381,7 @@ namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
|
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,6 +1410,7 @@ namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Invalid ASIMD instruction encoding");
|
throw new ArgumentException("Invalid ASIMD instruction encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace ARMeilleure.Decoders.Optimizations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newBlocks = new List<Block>(blocks.Count);
|
List<Block> newBlocks = new(blocks.Count);
|
||||||
|
|
||||||
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
|
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
|
||||||
{
|
{
|
||||||
class IRDumper
|
class IRDumper
|
||||||
{
|
{
|
||||||
private const string Indentation = " ";
|
private const char Indentation = ' ';
|
||||||
|
|
||||||
private int _indentLevel;
|
private int _indentLevel;
|
||||||
|
|
||||||
|
@ -30,14 +30,11 @@ namespace ARMeilleure.Diagnostics
|
||||||
|
|
||||||
private void Indent()
|
private void Indent()
|
||||||
{
|
{
|
||||||
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length);
|
if (_indentLevel == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int index = 0; index < _indentLevel; index++)
|
_builder.EnsureCapacity(_builder.Capacity + _indentLevel);
|
||||||
{
|
_builder.Append(Indentation, _indentLevel);
|
||||||
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
|
|
||||||
_builder.Append(Indentation);
|
|
||||||
#pragma warning restore CA1834
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncreaseIndentation()
|
private void IncreaseIndentation()
|
||||||
|
@ -141,7 +138,7 @@ namespace ARMeilleure.Diagnostics
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandKind.Memory:
|
case OperandKind.Memory:
|
||||||
var memOp = operand.GetMemory();
|
MemoryOperand memOp = operand.GetMemory();
|
||||||
|
|
||||||
_builder.Append('[');
|
_builder.Append('[');
|
||||||
|
|
||||||
|
@ -235,8 +232,8 @@ namespace ARMeilleure.Diagnostics
|
||||||
{
|
{
|
||||||
_builder.Append('.').Append(operation.Intrinsic);
|
_builder.Append('.').Append(operation.Intrinsic);
|
||||||
}
|
}
|
||||||
else if (operation.Instruction == Instruction.BranchIf ||
|
else if (operation.Instruction is Instruction.BranchIf or
|
||||||
operation.Instruction == Instruction.Compare)
|
Instruction.Compare)
|
||||||
{
|
{
|
||||||
comparison = true;
|
comparison = true;
|
||||||
}
|
}
|
||||||
|
@ -262,6 +259,7 @@ namespace ARMeilleure.Diagnostics
|
||||||
DumpOperand(source);
|
DumpOperand(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +283,7 @@ namespace ARMeilleure.Diagnostics
|
||||||
|
|
||||||
public static string GetDump(ControlFlowGraph cfg)
|
public static string GetDump(ControlFlowGraph cfg)
|
||||||
{
|
{
|
||||||
var dumper = new IRDumper(1);
|
IRDumper dumper = new(1);
|
||||||
|
|
||||||
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ARMeilleure.Diagnostics
|
||||||
static Symbols()
|
static Symbols()
|
||||||
{
|
{
|
||||||
_symbols = new ConcurrentDictionary<ulong, string>();
|
_symbols = new ConcurrentDictionary<ulong, string>();
|
||||||
_rangedSymbols = new List<RangedSymbol>();
|
_rangedSymbols = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Get(ulong address)
|
public static string Get(ulong address)
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
#region "LookUp Tables"
|
#region "LookUp Tables"
|
||||||
#pragma warning disable IDE1006 // Naming rule violation
|
#pragma warning disable IDE1006 // Naming rule violation
|
||||||
private static ReadOnlySpan<byte> _sBox => new byte[]
|
private static ReadOnlySpan<byte> _sBox =>
|
||||||
{
|
[
|
||||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||||
|
@ -26,11 +26,11 @@ namespace ARMeilleure.Instructions
|
||||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
|
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _invSBox => new byte[]
|
private static ReadOnlySpan<byte> _invSBox =>
|
||||||
{
|
[
|
||||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||||
|
@ -46,11 +46,11 @@ namespace ARMeilleure.Instructions
|
||||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
|
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul02 => new byte[]
|
private static ReadOnlySpan<byte> _gfMul02 =>
|
||||||
{
|
[
|
||||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||||
|
@ -66,11 +66,11 @@ namespace ARMeilleure.Instructions
|
||||||
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
||||||
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
||||||
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
||||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5,
|
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul03 => new byte[]
|
private static ReadOnlySpan<byte> _gfMul03 =>
|
||||||
{
|
[
|
||||||
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
|
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
|
||||||
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
|
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
|
||||||
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
|
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
|
||||||
|
@ -86,11 +86,11 @@ namespace ARMeilleure.Instructions
|
||||||
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
|
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
|
||||||
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
|
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
|
||||||
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
|
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
|
||||||
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a,
|
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul09 => new byte[]
|
private static ReadOnlySpan<byte> _gfMul09 =>
|
||||||
{
|
[
|
||||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||||
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
||||||
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
||||||
|
@ -106,11 +106,11 @@ namespace ARMeilleure.Instructions
|
||||||
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
|
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
|
||||||
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
|
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
|
||||||
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
|
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
|
||||||
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46,
|
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul0B => new byte[]
|
private static ReadOnlySpan<byte> _gfMul0B =>
|
||||||
{
|
[
|
||||||
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
||||||
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
||||||
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
|
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
|
||||||
|
@ -126,11 +126,11 @@ namespace ARMeilleure.Instructions
|
||||||
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
|
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
|
||||||
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
|
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
|
||||||
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
|
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
|
||||||
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3,
|
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul0D => new byte[]
|
private static ReadOnlySpan<byte> _gfMul0D =>
|
||||||
{
|
[
|
||||||
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
||||||
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
||||||
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
|
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
|
||||||
|
@ -146,11 +146,11 @@ namespace ARMeilleure.Instructions
|
||||||
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
|
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
|
||||||
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
|
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
|
||||||
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
|
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
|
||||||
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97,
|
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _gfMul0E => new byte[]
|
private static ReadOnlySpan<byte> _gfMul0E =>
|
||||||
{
|
[
|
||||||
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
||||||
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
||||||
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
|
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
|
||||||
|
@ -166,18 +166,18 @@ namespace ARMeilleure.Instructions
|
||||||
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
|
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
|
||||||
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
|
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
|
||||||
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
|
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
|
||||||
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d,
|
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _srPerm => new byte[]
|
private static ReadOnlySpan<byte> _srPerm =>
|
||||||
{
|
[
|
||||||
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3,
|
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
|
||||||
};
|
];
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> _isrPerm => new byte[]
|
private static ReadOnlySpan<byte> _isrPerm =>
|
||||||
{
|
[
|
||||||
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11,
|
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
|
||||||
};
|
];
|
||||||
#pragma warning restore IDE1006
|
#pragma warning restore IDE1006
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -415,7 +415,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||||
|
|
||||||
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||||
|
|
||||||
Operand n = GetIntA32(context, op.Rn);
|
Operand n = GetIntA32(context, op.Rn);
|
||||||
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
||||||
|
@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||||
|
|
||||||
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||||
|
|
||||||
Operand n = GetIntA32(context, op.Rn);
|
Operand n = GetIntA32(context, op.Rn);
|
||||||
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
||||||
|
@ -899,6 +899,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
n = context.ShiftLeft(n, Const(shift));
|
n = context.ShiftLeft(n, Const(shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShiftType.Asr:
|
case ShiftType.Asr:
|
||||||
if (shift == 32)
|
if (shift == 32)
|
||||||
|
@ -909,6 +910,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
n = context.ShiftRightSI(n, Const(shift));
|
n = context.ShiftRightSI(n, Const(shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ namespace ARMeilleure.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Exception InvalidOpCodeType(OpCode opCode)
|
private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
|
||||||
{
|
{
|
||||||
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
|
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
|
||||||
}
|
}
|
||||||
|
@ -318,6 +318,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
m = GetRrxC(context, m, setCarry);
|
m = GetRrxC(context, m, setCarry);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using ARMeilleure.CodeGen.Linking;
|
using ARMeilleure.CodeGen.Linking;
|
||||||
|
using ARMeilleure.Common;
|
||||||
using ARMeilleure.Decoders;
|
using ARMeilleure.Decoders;
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
|
@ -193,6 +194,8 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
Operand hostAddress;
|
Operand hostAddress;
|
||||||
|
|
||||||
|
IAddressTable<ulong> table = context.FunctionTable;
|
||||||
|
|
||||||
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
|
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
|
||||||
// onto the dispatch stub.
|
// onto the dispatch stub.
|
||||||
if (guestAddress.Kind == OperandKind.Constant && context.FunctionTable.IsValid(guestAddress.Value))
|
if (guestAddress.Kind == OperandKind.Constant && context.FunctionTable.IsValid(guestAddress.Value))
|
||||||
|
@ -203,6 +206,30 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
hostAddress = context.Load(OperandType.I64, hostAddressAddr);
|
hostAddress = context.Load(OperandType.I64, hostAddressAddr);
|
||||||
}
|
}
|
||||||
|
else if (table.Sparse)
|
||||||
|
{
|
||||||
|
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||||
|
// Deliberately attempts to avoid branches.
|
||||||
|
|
||||||
|
Operand tableBase = !context.HasPtc ?
|
||||||
|
Const(table.Base) :
|
||||||
|
Const(table.Base, Ptc.FunctionTableSymbol);
|
||||||
|
|
||||||
|
hostAddress = tableBase;
|
||||||
|
|
||||||
|
for (int i = 0; i < table.Levels.Length; i++)
|
||||||
|
{
|
||||||
|
AddressTableLevel level = table.Levels[i];
|
||||||
|
int clearBits = 64 - (level.Index + level.Length);
|
||||||
|
|
||||||
|
Operand index = context.ShiftLeft(
|
||||||
|
context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits)), Const(clearBits + level.Index)),
|
||||||
|
Const(3)
|
||||||
|
);
|
||||||
|
|
||||||
|
hostAddress = context.Load(OperandType.I64, context.Add(hostAddress, index));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hostAddress = !context.HasPtc ?
|
hostAddress = !context.HasPtc ?
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
|
||||||
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
|
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
|
||||||
{
|
{
|
||||||
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
|
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
|
||||||
Debug.Assert(size >= 0 && size < 4);
|
Debug.Assert(size is >= 0 and < 4);
|
||||||
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
|
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
|
||||||
|
|
||||||
if (castagnoli && Optimizations.UseSse42)
|
if (castagnoli && Optimizations.UseSse42)
|
||||||
|
|
|
@ -90,6 +90,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
value = context.ConvertI64ToI32(value);
|
value = context.ConvertI64ToI32(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
|
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
|
||||||
|
|
||||||
context.Copy(reg, value);
|
context.Copy(reg, value);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue