Merge branch 'master' of https://github.com/Ryujinx/Ryujinx into mmdurrant/texture-tests

This commit is contained in:
Michael Durrant 2023-07-31 13:32:39 -06:00
commit 4ce3f5b29d
2876 changed files with 34266 additions and 34342 deletions

View file

@ -1,8 +1,7 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories # Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true root = true
# C# files [*]
[*.cs]
#### Core EditorConfig Options #### #### Core EditorConfig Options ####
@ -12,8 +11,11 @@ indent_style = space
tab_width = 4 tab_width = 4
# New line preferences # New line preferences
end_of_line = crlf end_of_line = lf
insert_final_newline = false insert_final_newline = true
# C# files
[*.cs]
#### .NET Coding Conventions #### #### .NET Coding Conventions ####
@ -59,7 +61,7 @@ dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_readonly_field = true:suggestion dotnet_style_readonly_field = true:suggestion
# Parameter preferences # Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion dotnet_code_quality_unused_parameters = all:silent
#### C# Coding Conventions #### #### C# Coding Conventions ####
@ -85,7 +87,7 @@ csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences # Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion csharp_style_prefer_switch_expression = false:silent
# Null-checking preferences # Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion csharp_style_conditional_delegate_call = true:suggestion
@ -94,6 +96,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
# Code-block preferences # Code-block preferences
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent
@ -109,6 +112,7 @@ csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_implicit_object_creation_when_type_is_apparent = true
# 'using' directive preferences # 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent csharp_using_directive_placement = outside_namespace:silent
@ -140,7 +144,6 @@ csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false csharp_space_before_comma = false
csharp_space_before_dot = false csharp_space_before_dot = false
@ -158,23 +161,31 @@ csharp_space_between_square_brackets = false
# Wrapping preferences # Wrapping preferences
csharp_preserve_single_line_blocks = true csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true csharp_preserve_single_line_statements = false
#### Naming styles #### #### Naming styles ####
# Naming rules # Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i 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
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case dotnet_naming_rule.types_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case dotnet_naming_rule.non_field_members_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.style = _camelCase
dotnet_naming_rule.local_constants_should_be_pascal_case.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_constants_should_be_pascal_case.style = PascalCase
# Symbol specifications # Symbol specifications
@ -190,14 +201,39 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers = dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = static, readonly
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
# Naming styles # Naming styles
dotnet_naming_style.pascal_case.required_prefix = dotnet_naming_style._camelCase.required_prefix = _
dotnet_naming_style.pascal_case.required_suffix = dotnet_naming_style._camelCase.required_suffix =
dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style._camelCase.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case dotnet_naming_style._camelCase.capitalization = camel_case
dotnet_naming_style.begins_with_i.required_prefix = I dotnet_naming_style.PascalCase.required_prefix =
dotnet_naming_style.begins_with_i.required_suffix = dotnet_naming_style.PascalCase.required_suffix =
dotnet_naming_style.begins_with_i.word_separator = dotnet_naming_style.PascalCase.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case dotnet_naming_style.PascalCase.capitalization = pascal_case
dotnet_naming_style.IPascalCase.required_prefix = I
dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case
[src/Ryujinx.HLE/HOS/Services/**.cs]
# Disable "mark members as static" rule for services
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Ava/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Tests/Cpu/*.cs]
# Disable naming rules for CPU tests
dotnet_diagnostic.IDE1006.severity = none

33
.github/labeler.yml vendored Normal file
View file

@ -0,0 +1,33 @@
audio: 'src/Ryujinx.Audio*/**'
cpu:
- 'src/ARMeilleure/**'
- 'src/Ryujinx.Cpu/**'
- 'src/Ryujinx.Memory/**'
gpu:
- 'src/Ryujinx.Graphics.*/**'
- 'src/Spv.Generator/**'
- 'src/Ryujinx.ShaderTools/**'
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
'graphics-backend:vulkan':
- 'src/Ryujinx.Graphics.Vulkan/**'
- 'src/Spv.Generator/**'
gui:
- 'src/Ryujinx/**'
- 'src/Ryujinx.Ui.Common/**'
- 'src/Ryujinx.Ui.LocaleGenerator/**'
- 'src/Ryujinx.Ava/**'
horizon:
- 'src/Ryujinx.HLE/**'
- 'src/Ryujinx.Horizon*/**'
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
infra:
- '.github/**'
- 'distribution/**'
- 'Directory.Packages.props'

32
.github/reviewers.yml vendored Normal file
View file

@ -0,0 +1,32 @@
audio:
- marysaka
cpu:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
gpu:
- gdkchan
- riperiperi
- marysaka
gui:
- Ack77
- emmauss
- TSRBerry
- marysaka
horizon:
- gdkchan
- Ack77
- marysaka
- TSRBerry
infra:
- marysaka
- TSRBerry
default:
- marysaka

79
.github/update_reviewers.py vendored Normal file
View file

@ -0,0 +1,79 @@
from pathlib import Path
from typing import List, Set
from github import Github
from github.Repository import Repository
from github.GithubException import GithubException
import sys
import yaml
def add_reviewers(
reviewers: Set[str], team_reviewers: Set[str], new_entries: List[str]
):
for reviewer in new_entries:
if reviewer.startswith("@"):
team_reviewers.add(reviewer[1:])
else:
reviewers.add(reviewer)
def update_reviewers(config, repo: Repository, pr_id: int) -> int:
pull_request = repo.get_pull(pr_id)
if not pull_request:
sys.stderr.writable(f"Unknown PR #{pr_id}\n")
return 1
pull_request_author = pull_request.user.login
reviewers = set()
team_reviewers = set()
for label in pull_request.labels:
if label.name in config:
add_reviewers(reviewers, team_reviewers, config[label.name])
if "default" in config:
add_reviewers(reviewers, team_reviewers, config["default"])
if pull_request_author in reviewers:
reviewers.remove(pull_request_author)
try:
reviewers = list(reviewers)
team_reviewers = list(team_reviewers)
print(
f"Attempting to assign reviewers ({reviewers}) and team_reviewers ({team_reviewers})"
)
pull_request.create_review_request(reviewers, team_reviewers)
return 0
except GithubException as e:
sys.stderr.write(f"Cannot assign review request for PR #{pr_id}: {e}\n")
return 1
if __name__ == "__main__":
if len(sys.argv) != 5:
sys.stderr.write("usage: <token> <repo_path> <pr_id> <config_path>\n")
sys.exit(1)
token = sys.argv[1]
repo_path = sys.argv[2]
pr_id = int(sys.argv[3])
config_path = Path(sys.argv[4])
g = Github(token)
repo = g.get_repo(repo_path)
if not repo:
sys.stderr.write("Repository not found!\n")
sys.exit(1)
if not config_path.exists():
sys.stderr.write(f'Config "{config_path}" not found!\n')
sys.exit(1)
with open(config_path, "r") as f:
config = yaml.safe_load(f)
sys.exit(update_reviewers(config, repo, pr_id))

View file

@ -1,25 +1,10 @@
name: Build job name: Build job
on: on:
workflow_dispatch: workflow_call:
inputs: {}
#push:
# branches: [ master ]
# paths-ignore:
# - '.github/*'
# - '.github/ISSUE_TEMPLATE/**'
# - '*.yml'
# - 'README.md'
pull_request:
branches: [ master ]
paths-ignore:
- '.github/*'
- '.github/ISSUE_TEMPLATE/**'
- '*.yml'
- 'README.md'
concurrency: concurrency:
group: pr-checks-${{ github.event.number }} group: pr-builds-${{ github.event.number }}
cancel-in-progress: true cancel-in-progress: true
env: env:

71
.github/workflows/checks.yml vendored Normal file
View file

@ -0,0 +1,71 @@
name: Perform checks
on:
pull_request:
branches: [ master ]
paths:
- '**'
- '!.github/**'
- '!*.yml'
- '!*.config'
- '!README.md'
- '.github/workflows/*.yml'
permissions:
pull-requests: write
checks: write
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.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
- name: Run dotnet format style
run: |
dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d
# For some reason this step sometimes fails with exit code 139 (segfault?),
# so should that be the case we'll try again (3 tries max).
- name: Run dotnet format analyzers
run: |
attempt=0
exit_code=139
until [ $attempt -ge 3 ] || [ $exit_code -ne 139 ]; do
((attempt+=1))
exit_code=0
echo "Attempt: ${attempt}/3"
dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d || exit_code=$?
done
exit $exit_code
- name: Upload report
if: failure()
uses: actions/upload-artifact@v3
with:
name: dotnet-format
path: ./*-report.json
pr_build:
uses: ./.github/workflows/build.yml
needs: format
secrets: inherit

View file

@ -1,8 +1,10 @@
name: Comment PR artifacts links name: Comment PR artifacts links
on: on:
workflow_run: workflow_run:
workflows: ['Build job'] workflows: ['Perform checks']
types: [completed] types: [completed]
jobs: jobs:
pr_comment: pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'

34
.github/workflows/pr_triage.yml vendored Normal file
View file

@ -0,0 +1,34 @@
name: "Pull Request Triage"
on:
pull_request_target:
types: [opened, ready_for_review]
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
# Grab sources to get update_reviewers.py and reviewers.yml
- name: Fetch sources
uses: actions/checkout@v3
with:
# Ensure we pin the source origin as pull_request_target run under forks.
fetch-depth: 0
repository: Ryujinx/Ryujinx
ref: master
- name: Update labels based on changes
uses: actions/labeler@v4
with:
sync-labels: true
dot: true
- name: Assign reviewers
run: |
pip3 install PyGithub
python3 .github/update_reviewers.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
shell: bash

View file

@ -6,9 +6,10 @@ on:
push: push:
branches: [ master ] branches: [ master ]
paths-ignore: paths-ignore:
- '.github/*' - '.github/**'
- '.github/ISSUE_TEMPLATE/**'
- '*.yml' - '*.yml'
- '*.json'
- '*.config'
- 'README.md' - 'README.md'
concurrency: release concurrency: release

View file

@ -20,8 +20,8 @@
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" /> <PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
<PackageVersion Include="LibHac" Version="0.18.0" /> <PackageVersion Include="LibHac" Version="0.18.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.5.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.1" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NUnit" Version="3.13.3" /> <PackageVersion Include="NUnit" Version="3.13.3" />
@ -34,7 +34,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
<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.GtkSharp" Version="3.24.24.59-ryujinx" /> <PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" />
<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.16.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
@ -44,9 +44,9 @@
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" /> <PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" /> <PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" /> <PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.30.1" /> <PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" /> <PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.1" /> <PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" /> <PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup> </ItemGroup>

View file

@ -39,10 +39,15 @@
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 - 2022 Ryujinx Team and Contributors.</string> <string>Copyright © 2018 - 2023 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>
<string>11.0</string> <string>11.0</string>
<key>LSEnvironment</key>
<dict>
<key>COMPlus_DefaultStackSize</key>
<string>200000</string>
</dict>
</dict> </dict>
</plist> </plist>

View file

@ -35,12 +35,12 @@ EXECUTABLE_SUB_PATH=Contents/MacOS/Ryujinx
rm -rf "$TEMP_DIRECTORY" rm -rf "$TEMP_DIRECTORY"
mkdir -p "$TEMP_DIRECTORY" mkdir -p "$TEMP_DIRECTORY"
DOTNET_COMMON_ARGS="-p:DebugType=embedded -p:Version=$VERSION -p:SourceRevisionId=$SOURCE_REVISION_ID --self-contained true $EXTRA_ARGS" DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
dotnet restore dotnet restore
dotnet build -c $CONFIGURATION src/Ryujinx.Ava dotnet build -c "$CONFIGURATION" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64) # Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib" rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
@ -104,10 +104,10 @@ fi
echo "Creating archive" echo "Creating archive"
pushd "$OUTPUT_DIRECTORY" pushd "$OUTPUT_DIRECTORY"
tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf $RELEASE_TAR_FILE_NAME Ryujinx.app 1> /dev/null tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf "$RELEASE_TAR_FILE_NAME" Ryujinx.app 1> /dev/null
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" $RELEASE_TAR_FILE_NAME "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx" python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx"
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"
popd popd
echo "Done" echo "Done"

View file

@ -5,7 +5,7 @@ set -e
INSTALL_DIRECTORY=$1 INSTALL_DIRECTORY=$1
NEW_APP_DIRECTORY=$2 NEW_APP_DIRECTORY=$2
APP_PID=$3 APP_PID=$3
APP_ARGUMENTS="${@:4}" APP_ARGUMENTS=("${@:4}")
error_handler() { error_handler() {
local lineno="$1" local lineno="$1"
@ -33,7 +33,7 @@ trap 'error_handler ${LINENO}' ERR
attempt=0 attempt=0
while true; do while true; do
if lsof -p $APP_PID +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then if lsof -p "$APP_PID" +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then
if [ "$attempt" -eq 4 ]; then if [ "$attempt" -eq 4 ]; then
exit 1 exit 1
fi fi
@ -53,5 +53,5 @@ mv "$NEW_APP_DIRECTORY" "$INSTALL_DIRECTORY"
if [ "$#" -le 3 ]; then if [ "$#" -le 3 ]; then
open -a "$INSTALL_DIRECTORY" open -a "$INSTALL_DIRECTORY"
else else
open -a "$INSTALL_DIRECTORY" --args "$APP_ARGUMENTS" open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
fi fi

View file

@ -23,10 +23,7 @@ namespace ARMeilleure
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ArenaAllocator GetAllocator(ref ArenaAllocator alloc, uint pageSize, uint pageCount) private static ArenaAllocator GetAllocator(ref ArenaAllocator alloc, uint pageSize, uint pageCount)
{ {
if (alloc == null) alloc ??= new ArenaAllocator(pageSize, pageCount);
{
alloc = new ArenaAllocator(pageSize, pageCount);
}
return alloc; return alloc;
} }

View file

@ -221,7 +221,7 @@ namespace ARMeilleure.CodeGen.Arm64
2 => Multiplier.x4, 2 => Multiplier.x4,
3 => Multiplier.x8, 3 => Multiplier.x8,
4 => Multiplier.x16, 4 => Multiplier.x16,
_ => Multiplier.x1 _ => Multiplier.x1,
}; };
baseOp = indexOnSrc2 ? src1 : src2; baseOp = indexOnSrc2 ? src1 : src2;

View file

@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.Arm64
Gt = 12, Gt = 12,
Le = 13, Le = 13,
Al = 14, Al = 14,
Nv = 15 Nv = 15,
} }
static class ComparisonArm64Extensions static class ComparisonArm64Extensions
@ -29,6 +29,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
return comp switch return comp switch
{ {
#pragma warning disable IDE0055 // Disable formatting
Comparison.Equal => ArmCondition.Eq, Comparison.Equal => ArmCondition.Eq,
Comparison.NotEqual => ArmCondition.Ne, Comparison.NotEqual => ArmCondition.Ne,
Comparison.Greater => ArmCondition.Gt, Comparison.Greater => ArmCondition.Gt,
@ -39,8 +40,9 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison.Less => ArmCondition.Lt, Comparison.Less => ArmCondition.Lt,
Comparison.GreaterOrEqualUI => ArmCondition.GeUn, Comparison.GreaterOrEqualUI => ArmCondition.GeUn,
Comparison.LessUI => ArmCondition.LtUn, Comparison.LessUI => ArmCondition.LtUn,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)) _ => throw new ArgumentException(null, nameof(comp)),
}; };
} }
} }

View file

@ -9,6 +9,6 @@ namespace ARMeilleure.CodeGen.Arm64
Sxtb = 4, Sxtb = 4,
Sxth = 5, Sxth = 5,
Sxtw = 6, Sxtw = 6,
Sxtx = 7 Sxtx = 7,
} }
} }

View file

@ -6,6 +6,6 @@ namespace ARMeilleure.CodeGen.Arm64
Lsl = 0, Lsl = 0,
Lsr = 1, Lsr = 1,
Asr = 2, Asr = 2,
Ror = 3 Ror = 3,
} }
} }

View file

@ -992,7 +992,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
OperandType.FP32 => 0, OperandType.FP32 => 0,
OperandType.FP64 => 1, OperandType.FP64 => 1,
_ => 2 _ => 2,
}; };
instruction = vecInst | ((uint)opc << 30); instruction = vecInst | ((uint)opc << 30);
@ -1124,10 +1124,11 @@ namespace ARMeilleure.CodeGen.Arm64
OperandType.FP32 => 2, OperandType.FP32 => 2,
OperandType.FP64 => 3, OperandType.FP64 => 3,
OperandType.V128 => 4, OperandType.V128 => 4,
_ => throw new ArgumentException($"Invalid type {type}.") _ => throw new ArgumentException($"Invalid type {type}."),
}; };
} }
#pragma warning disable IDE0051 // Remove unused private member
private void WriteInt16(short value) private void WriteInt16(short value)
{ {
WriteUInt16((ushort)value); WriteUInt16((ushort)value);
@ -1142,6 +1143,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
_stream.WriteByte(value); _stream.WriteByte(value);
} }
#pragma warning restore IDE0051
private void WriteUInt16(ushort value) private void WriteUInt16(ushort value)
{ {

View file

@ -14,7 +14,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 Stream _stream; private readonly Stream _stream;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;
@ -32,7 +32,7 @@ namespace ARMeilleure.CodeGen.Arm64
private readonly Dictionary<BasicBlock, long> _visitedBlocks; private readonly Dictionary<BasicBlock, long> _visitedBlocks;
private readonly Dictionary<BasicBlock, List<(ArmCondition Condition, long BranchPos)>> _pendingBranches; private readonly Dictionary<BasicBlock, List<(ArmCondition Condition, long BranchPos)>> _pendingBranches;
private struct ConstantPoolEntry private readonly struct ConstantPoolEntry
{ {
public readonly int Offset; public readonly int Offset;
public readonly Symbol Symbol; public readonly Symbol Symbol;
@ -58,7 +58,7 @@ namespace ARMeilleure.CodeGen.Arm64
private readonly bool _relocatable; private readonly bool _relocatable;
public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksCount, bool relocatable) public CodeGenContext(AllocationResult allocResult, int maxCallArgs, bool relocatable)
{ {
_stream = MemoryStreamManager.Shared.GetStream(); _stream = MemoryStreamManager.Shared.GetStream();
@ -93,10 +93,10 @@ namespace ARMeilleure.CodeGen.Arm64
if (_pendingBranches.TryGetValue(block, out var list)) if (_pendingBranches.TryGetValue(block, out var list))
{ {
foreach (var tuple in list) foreach ((ArmCondition condition, long branchPos) in list)
{ {
_stream.Seek(tuple.BranchPos, SeekOrigin.Begin); _stream.Seek(branchPos, SeekOrigin.Begin);
WriteBranch(tuple.Condition, target); WriteBranch(condition, target);
} }
_stream.Seek(target, SeekOrigin.Begin); _stream.Seek(target, SeekOrigin.Begin);

View file

@ -10,7 +10,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics; using System.Numerics;
using static ARMeilleure.IntermediateRepresentation.Operand; using static ARMeilleure.IntermediateRepresentation.Operand;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -31,15 +30,16 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
Byte, Byte,
Hword, Hword,
Auto Auto,
} }
private static Action<CodeGenContext, Operation>[] _instTable; private static readonly Action<CodeGenContext, Operation>[] _instTable;
static CodeGenerator() static CodeGenerator()
{ {
_instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))]; _instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))];
#pragma warning disable IDE0055 // Disable formatting
Add(Instruction.Add, GenerateAdd); Add(Instruction.Add, GenerateAdd);
Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd);
Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr);
@ -100,6 +100,7 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend16, GenerateZeroExtend16);
Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend32, GenerateZeroExtend32);
Add(Instruction.ZeroExtend8, GenerateZeroExtend8); Add(Instruction.ZeroExtend8, GenerateZeroExtend8);
#pragma warning restore IDE0055
static void Add(Instruction inst, Action<CodeGenContext, Operation> func) static void Add(Instruction inst, Action<CodeGenContext, Operation> func)
{ {
@ -131,7 +132,7 @@ namespace ARMeilleure.CodeGen.Arm64
StackAllocator stackAlloc = new(); StackAllocator stackAlloc = new();
PreAllocator.RunPass(cctx, stackAlloc, out int maxCallArgs); PreAllocator.RunPass(cctx, out int maxCallArgs);
Logger.EndPass(PassName.PreAllocation, cfg); Logger.EndPass(PassName.PreAllocation, cfg);
@ -168,11 +169,9 @@ namespace ARMeilleure.CodeGen.Arm64
Logger.StartPass(PassName.CodeGeneration); Logger.StartPass(PassName.CodeGeneration);
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0; bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable); CodeGenContext context = new(allocResult, maxCallArgs, relocatable);
UnwindInfo unwindInfo = WritePrologue(context); UnwindInfo unwindInfo = WritePrologue(context);
@ -1080,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>(); List<UnwindPushEntry> pushEntries = new();
Operand rsp = Register(SpRegister); Operand rsp = Register(SpRegister);
@ -1570,11 +1569,13 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
} }
#pragma warning disable IDE0051 // Remove unused private member
private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4) private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4)
{ {
Debug.Assert(op1.Type == op2.Type); Debug.Assert(op1.Type == op2.Type);
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
Debug.Assert(op1.Type == op4.Type); Debug.Assert(op1.Type == op4.Type);
} }
#pragma warning restore IDE0051
} }
} }

View file

@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
(uint)operation.GetSource(2).AsInt32()); (uint)operation.GetSource(2).AsInt32());
break; break;
case IntrinsicType.Vector128Unary:
GenerateVectorUnary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(0));
break;
case IntrinsicType.Vector128Binary:
GenerateVectorBinary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(0),
operation.GetSource(1));
break;
case IntrinsicType.Vector128BinaryRd:
GenerateVectorUnary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(1));
break;
case IntrinsicType.VectorUnary: case IntrinsicType.VectorUnary:
GenerateVectorUnary( GenerateVectorUnary(
context, context,

View file

@ -1,7 +1,4 @@
using System; using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.Arm;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -77,7 +74,7 @@ namespace ARMeilleure.CodeGen.Arm64
Ssbs = 1 << 28, Ssbs = 1 << 28,
Sb = 1 << 29, Sb = 1 << 29,
Paca = 1 << 30, Paca = 1 << 30,
Pacg = 1UL << 31 Pacg = 1UL << 31,
} }
[Flags] [Flags]
@ -119,7 +116,7 @@ namespace ARMeilleure.CodeGen.Arm64
Sve_Ebf16 = 1UL << 33, Sve_Ebf16 = 1UL << 33,
Cssc = 1UL << 34, Cssc = 1UL << 34,
Rprfm = 1UL << 35, Rprfm = 1UL << 35,
Sve2p1 = 1UL << 36 Sve2p1 = 1UL << 36,
} }
public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0; public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0;
@ -143,7 +140,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
private static string[] _sysctlNames = new string[] private static readonly string[] _sysctlNames = new string[]
{ {
"hw.optional.floatingpoint", "hw.optional.floatingpoint",
"hw.optional.AdvSIMD", "hw.optional.AdvSIMD",
@ -153,7 +150,7 @@ 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]
@ -167,7 +164,7 @@ namespace ARMeilleure.CodeGen.Arm64
Lse = 1 << 5, Lse = 1 << 5,
Crc32 = 1 << 6, Crc32 = 1 << 6,
Sha1 = 1 << 7, Sha1 = 1 << 7,
Sha256 = 1 << 8 Sha256 = 1 << 8,
} }
public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0; public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0;

View file

@ -1,6 +1,6 @@
namespace ARMeilleure.CodeGen.Arm64 namespace ARMeilleure.CodeGen.Arm64
{ {
struct IntrinsicInfo readonly struct IntrinsicInfo
{ {
public uint Inst { get; } public uint Inst { get; }
public IntrinsicType Type { get; } public IntrinsicType Type { get; }

View file

@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static IntrinsicInfo[] _intrinTable; private static readonly IntrinsicInfo[] _intrinTable;
static IntrinsicTable() static IntrinsicTable()
{ {
_intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))];
#pragma warning disable IDE0055 // Disable formatting
Add(Intrinsic.Arm64AbsS, new IntrinsicInfo(0x5e20b800u, IntrinsicType.ScalarUnary)); Add(Intrinsic.Arm64AbsS, new IntrinsicInfo(0x5e20b800u, IntrinsicType.ScalarUnary));
Add(Intrinsic.Arm64AbsV, new IntrinsicInfo(0x0e20b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AbsV, new IntrinsicInfo(0x0e20b800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64AddhnV, new IntrinsicInfo(0x0e204000u, IntrinsicType.VectorTernaryRd)); Add(Intrinsic.Arm64AddhnV, new IntrinsicInfo(0x0e204000u, IntrinsicType.VectorTernaryRd));
@ -19,8 +20,8 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary)); Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise)); Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
@ -448,6 +449,7 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)

View file

@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
ScalarTernaryShlRd, ScalarTernaryShlRd,
ScalarTernaryShrRd, ScalarTernaryShrRd,
Vector128Unary,
Vector128Binary,
Vector128BinaryRd,
VectorUnary, VectorUnary,
VectorUnaryBitwise, VectorUnaryBitwise,
VectorUnaryByElem, VectorUnaryByElem,
@ -50,10 +54,7 @@ namespace ARMeilleure.CodeGen.Arm64
VectorTernaryShlRd, VectorTernaryShlRd,
VectorTernaryShrRd, VectorTernaryShrRd,
Vector128Unary,
Vector128Binary,
GetRegister, GetRegister,
SetRegister SetRegister,
} }
} }

View file

@ -1,4 +1,3 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
@ -31,7 +30,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
} }
public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out int maxCallArgs) public static void RunPass(CompilerContext cctx, out int maxCallArgs)
{ {
maxCallArgs = -1; maxCallArgs = -1;
@ -41,7 +40,7 @@ namespace ARMeilleure.CodeGen.Arm64
for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext)
{ {
ConstantDict constants = new ConstantDict(); ConstantDict constants = new();
Operation nextNode; Operation nextNode;
@ -92,7 +91,7 @@ namespace ARMeilleure.CodeGen.Arm64
InsertReturnCopy(block.Operations, node); InsertReturnCopy(block.Operations, node);
break; break;
case Instruction.Tailcall: case Instruction.Tailcall:
InsertTailcallCopies(constants, block.Operations, stackAlloc, node, node); InsertTailcallCopies(constants, block.Operations, node, node);
break; break;
} }
} }
@ -138,10 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
src2 = node.GetSource(1); src2 = node.GetSource(1);
Operand temp = src1; (src2, src1) = (src1, src2);
src1 = src2;
src2 = temp;
node.SetSource(0, src1); node.SetSource(0, src1);
node.SetSource(1, src2); node.SetSource(1, src2);
@ -265,9 +261,9 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
operation.GetSource(0) operation.GetSource(0),
}; };
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@ -364,16 +360,14 @@ namespace ARMeilleure.CodeGen.Arm64
operation.SetSources(sources.ToArray()); operation.SetSources(sources.ToArray());
} }
private static void InsertTailcallCopies( private static void InsertTailcallCopies(ConstantDict constants,
ConstantDict constants,
IntrusiveList<Operation> nodes, IntrusiveList<Operation> nodes,
StackAllocator stackAlloc,
Operation node, Operation node,
Operation operation) Operation operation)
{ {
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
operation.GetSource(0) operation.GetSource(0),
}; };
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@ -746,6 +740,7 @@ namespace ARMeilleure.CodeGen.Arm64
info.Type == IntrinsicType.ScalarTernaryFPRdByElem || info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
info.Type == IntrinsicType.ScalarTernaryShlRd || info.Type == IntrinsicType.ScalarTernaryShlRd ||
info.Type == IntrinsicType.ScalarTernaryShrRd || info.Type == IntrinsicType.ScalarTernaryShrRd ||
info.Type == IntrinsicType.Vector128BinaryRd ||
info.Type == IntrinsicType.VectorBinaryRd || info.Type == IntrinsicType.VectorBinaryRd ||
info.Type == IntrinsicType.VectorInsertByElem || info.Type == IntrinsicType.VectorInsertByElem ||
info.Type == IntrinsicType.VectorTernaryRd || info.Type == IntrinsicType.VectorTernaryRd ||

View file

@ -23,6 +23,6 @@
/// <summary> /// <summary>
/// Refers to a special symbol which is handled by <see cref="Translation.PTC.Ptc.PatchCode"/>. /// Refers to a special symbol which is handled by <see cref="Translation.PTC.Ptc.PatchCode"/>.
/// </summary> /// </summary>
Special Special,
} }
} }

View file

@ -171,13 +171,12 @@ namespace ARMeilleure.CodeGen.Optimizations
private static ulong AllOnes(OperandType type) private static ulong AllOnes(OperandType type)
{ {
switch (type) return type switch
{ {
case OperandType.I32: return ~0U; OperandType.I32 => ~0U,
case OperandType.I64: return ~0UL; OperandType.I64 => ~0UL,
} _ => throw new ArgumentException("Invalid operand type \"" + type + "\"."),
};
throw new ArgumentException("Invalid operand type \"" + type + "\".");
} }
} }
} }

View file

@ -1,7 +1,6 @@
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using static ARMeilleure.IntermediateRepresentation.Operation.Factory; using static ARMeilleure.IntermediateRepresentation.Operation.Factory;
@ -42,13 +41,13 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public void Sequence(List<Operation> sequence) public void Sequence(List<Operation> sequence)
{ {
Dictionary<Register, Register> locations = new Dictionary<Register, Register>(); Dictionary<Register, Register> locations = new();
Dictionary<Register, Register> sources = new Dictionary<Register, Register>(); Dictionary<Register, Register> sources = new();
Dictionary<Register, OperandType> types = new Dictionary<Register, OperandType>(); Dictionary<Register, OperandType> types = new();
Queue<Register> pendingQueue = new Queue<Register>(); Queue<Register> pendingQueue = new();
Queue<Register> readyQueue = new Queue<Register>(); Queue<Register> readyQueue = new();
foreach (Copy copy in _copies) foreach (Copy copy in _copies)
{ {
@ -186,10 +185,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_fillQueue == null) _fillQueue ??= new Queue<Operation>();
{
_fillQueue = new Queue<Operation>();
}
Operand register = GetRegister(right.Register, type); Operand register = GetRegister(right.Register, type);
Operand offset = Const(left.SpillOffset); Operand offset = Const(left.SpillOffset);
@ -201,10 +197,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_spillQueue == null) _spillQueue ??= new Queue<Operation>();
{
_spillQueue = new Queue<Operation>();
}
Operand offset = Const(right.SpillOffset); Operand offset = Const(right.SpillOffset);
Operand register = GetRegister(left.Register, type); Operand register = GetRegister(left.Register, type);
@ -216,10 +209,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_parallelCopy == null) _parallelCopy ??= new ParallelCopy();
{
_parallelCopy = new ParallelCopy();
}
_parallelCopy.AddCopy(right.Register, left.Register, type); _parallelCopy.AddCopy(right.Register, left.Register, type);
@ -228,7 +218,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public Operation[] Sequence() public Operation[] Sequence()
{ {
List<Operation> sequence = new List<Operation>(); List<Operation> sequence = new();
if (_spillQueue != null) if (_spillQueue != null)
{ {

View file

@ -39,7 +39,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private int _first; private int _first;
private int _last; private int _last;
public bool IsBlockLocal => _first == _last; public readonly bool IsBlockLocal => _first == _last;
public LocalInfo(OperandType type, int uses, int blkIndex) public LocalInfo(OperandType type, int uses, int blkIndex)
{ {

View file

@ -545,7 +545,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
_intervals.Insert(insertIndex, interval); _intervals.Insert(insertIndex, interval);
} }
private void Spill(AllocationContext context, LiveInterval interval) private static void Spill(AllocationContext context, LiveInterval interval)
{ {
Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval."); Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval.");
Debug.Assert(interval.UsesCount == 0, "Trying to spill a interval with uses."); Debug.Assert(interval.UsesCount == 0, "Trying to spill a interval with uses.");
@ -561,7 +561,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void InsertSplitCopies() private void InsertSplitCopies()
{ {
Dictionary<int, CopyResolver> copyResolvers = new Dictionary<int, CopyResolver>(); Dictionary<int, CopyResolver> copyResolvers = new();
CopyResolver GetCopyResolver(int position) CopyResolver GetCopyResolver(int position)
{ {
@ -676,10 +676,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (left != default && right != default && left != right) if (left != default && right != default && left != right)
{ {
if (copyResolver == null) copyResolver ??= new CopyResolver();
{
copyResolver = new CopyResolver();
}
copyResolver.AddSplit(left, right); copyResolver.AddSplit(left, right);
} }
@ -862,8 +859,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Compute local live sets. // Compute local live sets.
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {
BitMap liveGen = new BitMap(Allocators.Default, mapSize); BitMap liveGen = new(Allocators.Default, mapSize);
BitMap liveKill = new BitMap(Allocators.Default, mapSize); BitMap liveKill = new(Allocators.Default, mapSize);
for (Operation node = block.Operations.First; node != default; node = node.ListNext) for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{ {
@ -1061,7 +1058,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
int regIndex = BitOperations.TrailingZeroCount(mask); int regIndex = BitOperations.TrailingZeroCount(mask);
Register callerSavedReg = new Register(regIndex, regType); Register callerSavedReg = new(regIndex, regType);
LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)]; LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)];

View file

@ -240,8 +240,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public LiveInterval Split(int position) public LiveInterval Split(int position)
{ {
LiveInterval result = new(Local, Parent); LiveInterval result = new(Local, Parent)
result.End = End; {
End = End,
};
LiveRange prev = PrevRange; LiveRange prev = PrevRange;
LiveRange curr = CurrRange; LiveRange curr = CurrRange;

View file

@ -8,8 +8,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private int _count; private int _count;
private int _capacity; private int _capacity;
public int Count => _count; public readonly int Count => _count;
public Span<LiveInterval> Span => new(_items, _count); public readonly Span<LiveInterval> Span => new(_items, _count);
public void Add(LiveInterval interval) public void Add(LiveInterval interval)
{ {

View file

@ -6,15 +6,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
private int* _items; private int* _items;
private int _capacity; private int _capacity;
private int _count;
public int Count => _count; public int Count { get; private set; }
public int FirstUse => _count > 0 ? _items[_count - 1] : LiveInterval.NotFound;
public Span<int> Span => new(_items, _count); public readonly int FirstUse => Count > 0 ? _items[Count - 1] : LiveInterval.NotFound;
public readonly Span<int> Span => new(_items, Count);
public void Add(int position) public void Add(int position)
{ {
if (_count + 1 > _capacity) if (Count + 1 > _capacity)
{ {
var oldSpan = Span; var oldSpan = Span;
@ -28,7 +28,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Use positions are usually inserted in descending order, so inserting in descending order is faster, // Use positions are usually inserted in descending order, so inserting in descending order is faster,
// since the number of half exchanges is reduced. // since the number of half exchanges is reduced.
int i = _count - 1; int i = Count - 1;
while (i >= 0 && _items[i] < position) while (i >= 0 && _items[i] < position)
{ {
@ -36,19 +36,19 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
} }
_items[i + 1] = position; _items[i + 1] = position;
_count++; Count++;
} }
public int NextUse(int position) public readonly int NextUse(int position)
{ {
int index = NextUseIndex(position); int index = NextUseIndex(position);
return index != LiveInterval.NotFound ? _items[index] : LiveInterval.NotFound; return index != LiveInterval.NotFound ? _items[index] : LiveInterval.NotFound;
} }
public int NextUseIndex(int position) public readonly int NextUseIndex(int position)
{ {
int i = _count - 1; int i = Count - 1;
if (i == -1 || position > _items[0]) if (i == -1 || position > _items[0])
{ {
@ -69,14 +69,16 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Since the list is in descending order, the new split list takes the front of the list and the current // Since the list is in descending order, the new split list takes the front of the list and the current
// list takes the back of the list. // list takes the back of the list.
UseList result = new(); UseList result = new()
result._count = index + 1; {
result._capacity = result._count; Count = index + 1,
};
result._capacity = result.Count;
result._items = _items; result._items = _items;
_count = _count - result._count; Count -= result.Count;
_capacity = _count; _capacity = Count;
_items = _items + result._count; _items += result.Count;
return result; return result;
} }

View file

@ -6,6 +6,6 @@ namespace ARMeilleure.CodeGen.Unwinding
SetFrame = 1, SetFrame = 1,
AllocStack = 2, AllocStack = 2,
SaveReg = 3, SaveReg = 3,
SaveXmm128 = 4 SaveXmm128 = 4,
} }
} }

View file

@ -799,7 +799,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
JumpIndex = _jumps.Count - 1, JumpIndex = _jumps.Count - 1,
Position = (int)_stream.Position, Position = (int)_stream.Position,
Symbol = source.Symbol Symbol = source.Symbol,
}); });
} }
@ -1049,7 +1049,7 @@ namespace ARMeilleure.CodeGen.X86
InstructionFlags.Prefix66 => 1, InstructionFlags.Prefix66 => 1,
InstructionFlags.PrefixF3 => 2, InstructionFlags.PrefixF3 => 2,
InstructionFlags.PrefixF2 => 3, InstructionFlags.PrefixF2 => 3,
_ => 0 _ => 0,
}; };
if (src1 != default) if (src1 != default)
@ -1081,11 +1081,19 @@ namespace ARMeilleure.CodeGen.X86
switch (opCodeHigh) switch (opCodeHigh)
{ {
case 0xf: vexByte1 |= 1; break; case 0xf:
case 0xf38: vexByte1 |= 2; break; vexByte1 |= 1;
case 0xf3a: vexByte1 |= 3; break; break;
case 0xf38:
vexByte1 |= 2;
break;
case 0xf3a:
vexByte1 |= 3;
break;
default: Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}."); break; default:
Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}.");
break;
} }
vexByte2 |= (rexPrefix & 8) << 4; vexByte2 |= (rexPrefix & 8) << 4;
@ -1191,11 +1199,19 @@ namespace ARMeilleure.CodeGen.X86
switch ((ushort)(opCode >> 8)) switch ((ushort)(opCode >> 8))
{ {
case 0xf00: mm = 0b01; break; case 0xf00:
case 0xf38: mm = 0b10; break; mm = 0b01;
case 0xf3a: mm = 0b11; break; break;
case 0xf38:
mm = 0b10;
break;
case 0xf3a:
mm = 0b11;
break;
default: Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}."); break; default:
Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}.");
break;
} }
WriteByte( WriteByte(
@ -1217,7 +1233,7 @@ namespace ARMeilleure.CodeGen.X86
InstructionFlags.Prefix66 => 0b01, InstructionFlags.Prefix66 => 0b01,
InstructionFlags.PrefixF3 => 0b10, InstructionFlags.PrefixF3 => 0b10,
InstructionFlags.PrefixF2 => 0b11, InstructionFlags.PrefixF2 => 0b11,
_ => 0 _ => 0,
}; };
WriteByte( WriteByte(
(byte)( (byte)(
@ -1233,11 +1249,19 @@ namespace ARMeilleure.CodeGen.X86
byte ll = 0b00; byte ll = 0b00;
switch (registerWidth) switch (registerWidth)
{ {
case 128: ll = 0b00; break; case 128:
case 256: ll = 0b01; break; ll = 0b00;
case 512: ll = 0b10; break; break;
case 256:
ll = 0b01;
break;
case 512:
ll = 0b10;
break;
default: Debug.Fail($"Invalid EVEX vector register width {registerWidth}."); break; default:
Debug.Fail($"Invalid EVEX vector register width {registerWidth}.");
break;
} }
// Embedded broadcast in the case of a memory operand // Embedded broadcast in the case of a memory operand
bool bcast = broadcast; bool bcast = broadcast;
@ -1315,10 +1339,7 @@ namespace ARMeilleure.CodeGen.X86
ref Jump jump = ref jumps[i]; ref Jump jump = ref jumps[i];
// If jump target not resolved yet, resolve it. // If jump target not resolved yet, resolve it.
if (jump.JumpTarget == null) jump.JumpTarget ??= _labels[jump.JumpLabel];
{
jump.JumpTarget = _labels[jump.JumpLabel];
}
long jumpTarget = jump.JumpTarget.Value; long jumpTarget = jump.JumpTarget.Value;
long offset = jumpTarget - jump.JumpPosition; long offset = jumpTarget - jump.JumpPosition;

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
@ -12,6 +13,7 @@ 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,
@ -26,7 +28,7 @@ namespace ARMeilleure.CodeGen.X86
PrefixMask = 7 << PrefixBit, PrefixMask = 7 << PrefixBit,
Prefix66 = 1 << PrefixBit, Prefix66 = 1 << PrefixBit,
PrefixF3 = 2 << PrefixBit, PrefixF3 = 2 << PrefixBit,
PrefixF2 = 4 << PrefixBit PrefixF2 = 4 << PrefixBit,
} }
private readonly struct InstructionInfo private readonly struct InstructionInfo
@ -62,6 +64,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
_instTable = new InstructionInfo[(int)X86Instruction.Count]; _instTable = new InstructionInfo[(int)X86Instruction.Count];
#pragma warning disable IDE0055 // Disable formatting
// Name RM/R RM/I8 RM/I32 R/I64 R/RM Flags // Name RM/R RM/I8 RM/I32 R/I64 R/RM Flags
Add(X86Instruction.Add, new InstructionInfo(0x00000001, 0x00000083, 0x00000081, BadOp, 0x00000003, InstructionFlags.None)); Add(X86Instruction.Add, new InstructionInfo(0x00000001, 0x00000083, 0x00000081, BadOp, 0x00000003, InstructionFlags.None));
Add(X86Instruction.Addpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f58, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Addpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f58, InstructionFlags.Vex | InstructionFlags.Prefix66));
@ -285,6 +288,7 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None)); Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None));
Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex)); Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex));
#pragma warning restore IDE0055
static void Add(X86Instruction inst, in InstructionInfo info) static void Add(X86Instruction inst, in InstructionInfo info)
{ {

View file

@ -3,6 +3,6 @@ namespace ARMeilleure.CodeGen.X86
enum CallConvName enum CallConvName
{ {
SystemV, SystemV,
Windows Windows,
} }
} }

View file

@ -20,6 +20,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
if (GetCurrentCallConv() == CallConvName.Windows) if (GetCurrentCallConv() == CallConvName.Windows)
{ {
#pragma warning disable IDE0055 // Disable formatting
return (1 << (int)X86Register.Rax) | return (1 << (int)X86Register.Rax) |
(1 << (int)X86Register.Rcx) | (1 << (int)X86Register.Rcx) |
(1 << (int)X86Register.Rdx) | (1 << (int)X86Register.Rdx) |
@ -39,6 +40,7 @@ namespace ARMeilleure.CodeGen.X86
(1 << (int)X86Register.R9) | (1 << (int)X86Register.R9) |
(1 << (int)X86Register.R10) | (1 << (int)X86Register.R10) |
(1 << (int)X86Register.R11); (1 << (int)X86Register.R11);
#pragma warning restore IDE0055
} }
} }
@ -90,22 +92,32 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (index) switch (index)
{ {
case 0: return X86Register.Rcx; case 0:
case 1: return X86Register.Rdx; return X86Register.Rcx;
case 2: return X86Register.R8; case 1:
case 3: return X86Register.R9; return X86Register.Rdx;
case 2:
return X86Register.R8;
case 3:
return X86Register.R9;
} }
} }
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */ else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
{ {
switch (index) switch (index)
{ {
case 0: return X86Register.Rdi; case 0:
case 1: return X86Register.Rsi; return X86Register.Rdi;
case 2: return X86Register.Rdx; case 1:
case 3: return X86Register.Rcx; return X86Register.Rsi;
case 4: return X86Register.R8; case 2:
case 5: return X86Register.R9; return X86Register.Rdx;
case 3:
return X86Register.Rcx;
case 4:
return X86Register.R8;
case 5:
return X86Register.R9;
} }
} }

View file

@ -26,6 +26,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
_instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))]; _instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))];
#pragma warning disable IDE0055 // Disable formatting
Add(Instruction.Add, GenerateAdd); Add(Instruction.Add, GenerateAdd);
Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd);
Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr);
@ -85,6 +86,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend16, GenerateZeroExtend16);
Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend32, GenerateZeroExtend32);
Add(Instruction.ZeroExtend8, GenerateZeroExtend8); Add(Instruction.ZeroExtend8, GenerateZeroExtend8);
#pragma warning restore IDE0055
static void Add(Instruction inst, Action<CodeGenContext, Operation> func) static void Add(Instruction inst, Action<CodeGenContext, Operation> func)
{ {
@ -1294,11 +1296,11 @@ namespace ARMeilleure.CodeGen.X86
} }
else else
{ {
const byte mask = 0b01_00_11_10; const byte Mask = 0b01_00_11_10;
context.Assembler.Pshufd(src1, src1, mask); context.Assembler.Pshufd(src1, src1, Mask);
context.Assembler.Movq(dest, src1); context.Assembler.Movq(dest, src1);
context.Assembler.Pshufd(src1, src1, mask); context.Assembler.Pshufd(src1, src1, Mask);
} }
} }
else else
@ -1613,13 +1615,25 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: context.Assembler.Mov (value, address, OperandType.I32); break; case OperandType.I32:
case OperandType.I64: context.Assembler.Mov (value, address, OperandType.I64); break; context.Assembler.Mov(value, address, OperandType.I32);
case OperandType.FP32: context.Assembler.Movd (value, address); break; break;
case OperandType.FP64: context.Assembler.Movq (value, address); break; case OperandType.I64:
case OperandType.V128: context.Assembler.Movdqu(value, address); break; context.Assembler.Mov(value, address, OperandType.I64);
break;
case OperandType.FP32:
context.Assembler.Movd(value, address);
break;
case OperandType.FP64:
context.Assembler.Movq(value, address);
break;
case OperandType.V128:
context.Assembler.Movdqu(value, address);
break;
default: Debug.Assert(false); break; default:
Debug.Assert(false);
break;
} }
} }
@ -1627,13 +1641,25 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: context.Assembler.Mov (address, value, OperandType.I32); break; case OperandType.I32:
case OperandType.I64: context.Assembler.Mov (address, value, OperandType.I64); break; context.Assembler.Mov(address, value, OperandType.I32);
case OperandType.FP32: context.Assembler.Movd (address, value); break; break;
case OperandType.FP64: context.Assembler.Movq (address, value); break; case OperandType.I64:
case OperandType.V128: context.Assembler.Movdqu(address, value); break; context.Assembler.Mov(address, value, OperandType.I64);
break;
case OperandType.FP32:
context.Assembler.Movd(address, value);
break;
case OperandType.FP64:
context.Assembler.Movq(address, value);
break;
case OperandType.V128:
context.Assembler.Movdqu(address, value);
break;
default: Debug.Assert(false); break; default:
Debug.Assert(false);
break;
} }
} }
@ -1722,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>(); List<UnwindPushEntry> pushEntries = new();
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
@ -1827,9 +1853,9 @@ namespace ARMeilleure.CodeGen.X86
// that the OS will map all pages that we'll use. We do that by // that the OS will map all pages that we'll use. We do that by
// doing a dummy read on those pages, forcing a page fault and // doing a dummy read on those pages, forcing a page fault and
// the OS to map them. If they are already mapped, nothing happens. // the OS to map them. If they are already mapped, nothing happens.
const int pageMask = PageSize - 1; const int PageMask = PageSize - 1;
size = (size + pageMask) & ~pageMask; size = (size + PageMask) & ~PageMask;
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
Operand temp = Register(CallingConvention.GetIntReturnRegister()); Operand temp = Register(CallingConvention.GetIntReturnRegister());

View file

@ -47,7 +47,7 @@ namespace ARMeilleure.CodeGen.X86
0xc3, // ret 0xc3, // ret
}; };
using MemoryBlock memGetXcr0 = new MemoryBlock((ulong)asmGetXcr0.Length); using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);
memGetXcr0.Write(0, asmGetXcr0); memGetXcr0.Write(0, asmGetXcr0);
@ -62,7 +62,7 @@ namespace ARMeilleure.CodeGen.X86
public enum FeatureFlags1Edx public enum FeatureFlags1Edx
{ {
Sse = 1 << 25, Sse = 1 << 25,
Sse2 = 1 << 26 Sse2 = 1 << 26,
} }
[Flags] [Flags]
@ -79,7 +79,7 @@ namespace ARMeilleure.CodeGen.X86
Xsave = 1 << 26, Xsave = 1 << 26,
Osxsave = 1 << 27, Osxsave = 1 << 27,
Avx = 1 << 28, Avx = 1 << 28,
F16c = 1 << 29 F16c = 1 << 29,
} }
[Flags] [Flags]
@ -90,7 +90,7 @@ namespace ARMeilleure.CodeGen.X86
Avx512dq = 1 << 17, Avx512dq = 1 << 17,
Sha = 1 << 29, Sha = 1 << 29,
Avx512bw = 1 << 30, Avx512bw = 1 << 30,
Avx512vl = 1 << 31 Avx512vl = 1 << 31,
} }
[Flags] [Flags]
@ -106,7 +106,7 @@ namespace ARMeilleure.CodeGen.X86
YmmHi128 = 1 << 2, YmmHi128 = 1 << 2,
Opmask = 1 << 5, Opmask = 1 << 5,
ZmmHi256 = 1 << 6, ZmmHi256 = 1 << 6,
Hi16Zmm = 1 << 7 Hi16Zmm = 1 << 7,
} }
public static FeatureFlags1Edx FeatureInfo1Edx { get; } public static FeatureFlags1Edx FeatureInfo1Edx { get; }

View file

@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.X86
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static IntrinsicInfo[] _intrinTable; private static readonly IntrinsicInfo[] _intrinTable;
static IntrinsicTable() static IntrinsicTable()
{ {
_intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))];
#pragma warning disable IDE0055 // Disable formatting
Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary)); Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary));
Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary)); Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary));
Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary)); Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary));
@ -185,6 +186,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm)); Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary)); Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary));
Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary)); Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)

View file

@ -13,6 +13,6 @@ namespace ARMeilleure.CodeGen.X86
Crc32, Crc32,
Ternary, Ternary,
TernaryImm, TernaryImm,
Fma Fma,
} }
} }

View file

@ -10,6 +10,6 @@ namespace ARMeilleure.CodeGen.X86
Rlo = 1 << 13, // Round Mode low bit. Rlo = 1 << 13, // Round Mode low bit.
Um = 1 << 11, // Underflow Mask. Um = 1 << 11, // Underflow Mask.
Dm = 1 << 8, // Denormal Mask. Dm = 1 << 8, // Denormal Mask.
Daz = 1 << 6 // Denormals Are Zero. Daz = 1 << 6, // Denormals Are Zero.
} }
} }

View file

@ -104,11 +104,11 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Tailcall: case Instruction.Tailcall:
if (callConv == CallConvName.Windows) if (callConv == CallConvName.Windows)
{ {
PreAllocatorWindows.InsertTailcallCopies(block.Operations, stackAlloc, node); PreAllocatorWindows.InsertTailcallCopies(block.Operations, node);
} }
else else
{ {
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, stackAlloc, node); PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
} }
break; break;
@ -177,10 +177,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
src2 = node.GetSource(1); src2 = node.GetSource(1);
Operand temp = src1; (src2, src1) = (src1, src2);
src1 = src2;
src2 = temp;
node.SetSource(0, src1); node.SetSource(0, src1);
node.SetSource(1, src2); node.SetSource(1, src2);
@ -473,7 +470,7 @@ namespace ARMeilleure.CodeGen.X86
Operand zex = Local(OperandType.I64); Operand zex = Local(OperandType.I64);
node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source)); node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source));
node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex)); nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex));
} }
else /* if (source.Type == OperandType.I64) */ else /* if (source.Type == OperandType.I64) */
{ {
@ -709,16 +706,11 @@ namespace ARMeilleure.CodeGen.X86
private static bool HasConstSrc1(Instruction inst) private static bool HasConstSrc1(Instruction inst)
{ {
switch (inst) return inst switch
{ {
case Instruction.Copy: Instruction.Copy or Instruction.LoadArgument or Instruction.Spill or Instruction.SpillArg => true,
case Instruction.LoadArgument: _ => false,
case Instruction.Spill: };
case Instruction.SpillArg:
return true;
}
return false;
} }
private static bool HasConstSrc2(Instruction inst) private static bool HasConstSrc2(Instruction inst)

View file

@ -1,4 +1,3 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
@ -15,9 +14,9 @@ namespace ARMeilleure.CodeGen.X86
{ {
Operand dest = node.Destination; Operand dest = node.Destination;
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
node.GetSource(0) node.GetSource(0),
}; };
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
@ -116,11 +115,11 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
{ {
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
node.GetSource(0) node.GetSource(0),
}; };
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;

View file

@ -155,7 +155,7 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources(sources); node.SetSources(sources);
} }
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
{ {
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
int maxArgs = CallingConvention.GetArgumentsOnRegsCount(); int maxArgs = CallingConvention.GetArgumentsOnRegsCount();

View file

@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.X86
Less = 0xc, Less = 0xc,
GreaterOrEqual = 0xd, GreaterOrEqual = 0xd,
LessOrEqual = 0xe, LessOrEqual = 0xe,
Greater = 0xf Greater = 0xf,
} }
static class ComparisonX86Extensions static class ComparisonX86Extensions
@ -29,6 +29,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
return comp switch return comp switch
{ {
#pragma warning disable IDE0055 // Disable formatting
Comparison.Equal => X86Condition.Equal, Comparison.Equal => X86Condition.Equal,
Comparison.NotEqual => X86Condition.NotEqual, Comparison.NotEqual => X86Condition.NotEqual,
Comparison.Greater => X86Condition.Greater, Comparison.Greater => X86Condition.Greater,
@ -39,8 +40,9 @@ namespace ARMeilleure.CodeGen.X86
Comparison.Less => X86Condition.Less, Comparison.Less => X86Condition.Less,
Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual, Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual,
Comparison.LessUI => X86Condition.Below, Comparison.LessUI => X86Condition.Below,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)) _ => throw new ArgumentException(null, nameof(comp)),
}; };
} }
} }

View file

@ -226,6 +226,6 @@ namespace ARMeilleure.CodeGen.X86
Xorpd, Xorpd,
Xorps, Xorps,
Count Count,
} }
} }

View file

@ -215,7 +215,7 @@ namespace ARMeilleure.CodeGen.X86
1 => Multiplier.x2, 1 => Multiplier.x2,
2 => Multiplier.x4, 2 => Multiplier.x4,
3 => Multiplier.x8, 3 => Multiplier.x8,
_ => Multiplier.x1 _ => Multiplier.x1,
}; };
baseOp = indexOnSrc2 ? src1 : src2; baseOp = indexOnSrc2 ? src1 : src2;

View file

@ -1,5 +1,8 @@
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,
@ -36,6 +39,6 @@ namespace ARMeilleure.CodeGen.X86
Xmm12 = 12, Xmm12 = 12,
Xmm13 = 13, Xmm13 = 13,
Xmm14 = 14, Xmm14 = 14,
Xmm15 = 15 Xmm15 = 15,
} }
} }

View file

@ -82,8 +82,10 @@ namespace ARMeilleure.Common
} }
else else
{ {
_page = new PageInfo(); _page = new PageInfo
_page.Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize); {
Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize),
};
_pages.Add(_page); _pages.Add(_page);
} }
@ -106,7 +108,7 @@ namespace ARMeilleure.Common
// Free excess pages that was allocated. // Free excess pages that was allocated.
while (_pages.Count > _pageCount) while (_pages.Count > _pageCount)
{ {
NativeAllocator.Instance.Free(_pages[_pages.Count - 1].Pointer); NativeAllocator.Instance.Free(_pages[^1].Pointer);
_pages.RemoveAt(_pages.Count - 1); _pages.RemoveAt(_pages.Count - 1);
} }
@ -125,12 +127,13 @@ namespace ARMeilleure.Common
// If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time. // If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time.
int now = Environment.TickCount; int now = Environment.TickCount;
int count = (now - _lastReset) switch { int count = (now - _lastReset) switch
{
>= 5000 => 0, >= 5000 => 0,
>= 2500 => 50, >= 2500 => 50,
>= 1000 => 100, >= 1000 => 100,
>= 10 => 1500, >= 10 => 1500,
_ => 5000 _ => 5000,
}; };
for (int i = _pages.Count - 1; i >= 0; i--) for (int i = _pages.Count - 1; i >= 0; i--)

View file

@ -138,7 +138,7 @@ namespace ARMeilleure.Common
var newSpan = new Span<long>(_masks, _count); var newSpan = new Span<long>(_masks, _count);
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
newSpan.Slice(oldSpan.Length).Clear(); newSpan[oldSpan.Length..].Clear();
_allocator.Free(oldMask); _allocator.Free(oldMask);
} }
@ -176,8 +176,8 @@ namespace ARMeilleure.Common
private int _bit; private int _bit;
private readonly BitMap _map; private readonly BitMap _map;
public int Current => (int)_index * IntSize + _bit; public readonly int Current => (int)_index * IntSize + _bit;
object IEnumerator.Current => Current; readonly object IEnumerator.Current => Current;
public Enumerator(BitMap map) public Enumerator(BitMap map)
{ {
@ -214,9 +214,9 @@ namespace ARMeilleure.Common
return true; return true;
} }
public void Reset() { } public readonly void Reset() { }
public void Dispose() { } public readonly void Dispose() { }
} }
} }
} }

View file

@ -92,7 +92,7 @@ namespace ARMeilleure.Decoders
{ {
if (OpCodes.Count > 0) if (OpCodes.Count > 0)
{ {
return OpCodes[OpCodes.Count - 1]; return OpCodes[^1];
} }
return null; return null;

View file

@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders
Gt = 12, Gt = 12,
Le = 13, Le = 13,
Al = 14, Al = 14,
Nv = 15 Nv = 15,
} }
static class ConditionExtensions static class ConditionExtensions

View file

@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
Adr = 0, Adr = 0,
Arithmetic = 1, Arithmetic = 1,
Logical = 2, Logical = 2,
BitField = 3 BitField = 3,
} }
} }

View file

@ -20,11 +20,11 @@ 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>(); List<Block> blocks = new();
Queue<Block> workQueue = new Queue<Block>(); Queue<Block> workQueue = new();
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>(); Dictionary<ulong, Block> visited = new();
Debug.Assert(MaxInstsPerFunctionLowCq <= MaxInstsPerFunction); Debug.Assert(MaxInstsPerFunctionLowCq <= MaxInstsPerFunction);
@ -246,7 +246,7 @@ namespace ARMeilleure.Decoders
private static bool IsAarch32UnconditionalBranch(OpCode opCode) private static bool IsAarch32UnconditionalBranch(OpCode opCode)
{ {
if (!(opCode is OpCode32 op)) if (opCode is not OpCode32 op)
{ {
return false; return false;
} }
@ -304,9 +304,9 @@ namespace ARMeilleure.Decoders
} }
else if (opCode is IOpCode32MemMult opMemMult) else if (opCode is IOpCode32MemMult opMemMult)
{ {
const int pcMask = 1 << RegisterAlias.Aarch32Pc; const int PCMask = 1 << RegisterAlias.Aarch32Pc;
rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0; rt = (opMemMult.RegisterMask & PCMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
rn = opMemMult.Rn; rn = opMemMult.Rn;
wBack = opMemMult.PostOffset != 0; wBack = opMemMult.PostOffset != 0;
isLoad = opMemMult.IsLoad; isLoad = opMemMult.IsLoad;

View file

@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
// abcdefgh -> aBbbbbbc defgh000 00000000 00000000 (B = ~b) // abcdefgh -> aBbbbbbc defgh000 00000000 00000000 (B = ~b)
private static uint ExpandImm8ToFP32(uint imm) private static uint ExpandImm8ToFP32(uint imm)
{ {
uint MoveBit(uint bits, int from, int to) static uint MoveBit(uint bits, int from, int to)
{ {
return ((bits >> from) & 1U) << to; return ((bits >> from) & 1U) << to;
} }
@ -57,7 +57,7 @@ namespace ARMeilleure.Decoders
// abcdefgh -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = ~b) // abcdefgh -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = ~b)
private static ulong ExpandImm8ToFP64(ulong imm) private static ulong ExpandImm8ToFP64(ulong imm)
{ {
ulong MoveBit(ulong bits, int from, int to) static ulong MoveBit(ulong bits, int from, int to)
{ {
return ((bits >> from) & 1UL) << to; return ((bits >> from) & 1UL) << to;
} }
@ -80,7 +80,7 @@ namespace ARMeilleure.Decoders
public int Shift; public int Shift;
public bool IsUndefined; public bool IsUndefined;
public static BitMask Invalid => new BitMask { IsUndefined = true }; public static BitMask Invalid => new() { IsUndefined = true };
} }
public static BitMask DecodeBitMask(int opCode, bool immediate) public static BitMask DecodeBitMask(int opCode, bool immediate)
@ -125,7 +125,7 @@ namespace ARMeilleure.Decoders
TMask = BitUtils.Replicate(tMask, size), TMask = BitUtils.Replicate(tMask, size),
Pos = immS, Pos = immS,
Shift = immR Shift = immR,
}; };
} }

View file

@ -4,7 +4,7 @@ namespace ARMeilleure.Decoders
{ {
readonly struct InstDescriptor readonly struct InstDescriptor
{ {
public static InstDescriptor Undefined => new InstDescriptor(InstName.Und, InstEmit.Und); public static InstDescriptor Undefined => new(InstName.Und, InstEmit.Und);
public InstName Name { get; } public InstName Name { get; }
public InstEmitter Emitter { get; } public InstEmitter Emitter { get; }

View file

@ -9,6 +9,6 @@ namespace ARMeilleure.Decoders
Int8 = 4, Int8 = 4,
Int16 = 5, Int16 = 5,
Int32 = 6, Int32 = 6,
Int64 = 7 Int64 = 7,
} }
} }

View file

@ -14,7 +14,7 @@ namespace ARMeilleure.Decoders
public RegisterSize RegisterSize { get; protected set; } public RegisterSize RegisterSize { get; protected set; }
public static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode(inst, address, opCode); public static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new(inst, address, opCode);
public OpCode(InstDescriptor inst, ulong address, int opCode) public OpCode(InstDescriptor inst, ulong address, int opCode)
{ {
@ -30,15 +30,14 @@ namespace ARMeilleure.Decoders
public int GetBitsCount() public int GetBitsCount()
{ {
switch (RegisterSize) return RegisterSize switch
{ {
case RegisterSize.Int32: return 32; RegisterSize.Int32 => 32,
case RegisterSize.Int64: return 64; RegisterSize.Int64 => 64,
case RegisterSize.Simd64: return 64; RegisterSize.Simd64 => 64,
case RegisterSize.Simd128: return 128; RegisterSize.Simd128 => 128,
} _ => throw new InvalidOperationException(),
};
throw new InvalidOperationException();
} }
public OperandType GetOperandType() public OperandType GetOperandType()

View file

@ -24,27 +24,21 @@ namespace ARMeilleure.Decoders
protected int GetQuadwordIndex(int index) protected int GetQuadwordIndex(int index)
{ {
switch (RegisterSize) return RegisterSize switch
{ {
case RegisterSize.Simd128: RegisterSize.Simd128 or RegisterSize.Simd64 => index >> 1,
case RegisterSize.Simd64: _ => throw new InvalidOperationException(),
return index >> 1; };
}
throw new InvalidOperationException();
} }
protected int GetQuadwordSubindex(int index) protected int GetQuadwordSubindex(int index)
{ {
switch (RegisterSize) return RegisterSize switch
{ {
case RegisterSize.Simd128: RegisterSize.Simd128 => 0,
return 0; RegisterSize.Simd64 => index & 1,
case RegisterSize.Simd64: _ => throw new InvalidOperationException(),
return index & 1; };
}
throw new InvalidOperationException();
} }
protected OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode) protected OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)

View file

@ -0,0 +1,23 @@
namespace ARMeilleure.Decoders
{
class OpCode32SimdCvtFFixed : OpCode32Simd
{
public int Fbits { get; protected set; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, false);
public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, true);
public OpCode32SimdCvtFFixed(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
{
Opc = (opCode >> 8) & 0x1;
Size = Opc == 1 ? 0 : 2;
Fbits = 64 - ((opCode >> 16) & 0x3f);
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
{
Instruction = InstDescriptor.Undefined;
}
}
}
}

View file

@ -14,9 +14,15 @@
// The value must be a power of 2, otherwise it is the encoding of another instruction. // The value must be a power of 2, otherwise it is the encoding of another instruction.
switch (imm3h) switch (imm3h)
{ {
case 1: Size = 0; break; case 1:
case 2: Size = 1; break; Size = 0;
case 4: Size = 2; break; break;
case 2:
Size = 1;
break;
case 4:
Size = 2;
break;
} }
U = ((opCode >> (isThumb ? 28 : 24)) & 0x1) != 0; U = ((opCode >> (isThumb ? 28 : 24)) & 0x1) != 0;

View file

@ -4,12 +4,12 @@ namespace ARMeilleure.Decoders
{ {
class OpCode32SimdMemPair : OpCode32, IOpCode32Simd class OpCode32SimdMemPair : OpCode32, IOpCode32Simd
{ {
private static 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; }

View file

@ -13,11 +13,11 @@
} }
} }
enum OpCode32SimdSelMode : int enum OpCode32SimdSelMode
{ {
Eq = 0, Eq = 0,
Vs, Vs,
Ge, Ge,
Gt Gt,
} }
} }

View file

@ -33,7 +33,7 @@ namespace ARMeilleure.Decoders
} }
else else
{ {
throw new ArgumentException(nameof(opCode)); throw new ArgumentException($"Invalid data operation: {DataOp}", nameof(opCode));
} }
} }
} }

View file

@ -13,7 +13,7 @@ namespace ARMeilleure.Decoders
PostIndexed = 1, PostIndexed = 1,
Unprivileged = 2, Unprivileged = 2,
PreIndexed = 3, PreIndexed = 3,
Unsigned Unsigned,
} }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemImm(inst, address, opCode); public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemImm(inst, address, opCode);

View file

@ -18,10 +18,26 @@ namespace ARMeilleure.Decoders
switch ((opCode >> 30) & 3) switch ((opCode >> 30) & 3)
{ {
case 0: Size = 2; Signed = false; Prefetch = false; break; case 0:
case 1: Size = 3; Signed = false; Prefetch = false; break; Size = 2;
case 2: Size = 2; Signed = true; Prefetch = false; break; Signed = false;
case 3: Size = 0; Signed = false; Prefetch = true; break; Prefetch = false;
break;
case 1:
Size = 3;
Signed = false;
Prefetch = false;
break;
case 2:
Size = 2;
Signed = true;
Prefetch = false;
break;
case 3:
Size = 0;
Signed = false;
Prefetch = true;
break;
} }
} }
} }

View file

@ -52,17 +52,20 @@
else if ((modeHigh & 0b110) == 0b100) else if ((modeHigh & 0b110) == 0b100)
{ {
// 16-bits shifted Immediate. // 16-bits shifted Immediate.
size = 1; imm <<= (modeHigh & 1) << 3; size = 1;
imm <<= (modeHigh & 1) << 3;
} }
else if ((modeHigh & 0b100) == 0b000) else if ((modeHigh & 0b100) == 0b000)
{ {
// 32-bits shifted Immediate. // 32-bits shifted Immediate.
size = 2; imm <<= modeHigh << 3; size = 2;
imm <<= modeHigh << 3;
} }
else if ((modeHigh & 0b111) == 0b110) else if ((modeHigh & 0b111) == 0b110)
{ {
// 32-bits shifted Immediate (fill with ones). // 32-bits shifted Immediate (fill with ones).
size = 2; imm = ShlOnes(imm, 8 << modeLow); size = 2;
imm = ShlOnes(imm, 8 << modeLow);
} }
else else
{ {

View file

@ -67,17 +67,20 @@ namespace ARMeilleure.Decoders
else if ((modeHigh & 0b110) == 0b100) else if ((modeHigh & 0b110) == 0b100)
{ {
// 16-bits shifted Immediate. // 16-bits shifted Immediate.
Size = 1; imm <<= (modeHigh & 1) << 3; Size = 1;
imm <<= (modeHigh & 1) << 3;
} }
else if ((modeHigh & 0b100) == 0b000) else if ((modeHigh & 0b100) == 0b000)
{ {
// 32-bits shifted Immediate. // 32-bits shifted Immediate.
Size = 2; imm <<= modeHigh << 3; Size = 2;
imm <<= modeHigh << 3;
} }
else if ((modeHigh & 0b111) == 0b110) else if ((modeHigh & 0b111) == 0b110)
{ {
// 32-bits shifted Immediate (fill with ones). // 32-bits shifted Immediate (fill with ones).
Size = 2; imm = ShlOnes(imm, 8 << modeLow); Size = 2;
imm = ShlOnes(imm, 8 << modeLow);
} }
else else
{ {

View file

@ -23,10 +23,18 @@ namespace ARMeilleure.Decoders
switch (Size) switch (Size)
{ {
case 1: Size = 0; break; case 1:
case 2: Size = 1; break; Size = 0;
case 4: Size = 2; break; break;
case 8: Size = 3; break; case 2:
Size = 1;
break;
case 4:
Size = 2;
break;
case 8:
Size = 3;
break;
} }
SrcIndex = imm4 >> Size; SrcIndex = imm4 >> Size;

View file

@ -13,15 +13,38 @@ namespace ARMeilleure.Decoders
{ {
switch ((opCode >> 12) & 0xf) switch ((opCode >> 12) & 0xf)
{ {
case 0b0000: Reps = 1; SElems = 4; break; case 0b0000:
case 0b0010: Reps = 4; SElems = 1; break; Reps = 1;
case 0b0100: Reps = 1; SElems = 3; break; SElems = 4;
case 0b0110: Reps = 3; SElems = 1; break; break;
case 0b0111: Reps = 1; SElems = 1; break; case 0b0010:
case 0b1000: Reps = 1; SElems = 2; break; Reps = 4;
case 0b1010: Reps = 2; SElems = 1; break; SElems = 1;
break;
case 0b0100:
Reps = 1;
SElems = 3;
break;
case 0b0110:
Reps = 3;
SElems = 1;
break;
case 0b0111:
Reps = 1;
SElems = 1;
break;
case 0b1000:
Reps = 1;
SElems = 2;
break;
case 0b1010:
Reps = 2;
SElems = 1;
break;
default: Instruction = InstDescriptor.Undefined; return; default:
Instruction = InstDescriptor.Undefined;
return;
} }
Size = (opCode >> 10) & 3; Size = (opCode >> 10) & 3;

View file

@ -24,7 +24,9 @@ namespace ARMeilleure.Decoders
break; break;
default: Instruction = InstDescriptor.Undefined; break; default:
Instruction = InstDescriptor.Undefined;
break;
} }
} }
} }

View file

@ -26,7 +26,9 @@ namespace ARMeilleure.Decoders
break; break;
default: Instruction = InstDescriptor.Undefined; break; default:
Instruction = InstDescriptor.Undefined;
break;
} }
} }
} }

View file

@ -36,23 +36,13 @@ namespace ARMeilleure.Decoders
break; break;
} }
switch (inst.Name) Immediate = inst.Name switch
{ {
case InstName.Str: InstName.Str or InstName.Ldr => ((opCode >> 6) & 0x1f) << 2,
case InstName.Ldr: InstName.Strb or InstName.Ldrb => ((opCode >> 6) & 0x1f),
Immediate = ((opCode >> 6) & 0x1f) << 2; InstName.Strh or InstName.Ldrh => ((opCode >> 6) & 0x1f) << 1,
break; _ => throw new InvalidOperationException(),
case InstName.Strb: };
case InstName.Ldrb:
Immediate = ((opCode >> 6) & 0x1f);
break;
case InstName.Strh:
case InstName.Ldrh:
Immediate = ((opCode >> 6) & 0x1f) << 1;
break;
default:
throw new InvalidOperationException();
}
} }
} }
} }

View file

@ -27,7 +27,7 @@ namespace ARMeilleure.Decoders
{ {
InstName.Ldm => true, InstName.Ldm => true,
InstName.Stm => false, InstName.Stm => false,
_ => throw new InvalidOperationException() _ => throw new InvalidOperationException(),
}; };
} }
} }

View file

@ -4,8 +4,6 @@ namespace ARMeilleure.Decoders
{ {
public int Immediate { get; } public int Immediate { get; }
public bool IsRotated => false;
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MovImm16(inst, address, opCode); public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MovImm16(inst, address, opCode);
public OpCodeT32MovImm16(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCodeT32MovImm16(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)

View file

@ -29,16 +29,17 @@ namespace ARMeilleure.Decoders
} }
} }
private static List<InstInfo> AllInstA32 = new(); private static readonly List<InstInfo> _allInstA32 = new();
private static List<InstInfo> AllInstT32 = new(); private static readonly List<InstInfo> _allInstT32 = new();
private static List<InstInfo> AllInstA64 = new(); private static readonly List<InstInfo> _allInstA64 = new();
private static InstInfo[][] InstA32FastLookup = new InstInfo[FastLookupSize][]; private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][];
private static InstInfo[][] InstT32FastLookup = new InstInfo[FastLookupSize][]; private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][];
private static InstInfo[][] InstA64FastLookup = new InstInfo[FastLookupSize][]; private static readonly InstInfo[][] _instA64FastLookup = new InstInfo[FastLookupSize][];
static OpCodeTable() static OpCodeTable()
{ {
#pragma warning disable IDE0055 // Disable formatting
#region "OpCode Table (AArch64)" #region "OpCode Table (AArch64)"
// Base // Base
SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstName.Adc, InstEmit.Adc, OpCodeAluRs.Create); SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstName.Adc, InstEmit.Adc, OpCodeAluRs.Create);
@ -329,6 +330,7 @@ namespace ARMeilleure.Decoders
SetA64("011111100x110000110010xxxxxxxxxx", InstName.Fmaxnmp_S, InstEmit.Fmaxnmp_S, OpCodeSimd.Create); SetA64("011111100x110000110010xxxxxxxxxx", InstName.Fmaxnmp_S, InstEmit.Fmaxnmp_S, OpCodeSimd.Create);
SetA64("0>1011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnmp_V, InstEmit.Fmaxnmp_V, OpCodeSimdReg.Create); SetA64("0>1011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnmp_V, InstEmit.Fmaxnmp_V, OpCodeSimdReg.Create);
SetA64("0110111000110000110010xxxxxxxxxx", InstName.Fmaxnmv_V, InstEmit.Fmaxnmv_V, OpCodeSimd.Create); SetA64("0110111000110000110010xxxxxxxxxx", InstName.Fmaxnmv_V, InstEmit.Fmaxnmv_V, OpCodeSimd.Create);
SetA64("011111100x110000111110xxxxxxxxxx", InstName.Fmaxp_S, InstEmit.Fmaxp_S, OpCodeSimd.Create);
SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, OpCodeSimdReg.Create); SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, OpCodeSimdReg.Create);
SetA64("0110111000110000111110xxxxxxxxxx", InstName.Fmaxv_V, InstEmit.Fmaxv_V, OpCodeSimd.Create); SetA64("0110111000110000111110xxxxxxxxxx", InstName.Fmaxv_V, InstEmit.Fmaxv_V, OpCodeSimd.Create);
SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, OpCodeSimdReg.Create); SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, OpCodeSimdReg.Create);
@ -338,6 +340,7 @@ namespace ARMeilleure.Decoders
SetA64("011111101x110000110010xxxxxxxxxx", InstName.Fminnmp_S, InstEmit.Fminnmp_S, OpCodeSimd.Create); SetA64("011111101x110000110010xxxxxxxxxx", InstName.Fminnmp_S, InstEmit.Fminnmp_S, OpCodeSimd.Create);
SetA64("0>1011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnmp_V, InstEmit.Fminnmp_V, OpCodeSimdReg.Create); SetA64("0>1011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnmp_V, InstEmit.Fminnmp_V, OpCodeSimdReg.Create);
SetA64("0110111010110000110010xxxxxxxxxx", InstName.Fminnmv_V, InstEmit.Fminnmv_V, OpCodeSimd.Create); SetA64("0110111010110000110010xxxxxxxxxx", InstName.Fminnmv_V, InstEmit.Fminnmv_V, OpCodeSimd.Create);
SetA64("011111101x110000111110xxxxxxxxxx", InstName.Fminp_S, InstEmit.Fminp_S, OpCodeSimd.Create);
SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, OpCodeSimdReg.Create); SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, OpCodeSimdReg.Create);
SetA64("0110111010110000111110xxxxxxxxxx", InstName.Fminv_V, InstEmit.Fminv_V, OpCodeSimd.Create); SetA64("0110111010110000111110xxxxxxxxxx", InstName.Fminv_V, InstEmit.Fminv_V, OpCodeSimd.Create);
SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, OpCodeSimdRegElemF.Create); SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, OpCodeSimdRegElemF.Create);
@ -917,6 +920,7 @@ namespace ARMeilleure.Decoders
SetAsimd("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32); SetAsimd("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32);
SetAsimd("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32); SetAsimd("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32);
SetAsimd("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32); // FP and integer, vector. SetAsimd("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32); // FP and integer, vector.
SetAsimd("1111001x1x1xxxxxxxxx111x0xx1xxxx", InstName.Vcvt, InstEmit32.Vcvt_V_Fixed, OpCode32SimdCvtFFixed.Create, OpCode32SimdCvtFFixed.CreateT32); // Between floating point and fixed point, vector.
SetAsimd("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create, OpCode32SimdDupElem.CreateT32); SetAsimd("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create, OpCode32SimdDupElem.CreateT32);
SetAsimd("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create, OpCode32SimdBinary.CreateT32); SetAsimd("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create, OpCode32SimdBinary.CreateT32);
SetAsimd("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create, OpCode32SimdExt.CreateT32); SetAsimd("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create, OpCode32SimdExt.CreateT32);
@ -1299,12 +1303,13 @@ namespace ARMeilleure.Decoders
SetT32("11110011101011111000000000000001", InstName.Yield, InstEmit32.Nop, OpCodeT32.Create); SetT32("11110011101011111000000000000001", InstName.Yield, InstEmit32.Nop, OpCodeT32.Create);
#endregion #endregion
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA); FillFastLookupTable(_instA32FastLookup, _allInstA32, ToFastLookupIndexA);
FillFastLookupTable(InstT32FastLookup, AllInstT32, ToFastLookupIndexT); FillFastLookupTable(_instT32FastLookup, _allInstT32, ToFastLookupIndexT);
FillFastLookupTable(InstA64FastLookup, AllInstA64, ToFastLookupIndexA); FillFastLookupTable(_instA64FastLookup, _allInstA64, ToFastLookupIndexA);
#pragma warning restore IDE0055
} }
private static void FillFastLookupTable(InstInfo[][] table, List<InstInfo> allInsts, Func<int, int> ToFastLookupIndex) private static void FillFastLookupTable(InstInfo[][] table, List<InstInfo> allInsts, Func<int, int> toFastLookupIndex)
{ {
List<InstInfo>[] temp = new List<InstInfo>[FastLookupSize]; List<InstInfo>[] temp = new List<InstInfo>[FastLookupSize];
@ -1315,8 +1320,8 @@ namespace ARMeilleure.Decoders
foreach (InstInfo inst in allInsts) foreach (InstInfo inst in allInsts)
{ {
int mask = ToFastLookupIndex(inst.Mask); int mask = toFastLookupIndex(inst.Mask);
int value = ToFastLookupIndex(inst.Value); int value = toFastLookupIndex(inst.Value);
for (int index = 0; index < temp.Length; index++) for (int index = 0; index < temp.Length; index++)
{ {
@ -1335,22 +1340,21 @@ namespace ARMeilleure.Decoders
private static void SetA32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) private static void SetA32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{ {
Set(encoding, AllInstA32, new InstDescriptor(name, emitter), makeOp); Set(encoding, _allInstA32, new InstDescriptor(name, emitter), makeOp);
} }
private static void SetT16(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) private static void SetT16(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{ {
encoding = "xxxxxxxxxxxxxxxx" + encoding; encoding = "xxxxxxxxxxxxxxxx" + encoding;
Set(encoding, AllInstT32, new InstDescriptor(name, emitter), makeOp); Set(encoding, _allInstT32, new InstDescriptor(name, emitter), makeOp);
} }
private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{ {
string reversedEncoding = $"{encoding.AsSpan(16)}{encoding.AsSpan(0, 16)}"; string reversedEncoding = $"{encoding.AsSpan(16)}{encoding.AsSpan(0, 16)}";
MakeOp reversedMakeOp = OpCode ReversedMakeOp(InstDescriptor inst, ulong address, int opCode)
(inst, address, opCode)
=> makeOp(inst, address, (int)BitOperations.RotateRight((uint)opCode, 16)); => makeOp(inst, address, (int)BitOperations.RotateRight((uint)opCode, 16));
Set(reversedEncoding, AllInstT32, new InstDescriptor(name, emitter), reversedMakeOp); Set(reversedEncoding, _allInstT32, new InstDescriptor(name, emitter), ReversedMakeOp);
} }
private static void SetVfp(string encoding, InstName name, InstEmitter emitter, MakeOp makeOpA32, MakeOp makeOpT32) private static void SetVfp(string encoding, InstName name, InstEmitter emitter, MakeOp makeOpA32, MakeOp makeOpT32)
@ -1395,7 +1399,7 @@ namespace ARMeilleure.Decoders
private static void SetA64(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp) private static void SetA64(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{ {
Set(encoding, AllInstA64, new InstDescriptor(name, emitter), makeOp); Set(encoding, _allInstA64, new InstDescriptor(name, emitter), makeOp);
} }
private static void Set(string encoding, List<InstInfo> list, InstDescriptor inst, MakeOp makeOp) private static void Set(string encoding, List<InstInfo> list, InstDescriptor inst, MakeOp makeOp)
@ -1439,7 +1443,7 @@ namespace ARMeilleure.Decoders
} }
else if (chr != '0') else if (chr != '0')
{ {
throw new ArgumentException(nameof(encoding)); throw new ArgumentException($"Invalid encoding: {encoding}", nameof(encoding));
} }
} }
@ -1470,17 +1474,17 @@ namespace ARMeilleure.Decoders
public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode)
{ {
return GetInstFromList(InstA32FastLookup[ToFastLookupIndexA(opCode)], opCode); return GetInstFromList(_instA32FastLookup[ToFastLookupIndexA(opCode)], opCode);
} }
public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode)
{ {
return GetInstFromList(InstT32FastLookup[ToFastLookupIndexT(opCode)], opCode); return GetInstFromList(_instT32FastLookup[ToFastLookupIndexT(opCode)], opCode);
} }
public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode)
{ {
return GetInstFromList(InstA64FastLookup[ToFastLookupIndexA(opCode)], opCode); return GetInstFromList(_instA64FastLookup[ToFastLookupIndexA(opCode)], opCode);
} }
private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode) private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode)

View file

@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders.Optimizations
throw new InvalidOperationException("Function entry point is not contained in a block."); throw new InvalidOperationException("Function entry point is not contained in a block.");
} }
const ulong allowance = 4; const ulong Allowance = 4;
Block entryBlock = blocks[entryBlockId]; Block entryBlock = blocks[entryBlockId];
@ -31,7 +31,7 @@ namespace ARMeilleure.Decoders.Optimizations
{ {
Block block = blocks[i]; Block block = blocks[i];
if (endBlock.EndAddress < block.Address - allowance) if (endBlock.EndAddress < block.Address - Allowance)
{ {
break; // End of contiguous function. break; // End of contiguous function.
} }
@ -44,7 +44,7 @@ namespace ARMeilleure.Decoders.Optimizations
{ {
Block block = blocks[i]; Block block = blocks[i];
if (startBlock.Address > block.EndAddress + allowance) if (startBlock.Address > block.EndAddress + Allowance)
{ {
break; // End of contiguous function. break; // End of contiguous function.
} }

View file

@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
Int32, Int32,
Int64, Int64,
Simd64, Simd64,
Simd128 Simd128,
} }
} }

View file

@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
Lsl = 0, Lsl = 0,
Lsr = 1, Lsr = 1,
Asr = 2, Asr = 2,
Ror = 3 Ror = 3,
} }
} }

View file

@ -34,7 +34,9 @@ namespace ARMeilleure.Diagnostics
for (int index = 0; index < _indentLevel; index++) for (int index = 0; index < _indentLevel; index++)
{ {
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
_builder.Append(Indentation); _builder.Append(Indentation);
#pragma warning restore CA1834
} }
} }
@ -110,10 +112,18 @@ namespace ARMeilleure.Diagnostics
switch (reg.Type) switch (reg.Type)
{ {
case RegisterType.Flag: _builder.Append('b'); break; case RegisterType.Flag:
case RegisterType.FpFlag: _builder.Append('f'); break; _builder.Append('b');
case RegisterType.Integer: _builder.Append('r'); break; break;
case RegisterType.Vector: _builder.Append('v'); break; case RegisterType.FpFlag:
_builder.Append('f');
break;
case RegisterType.Integer:
_builder.Append('r');
break;
case RegisterType.Vector:
_builder.Append('v');
break;
} }
_builder.Append(reg.Index); _builder.Append(reg.Index);
@ -145,9 +155,15 @@ namespace ARMeilleure.Diagnostics
switch (memOp.Scale) switch (memOp.Scale)
{ {
case Multiplier.x2: _builder.Append("*2"); break; case Multiplier.x2:
case Multiplier.x4: _builder.Append("*4"); break; _builder.Append("*2");
case Multiplier.x8: _builder.Append("*8"); break; break;
case Multiplier.x4:
_builder.Append("*4");
break;
case Multiplier.x8:
_builder.Append("*8");
break;
} }
} }

View file

@ -8,7 +8,7 @@ namespace ARMeilleure.Diagnostics
{ {
private static long _startTime; private static long _startTime;
private static long[] _accumulatedTime; private static readonly long[] _accumulatedTime;
static Logger() static Logger()
{ {

View file

@ -14,6 +14,6 @@ namespace ARMeilleure.Diagnostics
RegisterAllocation, RegisterAllocation,
CodeGeneration, CodeGeneration,
Count Count,
} }
} }

View file

@ -33,9 +33,8 @@ namespace ARMeilleure.Diagnostics
public static string Get(ulong address) public static string Get(ulong address)
{ {
string result;
if (_symbols.TryGetValue(address, out result)) if (_symbols.TryGetValue(address, out string result))
{ {
return result; return result;
} }

View file

@ -19,19 +19,19 @@ namespace ARMeilleure.Diagnostics
{ {
_rejitQueueCounter = new PollingCounter("rejit-queue-length", this, () => _rejitQueue) _rejitQueueCounter = new PollingCounter("rejit-queue-length", this, () => _rejitQueue)
{ {
DisplayName = "Rejit Queue Length" DisplayName = "Rejit Queue Length",
}; };
_funcTabSizeCounter = new PollingCounter("addr-tab-alloc", this, () => _funcTabSize / 1024d / 1024d) _funcTabSizeCounter = new PollingCounter("addr-tab-alloc", this, () => _funcTabSize / 1024d / 1024d)
{ {
DisplayName = "AddressTable Total Bytes Allocated", DisplayName = "AddressTable Total Bytes Allocated",
DisplayUnits = "MiB" DisplayUnits = "MiB",
}; };
_funcTabLeafSizeCounter = new PollingCounter("addr-tab-leaf-alloc", this, () => _funcTabLeafSize / 1024d / 1024d) _funcTabLeafSizeCounter = new PollingCounter("addr-tab-leaf-alloc", this, () => _funcTabLeafSize / 1024d / 1024d)
{ {
DisplayName = "AddressTable Total Leaf Bytes Allocated", DisplayName = "AddressTable Total Leaf Bytes Allocated",
DisplayUnits = "MiB" DisplayUnits = "MiB",
}; };
} }

View file

@ -8,6 +8,7 @@ namespace ARMeilleure.Instructions
static class CryptoHelper static class CryptoHelper
{ {
#region "LookUp Tables" #region "LookUp Tables"
#pragma warning disable IDE1006 // Naming rule violation
private static ReadOnlySpan<byte> _sBox => new byte[] private static ReadOnlySpan<byte> _sBox => new byte[]
{ {
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,
@ -25,7 +26,7 @@ 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 => new byte[]
@ -45,7 +46,7 @@ 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 => new byte[]
@ -65,7 +66,7 @@ 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 => new byte[]
@ -85,7 +86,7 @@ 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 => new byte[]
@ -105,7 +106,7 @@ 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 => new byte[]
@ -125,7 +126,7 @@ 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 => new byte[]
@ -145,7 +146,7 @@ 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 => new byte[]
@ -165,18 +166,19 @@ 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 => new byte[]
{ {
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 => new byte[]
{ {
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
#endregion #endregion
public static V128 AesInvMixColumns(V128 op) public static V128 AesInvMixColumns(V128 op)

View file

@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System.Diagnostics; using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitAluHelper;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;

View file

@ -2,13 +2,14 @@ using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System.Diagnostics.CodeAnalysis;
using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitAluHelper;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
[SuppressMessage("Style", "IDE0059: Remove unnecessary value assignment")]
static partial class InstEmit32 static partial class InstEmit32
{ {
public static void Add(ArmEmitterContext context) public static void Add(ArmEmitterContext context)

View file

@ -205,12 +205,16 @@ namespace ARMeilleure.Instructions
return Const(op.Immediate); return Const(op.Immediate);
} }
case IOpCode32AluImm16 op: return Const(op.Immediate); case IOpCode32AluImm16 op:
return Const(op.Immediate);
case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry); case IOpCode32AluRsImm op:
case IOpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry); return GetMShiftedByImmediate(context, op, setCarry);
case IOpCode32AluRsReg op:
return GetMShiftedByReg(context, op, setCarry);
case IOpCode32AluReg op: return GetIntA32(context, op.Rm); case IOpCode32AluReg op:
return GetIntA32(context, op.Rm);
// ARM64. // ARM64.
case IOpCodeAluImm op: case IOpCodeAluImm op:
@ -231,10 +235,18 @@ namespace ARMeilleure.Instructions
switch (op.ShiftType) switch (op.ShiftType)
{ {
case ShiftType.Lsl: value = context.ShiftLeft (value, Const(op.Shift)); break; case ShiftType.Lsl:
case ShiftType.Lsr: value = context.ShiftRightUI(value, Const(op.Shift)); break; value = context.ShiftLeft(value, Const(op.Shift));
case ShiftType.Asr: value = context.ShiftRightSI(value, Const(op.Shift)); break; break;
case ShiftType.Ror: value = context.RotateRight (value, Const(op.Shift)); break; case ShiftType.Lsr:
value = context.ShiftRightUI(value, Const(op.Shift));
break;
case ShiftType.Asr:
value = context.ShiftRightSI(value, Const(op.Shift));
break;
case ShiftType.Ror:
value = context.RotateRight(value, Const(op.Shift));
break;
} }
return value; return value;
@ -249,7 +261,8 @@ namespace ARMeilleure.Instructions
return value; return value;
} }
default: throw InvalidOpCodeType(context.CurrOp); default:
throw InvalidOpCodeType(context.CurrOp);
} }
} }
@ -269,9 +282,15 @@ namespace ARMeilleure.Instructions
{ {
switch (op.ShiftType) switch (op.ShiftType)
{ {
case ShiftType.Lsr: shift = 32; break; case ShiftType.Lsr:
case ShiftType.Asr: shift = 32; break; shift = 32;
case ShiftType.Ror: shift = 1; break; break;
case ShiftType.Asr:
shift = 32;
break;
case ShiftType.Ror:
shift = 1;
break;
} }
} }
@ -281,9 +300,15 @@ namespace ARMeilleure.Instructions
switch (op.ShiftType) switch (op.ShiftType)
{ {
case ShiftType.Lsl: m = GetLslC(context, m, setCarry, shift); break; case ShiftType.Lsl:
case ShiftType.Lsr: m = GetLsrC(context, m, setCarry, shift); break; m = GetLslC(context, m, setCarry, shift);
case ShiftType.Asr: m = GetAsrC(context, m, setCarry, shift); break; break;
case ShiftType.Lsr:
m = GetLsrC(context, m, setCarry, shift);
break;
case ShiftType.Asr:
m = GetAsrC(context, m, setCarry, shift);
break;
case ShiftType.Ror: case ShiftType.Ror:
if (op.Immediate != 0) if (op.Immediate != 0)
{ {
@ -306,9 +331,15 @@ namespace ARMeilleure.Instructions
{ {
switch (shiftType) switch (shiftType)
{ {
case ShiftType.Lsr: shift = 32; break; case ShiftType.Lsr:
case ShiftType.Asr: shift = 32; break; shift = 32;
case ShiftType.Ror: shift = 1; break; break;
case ShiftType.Asr:
shift = 32;
break;
case ShiftType.Ror:
shift = 1;
break;
} }
} }
@ -328,10 +359,18 @@ namespace ARMeilleure.Instructions
switch (op.ShiftType) switch (op.ShiftType)
{ {
case ShiftType.Lsl: shiftResult = EmitLslC(context, m, setCarry, s, shiftIsZero); break; case ShiftType.Lsl:
case ShiftType.Lsr: shiftResult = EmitLsrC(context, m, setCarry, s, shiftIsZero); break; shiftResult = EmitLslC(context, m, setCarry, s, shiftIsZero);
case ShiftType.Asr: shiftResult = EmitAsrC(context, m, setCarry, s, shiftIsZero); break; break;
case ShiftType.Ror: shiftResult = EmitRorC(context, m, setCarry, s, shiftIsZero); break; case ShiftType.Lsr:
shiftResult = EmitLsrC(context, m, setCarry, s, shiftIsZero);
break;
case ShiftType.Asr:
shiftResult = EmitAsrC(context, m, setCarry, s, shiftIsZero);
break;
case ShiftType.Ror:
shiftResult = EmitRorC(context, m, setCarry, s, shiftIsZero);
break;
} }
return context.ConditionalSelect(shiftIsZero, zeroResult, shiftResult); return context.ConditionalSelect(shiftIsZero, zeroResult, shiftResult);

View file

@ -2,7 +2,6 @@ using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitAluHelper; using static ARMeilleure.Instructions.InstEmitAluHelper;
using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;

View file

@ -1,7 +1,6 @@
using ARMeilleure.Decoders; using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -15,7 +14,7 @@ namespace ARMeilleure.Instructions
None, None,
Increment, Increment,
Invert, Invert,
Negate Negate,
} }
public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None); public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None);

View file

@ -1,7 +1,6 @@
using ARMeilleure.Decoders; using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;

View file

@ -55,7 +55,7 @@ namespace ARMeilleure.Instructions
(1, true) => nameof(SoftFallback.Crc32ch), (1, true) => nameof(SoftFallback.Crc32ch),
(2, true) => nameof(SoftFallback.Crc32cw), (2, true) => nameof(SoftFallback.Crc32cw),
(3, true) => nameof(SoftFallback.Crc32cx), (3, true) => nameof(SoftFallback.Crc32cx),
_ => throw new ArgumentOutOfRangeException(nameof(size)) _ => throw new ArgumentOutOfRangeException(nameof(size)),
}; };
return context.Call(typeof(SoftFallback).GetMethod(name), crc, value); return context.Call(typeof(SoftFallback).GetMethod(name), crc, value);
@ -71,9 +71,15 @@ namespace ARMeilleure.Instructions
switch (size) switch (size)
{ {
case 0: data = context.VectorInsert8(context.VectorZero(), data, 0); break; case 0:
case 1: data = context.VectorInsert16(context.VectorZero(), data, 0); break; data = context.VectorInsert8(context.VectorZero(), data, 0);
case 2: data = context.VectorInsert(context.VectorZero(), data, 0); break; break;
case 1:
data = context.VectorInsert16(context.VectorZero(), data, 0);
break;
case 2:
data = context.VectorInsert(context.VectorZero(), data, 0);
break;
} }
int bitsize = 8 << size; int bitsize = 8 << size;

View file

@ -16,13 +16,25 @@ namespace ARMeilleure.Instructions
switch (type) switch (type)
{ {
case IntType.UInt8: value = context.ZeroExtend8 (value.Type, value); break; case IntType.UInt8:
case IntType.UInt16: value = context.ZeroExtend16(value.Type, value); break; value = context.ZeroExtend8(value.Type, value);
case IntType.UInt32: value = context.ZeroExtend32(value.Type, value); break; break;
case IntType.UInt16:
value = context.ZeroExtend16(value.Type, value);
break;
case IntType.UInt32:
value = context.ZeroExtend32(value.Type, value);
break;
case IntType.Int8: value = context.SignExtend8 (value.Type, value); break; case IntType.Int8:
case IntType.Int16: value = context.SignExtend16(value.Type, value); break; value = context.SignExtend8(value.Type, value);
case IntType.Int32: value = context.SignExtend32(value.Type, value); break; break;
case IntType.Int16:
value = context.SignExtend16(value.Type, value);
break;
case IntType.Int32:
value = context.SignExtend32(value.Type, value);
break;
} }
return value; return value;
@ -100,78 +112,51 @@ namespace ARMeilleure.Instructions
public static int GetBankedRegisterAlias(Aarch32Mode mode, int regIndex) public static int GetBankedRegisterAlias(Aarch32Mode mode, int regIndex)
{ {
switch (regIndex) return regIndex switch
{ {
case 8: return mode == Aarch32Mode.Fiq #pragma warning disable IDE0055 // Disable formatting
? RegisterAlias.R8Fiq 8 => mode == Aarch32Mode.Fiq ? RegisterAlias.R8Fiq : RegisterAlias.R8Usr,
: RegisterAlias.R8Usr; 9 => mode == Aarch32Mode.Fiq ? RegisterAlias.R9Fiq : RegisterAlias.R9Usr,
10 => mode == Aarch32Mode.Fiq ? RegisterAlias.R10Fiq : RegisterAlias.R10Usr,
case 9: return mode == Aarch32Mode.Fiq 11 => mode == Aarch32Mode.Fiq ? RegisterAlias.R11Fiq : RegisterAlias.R11Usr,
? RegisterAlias.R9Fiq 12 => mode == Aarch32Mode.Fiq ? RegisterAlias.R12Fiq : RegisterAlias.R12Usr,
: RegisterAlias.R9Usr; 13 => mode switch
case 10: return mode == Aarch32Mode.Fiq
? RegisterAlias.R10Fiq
: RegisterAlias.R10Usr;
case 11: return mode == Aarch32Mode.Fiq
? RegisterAlias.R11Fiq
: RegisterAlias.R11Usr;
case 12: return mode == Aarch32Mode.Fiq
? RegisterAlias.R12Fiq
: RegisterAlias.R12Usr;
case 13:
switch (mode)
{ {
case Aarch32Mode.User: Aarch32Mode.User or Aarch32Mode.System => RegisterAlias.SpUsr,
case Aarch32Mode.System: return RegisterAlias.SpUsr; Aarch32Mode.Fiq => RegisterAlias.SpFiq,
case Aarch32Mode.Fiq: return RegisterAlias.SpFiq; Aarch32Mode.Irq => RegisterAlias.SpIrq,
case Aarch32Mode.Irq: return RegisterAlias.SpIrq; Aarch32Mode.Supervisor => RegisterAlias.SpSvc,
case Aarch32Mode.Supervisor: return RegisterAlias.SpSvc; Aarch32Mode.Abort => RegisterAlias.SpAbt,
case Aarch32Mode.Abort: return RegisterAlias.SpAbt; Aarch32Mode.Hypervisor => RegisterAlias.SpHyp,
case Aarch32Mode.Hypervisor: return RegisterAlias.SpHyp; Aarch32Mode.Undefined => RegisterAlias.SpUnd,
case Aarch32Mode.Undefined: return RegisterAlias.SpUnd; _ => throw new ArgumentException($"No such AArch32Mode: {mode}", nameof(mode)),
},
default: throw new ArgumentException(nameof(mode)); 14 => mode switch
}
case 14:
switch (mode)
{ {
case Aarch32Mode.User: Aarch32Mode.User or Aarch32Mode.Hypervisor or Aarch32Mode.System => RegisterAlias.LrUsr,
case Aarch32Mode.Hypervisor: Aarch32Mode.Fiq => RegisterAlias.LrFiq,
case Aarch32Mode.System: return RegisterAlias.LrUsr; Aarch32Mode.Irq => RegisterAlias.LrIrq,
case Aarch32Mode.Fiq: return RegisterAlias.LrFiq; Aarch32Mode.Supervisor => RegisterAlias.LrSvc,
case Aarch32Mode.Irq: return RegisterAlias.LrIrq; Aarch32Mode.Abort => RegisterAlias.LrAbt,
case Aarch32Mode.Supervisor: return RegisterAlias.LrSvc; Aarch32Mode.Undefined => RegisterAlias.LrUnd,
case Aarch32Mode.Abort: return RegisterAlias.LrAbt; _ => throw new ArgumentException($"No such AArch32Mode: {mode}", nameof(mode)),
case Aarch32Mode.Undefined: return RegisterAlias.LrUnd; },
_ => throw new ArgumentOutOfRangeException(nameof(regIndex), regIndex, null),
default: throw new ArgumentException(nameof(mode)); #pragma warning restore IDE0055
} };
default: throw new ArgumentOutOfRangeException(nameof(regIndex));
}
} }
public static bool IsA32Return(ArmEmitterContext context) public static bool IsA32Return(ArmEmitterContext context)
{ {
switch (context.CurrOp) return context.CurrOp switch
{ {
case IOpCode32MemMult op: IOpCode32MemMult => true, // Setting PC using LDM is nearly always a return.
return true; // Setting PC using LDM is nearly always a return. OpCode32AluRsImm op => op.Rm == RegisterAlias.Aarch32Lr,
case OpCode32AluRsImm op: OpCode32AluRsReg op => op.Rm == RegisterAlias.Aarch32Lr,
return op.Rm == RegisterAlias.Aarch32Lr; OpCode32AluReg op => op.Rm == RegisterAlias.Aarch32Lr,
case OpCode32AluRsReg op: OpCode32Mem op => op.Rn == RegisterAlias.Aarch32Sp && op.WBack && !op.Index, // Setting PC to an address stored on the stack is nearly always a return.
return op.Rm == RegisterAlias.Aarch32Lr; _ => false,
case OpCode32AluReg op: };
return op.Rm == RegisterAlias.Aarch32Lr;
case OpCode32Mem op:
return op.Rn == RegisterAlias.Aarch32Sp && op.WBack && !op.Index; // Setting PC to an address stored on the stack is nearly always a return.
}
return false;
} }
public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0) public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0)

View file

@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitMemoryHelper; using static ARMeilleure.Instructions.InstEmitMemoryHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;

View file

@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitMemoryExHelper; using static ARMeilleure.Instructions.InstEmitMemoryExHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -18,7 +17,7 @@ namespace ARMeilleure.Instructions
None = 0, None = 0,
Ordered = 1, Ordered = 1,
Exclusive = 2, Exclusive = 2,
OrderedEx = Ordered | Exclusive OrderedEx = Ordered | Exclusive,
} }
public static void Clrex(ArmEmitterContext context) public static void Clrex(ArmEmitterContext context)

View file

@ -1,7 +1,6 @@
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -118,14 +117,14 @@ namespace ARMeilleure.Instructions
1 => context.Load16(exValuePtr), 1 => context.Load16(exValuePtr),
2 => context.Load(OperandType.I32, exValuePtr), 2 => context.Load(OperandType.I32, exValuePtr),
3 => context.Load(OperandType.I64, exValuePtr), 3 => context.Load(OperandType.I64, exValuePtr),
_ => context.Load(OperandType.V128, exValuePtr) _ => context.Load(OperandType.V128, exValuePtr),
}; };
Operand currValue = size switch Operand currValue = size switch
{ {
0 => context.CompareAndSwap8(physAddr, exValue, value), 0 => context.CompareAndSwap8(physAddr, exValue, value),
1 => context.CompareAndSwap16(physAddr, exValue, value), 1 => context.CompareAndSwap16(physAddr, exValue, value),
_ => context.CompareAndSwap(physAddr, exValue, value) _ => context.CompareAndSwap(physAddr, exValue, value),
}; };
// STEP 3: Check if we succeeded by comparing expected and in-memory values. // STEP 3: Check if we succeeded by comparing expected and in-memory values.

Some files were not shown because too many files have changed in this diff Show more