mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 13:16:43 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d942c5ae2 |
Vendored
+315
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+321
-352
File diff suppressed because it is too large
Load Diff
Vendored
+314
-344
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-346
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+315
-345
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
Vendored
+316
-346
File diff suppressed because it is too large
Load Diff
@@ -462,8 +462,8 @@
|
||||
<string name="renderer_resolution">الدقة (الإرساء/محمول)</string>
|
||||
<string name="renderer_vsync">VSync وضع</string>
|
||||
<string name="renderer_scaling_filter">مرشح ملائم للنافذة</string>
|
||||
<string name="fsr_sharpness">حدة FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام مرشحات FSR أو SGSR</string>
|
||||
<string name="fsr_sharpness">حدة FSR</string>
|
||||
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام التباين الديناميكي لـ FSR</string>
|
||||
<string name="renderer_anti_aliasing">طريقة مضاد التعرج</string>
|
||||
|
||||
|
||||
@@ -503,8 +503,6 @@
|
||||
<string name="fast_gpu_time_description">يُجبر هذا الخيار معظم الألعاب على العمل بأعلى دقة عرض أصلية. استخدم 256 للحصول على أقصى أداء و512 للحصول على أعلى جودة رسومات.</string>
|
||||
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
|
||||
<string name="antiflicker">مضاد الوميض</string>
|
||||
<string name="antiflicker_description">يُجبر هذا الوضع وظائف وحدة معالجة الرسومات على الانتظار حتى يتم إرسال العمل إليها. استخدمه مع وضع وحدة معالجة الرسومات السريع لتجنب الوميض مع تأثير أقل على الأداء.</string>
|
||||
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
|
||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
||||
<string name="emulate_bgr565">محاكاة BGR565</string>
|
||||
|
||||
@@ -329,6 +329,8 @@
|
||||
<string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
|
||||
<string name="renderer_vsync">دۆخی VSync</string>
|
||||
<string name="renderer_scaling_filter">فلتەری گونجاندنی پەنجەرە</string>
|
||||
<string name="fsr_sharpness">تیژی FSR</string>
|
||||
<string name="fsr_sharpness_description">دیاریکردنی تیژی وێنە لە کاتی بەکارهێنانی FSR</string>
|
||||
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
|
||||
|
||||
|
||||
|
||||
@@ -439,6 +439,8 @@
|
||||
<string name="renderer_resolution">Rozlišení (Handheld/V doku)</string>
|
||||
<string name="renderer_vsync">Režim VSync</string>
|
||||
<string name="renderer_scaling_filter">Škálovací filtr</string>
|
||||
<string name="fsr_sharpness">Ostrost FSR</string>
|
||||
<string name="fsr_sharpness_description">Určuje jak ostře bude obraz vypadat při použití dynamického kontrastu FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Metoda anti-aliasingu</string>
|
||||
|
||||
|
||||
|
||||
@@ -439,6 +439,8 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
|
||||
<string name="renderer_resolution">Auflösung (Handheld/Gedockt)</string>
|
||||
<string name="renderer_vsync">VSync-Modus</string>
|
||||
<string name="renderer_scaling_filter">Skalierungsfilter</string>
|
||||
<string name="fsr_sharpness">FSR-Schärfe</string>
|
||||
<string name="fsr_sharpness_description">Bestimmt die Schärfe bei FSR-Nutzung.</string>
|
||||
<string name="renderer_anti_aliasing">Kantenglättung</string>
|
||||
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
<string name="qlaunch_description">Iniciar aplicaciones desde la pantalla de inicio del sistema</string>
|
||||
<string name="applets">Lanzador de Applet</string>
|
||||
<string name="applets_description">Ejecutar applets del sistema usando el firmware instalado</string>
|
||||
<string name="applets_description">Ejecutar applets de sistema usando el firmware instalado</string>
|
||||
<string name="applets_error_firmware">El firmware no está instalado</string>
|
||||
<string name="applets_error_applet">Applet no disponible</string>
|
||||
<string name="applets_error_description"><![CDATA[Por favor, asegúrese de que su archivo <a href=\"https://yuzu-mirror.github.io/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> y el <a href=\"https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware\">firmware</a> están instalados e inténtelo de nuevo.]]></string>
|
||||
@@ -456,8 +456,8 @@
|
||||
<string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
|
||||
<string name="renderer_vsync">Modo de sincronización vertical</string>
|
||||
<string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
|
||||
<string name="fsr_sharpness">Nitidez FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Determina el grado de nitidez de la imagen al usar filtros FSR o SGSR</string>
|
||||
<string name="fsr_sharpness">Nitidez FSR</string>
|
||||
<string name="fsr_sharpness_description">Ajusta la intensidad del filtro de enfoque al usar el contraste dinámico de FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Método de suavizado de bordes</string>
|
||||
|
||||
|
||||
@@ -497,8 +497,6 @@
|
||||
<string name="fast_gpu_time_description">Fuerza a la mayoría de los juegos a ejecutarse a su resolución nativa más alta. Usa 256 para un máximo rendimiento y 512 para una fidelidad gráfica óptima.</string>
|
||||
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
|
||||
<string name="antiflicker">Antiparpadeo</string>
|
||||
<string name="antiflicker_description">Fuerza a las funciones de devolución de llamada de la GPU a esperar a que se envíen las tareas a la GPU.\nÚsalo con el modo de GPU rápida para evitar el parpadeo con un menor impacto en el rendimiento.</string>
|
||||
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
|
||||
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
||||
<string name="emulate_bgr565">Emular BGR565</string>
|
||||
@@ -1074,7 +1072,7 @@
|
||||
|
||||
<!-- Black backgrounds theme -->
|
||||
<string name="use_black_backgrounds">Fondos oscuros</string>
|
||||
<string name="use_black_backgrounds_description">Cuando se usa el modo oscuro, aplicar fondos de pantalla negros.</string>
|
||||
<string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
|
||||
|
||||
<!-- Buttons -->
|
||||
<string name="enable_folder_button">Carpeta</string>
|
||||
|
||||
@@ -454,6 +454,8 @@
|
||||
<string name="renderer_resolution">Résolution (Mode Portable/Mode TV)</string>
|
||||
<string name="renderer_vsync">Mode VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtre de fenêtre adaptatif</string>
|
||||
<string name="fsr_sharpness">Netteté FSR</string>
|
||||
<string name="fsr_sharpness_description">Détermine à quel point l\'image sera affinée lors de l\'utilisation du contraste dynamique FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
|
||||
|
||||
|
||||
|
||||
@@ -359,6 +359,8 @@
|
||||
<string name="renderer_resolution">רזולוציה (מעוגן/נייד)</string>
|
||||
<string name="renderer_vsync">מצב VSync</string>
|
||||
<string name="renderer_scaling_filter">פילטר מתאם חלון</string>
|
||||
<string name="fsr_sharpness">חדות FSR</string>
|
||||
<string name="fsr_sharpness_description">קובע את מידת החדות בעת שימוש ב-FSR.</string>
|
||||
<string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
|
||||
|
||||
|
||||
|
||||
@@ -348,6 +348,8 @@
|
||||
<string name="renderer_resolution">Felbontás (Kézi/Dockolt)</string>
|
||||
<string name="renderer_vsync">VSync mód</string>
|
||||
<string name="renderer_scaling_filter">Ablakhoz alkalmazkodó szűrő</string>
|
||||
<string name="fsr_sharpness">FSR élesség</string>
|
||||
<string name="fsr_sharpness_description">Meghatározza, milyen éles lesz a kép az FSR dinamikus kontraszt használata közben.</string>
|
||||
<string name="renderer_anti_aliasing">Élsimítási módszer</string>
|
||||
|
||||
|
||||
|
||||
@@ -380,6 +380,8 @@
|
||||
<string name="renderer_resolution">Resolusi (Handheld/Docked)</string>
|
||||
<string name="renderer_vsync">Mode Sinkronisasi Vertikal</string>
|
||||
<string name="renderer_scaling_filter">Filter penyesuaian jendela</string>
|
||||
<string name="fsr_sharpness">Ketajaman FSR</string>
|
||||
<string name="fsr_sharpness_description">Menentukan seberapa tajam gambar akan terlihat saat menggunakan kontras dinamis FSR</string>
|
||||
<string name="renderer_anti_aliasing">Metode anti-aliasing</string>
|
||||
|
||||
|
||||
|
||||
@@ -387,6 +387,8 @@
|
||||
<string name="renderer_resolution">Risoluzione (Portatile/Docked)</string>
|
||||
<string name="renderer_vsync">Modalità VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro adattivo della finestra </string>
|
||||
<string name="fsr_sharpness">Nitidezza FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina quanto sarà nitida l\'immagine utilizzando il contrasto dinamico di FSR</string>
|
||||
<string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
|
||||
|
||||
|
||||
|
||||
@@ -329,6 +329,8 @@
|
||||
<string name="renderer_resolution">Oppløsning (håndholdt/dokket)</string>
|
||||
<string name="renderer_vsync">VSync-modus</string>
|
||||
<string name="renderer_scaling_filter">Filter for vindustilpasning</string>
|
||||
<string name="fsr_sharpness">FSR-skarphet</string>
|
||||
<string name="fsr_sharpness_description">Bestemmer bildekvalitet med FSR</string>
|
||||
<string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
|
||||
|
||||
|
||||
|
||||
@@ -439,6 +439,8 @@
|
||||
<string name="renderer_resolution">Rozdzielczość (Handheld/Zadokowany)</string>
|
||||
<string name="renderer_vsync">Synchronizacja pionowa VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtr adaptacji rozdzielczości</string>
|
||||
<string name="fsr_sharpness">Ostrość FSR</string>
|
||||
<string name="fsr_sharpness_description">Kontroluje ostrość obrazu w FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Metoda wygładzania krawędzi</string>
|
||||
|
||||
|
||||
|
||||
@@ -430,6 +430,8 @@
|
||||
<string name="renderer_resolution">Resolução (Portátil/Modo TV)</string>
|
||||
<string name="renderer_vsync">Modo de VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
|
||||
<string name="fsr_sharpness">Nitidez do FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao utilizar o contraste dinâmico do FSR</string>
|
||||
<string name="renderer_anti_aliasing">Método de Anti-aliasing</string>
|
||||
|
||||
|
||||
|
||||
@@ -352,6 +352,8 @@
|
||||
<string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
|
||||
<string name="renderer_vsync">Modo VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
|
||||
<string name="fsr_sharpness">Nitidez do FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao usar contraste dinâmico do FSR</string>
|
||||
<string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
|
||||
|
||||
|
||||
|
||||
@@ -458,8 +458,8 @@
|
||||
<string name="renderer_resolution">Разрешение (портативное/в док-станции)</string>
|
||||
<string name="renderer_vsync">Режим верт. синхронизации</string>
|
||||
<string name="renderer_scaling_filter">Фильтр адаптации окна</string>
|
||||
<string name="fsr_sharpness">Резкость FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR или SGSR фильтров</string>
|
||||
<string name="fsr_sharpness">Резкость FSR</string>
|
||||
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Метод сглаживания</string>
|
||||
|
||||
|
||||
@@ -499,8 +499,6 @@
|
||||
<string name="fast_gpu_time_description">Принудительно запускает большинство игр в их максимальном нативном разрешении. Используйте значение 256 для максимальной производительности и 512 для максимального качества графики.</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
||||
<string name="antiflicker">Анти-мерцание</string>
|
||||
<string name="antiflicker_description">Принудительно заставляет обратные вызовы ГПУ-фильтра ожидать выполнения отправленных задач на ГПУ. Используйте с Быстрым режимом ГПУ, что бы избежать мерцаний с меньшим влиянием на производительность.</string>
|
||||
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
|
||||
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
||||
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
||||
|
||||
@@ -351,6 +351,8 @@
|
||||
<string name="renderer_resolution">Резолуција (ручно / прикључено)</string>
|
||||
<string name="renderer_vsync">Всинц мод</string>
|
||||
<string name="renderer_scaling_filter">Филтер прилагођавања прозора</string>
|
||||
<string name="fsr_sharpness">ФСР оштрина</string>
|
||||
<string name="fsr_sharpness_description">Одређује колико ће се слика наоштрен трајати док користи \"ФСР\" динамички контраст</string>
|
||||
<string name="renderer_anti_aliasing">Метода против алиасирања</string>
|
||||
|
||||
|
||||
|
||||
@@ -458,8 +458,8 @@
|
||||
<string name="renderer_resolution">Роздільна здатність (Портативний/Док)</string>
|
||||
<string name="renderer_vsync">Режим верт. синхронізації</string>
|
||||
<string name="renderer_scaling_filter">Фільтр масштабування вікна</string>
|
||||
<string name="fsr_sharpness">Різкість FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні фільтрів FSR або SGSR.</string>
|
||||
<string name="fsr_sharpness">Різкість FSR</string>
|
||||
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Згладжування</string>
|
||||
|
||||
|
||||
@@ -499,8 +499,6 @@
|
||||
<string name="fast_gpu_time_description">Примушує більшість ігор працювати на їхній максимальній нативній роздільності. Використовуйте 256 для максимальної продуктивності та 512 для найкращої якості.</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
||||
<string name="antiflicker">Антимерехтіння</string>
|
||||
<string name="antiflicker_description">Змушує механізм синхронізації чекати, доки ГП завершить подані завдання. Використовуйте з режимом ГП «Швидко», щоб уникнути мерехтіння з меншими втратами продуктивності.</string>
|
||||
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
|
||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
||||
<string name="emulate_bgr565">Емулювати BGR565</string>
|
||||
|
||||
@@ -327,6 +327,8 @@
|
||||
<string name="renderer_resolution">Độ phân giải (Handheld/Docked)</string>
|
||||
<string name="renderer_vsync">Chế độ VSync</string>
|
||||
<string name="renderer_scaling_filter">Bộ lọc điều chỉnh cửa sổ</string>
|
||||
<string name="fsr_sharpness">Độ sắc nét FSR</string>
|
||||
<string name="fsr_sharpness_description">Độ sắc nét khi dùng FSR</string>
|
||||
<string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
|
||||
|
||||
|
||||
|
||||
@@ -452,8 +452,8 @@
|
||||
<string name="renderer_resolution">分辨率 (掌机模式/主机模式)</string>
|
||||
<string name="renderer_vsync">垂直同步模式</string>
|
||||
<string name="renderer_scaling_filter">窗口滤镜</string>
|
||||
<string name="fsr_sharpness">FSR/SGSR 锐度</string>
|
||||
<string name="fsr_sharpness_description">确定在使用 FSR 或 SGSR 过滤器时的图像锐度</string>
|
||||
<string name="fsr_sharpness">FSR 锐化度</string>
|
||||
<string name="fsr_sharpness_description">确定使用 FSR 的动态对比度功能时的图像锐化程度</string>
|
||||
<string name="renderer_anti_aliasing">抗锯齿方式</string>
|
||||
|
||||
|
||||
@@ -493,8 +493,6 @@
|
||||
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 可获得最佳性能,设置为 512 可获得最佳画面保真度。</string>
|
||||
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
|
||||
<string name="antiflicker">防闪烁</string>
|
||||
<string name="antiflicker_description">强制 GPU 围栏回调等待已提交的 GPU 任务。配合“快速 GPU 模式”一起使用,以避免画面闪烁现象,仅会牺牲少量性能。</string>
|
||||
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
||||
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
||||
<string name="emulate_bgr565">模拟 BGR565</string>
|
||||
|
||||
@@ -437,6 +437,8 @@
|
||||
<string name="renderer_resolution">解析度 (手提/底座)</string>
|
||||
<string name="renderer_vsync">垂直同步</string>
|
||||
<string name="renderer_scaling_filter">視窗適應過濾器</string>
|
||||
<string name="fsr_sharpness">FSR 銳化度</string>
|
||||
<string name="fsr_sharpness_description">使用 FSR 時圖片的銳化程度</string>
|
||||
<string name="renderer_anti_aliasing">抗鋸齒</string>
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
@@ -177,8 +177,10 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
||||
queued_buffers.store(0);
|
||||
release_cv.notify_one();
|
||||
}
|
||||
|
||||
static constexpr std::array<s16, 6> silence{};
|
||||
for (size_t i = 0; i < num_frames; i++)
|
||||
std::memset(&output_buffer[i * frame_size], 0, frame_size_bytes);
|
||||
std::memcpy(&output_buffer[i * frame_size], silence.data(), frame_size_bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,11 +184,7 @@ bool Event::WaitFor(const std::chrono::nanoseconds time) {
|
||||
_mm_monitorx(reinterpret_cast<u64*>(std::addressof(is_set)), 0, 0);
|
||||
if (!is_set.load()) {
|
||||
// RDTSC may be fenced here due to atomic load
|
||||
#ifdef _MSC_VER
|
||||
auto const now = __rdtsc();
|
||||
#else
|
||||
auto const now = _rdtsc();
|
||||
#endif
|
||||
if (end > now) {
|
||||
u32 const cycles = std::min<u32>((std::numeric_limits<u32>::max)(), s64(end) - s64(now));
|
||||
// See here: https://github.com/torvalds/linux/blob/948a64995aca6820abefd17f1a4258f5835c5ad9/arch/x86/lib/delay.c#L93
|
||||
@@ -217,13 +213,8 @@ bool Event::WaitFor(const std::chrono::nanoseconds time) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
#ifdef _MSC_VER
|
||||
while (!is_set.load() && end > __rdtsc())
|
||||
Common::Windows::SleepForOneTick();
|
||||
#else
|
||||
while (!is_set.load() && end > _rdtsc())
|
||||
Common::Windows::SleepForOneTick();
|
||||
#endif
|
||||
if (is_set.load())
|
||||
Reset();
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -375,10 +372,6 @@ bool LifecycleManager::UpdateRequestedFocusState() {
|
||||
// Mark the focus state as ready for update.
|
||||
m_requested_focus_state = new_state;
|
||||
|
||||
if (m_is_application) {
|
||||
m_has_focus_state_changed = true;
|
||||
}
|
||||
|
||||
// We changed the focus state.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||
constexpr std::size_t xmrx(std::size_t x) noexcept {
|
||||
x ^= x >> 32;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= std::rotr(x, 47) ^ std::rotr(x, 23);
|
||||
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@@ -1532,7 +1532,7 @@ void EmitX64::EmitFPSingleToHalf(EmitContext& ctx, IR::Inst* inst) {
|
||||
if (ctx.FPCR().DN()) {
|
||||
ForceToDefaultNaN<32>(code, result);
|
||||
}
|
||||
code.vcvtps2ph(result, result, u8(*round_imm));
|
||||
code.vcvtps2ph(result, result, static_cast<u8>(*round_imm));
|
||||
|
||||
ctx.reg_alloc.DefineValue(code, inst, result);
|
||||
return;
|
||||
@@ -1540,7 +1540,7 @@ void EmitX64::EmitFPSingleToHalf(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
||||
ctx.reg_alloc.HostCall(code, inst, args[0]);
|
||||
code.mov(code.ABI_PARAM2.cvt32(), ctx.FPCR().Value());
|
||||
code.mov(code.ABI_PARAM3.cvt32(), u32(rounding_mode));
|
||||
code.mov(code.ABI_PARAM3.cvt32(), static_cast<u32>(rounding_mode));
|
||||
code.lea(code.ABI_PARAM4, code.ptr[code.ABI_JIT_PTR + code.GetJitStateInfo().offsetof_fpsr_exc]);
|
||||
code.CallFunction(&FP::FPConvert<u16, u32>);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
||||
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(code, args[1]).changeBit(size);
|
||||
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr(code).changeBit(size);
|
||||
|
||||
constexpr u64 int_max = u64((std::numeric_limits<std::make_signed_t<mcl::unsigned_integer_of_size<size>>>::max)());
|
||||
constexpr u64 int_max = static_cast<u64>((std::numeric_limits<mcl::signed_integer_of_size<size>>::max)());
|
||||
if constexpr (size < 64) {
|
||||
code.xor_(overflow.cvt32(), overflow.cvt32());
|
||||
code.bt(result.cvt32(), size - 1);
|
||||
|
||||
@@ -3553,7 +3553,7 @@ void EmitX64::EmitVectorPopulationCount(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
||||
EmitOneArgumentFallback(code, ctx, inst, [](VectorArray<u8>& result, const VectorArray<u8>& a) {
|
||||
std::transform(a.begin(), a.end(), result.begin(), [](u8 val) {
|
||||
return static_cast<u8>(std::popcount(val));
|
||||
return static_cast<u8>(mcl::bit::count_ones(val));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1657,10 +1657,20 @@ void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
|
||||
if constexpr (fsize != 16) {
|
||||
if (code.HasHostFeature(HostFeature::SSE41) && rounding != FP::RoundingMode::ToNearest_TieAwayFromZero && !exact) {
|
||||
const auto round_imm = ConvertRoundingModeToX64Immediate(rounding);
|
||||
const u8 round_imm = [&]() -> u8 {
|
||||
switch (rounding) {
|
||||
case FP::RoundingMode::ToNearest_TieEven: return 0b00;
|
||||
case FP::RoundingMode::TowardsPlusInfinity: return 0b10;
|
||||
case FP::RoundingMode::TowardsMinusInfinity: return 0b01;
|
||||
case FP::RoundingMode::TowardsZero: return 0b11;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}();
|
||||
|
||||
EmitTwoOpVectorOperation<fsize, DefaultIndexer, 3>(code, ctx, inst, [&](const Xbyak::Xmm& result, const Xbyak::Xmm& xmm_a) {
|
||||
FCODE(roundp)(result, xmm_a, *round_imm);
|
||||
FCODE(roundp)(result, xmm_a, round_imm);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1992,7 +2002,19 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm src = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
const auto round_imm = ConvertRoundingModeToX64Immediate(rounding);
|
||||
const int round_imm = [&] {
|
||||
switch (rounding) {
|
||||
case FP::RoundingMode::ToNearest_TieEven:
|
||||
default:
|
||||
return 0b00;
|
||||
case FP::RoundingMode::TowardsPlusInfinity:
|
||||
return 0b10;
|
||||
case FP::RoundingMode::TowardsMinusInfinity:
|
||||
return 0b01;
|
||||
case FP::RoundingMode::TowardsZero:
|
||||
return 0b11;
|
||||
}
|
||||
}();
|
||||
const auto perform_conversion = [&code, &ctx](const Xbyak::Xmm& src) {
|
||||
// MSVC doesn't allow us to use a [&] capture, so we have to do this instead.
|
||||
(void)ctx;
|
||||
@@ -2024,7 +2046,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
FCODE(mulp)(src, GetVectorOf<fsize>(code, scale_factor));
|
||||
}
|
||||
|
||||
FCODE(roundp)(src, src, u8(*round_imm));
|
||||
FCODE(roundp)(src, src, u8(round_imm));
|
||||
const Xbyak::Xmm nan_mask = xmm0;
|
||||
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
|
||||
static constexpr u32 nan_to_zero = FixupLUT(FpFixup::PosZero, FpFixup::PosZero);
|
||||
|
||||
@@ -52,7 +52,7 @@ struct TranslatorVisitor final {
|
||||
u32 imm32 = imm8.ZeroExtend();
|
||||
auto carry_out = carry_in;
|
||||
if (rotate) {
|
||||
imm32 = std::rotr<u32>(imm8.ZeroExtend(), rotate * 2);
|
||||
imm32 = mcl::bit::rotate_right<u32>(imm8.ZeroExtend(), rotate * 2);
|
||||
carry_out = ir.Imm1(mcl::bit::get_bit<31>(imm32));
|
||||
}
|
||||
return {imm32, carry_out};
|
||||
@@ -81,7 +81,7 @@ struct TranslatorVisitor final {
|
||||
}();
|
||||
return {imm32, carry_in};
|
||||
}
|
||||
const u32 imm32 = std::rotr<u32>((1 << 7) | imm12.Bits<0, 6>(), imm12.Bits<7, 11>());
|
||||
const u32 imm32 = mcl::bit::rotate_right<u32>((1 << 7) | imm12.Bits<0, 6>(), imm12.Bits<7, 11>());
|
||||
return {imm32, ir.Imm1(mcl::bit::get_bit<31>(imm32))};
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ bool TranslatorVisitor::asimd_VDUP_scalar(bool D, Imm<4> imm4, size_t Vd, bool Q
|
||||
return UndefinedInstruction();
|
||||
}
|
||||
|
||||
const size_t imm4_lsb = std::countr_zero(imm4.ZeroExtend());
|
||||
const size_t imm4_lsb = mcl::bit::lowest_set_bit(imm4.ZeroExtend());
|
||||
const size_t esize = 8u << imm4_lsb;
|
||||
const size_t index = imm4.ZeroExtend() >> (imm4_lsb + 1);
|
||||
const auto d = ToVector(Q, Vd, D);
|
||||
|
||||
@@ -799,7 +799,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
|
||||
|
||||
// LDM <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (W && mcl::bit::get_bit(static_cast<size_t>(n), list)) {
|
||||
@@ -811,13 +811,13 @@ bool TranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
|
||||
}
|
||||
|
||||
const auto start_address = ir.GetRegister(n);
|
||||
const auto writeback_address = ir.Add(start_address, ir.Imm32(u32(std::popcount(list) * 4)));
|
||||
const auto writeback_address = ir.Add(start_address, ir.Imm32(u32(mcl::bit::count_ones(list) * 4)));
|
||||
return LDMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// LDMDA <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (W && mcl::bit::get_bit(static_cast<size_t>(n), list)) {
|
||||
@@ -828,14 +828,14 @@ bool TranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list) - 4)));
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list) - 4)));
|
||||
const auto writeback_address = ir.Sub(start_address, ir.Imm32(4));
|
||||
return LDMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// LDMDB <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (W && mcl::bit::get_bit(static_cast<size_t>(n), list)) {
|
||||
@@ -846,14 +846,14 @@ bool TranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list))));
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list))));
|
||||
const auto writeback_address = start_address;
|
||||
return LDMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// LDMIB <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (W && mcl::bit::get_bit(static_cast<size_t>(n), list)) {
|
||||
@@ -865,7 +865,7 @@ bool TranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||
}
|
||||
|
||||
const auto start_address = ir.Add(ir.GetRegister(n), ir.Imm32(4));
|
||||
const auto writeback_address = ir.Add(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list))));
|
||||
const auto writeback_address = ir.Add(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list))));
|
||||
return LDMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
@@ -896,7 +896,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
|
||||
|
||||
// STM <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -905,13 +905,13 @@ bool TranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) {
|
||||
}
|
||||
|
||||
const auto start_address = ir.GetRegister(n);
|
||||
const auto writeback_address = ir.Add(start_address, ir.Imm32(u32(std::popcount(list) * 4)));
|
||||
const auto writeback_address = ir.Add(start_address, ir.Imm32(u32(mcl::bit::count_ones(list) * 4)));
|
||||
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// STMDA <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -919,14 +919,14 @@ bool TranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list) - 4)));
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list) - 4)));
|
||||
const auto writeback_address = ir.Sub(start_address, ir.Imm32(4));
|
||||
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// STMDB <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -934,14 +934,14 @@ bool TranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list))));
|
||||
const auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list))));
|
||||
const auto writeback_address = start_address;
|
||||
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
// STMIB <Rn>{!}, <reg_list>
|
||||
bool TranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||
if (n == Reg::PC || std::popcount(list) < 1) {
|
||||
if (n == Reg::PC || mcl::bit::count_ones(list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -950,7 +950,7 @@ bool TranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||
}
|
||||
|
||||
const auto start_address = ir.Add(ir.GetRegister(n), ir.Imm32(4));
|
||||
const auto writeback_address = ir.Add(ir.GetRegister(n), ir.Imm32(u32(4 * std::popcount(list))));
|
||||
const auto writeback_address = ir.Add(ir.GetRegister(n), ir.Imm32(u32(4 * mcl::bit::count_ones(list))));
|
||||
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||
}
|
||||
|
||||
|
||||
@@ -688,7 +688,7 @@ bool TranslatorVisitor::thumb16_NOP() {
|
||||
// IT{<x>{<y>{<z>}}} <cond>
|
||||
bool TranslatorVisitor::thumb16_IT(Imm<8> imm8) {
|
||||
ASSERT((imm8.Bits<0, 3>() != 0b0000) && "Decode Error");
|
||||
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && std::popcount(imm8.Bits<0, 3>()) != 1)) {
|
||||
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && mcl::bit::count_ones(imm8.Bits<0, 3>()) != 1)) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (ir.current_location.IT().IsInITBlock()) {
|
||||
@@ -738,11 +738,11 @@ bool TranslatorVisitor::thumb16_PUSH(bool M, RegList reg_list) {
|
||||
if (M) {
|
||||
reg_list |= 1 << 14;
|
||||
}
|
||||
if (std::popcount(reg_list) < 1) {
|
||||
if (mcl::bit::count_ones(reg_list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const u32 num_bytes_to_push = static_cast<u32>(4 * std::popcount(reg_list));
|
||||
const u32 num_bytes_to_push = static_cast<u32>(4 * mcl::bit::count_ones(reg_list));
|
||||
const auto final_address = ir.Sub(ir.GetRegister(Reg::SP), ir.Imm32(num_bytes_to_push));
|
||||
auto address = final_address;
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
@@ -764,7 +764,7 @@ bool TranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
|
||||
if (P) {
|
||||
reg_list |= 1 << 15;
|
||||
}
|
||||
if (std::popcount(reg_list) < 1) {
|
||||
if (mcl::bit::count_ones(reg_list) < 1) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -851,10 +851,10 @@ bool TranslatorVisitor::thumb16_BKPT(Imm<8> /*imm8*/) {
|
||||
|
||||
// STM <Rn>!, <reg_list>
|
||||
bool TranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
|
||||
if (std::popcount(reg_list) == 0) {
|
||||
if (mcl::bit::count_ones(reg_list) == 0) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
if (mcl::bit::get_bit(static_cast<size_t>(n), reg_list) && n != static_cast<Reg>(std::countr_zero(reg_list))) {
|
||||
if (mcl::bit::get_bit(static_cast<size_t>(n), reg_list) && n != static_cast<Reg>(mcl::bit::lowest_set_bit(reg_list))) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
@@ -873,7 +873,7 @@ bool TranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
|
||||
|
||||
// LDM <Rn>!, <reg_list>
|
||||
bool TranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) {
|
||||
if (std::popcount(reg_list) == 0) {
|
||||
if (mcl::bit::count_ones(reg_list) == 0) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -53,7 +53,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, const IR::U32
|
||||
|
||||
bool TranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) {
|
||||
const auto regs_imm = reg_list.ZeroExtend();
|
||||
const auto num_regs = static_cast<u32>(std::popcount(regs_imm));
|
||||
const auto num_regs = static_cast<u32>(mcl::bit::count_ones(regs_imm));
|
||||
|
||||
if (n == Reg::PC || num_regs < 2) {
|
||||
return UnpredictableInstruction();
|
||||
@@ -78,7 +78,7 @@ bool TranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) {
|
||||
|
||||
bool TranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) {
|
||||
const auto regs_imm = reg_list.ZeroExtend();
|
||||
const auto num_regs = static_cast<u32>(std::popcount(regs_imm));
|
||||
const auto num_regs = static_cast<u32>(mcl::bit::count_ones(regs_imm));
|
||||
|
||||
if (n == Reg::PC || num_regs < 2) {
|
||||
return UnpredictableInstruction();
|
||||
@@ -111,7 +111,7 @@ bool TranslatorVisitor::thumb32_PUSH(Imm<15> reg_list) {
|
||||
|
||||
bool TranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) {
|
||||
const auto regs_imm = reg_list.ZeroExtend();
|
||||
const auto num_regs = static_cast<u32>(std::popcount(regs_imm));
|
||||
const auto num_regs = static_cast<u32>(mcl::bit::count_ones(regs_imm));
|
||||
|
||||
if (n == Reg::PC || num_regs < 2) {
|
||||
return UnpredictableInstruction();
|
||||
@@ -130,7 +130,7 @@ bool TranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) {
|
||||
|
||||
bool TranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) {
|
||||
const auto regs_imm = reg_list.ZeroExtend();
|
||||
const auto num_regs = static_cast<u32>(std::popcount(regs_imm));
|
||||
const auto num_regs = static_cast<u32>(mcl::bit::count_ones(regs_imm));
|
||||
|
||||
if (n == Reg::PC || num_regs < 2) {
|
||||
return UnpredictableInstruction();
|
||||
|
||||
@@ -55,7 +55,7 @@ std::optional<TranslatorVisitor::BitMasks> TranslatorVisitor::DecodeBitMasks(boo
|
||||
const size_t esize = size_t{1} << len;
|
||||
const u64 welem = mcl::bit::ones<u64>(S + 1);
|
||||
const u64 telem = mcl::bit::ones<u64>(d + 1);
|
||||
const u64 wmask = std::rotr(mcl::bit::replicate_element<u64>(esize, welem), R);
|
||||
const u64 wmask = mcl::bit::rotate_right(mcl::bit::replicate_element<u64>(esize, welem), R);
|
||||
const u64 tmask = mcl::bit::replicate_element<u64>(esize, telem);
|
||||
|
||||
return BitMasks{wmask, tmask};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size > 3) {
|
||||
return ReservedValue();
|
||||
}
|
||||
@@ -30,7 +30,7 @@ bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size > 3) {
|
||||
return ReservedValue();
|
||||
}
|
||||
@@ -51,7 +51,7 @@ bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::DUP_gen(bool Q, Imm<5> imm5, Reg Rn, Vec Vd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size > 3) {
|
||||
return ReservedValue();
|
||||
}
|
||||
@@ -73,7 +73,7 @@ bool TranslatorVisitor::DUP_gen(bool Q, Imm<5> imm5, Reg Rn, Vec Vd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size == 2 && !Q) {
|
||||
return UnallocatedEncoding();
|
||||
}
|
||||
@@ -96,7 +96,7 @@ bool TranslatorVisitor::SMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size < 3 && Q) {
|
||||
return UnallocatedEncoding();
|
||||
}
|
||||
@@ -123,7 +123,7 @@ bool TranslatorVisitor::UMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::INS_gen(Imm<5> imm5, Reg Rn, Vec Vd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size > 3) {
|
||||
return ReservedValue();
|
||||
}
|
||||
@@ -140,7 +140,7 @@ bool TranslatorVisitor::INS_gen(Imm<5> imm5, Reg Rn, Vec Vd) {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::INS_elt(Imm<5> imm5, Imm<4> imm4, Vec Vn, Vec Vd) {
|
||||
const size_t size = std::countr_zero(imm5.ZeroExtend());
|
||||
const size_t size = mcl::bit::lowest_set_bit(imm5.ZeroExtend());
|
||||
if (size > 3) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <bit>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include "boost/container/small_vector.hpp"
|
||||
@@ -29,6 +28,7 @@
|
||||
#include "dynarmic/ir/opt_passes.h"
|
||||
#include "dynarmic/ir/type.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
|
||||
namespace Dynarmic::Optimization {
|
||||
|
||||
@@ -1074,12 +1074,12 @@ static void ConstantPropagation(IR::Block& block) {
|
||||
break;
|
||||
case Op::BitRotateRight32:
|
||||
if (FoldShifts(inst)) {
|
||||
ReplaceUsesWith(inst, true, std::rotr<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||
ReplaceUsesWith(inst, true, mcl::bit::rotate_right<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||
}
|
||||
break;
|
||||
case Op::BitRotateRight64:
|
||||
if (FoldShifts(inst)) {
|
||||
ReplaceUsesWith(inst, false, std::rotr<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||
ReplaceUsesWith(inst, false, mcl::bit::rotate_right<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||
}
|
||||
break;
|
||||
case Op::LogicalShiftLeftMasked32:
|
||||
@@ -1114,12 +1114,12 @@ static void ConstantPropagation(IR::Block& block) {
|
||||
break;
|
||||
case Op::RotateRightMasked32:
|
||||
if (inst.AreAllArgsImmediates()) {
|
||||
ReplaceUsesWith(inst, true, std::rotr<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU32()));
|
||||
ReplaceUsesWith(inst, true, mcl::bit::rotate_right<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU32()));
|
||||
}
|
||||
break;
|
||||
case Op::RotateRightMasked64:
|
||||
if (inst.AreAllArgsImmediates()) {
|
||||
ReplaceUsesWith(inst, false, std::rotr<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU64()));
|
||||
ReplaceUsesWith(inst, false, mcl::bit::rotate_right<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU64()));
|
||||
}
|
||||
break;
|
||||
case Op::Add32:
|
||||
|
||||
@@ -8,15 +8,26 @@
|
||||
#include <bitset>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <concepts>
|
||||
#include <bit>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
|
||||
namespace mcl {
|
||||
namespace detail {
|
||||
template<typename T, typename U>
|
||||
concept SameHelper = std::is_same_v<T, U>;
|
||||
} // namespace detail
|
||||
template<typename T, typename U>
|
||||
concept SameAs = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
|
||||
template<typename T, typename... U>
|
||||
concept IsAnyOf = (SameAs<T, U> || ...);
|
||||
/// Integral upon which bit operations can be safely performed.
|
||||
template<typename T>
|
||||
concept BitIntegral = IsAnyOf<T, u8, u16, u32, u64, std::uintptr_t, size_t>;
|
||||
|
||||
template<typename T>
|
||||
constexpr std::size_t bitsizeof = CHAR_BIT * sizeof(T);
|
||||
|
||||
} // namespace mcl
|
||||
|
||||
namespace mcl::bit {
|
||||
@@ -60,37 +71,58 @@ constexpr u64 swap_words_64(u64 value) {
|
||||
| ((value & 0x00000000ffffffffull) << 32);
|
||||
}
|
||||
|
||||
template<BitIntegral T>
|
||||
constexpr T rotate_right(T x, size_t amount) {
|
||||
amount %= bitsizeof<T>;
|
||||
if (amount == 0) {
|
||||
return x;
|
||||
}
|
||||
return static_cast<T>((x >> amount) | (x << (bitsizeof<T> - amount)));
|
||||
}
|
||||
|
||||
template<BitIntegral T>
|
||||
constexpr T rotate_left(T x, size_t amount) {
|
||||
amount %= bitsizeof<T>;
|
||||
if (amount == 0) {
|
||||
return x;
|
||||
}
|
||||
return static_cast<T>((x << amount) | (x >> (bitsizeof<T> - amount)));
|
||||
}
|
||||
|
||||
/// Create a mask with `count` number of one bits.
|
||||
template<size_t count, std::integral T>
|
||||
template<size_t count, BitIntegral T>
|
||||
constexpr T ones() {
|
||||
static_assert(count <= bitsizeof<T>, "count larger than bitsize of T");
|
||||
|
||||
if constexpr (count == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return T(~T(0)) >> (bitsizeof<T> - count);
|
||||
return static_cast<T>(~static_cast<T>(0)) >> (bitsizeof<T> - count);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a mask with `count` number of one bits.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T ones(size_t count) {
|
||||
ASSERT(count <= bitsizeof<T> && "count larger than bitsize of T");
|
||||
if (count == 0)
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
return T(~T(0)) >> (bitsizeof<T> - count);
|
||||
}
|
||||
return static_cast<T>(~static_cast<T>(0)) >> (bitsizeof<T> - count);
|
||||
}
|
||||
|
||||
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||
template<size_t begin_bit, size_t end_bit, std::integral T>
|
||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||
constexpr T mask() {
|
||||
static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||
static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
||||
static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
||||
|
||||
return ones<end_bit - begin_bit + 1, T>() << begin_bit;
|
||||
}
|
||||
|
||||
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T mask(size_t begin_bit, size_t end_bit) {
|
||||
ASSERT(begin_bit <= end_bit && "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||
ASSERT(begin_bit < bitsizeof<T> && "begin_bit must be smaller than size of T");
|
||||
@@ -99,100 +131,101 @@ constexpr T mask(size_t begin_bit, size_t end_bit) {
|
||||
}
|
||||
|
||||
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||
template<size_t begin_bit, size_t end_bit, std::integral T>
|
||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||
constexpr T get_bits(T value) {
|
||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||
return (value & m) >> begin_bit;
|
||||
}
|
||||
|
||||
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T get_bits(size_t begin_bit, size_t end_bit, T value) {
|
||||
const T m = mask<T>(begin_bit, end_bit);
|
||||
return (value & m) >> begin_bit;
|
||||
}
|
||||
|
||||
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||
template<size_t begin_bit, size_t end_bit, std::integral T>
|
||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||
constexpr T clear_bits(T value) {
|
||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||
return value & ~m;
|
||||
}
|
||||
|
||||
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value) {
|
||||
const T m = mask<T>(begin_bit, end_bit);
|
||||
return value & ~m;
|
||||
}
|
||||
|
||||
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||
template<size_t begin_bit, size_t end_bit, std::integral T>
|
||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||
constexpr T set_bits(T value, T new_bits) {
|
||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||
}
|
||||
|
||||
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits) {
|
||||
const T m = mask<T>(begin_bit, end_bit);
|
||||
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||
}
|
||||
|
||||
/// Extract bit at bit_position from value of type T.
|
||||
template<size_t bit_position, std::integral T>
|
||||
template<size_t bit_position, BitIntegral T>
|
||||
constexpr bool get_bit(T value) {
|
||||
constexpr T m = mask<bit_position, bit_position, T>();
|
||||
return (value & m) != 0;
|
||||
}
|
||||
|
||||
/// Extract bit at bit_position from value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr bool get_bit(size_t bit_position, T value) {
|
||||
const T m = mask<T>(bit_position, bit_position);
|
||||
return (value & m) != 0;
|
||||
}
|
||||
|
||||
/// Clears bit at bit_position of value of type T.
|
||||
template<size_t bit_position, std::integral T>
|
||||
template<size_t bit_position, BitIntegral T>
|
||||
constexpr T clear_bit(T value) {
|
||||
constexpr T m = mask<bit_position, bit_position, T>();
|
||||
return value & ~m;
|
||||
}
|
||||
|
||||
/// Clears bit at bit_position of value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T clear_bit(size_t bit_position, T value) {
|
||||
const T m = mask<T>(bit_position, bit_position);
|
||||
return value & ~m;
|
||||
}
|
||||
|
||||
/// Modifies bit at bit_position of value of type T.
|
||||
template<size_t bit_position, std::integral T>
|
||||
template<size_t bit_position, BitIntegral T>
|
||||
constexpr T set_bit(T value, bool new_bit) {
|
||||
constexpr T m = mask<bit_position, bit_position, T>();
|
||||
return (value & ~m) | (new_bit ? m : T(0));
|
||||
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||
}
|
||||
|
||||
/// Modifies bit at bit_position of value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T set_bit(size_t bit_position, T value, bool new_bit) {
|
||||
const T m = mask<T>(bit_position, bit_position);
|
||||
return (value & ~m) | (new_bit ? m : T(0));
|
||||
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||
}
|
||||
|
||||
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||
template<size_t bit_count, std::integral T>
|
||||
template<size_t bit_count, BitIntegral T>
|
||||
constexpr T sign_extend(T value) {
|
||||
static_assert(bit_count != 0, "cannot sign-extend zero-sized value");
|
||||
|
||||
using S = std::make_signed_t<T>;
|
||||
constexpr size_t shift_amount = bitsizeof<T> - bit_count;
|
||||
return T(S(value << shift_amount) >> shift_amount);
|
||||
return static_cast<T>(static_cast<S>(value << shift_amount) >> shift_amount);
|
||||
}
|
||||
|
||||
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T sign_extend(size_t bit_count, T value) {
|
||||
ASSERT(bit_count != 0 && "cannot sign-extend zero-sized value");
|
||||
using S = std::make_signed_t<T>;
|
||||
@@ -201,42 +234,78 @@ constexpr T sign_extend(size_t bit_count, T value) {
|
||||
}
|
||||
|
||||
/// Replicate an element across a value of type T.
|
||||
template<size_t element_size, std::integral T>
|
||||
template<size_t element_size, BitIntegral T>
|
||||
constexpr T replicate_element(T value) {
|
||||
static_assert(element_size <= bitsizeof<T>, "element_size is too large");
|
||||
static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
||||
|
||||
if constexpr (element_size == bitsizeof<T>) {
|
||||
return value;
|
||||
} else {
|
||||
return replicate_element<element_size * 2, T>(T(value | (value << element_size)));
|
||||
return replicate_element<element_size * 2, T>(static_cast<T>(value | (value << element_size)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Replicate an element of type U across a value of type T.
|
||||
template<std::integral U, std::integral T>
|
||||
template<BitIntegral U, BitIntegral T>
|
||||
constexpr T replicate_element(T value) {
|
||||
static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large");
|
||||
|
||||
return replicate_element<bitsizeof<U>, T>(value);
|
||||
}
|
||||
|
||||
/// Replicate an element across a value of type T.
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr T replicate_element(size_t element_size, T value) {
|
||||
ASSERT(element_size <= bitsizeof<T> && "element_size is too large");
|
||||
ASSERT(bitsizeof<T> % element_size == 0 && "bitsize of T not divisible by element_size");
|
||||
if (element_size == bitsizeof<T>)
|
||||
return value;
|
||||
return replicate_element<T>(element_size * 2, T(value | (value << element_size)));
|
||||
return replicate_element<T>(element_size * 2, static_cast<T>(value | (value << element_size)));
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
constexpr bool most_significant_bit(T value) {
|
||||
return get_bit<bitsizeof<T> - 1, T>(value);
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
template<BitIntegral T>
|
||||
inline size_t count_ones(T x) {
|
||||
return std::bitset<bitsizeof<T>>(x).count();
|
||||
}
|
||||
|
||||
template<BitIntegral T>
|
||||
constexpr size_t count_leading_zeros(T x) {
|
||||
size_t result = bitsizeof<T>;
|
||||
while (x != 0) {
|
||||
x >>= 1;
|
||||
result--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<BitIntegral T>
|
||||
constexpr int highest_set_bit(T x) {
|
||||
return std::bit_width(x) - 1;
|
||||
int result = -1;
|
||||
while (x != 0) {
|
||||
x >>= 1;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<BitIntegral T>
|
||||
constexpr size_t lowest_set_bit(T x) {
|
||||
if (x == 0) {
|
||||
return bitsizeof<T>;
|
||||
}
|
||||
|
||||
size_t result = 0;
|
||||
while ((x & 1) == 0) {
|
||||
x >>= 1;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace mcl::bit
|
||||
|
||||
@@ -17,25 +17,25 @@ struct integer_of_size_impl {};
|
||||
template<>
|
||||
struct integer_of_size_impl<8> {
|
||||
using unsigned_type = u8;
|
||||
using signed_type = std::make_signed_t<unsigned_type>;
|
||||
using signed_type = s8;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<16> {
|
||||
using unsigned_type = u16;
|
||||
using signed_type = std::make_signed_t<unsigned_type>;
|
||||
using signed_type = s16;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<32> {
|
||||
using unsigned_type = u32;
|
||||
using signed_type = std::make_signed_t<unsigned_type>;
|
||||
using signed_type = s32;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct integer_of_size_impl<64> {
|
||||
using unsigned_type = u64;
|
||||
using signed_type = std::make_signed_t<unsigned_type>;
|
||||
using signed_type = s64;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -10,12 +10,23 @@
|
||||
|
||||
namespace mcl {
|
||||
|
||||
/// A metavalue (of type VT and value v).
|
||||
template<class VT, VT v> using value = std::integral_constant<VT, v>;
|
||||
/// A metavalue of type size_t (and value v).
|
||||
template<size_t v> using size_value = value<size_t, v>;
|
||||
/// A metavalue of type bool (and value v). (Aliases to std::bool_constant.)
|
||||
template<bool v> using bool_value = value<bool, v>;
|
||||
/// true metavalue (Aliases to std::true_type).
|
||||
using true_type = bool_value<true>;
|
||||
/// false metavalue (Aliases to std::false_type).
|
||||
using false_type = bool_value<false>;
|
||||
|
||||
/// Is type T an instance of template class C?
|
||||
template<template<class...> class, class>
|
||||
struct is_instance_of_template : std::false_type {};
|
||||
struct is_instance_of_template : false_type {};
|
||||
|
||||
template<template<class...> class C, class... As>
|
||||
struct is_instance_of_template<C, C<As...>> : std::true_type {};
|
||||
struct is_instance_of_template<C, C<As...>> : true_type {};
|
||||
|
||||
/// Is type T an instance of template class C?
|
||||
template<template<class...> class C, class T>
|
||||
|
||||
@@ -665,7 +665,7 @@ TEST_CASE("A32: Test thumb IT instruction", "[thumb]") {
|
||||
A32::ITState it_state = [&] {
|
||||
while (true) {
|
||||
const u16 imm8 = RandInt<u16>(0, 0xFF);
|
||||
if (mcl::bit::get_bits<0, 3>(imm8) == 0b0000 || mcl::bit::get_bits<4, 7>(imm8) == 0b1111 || (mcl::bit::get_bits<4, 7>(imm8) == 0b1110 && std::popcount(mcl::bit::get_bits<0, 3>(imm8)) != 1)) {
|
||||
if (mcl::bit::get_bits<0, 3>(imm8) == 0b0000 || mcl::bit::get_bits<4, 7>(imm8) == 0b1111 || (mcl::bit::get_bits<4, 7>(imm8) == 0b1110 && mcl::bit::count_ones(mcl::bit::get_bits<0, 3>(imm8)) != 1)) {
|
||||
continue;
|
||||
}
|
||||
instructions.push_back(0b1011111100000000 | imm8);
|
||||
|
||||
@@ -267,7 +267,8 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
};
|
||||
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
|
||||
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, WRITE_BARRIER);
|
||||
upload_cmdbuf.End();
|
||||
cmdbuf.End();
|
||||
|
||||
|
||||
+3
-18
@@ -15,10 +15,6 @@
|
||||
#include "qt_common/gui_settings.h"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "main_window.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -110,27 +106,16 @@ int main(int argc, char* argv[]) {
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("eden"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("eden"));
|
||||
|
||||
// Increases the maximum open file limit.
|
||||
// TODO: This should be common to all frontends.
|
||||
#ifdef _WIN32
|
||||
// Increases the maximum open file limit.
|
||||
// MSVCRT limits this to 2048 for some inexplicable (and likely arcane) reason,
|
||||
// so we have to account for that as well.
|
||||
#ifdef __MSVCRT__
|
||||
_setmaxstdio(2048);
|
||||
#else
|
||||
_setmaxstdio(8192);
|
||||
#endif // __MSVCRT__
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
// Set the max open file limit to 8192, or the hard limit.
|
||||
// Most sane systems should not hit the hard limit here.
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
|
||||
rl.rlim_cur = std::min<rlim_t>(8192, rl.rlim_max);
|
||||
setrlimit(RLIMIT_NOFILE, &rl);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
// If you start a bundle (binary) on OSX without the Terminal, the working directory is "/".
|
||||
// But since we require the working directory to be the executable path for the location of
|
||||
// the user folder in the Qt Frontend, we need to cd into that working directory
|
||||
|
||||
+9
-3
@@ -17,6 +17,12 @@ namespace mcl {
|
||||
template<typename T>
|
||||
constexpr std::size_t bitsizeof = CHAR_BIT * sizeof(T);
|
||||
}
|
||||
namespace mcl::bit {
|
||||
template<typename T>
|
||||
inline size_t count_ones(T x) {
|
||||
return std::bitset<bitsizeof<T>>(x).count();
|
||||
}
|
||||
}
|
||||
template<size_t N>
|
||||
inline consteval std::array<char, N> StringToArray(const char (&str)[N + 1]) {
|
||||
std::array<char, N> result{};
|
||||
@@ -374,7 +380,7 @@ INST(arm_SRS, "SRS", "1111100--1-0110100000101000-----
|
||||
};
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(list.begin(), list.end(), [](const auto& matcher1, const auto& matcher2) {
|
||||
return std::popcount(matcher1.second) > std::popcount(matcher2.second);
|
||||
return mcl::bit::count_ones(matcher1.second) > mcl::bit::count_ones(matcher2.second);
|
||||
});
|
||||
for (auto const& e : list)
|
||||
printf("%s\n", e.inst_final);
|
||||
@@ -581,7 +587,7 @@ INST(v8_VLD_single, "VLD{1-4} (single)", "111101001D10nnnnddddzzN
|
||||
});
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(sort_begin, sort_end, [](const auto& a, const auto& b) {
|
||||
return std::popcount(a.second) > std::popcount(b.second);
|
||||
return mcl::bit::count_ones(a.second) > mcl::bit::count_ones(b.second);
|
||||
});
|
||||
for (auto const& e : table)
|
||||
printf("%s\n", e.inst_final);
|
||||
@@ -1622,7 +1628,7 @@ INST(FNMSUB_float, "FNMSUB", "00011
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(list.begin(), list.end(), [](const auto& a, const auto& b) {
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
return std::popcount(a.second) > std::popcount(b.second);
|
||||
return mcl::bit::count_ones(a.second) > mcl::bit::count_ones(b.second);
|
||||
});
|
||||
// Exceptions to the above rule of thumb.
|
||||
std::stable_partition(list.begin(), list.end(), [&](const auto& e) {
|
||||
|
||||
Reference in New Issue
Block a user