Merge branch 'master' of https://github.com/Ryujinx/Ryujinx into mmdurrant/texture-tests
This commit is contained in:
commit
4ce3f5b29d
2876 changed files with 34266 additions and 34342 deletions
|
@ -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
33
.github/labeler.yml
vendored
Normal 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
32
.github/reviewers.yml
vendored
Normal 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
79
.github/update_reviewers.py
vendored
Normal 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))
|
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
|
@ -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
71
.github/workflows/checks.yml
vendored
Normal 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
|
4
.github/workflows/nightly_pr_comment.yml
vendored
4
.github/workflows/nightly_pr_comment.yml
vendored
|
@ -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
34
.github/workflows/pr_triage.yml
vendored
Normal 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
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Sxtb = 4,
|
Sxtb = 4,
|
||||||
Sxth = 5,
|
Sxth = 5,
|
||||||
Sxtw = 6,
|
Sxtw = 6,
|
||||||
Sxtx = 7
|
Sxtx = 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||||
Lsl = 0,
|
Lsl = 0,
|
||||||
Lsr = 1,
|
Lsr = 1,
|
||||||
Asr = 2,
|
Asr = 2,
|
||||||
Ror = 3
|
Ror = 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 ||
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 + "\".");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)];
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ namespace ARMeilleure.CodeGen.Unwinding
|
||||||
SetFrame = 1,
|
SetFrame = 1,
|
||||||
AllocStack = 2,
|
AllocStack = 2,
|
||||||
SaveReg = 3,
|
SaveReg = 3,
|
||||||
SaveXmm128 = 4
|
SaveXmm128 = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,6 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
enum CallConvName
|
enum CallConvName
|
||||||
{
|
{
|
||||||
SystemV,
|
SystemV,
|
||||||
Windows
|
Windows,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -13,6 +13,6 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Crc32,
|
Crc32,
|
||||||
Ternary,
|
Ternary,
|
||||||
TernaryImm,
|
TernaryImm,
|
||||||
Fma
|
Fma,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,6 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
Xorpd,
|
Xorpd,
|
||||||
Xorps,
|
Xorps,
|
||||||
|
|
||||||
Count
|
Count,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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--)
|
||||||
|
|
|
@ -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() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
|
||||||
Adr = 0,
|
Adr = 0,
|
||||||
Arithmetic = 1,
|
Arithmetic = 1,
|
||||||
Logical = 2,
|
Logical = 2,
|
||||||
BitField = 3
|
BitField = 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -9,6 +9,6 @@ namespace ARMeilleure.Decoders
|
||||||
Int8 = 4,
|
Int8 = 4,
|
||||||
Int16 = 5,
|
Int16 = 5,
|
||||||
Int32 = 6,
|
Int32 = 6,
|
||||||
Int64 = 7
|
Int64 = 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
23
src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs
Normal file
23
src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OpCode32SimdSelMode : int
|
enum OpCode32SimdSelMode
|
||||||
{
|
{
|
||||||
Eq = 0,
|
Eq = 0,
|
||||||
Vs,
|
Vs,
|
||||||
Ge,
|
Ge,
|
||||||
Gt
|
Gt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace ARMeilleure.Decoders
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new ArgumentException(nameof(opCode));
|
throw new ArgumentException($"Invalid data operation: {DataOp}", nameof(opCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -24,7 +24,9 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: Instruction = InstDescriptor.Undefined; break;
|
default:
|
||||||
|
Instruction = InstDescriptor.Undefined;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: Instruction = InstDescriptor.Undefined; break;
|
default:
|
||||||
|
Instruction = InstDescriptor.Undefined;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
|
||||||
Int32,
|
Int32,
|
||||||
Int64,
|
Int64,
|
||||||
Simd64,
|
Simd64,
|
||||||
Simd128
|
Simd128,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
|
||||||
Lsl = 0,
|
Lsl = 0,
|
||||||
Lsr = 1,
|
Lsr = 1,
|
||||||
Asr = 2,
|
Asr = 2,
|
||||||
Ror = 3
|
Ror = 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace ARMeilleure.Diagnostics
|
||||||
RegisterAllocation,
|
RegisterAllocation,
|
||||||
CodeGeneration,
|
CodeGeneration,
|
||||||
|
|
||||||
Count
|
Count,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue