Compare commits
137 Commits
Author | SHA1 | Date | |
---|---|---|---|
01c2b8097c | |||
4bd2ca3f0d | |||
e63157cc33 | |||
7f2fb049f5 | |||
4744bde0e5 | |||
4a835bb2b9 | |||
ddc9ae2a83 | |||
d6d3cdd573 | |||
53bd4c9f60 | |||
eca8808649 | |||
f6c3f1cdfd | |||
8026e1c804 | |||
d9f9bbfaa6 | |||
fe9e19d8cc | |||
fb55f57da7 | |||
44862dce3e | |||
e601419bd4 | |||
d6bc0de785 | |||
9f26fd3600 | |||
88df636c87 | |||
7ccff037e8 | |||
a745913329 | |||
e6700b314f | |||
e2cfe6fe44 | |||
210f475484 | |||
ddb6493896 | |||
f631933e60 | |||
5ff6ea6d82 | |||
c2d9c6955d | |||
fbe0c211c1 | |||
db0f3c0b74 | |||
34447d7359 | |||
5f771f5661 | |||
93cd327873 | |||
12cbacffca | |||
437c78e198 | |||
f09bba82b9 | |||
93d78f9ac4 | |||
cd7b52f995 | |||
7f96dbc024 | |||
3e5c211394 | |||
153b8bfc7c | |||
c6a699414a | |||
2563f88de0 | |||
b0b7843d5c | |||
6ed613a6e6 | |||
64079c034c | |||
17354d59d1 | |||
0c445184c1 | |||
511b558ddc | |||
9b8625d999 | |||
b12ea343d0 | |||
abaa35ad3a | |||
effd546331 | |||
492a046335 | |||
550fd4a733 | |||
33f544fd92 | |||
b423197619 | |||
8edfb2bc7b | |||
ddefb4fff4 | |||
2efd74b9cb | |||
8c61ddd49d | |||
7b2225c6b0 | |||
fe15c77d30 | |||
5e9678c8fa | |||
773e239db7 | |||
42750a74f8 | |||
3ab0a71c7b | |||
6e784e0aca | |||
5a0aa074b6 | |||
93aa40f1fb | |||
bedee64af5 | |||
86931cc3f1 | |||
2be8b6ea45 | |||
f95b7c5877 | |||
eb528ae0f0 | |||
487261592e | |||
9e04e6cba1 | |||
4cf2419e6c | |||
440abac9f8 | |||
732714349e | |||
016262514d | |||
326749498b | |||
fec8291c17 | |||
c5d9e67cb2 | |||
e5261228d7 | |||
e61c09bc85 | |||
ac2444f908 | |||
9c6071a645 | |||
fa32ef9275 | |||
7805d27e67 | |||
6c515e1822 | |||
8a363b5df2 | |||
2b5abac809 | |||
c19c8bbade | |||
1c7a90ef35 | |||
3b46bb73f7 | |||
2457cfc911 | |||
515fc32b21 | |||
0684b00b3c | |||
02b5c7ea89 | |||
801b71a128 | |||
12c5f6ee89 | |||
79a1314ee4 | |||
e9848339dd | |||
6e28a4dd13 | |||
7c989f88bd | |||
16fa983704 | |||
40daca5684 | |||
981e0c082d | |||
cebfa54467 | |||
fc20d9b925 | |||
0a75b73fa4 | |||
46b7c905f5 | |||
40f2bd37e3 | |||
9288ffd26d | |||
2cdc82cb91 | |||
6aa8d71588 | |||
9becbd7d72 | |||
e055217292 | |||
fbaf62c230 | |||
b186ec9fc5 | |||
0191e2396a | |||
e96299eef5 | |||
ff53dcf560 | |||
2de78a2d55 | |||
b29ded1d60 | |||
9860bfb2cd | |||
f6ada8d169 | |||
42d31f646d | |||
07fc3ded68 | |||
fd01259d2b | |||
7ffe7f8442 | |||
2b2ce68f07 | |||
bc53d00463 | |||
bddb2a1483 | |||
e3bacfa774 |
@ -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,18 @@ 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
|
||||||
|
|
||||||
|
# JSON files
|
||||||
|
[*.json]
|
||||||
|
|
||||||
|
# Indentation and spacing
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
|
||||||
|
# C# files
|
||||||
|
[*.cs]
|
||||||
|
|
||||||
#### .NET Coding Conventions ####
|
#### .NET Coding Conventions ####
|
||||||
|
|
||||||
@ -59,7 +68,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 +94,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 +103,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 +119,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 +151,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 +168,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 +208,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
|
||||||
|
8
.github/assign/audio.yml
vendored
8
.github/assign/audio.yml
vendored
@ -1,8 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- audio
|
|
11
.github/assign/cpu.yml
vendored
11
.github/assign/cpu.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- riperiperi
|
|
||||||
- marysaka
|
|
||||||
- LDj3SNuD
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- cpu
|
|
4
.github/assign/global.yml
vendored
4
.github/assign/global.yml
vendored
@ -1,4 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- Ryujinx/developers
|
|
10
.github/assign/gpu.yml
vendored
10
.github/assign/gpu.yml
vendored
@ -1,10 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- riperiperi
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- gpu
|
|
11
.github/assign/gui.yml
vendored
11
.github/assign/gui.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- Ack77
|
|
||||||
- emmauss
|
|
||||||
- TSRBerry
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- gui
|
|
11
.github/assign/horizon.yml
vendored
11
.github/assign/horizon.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- Ack77
|
|
||||||
- marysaka
|
|
||||||
- TSRBerry
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- horizon
|
|
9
.github/assign/infra.yml
vendored
9
.github/assign/infra.yml
vendored
@ -1,9 +0,0 @@
|
|||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- marysaka
|
|
||||||
- TSRBerry
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- infra
|
|
18
.github/csc.json
vendored
Normal file
18
.github/csc.json
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"problemMatcher": [
|
||||||
|
{
|
||||||
|
"owner": "csc",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "^((?:\\\\|/)(?:[^\\\\/:]+(?:\\\\|/))+[^\\\\/]+)\\((\\d+),(\\d+)\\):\\s+([a-zA-Z]+)\\s+([^:]+):\\s+([^[]+)\\s+\\[",
|
||||||
|
"file": 1,
|
||||||
|
"line": 2,
|
||||||
|
"column": 3,
|
||||||
|
"severity": 4,
|
||||||
|
"code": 5,
|
||||||
|
"message": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
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:
|
||||||
|
- '@developers'
|
43
.github/workflows/build.yml
vendored
43
.github/workflows/build.yml
vendored
@ -1,20 +1,7 @@
|
|||||||
name: Build job
|
name: Build job
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_call:
|
||||||
inputs: {}
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
paths-ignore:
|
|
||||||
- '.github/**'
|
|
||||||
- '*.yml'
|
|
||||||
- '*.json'
|
|
||||||
- '*.config'
|
|
||||||
- 'README.md'
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: pr-checks-${{ github.event.number }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
@ -48,12 +35,15 @@ jobs:
|
|||||||
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Overwrite csc problem matcher
|
||||||
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
- name: Get git short hash
|
- name: Get git short hash
|
||||||
id: git_short_hash
|
id: git_short_hash
|
||||||
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
@ -63,7 +53,11 @@ jobs:
|
|||||||
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test --no-build -c "${{ matrix.configuration }}"
|
uses: TSRBerry/unstable-commands@v1
|
||||||
|
with:
|
||||||
|
commands: dotnet test --no-build -c "${{ matrix.configuration }}"
|
||||||
|
timeout-minutes: 10
|
||||||
|
retry-codes: 139
|
||||||
|
|
||||||
- name: Publish Ryujinx
|
- name: Publish Ryujinx
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
||||||
@ -114,7 +108,7 @@ jobs:
|
|||||||
configuration: [ Debug, Release ]
|
configuration: [ Debug, Release ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
@ -141,9 +135,13 @@ jobs:
|
|||||||
id: git_short_hash
|
id: git_short_hash
|
||||||
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Publish macOS
|
- name: Publish macOS Ryujinx.Ava
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
|
- name: Publish macOS Ryujinx.Headless.SDL2
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
- name: Upload Ryujinx.Ava artifact
|
- name: Upload Ryujinx.Ava artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@ -151,3 +149,10 @@ jobs:
|
|||||||
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
path: "publish_ava/*.tar.gz"
|
path: "publish_ava/*.tar.gz"
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
|
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
|
path: "publish_headless/*.tar.gz"
|
||||||
|
if: github.event_name == 'pull_request'
|
74
.github/workflows/checks.yml
vendored
Normal file
74
.github/workflows/checks.yml
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
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@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Overwrite csc problem matcher
|
||||||
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
|
- run: dotnet restore
|
||||||
|
|
||||||
|
- name: Print dotnet format version
|
||||||
|
run: dotnet format --version
|
||||||
|
|
||||||
|
- name: Run dotnet format whitespace
|
||||||
|
run: |
|
||||||
|
dotnet format whitespace --verify-no-changes --report ./whitespace-report.json -v d
|
||||||
|
|
||||||
|
# For some unknown reason this step sometimes fails with exit code 139 (segfault?),
|
||||||
|
# so in that case we'll try again (3 tries max).
|
||||||
|
- name: Run dotnet format style
|
||||||
|
uses: TSRBerry/unstable-commands@v1
|
||||||
|
with:
|
||||||
|
commands: dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d
|
||||||
|
timeout-minutes: 5
|
||||||
|
retry-codes: 139
|
||||||
|
|
||||||
|
# For some unknown reason this step sometimes fails with exit code 139 (segfault?),
|
||||||
|
# so in that case we'll try again (3 tries max).
|
||||||
|
- name: Run dotnet format analyzers
|
||||||
|
uses: TSRBerry/unstable-commands@v1
|
||||||
|
with:
|
||||||
|
commands: dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d
|
||||||
|
timeout-minutes: 5
|
||||||
|
retry-codes: 139
|
||||||
|
|
||||||
|
- name: Upload report
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dotnet-format
|
||||||
|
path: ./*-report.json
|
||||||
|
|
||||||
|
pr_build:
|
||||||
|
uses: ./.github/workflows/build.yml
|
||||||
|
needs: format
|
||||||
|
secrets: inherit
|
4
.github/workflows/flatpak.yml
vendored
4
.github/workflows/flatpak.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
|
RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: Ryujinx
|
path: Ryujinx
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: flathub/org.ryujinx.Ryujinx
|
repository: flathub/org.ryujinx.Ryujinx
|
||||||
token: ${{ secrets.RYUJINX_BOT_PAT }}
|
token: ${{ secrets.RYUJINX_BOT_PAT }}
|
||||||
|
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'
|
||||||
|
61
.github/workflows/pr_triage.yml
vendored
61
.github/workflows/pr_triage.yml
vendored
@ -12,43 +12,36 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
# Grab sources to get latest labeler.yml
|
||||||
|
- name: Fetch sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# Ensure we pin the source origin as pull_request_target run under forks.
|
||||||
|
fetch-depth: 0
|
||||||
|
repository: Ryujinx/Ryujinx
|
||||||
|
ref: master
|
||||||
|
|
||||||
|
- name: Checkout Ryujinx-Mako
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: Ryujinx/Ryujinx-Mako
|
||||||
|
ref: master
|
||||||
|
path: '.ryujinx-mako'
|
||||||
|
|
||||||
|
- name: Setup Ryujinx-Mako
|
||||||
|
uses: ./.ryujinx-mako/.github/actions/setup-mako
|
||||||
|
|
||||||
- name: Update labels based on changes
|
- name: Update labels based on changes
|
||||||
uses: actions/labeler@v4
|
uses: actions/labeler@v4
|
||||||
with:
|
with:
|
||||||
sync-labels: true
|
sync-labels: true
|
||||||
dot: true
|
dot: true
|
||||||
|
|
||||||
- name: Auto Assign [Audio]
|
- name: Assign reviewers
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
run: |
|
||||||
with:
|
poetry -n -C .ryujinx-mako run ryujinx-mako update-reviewers ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
|
||||||
configuration-path: '.github/assign/audio.yml'
|
shell: bash
|
||||||
|
env:
|
||||||
- name: Auto Assign [CPU]
|
MAKO_APP_ID: ${{ secrets.MAKO_APP_ID }}
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
MAKO_PRIVATE_KEY: ${{ secrets.MAKO_PRIVATE_KEY }}
|
||||||
with:
|
MAKO_INSTALLATION_ID: ${{ secrets.MAKO_INSTALLATION_ID }}
|
||||||
configuration-path: '.github/assign/cpu.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [GPU]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/gpu.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [GUI]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/gui.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Horizon]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/horizon.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Infra]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/infra.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Global]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/global.yml'
|
|
||||||
|
17
.github/workflows/release.yml
vendored
17
.github/workflows/release.yml
vendored
@ -62,12 +62,15 @@ jobs:
|
|||||||
DOTNET_RUNTIME_IDENTIFIER: win10-x64
|
DOTNET_RUNTIME_IDENTIFIER: win10-x64
|
||||||
RELEASE_ZIP_OS_NAME: win_x64
|
RELEASE_ZIP_OS_NAME: win_x64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Overwrite csc problem matcher
|
||||||
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
@ -147,7 +150,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
@ -185,15 +188,19 @@ jobs:
|
|||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Publish macOS
|
- name: Publish macOS Ryujinx.Ava
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
||||||
|
|
||||||
|
- name: Publish macOS Ryujinx.Headless.SDL2
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "publish_ava/*.tar.gz"
|
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
|
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
|
147
CONTRIBUTING.md
Normal file
147
CONTRIBUTING.md
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
# Contribution to Ryujinx
|
||||||
|
|
||||||
|
You can contribute to Ryujinx with PRs, testing of PRs and issues. Contributing code and other implementations is greatly appreciated alongside simply filing issues for problems you encounter.
|
||||||
|
Please read the entire document before continuing as it can potentially save everyone involved a significant amount of time.
|
||||||
|
|
||||||
|
# Quick Links
|
||||||
|
|
||||||
|
* [Code Style Documentation](docs/coding-guidelines/coding-style.md)
|
||||||
|
* [Pull Request Guidelines](docs/workflow/pr-guide.md)
|
||||||
|
|
||||||
|
## Reporting Issues
|
||||||
|
|
||||||
|
We always welcome bug reports, feature proposals and overall feedback. Here are a few tips on how you can make reporting your issue as effective as possible.
|
||||||
|
|
||||||
|
### Identify Where to Report
|
||||||
|
|
||||||
|
The Ryujinx codebase is distributed across multiple repositories in the [Ryujinx organization](https://github.com/Ryujinx). Depending on the feedback you might want to file the issue on a different repo. Here are a few common repos:
|
||||||
|
|
||||||
|
* [Ryujinx/Ryujinx](https://github.com/Ryujinx/Ryujinx) Ryujinx core project files.
|
||||||
|
* [Ryujinx/Ryujinx-Games-List](https://github.com/Ryujinx/Ryujinx-Games-List) Ryujinx game compatibility list.
|
||||||
|
* [Ryujinx/Ryujinx-Website](https://github.com/Ryujinx/Ryujinx-Website) Ryujinx website source code.
|
||||||
|
* [Ryujinx/Ryujinx-Ldn-Website](https://github.com/Ryujinx/Ryujinx-Ldn-Website) Ryujinx LDN website source code.
|
||||||
|
|
||||||
|
### Finding Existing Issues
|
||||||
|
|
||||||
|
Before filing a new issue, please search our [open issues](https://github.com/Ryujinx/Ryujinx/issues) to check if it already exists.
|
||||||
|
|
||||||
|
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
|
||||||
|
|
||||||
|
### Writing a Good Feature Request
|
||||||
|
|
||||||
|
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
|
||||||
|
|
||||||
|
### Writing a Good Bug Report
|
||||||
|
|
||||||
|
Good bug reports make it easier for maintainers to verify and root cause the underlying problem. The better a bug report, the faster the problem will be resolved.
|
||||||
|
Ideally, a bug report should contain the following information:
|
||||||
|
|
||||||
|
* A high-level description of the problem.
|
||||||
|
* A _minimal reproduction_, i.e. the smallest time commitment/configuration required to reproduce the wrong behavior. This can be in the form of a small homebrew application, or by providing a save file and reproduction steps for a specific game.
|
||||||
|
* A description of the _expected behavior_, contrasted with the _actual behavior_ observed.
|
||||||
|
* Information on the environment: OS/distro, CPU, GPU (including driver), RAM etc.
|
||||||
|
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
|
||||||
|
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
|
||||||
|
|
||||||
|
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryujinx/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
|
||||||
|
|
||||||
|
## Contributing Changes
|
||||||
|
|
||||||
|
Project maintainers will merge changes that both improve the project and meet our standards for code quality.
|
||||||
|
|
||||||
|
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryujinx/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
|
||||||
|
|
||||||
|
### DOs and DON'Ts
|
||||||
|
|
||||||
|
Please do:
|
||||||
|
|
||||||
|
* **DO** follow our [coding style](docs/coding-guidelines/coding-style.md) (C# code-specific).
|
||||||
|
* **DO** give priority to the current style of the project or file you're changing even if it diverges from the general guidelines.
|
||||||
|
* **DO** keep the discussions focused. When a new or related topic comes up
|
||||||
|
it's often better to create new issue than to side track the discussion.
|
||||||
|
* **DO** clearly state on an issue that you are going to take on implementing it.
|
||||||
|
* **DO** blog and tweet (or whatever) about your contributions, frequently!
|
||||||
|
|
||||||
|
Please do not:
|
||||||
|
|
||||||
|
* **DON'T** make PRs for style changes.
|
||||||
|
* **DON'T** surprise us with big pull requests. Instead, file an issue and talk with us on Discord to start
|
||||||
|
a discussion so we can agree on a direction before you invest a large amount
|
||||||
|
of time.
|
||||||
|
* **DON'T** commit code that you didn't write. If you find code that you think is a good fit to add to Ryujinx, file an issue or talk to us on Discord to start a discussion before proceeding.
|
||||||
|
* **DON'T** submit PRs that alter licensing related files or headers. If you believe there's a problem with them, file an issue and we'll be happy to discuss it.
|
||||||
|
|
||||||
|
### Suggested Workflow
|
||||||
|
|
||||||
|
We use and recommend the following workflow:
|
||||||
|
|
||||||
|
1. Create or find an issue for your work.
|
||||||
|
- You can skip this step for trivial changes.
|
||||||
|
- Get agreement from the team and the community that your proposed change is a good one if it is of significant size or changes core functionality.
|
||||||
|
- Clearly state that you are going to take on implementing it, if that's the case. You can request that the issue be assigned to you. Note: The issue filer and the implementer don't have to be the same person.
|
||||||
|
2. Create a personal fork of the repository on GitHub (if you don't already have one).
|
||||||
|
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
|
||||||
|
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
|
||||||
|
4. Make and commit your changes to your branch.
|
||||||
|
- [Build Instructions](https://github.com/Ryujinx/Ryujinx#building) explains how to build and test.
|
||||||
|
- Commit messages should be clear statements of action and intent.
|
||||||
|
6. Build the repository with your changes.
|
||||||
|
- Make sure that the builds are clean.
|
||||||
|
- Make sure that `dotnet format` has been run and any corrections tested and committed.
|
||||||
|
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
|
||||||
|
- State in the description what issue or improvement your change is addressing.
|
||||||
|
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryujinx/Ryujinx/actions) to check for outstanding errors.
|
||||||
|
8. Wait for feedback or approval of your changes from the [core development team](https://github.com/orgs/Ryujinx/teams/developers)
|
||||||
|
- Details about the pull request [review procedure](docs/workflow/ci/pr-guide.md).
|
||||||
|
9. When the team members have signed off, and all checks are green, your PR will be merged.
|
||||||
|
- The next official build will automatically include your change.
|
||||||
|
- You can delete the branch you used for making the change.
|
||||||
|
|
||||||
|
### Good First Issues
|
||||||
|
|
||||||
|
The team marks the most straightforward issues as [good first issues](https://github.com/Ryujinx/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
|
||||||
|
|
||||||
|
### Commit Messages
|
||||||
|
|
||||||
|
Please format commit messages as follows (based on [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)):
|
||||||
|
|
||||||
|
```
|
||||||
|
Summarize change in 50 characters or less
|
||||||
|
|
||||||
|
Provide more detail after the first line. Leave one blank line below the
|
||||||
|
summary and wrap all lines at 72 characters or less.
|
||||||
|
|
||||||
|
If the change fixes an issue, leave another blank line after the final
|
||||||
|
paragraph and indicate which issue is fixed in the specific format
|
||||||
|
below.
|
||||||
|
|
||||||
|
Fix #42
|
||||||
|
```
|
||||||
|
|
||||||
|
Also do your best to factor commits appropriately, not too large with unrelated things in the same commit, and not too small with the same small change applied N times in N different commits.
|
||||||
|
|
||||||
|
### PR - CI Process
|
||||||
|
|
||||||
|
The [Ryujinx continuous integration](https://github.com/Ryujinx/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
|
||||||
|
|
||||||
|
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
|
||||||
|
* `dotnet format` has not been run on the PR and has outstanding stylistic issues.
|
||||||
|
* There is an error within the PR that fails a test or errors the compiler.
|
||||||
|
* Random failure of the workflow can occasionally result in a CI failure. In this scenario a maintainer will manually restart the job.
|
||||||
|
|
||||||
|
### PR Feedback
|
||||||
|
|
||||||
|
Ryujinx team and community members will provide feedback on your change. Community feedback is highly valued. You may see the absence of team feedback if the community has already provided good review feedback.
|
||||||
|
|
||||||
|
Two Ryujinx team members must review and approve every PR prior to merge. They will often reply with "LGTM, see nit". That means that the PR will be merged once the feedback is resolved. "LGTM" == "looks good to me".
|
||||||
|
|
||||||
|
There are lots of thoughts and [approaches](https://github.com/antlr/antlr4-cpp/blob/master/CONTRIBUTING.md#emoji) for how to efficiently discuss changes. It is best to be clear and explicit with your feedback. Please be patient with people who might not understand the finer details about your approach to feedback.
|
||||||
|
|
||||||
|
#### Copying Changes from Other Projects
|
||||||
|
|
||||||
|
Ryujinx uses some implementations and frameworks from other projects. The following rules must be followed for PRs that include changes from another project:
|
||||||
|
|
||||||
|
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
|
||||||
|
- The license of the file is left in-tact.
|
||||||
|
- The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryujinx/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.
|
||||||
|
|
@ -3,25 +3,25 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="0.10.21" />
|
<PackageVersion Include="Avalonia" Version="11.0.3" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.21" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.3" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="0.10.21" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.0.3" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.21" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.3" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.21" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.3" />
|
||||||
<PackageVersion Include="Avalonia.Svg" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Svg" Version="11.0.0" />
|
||||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0" />
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="Concentus" Version="1.1.7" />
|
<PackageVersion Include="Concentus" Version="1.1.7" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||||
<PackageVersion Include="DynamicData" Version="7.14.2" />
|
<PackageVersion Include="DynamicData" Version="7.14.2" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.1" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
||||||
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
|
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" />
|
||||||
<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.2" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||||
<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,10 +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.31.0" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.0.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.2" />
|
<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" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -39,10 +39,120 @@
|
|||||||
<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>UTExportedTypeDeclarations</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Extensible Application Markup Language</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.xml</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.xaml</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>xaml</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Submission Package</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.nsp</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>nsp</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Switch Cartridge</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.xci</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>xci</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Content Archive</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.nca</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>nca</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Relocatable Object</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.nro</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>nro</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Shared Object</string>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.ryujinx.nso</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>nso</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>LSEnvironment</key>
|
||||||
|
<dict>
|
||||||
|
<key>DOTNET_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"
|
111
distribution/macos/create_macos_build_headless.sh
Executable file
111
distribution/macos/create_macos_build_headless.sh
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$#" -lt 7 ]; then
|
||||||
|
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <EXTRA_ARGS>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$1"
|
||||||
|
mkdir -p "$2"
|
||||||
|
mkdir -p "$3"
|
||||||
|
|
||||||
|
BASE_DIR=$(readlink -f "$1")
|
||||||
|
TEMP_DIRECTORY=$(readlink -f "$2")
|
||||||
|
OUTPUT_DIRECTORY=$(readlink -f "$3")
|
||||||
|
ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
|
||||||
|
VERSION=$5
|
||||||
|
SOURCE_REVISION_ID=$6
|
||||||
|
CONFIGURATION=$7
|
||||||
|
EXTRA_ARGS=$8
|
||||||
|
|
||||||
|
if [ "$VERSION" == "1.1.0" ];
|
||||||
|
then
|
||||||
|
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
|
||||||
|
else
|
||||||
|
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar
|
||||||
|
fi
|
||||||
|
|
||||||
|
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
||||||
|
X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
|
||||||
|
UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
|
||||||
|
EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2
|
||||||
|
|
||||||
|
rm -rf "$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 restore
|
||||||
|
dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2
|
||||||
|
dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
||||||
|
dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
||||||
|
|
||||||
|
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
|
||||||
|
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
|
||||||
|
|
||||||
|
# Get rid of libsoundio from arm64 builds as we don't have a arm64 variant
|
||||||
|
# TODO: remove this once done
|
||||||
|
rm -rf "$TEMP_DIRECTORY/publish_arm64/libsoundio.dylib"
|
||||||
|
|
||||||
|
rm -rf "$OUTPUT_DIRECTORY"
|
||||||
|
mkdir -p "$OUTPUT_DIRECTORY"
|
||||||
|
|
||||||
|
# Let's copy one of the two different outputs and remove the executable
|
||||||
|
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
|
||||||
|
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
|
||||||
|
|
||||||
|
# Make it libraries universal
|
||||||
|
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
|
||||||
|
|
||||||
|
if ! [ -x "$(command -v lipo)" ];
|
||||||
|
then
|
||||||
|
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
||||||
|
then
|
||||||
|
LIPO=llvm-lipo
|
||||||
|
else
|
||||||
|
LIPO=llvm-lipo-14
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LIPO=lipo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make the executable universal
|
||||||
|
$LIPO "$ARM64_OUTPUT/$EXECUTABLE_SUB_PATH" "$X64_OUTPUT/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" -create
|
||||||
|
|
||||||
|
# Now sign it
|
||||||
|
if ! [ -x "$(command -v codesign)" ];
|
||||||
|
then
|
||||||
|
if ! [ -x "$(command -v rcodesign)" ];
|
||||||
|
then
|
||||||
|
echo "Cannot find rcodesign on your system, please install rcodesign."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes.
|
||||||
|
# cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign"
|
||||||
|
echo "Using rcodesign for ad-hoc signing"
|
||||||
|
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
||||||
|
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
||||||
|
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Using codesign for ad-hoc signing"
|
||||||
|
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
||||||
|
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
||||||
|
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating archive"
|
||||||
|
pushd "$OUTPUT_DIRECTORY"
|
||||||
|
tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
|
||||||
|
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
|
||||||
|
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
||||||
|
rm "$RELEASE_TAR_FILE_NAME"
|
||||||
|
popd
|
||||||
|
|
||||||
|
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
|
40
docs/README.md
Normal file
40
docs/README.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Documents Index
|
||||||
|
|
||||||
|
This repo includes several documents that explain both high-level and low-level concepts about Ryujinx and its functions. These are very useful for contributors, to get context that can be very difficult to acquire from just reading code.
|
||||||
|
|
||||||
|
Intro to Ryujinx
|
||||||
|
==================
|
||||||
|
|
||||||
|
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
||||||
|
* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions.
|
||||||
|
* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
||||||
|
* Audio output is entirely supported via C# wrappers for SDL2, with OpenAL & libsoundio as fallbacks.
|
||||||
|
|
||||||
|
Getting Started
|
||||||
|
===============
|
||||||
|
|
||||||
|
- [Installing the .NET SDK](https://dotnet.microsoft.com/download)
|
||||||
|
- [Official .NET Docs](https://docs.microsoft.com/dotnet/core/)
|
||||||
|
|
||||||
|
Contributing (Building, testing, benchmarking, profiling, etc.)
|
||||||
|
===============
|
||||||
|
|
||||||
|
If you want to contribute a code change to this repo, start here.
|
||||||
|
|
||||||
|
- [Contributor Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
Coding Guidelines
|
||||||
|
=================
|
||||||
|
|
||||||
|
- [C# coding style](coding-guidelines/coding-style.md)
|
||||||
|
- [Service Implementation Guidelines - WIP](https://gist.github.com/gdkchan/84ba88cd50efbe58d1babfaa7cd7c455)
|
||||||
|
|
||||||
|
Project Docs
|
||||||
|
=================
|
||||||
|
|
||||||
|
To be added. Many project files will contain basic XML docs for key functions and classes in the meantime.
|
||||||
|
|
||||||
|
Other Information
|
||||||
|
=================
|
||||||
|
|
||||||
|
- N/A
|
116
docs/coding-guidelines/coding-style.md
Normal file
116
docs/coding-guidelines/coding-style.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# C# Coding Style
|
||||||
|
|
||||||
|
The general rule we follow is "use Visual Studio defaults".
|
||||||
|
Using an IDE that supports the `.editorconfig` standard will make this much simpler.
|
||||||
|
|
||||||
|
1. We use [Allman style](http://en.wikipedia.org/wiki/Indent_style#Allman_style) braces, where each brace begins on a new line. A single line statement block can go without braces but the block must be properly indented on its own line and must not be nested in other statement blocks that use braces (See rule 18 for more details). One exception is that a `using` statement is permitted to be nested within another `using` statement by starting on the following line at the same indentation level, even if the nested `using` contains a controlled block.
|
||||||
|
2. We use four spaces of indentation (no tabs).
|
||||||
|
3. We use `_camelCase` for internal and private fields and use `readonly` where possible. Prefix internal and private instance fields with `_`, static fields with `s_` and thread static fields with `t_`. When used on static fields, `readonly` should come after `static` (e.g. `static readonly` not `readonly static`). Public fields should be used sparingly and should use PascalCasing with no prefix when used.
|
||||||
|
4. We avoid `this.` unless absolutely necessary.
|
||||||
|
5. We always specify the visibility, even if it's the default (e.g.
|
||||||
|
`private string _foo` not `string _foo`). Visibility should be the first modifier (e.g.
|
||||||
|
`public abstract` not `abstract public`).
|
||||||
|
6. Namespace imports should be specified at the top of the file, *outside* of `namespace` declarations.
|
||||||
|
7. Avoid more than one empty line at any time. For example, do not have two
|
||||||
|
blank lines between members of a type.
|
||||||
|
8. Avoid spurious free spaces.
|
||||||
|
For example avoid `if (someVar == 0)...`, where the dots mark the spurious free spaces.
|
||||||
|
Consider enabling "View White Space (Ctrl+R, Ctrl+W)" or "Edit -> Advanced -> View White Space" if using Visual Studio to aid detection.
|
||||||
|
9. If a file happens to differ in style from these guidelines (e.g. private members are named `m_member`
|
||||||
|
rather than `_member`), the existing style in that file takes precedence.
|
||||||
|
10. We only use `var` when the type is explicitly named on the right-hand side, typically due to either `new` or an explicit cast, e.g. `var stream = new FileStream(...)` not `var stream = OpenStandardInput()`.
|
||||||
|
- Similarly, target-typed `new()` can only be used when the type is explicitly named on the left-hand side, in a variable definition statement or a field definition statement. e.g. `FileStream stream = new(...);`, but not `stream = new(...);` (where the type was specified on a previous line).
|
||||||
|
11. We use language keywords instead of BCL types (e.g. `int, string, float` instead of `Int32, String, Single`, etc) for both type references as well as method calls (e.g. `int.Parse` instead of `Int32.Parse`). See issue [#13976](https://github.com/dotnet/runtime/issues/13976) for examples.
|
||||||
|
12. We use PascalCasing to name all our constant local variables and fields. The only exception is for interop code where the constant value should exactly match the name and value of the code you are calling via interop.
|
||||||
|
13. We use PascalCasing for all method names, including local functions.
|
||||||
|
14. We use ```nameof(...)``` instead of ```"..."``` whenever possible and relevant.
|
||||||
|
15. Fields should be specified at the top within type declarations.
|
||||||
|
16. When including non-ASCII characters in the source code use Unicode escape sequences (\uXXXX) instead of literal characters. Literal non-ASCII characters occasionally get garbled by a tool or editor.
|
||||||
|
17. When using labels (for goto), indent the label one less than the current indentation.
|
||||||
|
18. When using a single-statement if, we follow these conventions:
|
||||||
|
- Never use single-line form (for example: `if (source == null) throw new ArgumentNullException("source");`)
|
||||||
|
- Using braces is always accepted, and required if any block of an `if`/`else if`/.../`else` compound statement uses braces or if a single statement body spans multiple lines.
|
||||||
|
- Braces may be omitted only if the body of *every* block associated with an `if`/`else if`/.../`else` compound statement is placed on a single line.
|
||||||
|
19. Make all internal and private types static or sealed unless derivation from them is required. As with any implementation detail, they can be changed if/when derivation is required in the future.
|
||||||
|
20. XML docs should be used when writing interfaces or when a class/method is deemed sufficient in scope or complexity.
|
||||||
|
21. So-called [Magic Numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)) should be defined as named constants before use (for example `for (int i = 56; i < 68; i++)` could read `for (int i = _currentAge; i < _retireAge; i++)`).
|
||||||
|
This may be ignored for trivial or syntactically common statements.
|
||||||
|
|
||||||
|
An [EditorConfig](https://editorconfig.org "EditorConfig homepage") file (`.editorconfig`) has been provided at the root of the runtime repository, enabling C# auto-formatting conforming to the above guidelines.
|
||||||
|
|
||||||
|
### Example File:
|
||||||
|
|
||||||
|
``ShaderCache.cs:``
|
||||||
|
|
||||||
|
```C#
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.Gpu.Engine.Threed;
|
||||||
|
using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||||
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
|
using Ryujinx.Graphics.Gpu.Memory;
|
||||||
|
using Ryujinx.Graphics.Gpu.Shader.DiskCache;
|
||||||
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Memory cache of shader code.
|
||||||
|
/// </summary>
|
||||||
|
class ShaderCache : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default flags used on the shader translation process.
|
||||||
|
/// </summary>
|
||||||
|
public const TranslationFlags DefaultFlags = TranslationFlags.DebugMode;
|
||||||
|
|
||||||
|
private readonly struct TranslatedShader
|
||||||
|
{
|
||||||
|
public readonly CachedShaderStage Shader;
|
||||||
|
public readonly ShaderProgram Program;
|
||||||
|
|
||||||
|
public TranslatedShader(CachedShaderStage shader, ShaderProgram program)
|
||||||
|
{
|
||||||
|
Shader = shader;
|
||||||
|
Program = program;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the queue of shaders that must save their binaries to the disk cache.
|
||||||
|
/// </summary>
|
||||||
|
public void ProcessShaderCacheQueue()
|
||||||
|
{
|
||||||
|
// Check to see if the binaries for previously compiled shaders are ready, and save them out.
|
||||||
|
|
||||||
|
while (_programsToSaveQueue.TryPeek(out ProgramToSave programToSave))
|
||||||
|
{
|
||||||
|
ProgramLinkStatus result = programToSave.HostProgram.CheckProgramLink(false);
|
||||||
|
|
||||||
|
if (result != ProgramLinkStatus.Incomplete)
|
||||||
|
{
|
||||||
|
if (result == ProgramLinkStatus.Success)
|
||||||
|
{
|
||||||
|
_cacheWriter.AddShader(programToSave.CachedProgram, programToSave.BinaryCode ?? programToSave.HostProgram.GetBinary());
|
||||||
|
}
|
||||||
|
|
||||||
|
_programsToSaveQueue.Dequeue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For other languages, our current best guidance is consistency. When editing files, keep new code and changes consistent with the style in the files. For new files, it should conform to the style for that component. If there is a completely new component, anything that is reasonably broadly accepted is fine.
|
56
docs/workflow/pr-guide.md
Normal file
56
docs/workflow/pr-guide.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Pull Request Guide
|
||||||
|
|
||||||
|
## Contributing Rules
|
||||||
|
|
||||||
|
All contributions to Ryujinx/Ryujinx repository are made via pull requests (PRs) rather than through direct commits. The pull requests are reviewed and merged by the maintainers after a review and at least two approvals from the core development team.
|
||||||
|
|
||||||
|
To merge pull requests, you must have write permissions in the repository.
|
||||||
|
|
||||||
|
## Quick Code Review Rules
|
||||||
|
|
||||||
|
* Do not mix unrelated changes in one pull request. For example, a code style change should never be mixed with a bug fix.
|
||||||
|
* All changes should follow the existing code style. You can read more about our code style at [docs/coding-guidelines](../coding-guidelines/coding-style.md).
|
||||||
|
* Adding external dependencies is to be avoided unless not doing so would introduce _significant_ complexity. Any dependency addition should be justified and discussed before merge.
|
||||||
|
* Use Draft pull requests for changes you are still working on but want early CI loop feedback. When you think your changes are ready for review, [change the status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request) of your pull request.
|
||||||
|
* Rebase your changes when required or directly requested. Changes should always be commited on top of the upstream branch, not the other way around.
|
||||||
|
* If you are asked to make changes during the review process do them as a new commit.
|
||||||
|
* Only resolve GitHub conversations with reviewers once they have been addressed with a commit, or via a mutual agreement.
|
||||||
|
|
||||||
|
## Pull Request Ownership
|
||||||
|
|
||||||
|
Every pull request will have automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
|
||||||
|
|
||||||
|
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
|
||||||
|
|
||||||
|
## Pull Request Builds
|
||||||
|
|
||||||
|
When submitting a PR to the `Ryujinx/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
|
||||||
|
|
||||||
|
## Review Turnaround Times
|
||||||
|
|
||||||
|
Ryujinx is a project that is maintained by volunteers on a completely free-time basis. As such we cannot guarantee any particular timeframe for pull request review and approval. Weeks to months are common for larger (>500 line) PRs but there are some additional best practises to avoid review purgatory.
|
||||||
|
|
||||||
|
* Make the reviewers life easier wherever possible. Make use of descriptive commit names, code comments and XML docs where applicable.
|
||||||
|
* If there is disagreement on feedback then always lean on the side of the development team and community over any personal opinion.
|
||||||
|
* We're human. We miss things. We forget things. If there has been radio silence on your changes for a substantial period of time then do not hesitate to reach out directly either with something simple like "bump" on GitHub or a directly on Discord.
|
||||||
|
|
||||||
|
To re-iterate, make the review as easy for us as possible, respond promptly and be comfortable to interact directly with us for anything else.
|
||||||
|
|
||||||
|
## Merging Pull Requests
|
||||||
|
|
||||||
|
Anyone with write access can merge a pull request manually when the following conditions have been met:
|
||||||
|
|
||||||
|
* The PR has been approved by two reviewers and any other objections are addressed.
|
||||||
|
* You can request follow up reviews from the original reviewers if they requested changes.
|
||||||
|
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryujinx/Ryujinx/actions) tab of your PR.
|
||||||
|
|
||||||
|
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.
|
||||||
|
|
||||||
|
## Blocking Pull Request Merging
|
||||||
|
|
||||||
|
If for whatever reason you would like to move your pull request back to an in-progress status to avoid merging it in the current form, you can turn the PR into a draft PR by selecting the option under the reviewers section. Alternatively, you can do that by adding [WIP] prefix to the pull request title.
|
||||||
|
|
||||||
|
## Old Pull Request Policy
|
||||||
|
|
||||||
|
From time to time we will review older PRs and check them for relevance. If we find the PR is inactive or no longer applies, we will close it. As the PR owner, you can simply reopen it if you feel your closed PR needs our attention.
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
@ -170,7 +171,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -1078,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);
|
||||||
|
|
||||||
@ -1568,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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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));
|
||||||
@ -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)
|
||||||
|
@ -55,6 +55,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
VectorTernaryShrRd,
|
VectorTernaryShrRd,
|
||||||
|
|
||||||
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;
|
||||||
|
@ -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; }
|
||||||
|
@ -18,6 +18,6 @@
|
|||||||
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)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user