Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
b2aed882d6 nuget: bump Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK
Bumps Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK from 1.2.0 to 1.2.3.

---
updated-dependencies:
- dependency-name: Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-31 07:09:40 +00:00
1891 changed files with 24763 additions and 26732 deletions

View File

@@ -1,19 +0,0 @@
name: Missing Shader Instruction
description: Shader Instruction is missing in Ryujinx.
title: "[GPU]"
labels: [gpu, not-implemented]
body:
- type: textarea
id: instruction
attributes:
label: Shader instruction
description: What shader instruction is missing?
validations:
required: true
- type: textarea
id: required
attributes:
label: Required by
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
validations:
required: true

View File

@@ -1,8 +0,0 @@
addReviewers: true
reviewers:
- marysaka
filterLabels:
include:
- audio

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
filterLabels:
include:
- cpu

View File

@@ -1,4 +0,0 @@
addReviewers: true
reviewers:
- Ryujinx/developers

View File

@@ -1,10 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
filterLabels:
include:
- gpu

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- Ack77
- emmauss
- TSRBerry
- marysaka
filterLabels:
include:
- gui

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- Ack77
- marysaka
- TSRBerry
filterLabels:
include:
- horizon

View File

@@ -1,9 +0,0 @@
addReviewers: true
reviewers:
- marysaka
- TSRBerry
filterLabels:
include:
- infra

33
.github/labeler.yml vendored
View File

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

View File

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

View File

@@ -1,54 +0,0 @@
name: "Pull Request Triage"
on:
pull_request_target:
types: [opened, ready_for_review]
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Update labels based on changes
uses: actions/labeler@v4
with:
sync-labels: true
dot: true
- name: Auto Assign [Audio]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/audio.yml'
- name: Auto Assign [CPU]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
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'

View File

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

View File

@@ -13,7 +13,7 @@
<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.1.3.18" />
<PackageVersion Include="DynamicData" Version="7.14.2" /> <PackageVersion Include="DynamicData" Version="7.13.8" />
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
<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" />
@@ -21,7 +21,7 @@
<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.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<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" />
@@ -32,7 +32,7 @@
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.7" /> <PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.7" />
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" /> <PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.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.3" />
<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.26.3-build25" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
@@ -44,9 +44,9 @@
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" /> <PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" /> <PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" /> <PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" /> <PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.30.1" />
<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.1" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" /> <PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup> </ItemGroup>

View File

@@ -39,15 +39,10 @@
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string> <string>Copyright © 2018 - 2022 Ryujinx Team and Contributors.</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>11.0</string> <string>11.0</string>
<key>LSEnvironment</key>
<dict>
<key>COMPlus_DefaultStackSize</key>
<string>200000</string>
</dict>
</dict> </dict>
</plist> </plist>

View File

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

View File

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

View File

@@ -23,7 +23,10 @@ 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)
{ {
alloc ??= new ArenaAllocator(pageSize, pageCount); if (alloc == null)
{
alloc = new ArenaAllocator(pageSize, pageCount);
}
return alloc; return alloc;
} }

View File

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

View File

@@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.Arm64
Gt = 12, Gt = 12,
Le = 13, Le = 13,
Al = 14, Al = 14,
Nv = 15, Nv = 15
} }
static class ComparisonArm64Extensions static class ComparisonArm64Extensions
@@ -29,7 +29,6 @@ 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,
@@ -40,9 +39,8 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison.Less => ArmCondition.Lt, Comparison.Less => ArmCondition.Lt,
Comparison.GreaterOrEqualUI => ArmCondition.GeUn, Comparison.GreaterOrEqualUI => ArmCondition.GeUn,
Comparison.LessUI => ArmCondition.LtUn, Comparison.LessUI => ArmCondition.LtUn,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)), _ => throw new ArgumentException(null, nameof(comp))
}; };
} }
} }

View File

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

View File

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

View File

@@ -992,7 +992,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
OperandType.FP32 => 0, OperandType.FP32 => 0,
OperandType.FP64 => 1, OperandType.FP64 => 1,
_ => 2, _ => 2
}; };
instruction = vecInst | ((uint)opc << 30); instruction = vecInst | ((uint)opc << 30);
@@ -1124,11 +1124,10 @@ 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);
@@ -1143,7 +1142,6 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
_stream.WriteByte(value); _stream.WriteByte(value);
} }
#pragma warning restore IDE0051
private void WriteUInt16(ushort value) private void WriteUInt16(ushort value)
{ {

View File

@@ -14,7 +14,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4; private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4; private const int LdrLitInstLength = 4;
private readonly Stream _stream; private 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 readonly struct ConstantPoolEntry private 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, bool relocatable) public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksCount, 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 ((ArmCondition condition, long branchPos) in list) foreach (var tuple in list)
{ {
_stream.Seek(branchPos, SeekOrigin.Begin); _stream.Seek(tuple.BranchPos, SeekOrigin.Begin);
WriteBranch(condition, target); WriteBranch(tuple.Condition, target);
} }
_stream.Seek(target, SeekOrigin.Begin); _stream.Seek(target, SeekOrigin.Begin);

View File

@@ -10,6 +10,7 @@ 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;
@@ -30,16 +31,15 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
Byte, Byte,
Hword, Hword,
Auto, Auto
} }
private static readonly Action<CodeGenContext, Operation>[] _instTable; private static 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,7 +100,6 @@ 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)
{ {
@@ -132,7 +131,7 @@ namespace ARMeilleure.CodeGen.Arm64
StackAllocator stackAlloc = new(); StackAllocator stackAlloc = new();
PreAllocator.RunPass(cctx, out int maxCallArgs); PreAllocator.RunPass(cctx, stackAlloc, out int maxCallArgs);
Logger.EndPass(PassName.PreAllocation, cfg); Logger.EndPass(PassName.PreAllocation, cfg);
@@ -169,9 +168,11 @@ namespace ARMeilleure.CodeGen.Arm64
Logger.StartPass(PassName.CodeGeneration); Logger.StartPass(PassName.CodeGeneration);
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0; bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
CodeGenContext context = new(allocResult, maxCallArgs, relocatable); CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
UnwindInfo unwindInfo = WritePrologue(context); UnwindInfo unwindInfo = WritePrologue(context);
@@ -1079,7 +1080,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new(); List<UnwindPushEntry> pushEntries = new List<UnwindPushEntry>();
Operand rsp = Register(SpRegister); Operand rsp = Register(SpRegister);
@@ -1569,13 +1570,11 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
} }
#pragma warning disable IDE0051 // Remove unused private member
private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4) private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4)
{ {
Debug.Assert(op1.Type == op2.Type); Debug.Assert(op1.Type == op2.Type);
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
Debug.Assert(op1.Type == op4.Type); Debug.Assert(op1.Type == op4.Type);
} }
#pragma warning restore IDE0051
} }
} }

View File

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

View File

@@ -1,4 +1,7 @@
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;
@@ -74,7 +77,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]
@@ -116,7 +119,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;
@@ -140,7 +143,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
private static readonly string[] _sysctlNames = new string[] private static string[] _sysctlNames = new string[]
{ {
"hw.optional.floatingpoint", "hw.optional.floatingpoint",
"hw.optional.AdvSIMD", "hw.optional.AdvSIMD",
@@ -150,7 +153,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]
@@ -164,7 +167,7 @@ namespace ARMeilleure.CodeGen.Arm64
Lse = 1 << 5, Lse = 1 << 5,
Crc32 = 1 << 6, Crc32 = 1 << 6,
Sha1 = 1 << 7, Sha1 = 1 << 7,
Sha256 = 1 << 8, Sha256 = 1 << 8
} }
public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0; public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0;

View File

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

View File

@@ -5,13 +5,12 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static readonly IntrinsicInfo[] _intrinTable; private static 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));
@@ -20,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary)); Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd)); Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd)); Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise)); Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
@@ -449,7 +448,6 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -545,7 +545,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
_intervals.Insert(insertIndex, interval); _intervals.Insert(insertIndex, interval);
} }
private static void Spill(AllocationContext context, LiveInterval interval) private 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> copyResolvers = new Dictionary<int, CopyResolver>();
CopyResolver GetCopyResolver(int position) CopyResolver GetCopyResolver(int position)
{ {
@@ -676,7 +676,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (left != default && right != default && left != right) if (left != default && right != default && left != right)
{ {
copyResolver ??= new CopyResolver(); if (copyResolver == null)
{
copyResolver = new CopyResolver();
}
copyResolver.AddSplit(left, right); copyResolver.AddSplit(left, right);
} }
@@ -859,8 +862,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(Allocators.Default, mapSize); BitMap liveGen = new BitMap(Allocators.Default, mapSize);
BitMap liveKill = new(Allocators.Default, mapSize); BitMap liveKill = new BitMap(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)
{ {
@@ -1058,7 +1061,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
int regIndex = BitOperations.TrailingZeroCount(mask); int regIndex = BitOperations.TrailingZeroCount(mask);
Register callerSavedReg = new(regIndex, regType); Register callerSavedReg = new Register(regIndex, regType);
LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)]; LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)];

View File

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

View File

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

View File

@@ -6,15 +6,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
private int* _items; private int* _items;
private int _capacity; private int _capacity;
private int _count;
public int Count { get; private set; } public int Count => _count;
public int FirstUse => _count > 0 ? _items[_count - 1] : LiveInterval.NotFound;
public readonly int FirstUse => Count > 0 ? _items[Count - 1] : LiveInterval.NotFound; public Span<int> Span => new(_items, _count);
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 readonly int NextUse(int position) public 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 readonly int NextUseIndex(int position) public 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,16 +69,14 @@ 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;
Count = index + 1, result._capacity = result._count;
};
result._capacity = result.Count;
result._items = _items; result._items = _items;
Count -= result.Count; _count = _count - result._count;
_capacity = Count; _capacity = _count;
_items += result.Count; _items = _items + result._count;
return result; return result;
} }

View File

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

View File

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

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
@@ -13,7 +12,6 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0; private const int BadOp = 0;
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags private enum InstructionFlags
{ {
None = 0, None = 0,
@@ -28,7 +26,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
@@ -64,7 +62,6 @@ 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));
@@ -288,7 +285,6 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None)); Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None));
Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex)); Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex));
#pragma warning restore IDE0055
static void Add(X86Instruction inst, in InstructionInfo info) static void Add(X86Instruction inst, in InstructionInfo info)
{ {

View File

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

View File

@@ -20,7 +20,6 @@ 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) |
@@ -40,7 +39,6 @@ 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
} }
} }
@@ -92,32 +90,22 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (index) switch (index)
{ {
case 0: case 0: return X86Register.Rcx;
return X86Register.Rcx; case 1: return X86Register.Rdx;
case 1: case 2: return X86Register.R8;
return X86Register.Rdx; case 3: return X86Register.R9;
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: case 0: return X86Register.Rdi;
return X86Register.Rdi; case 1: return X86Register.Rsi;
case 1: case 2: return X86Register.Rdx;
return X86Register.Rsi; case 3: return X86Register.Rcx;
case 2: case 4: return X86Register.R8;
return X86Register.Rdx; case 5: return X86Register.R9;
case 3:
return X86Register.Rcx;
case 4:
return X86Register.R8;
case 5:
return X86Register.R9;
} }
} }

View File

@@ -26,7 +26,6 @@ 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);
@@ -86,7 +85,6 @@ 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)
{ {
@@ -1296,11 +1294,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
@@ -1615,25 +1613,13 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: case OperandType.I32: context.Assembler.Mov (value, address, OperandType.I32); break;
context.Assembler.Mov(value, address, OperandType.I32); case OperandType.I64: context.Assembler.Mov (value, address, OperandType.I64); break;
break; case OperandType.FP32: context.Assembler.Movd (value, address); break;
case OperandType.I64: case OperandType.FP64: context.Assembler.Movq (value, address); break;
context.Assembler.Mov(value, address, OperandType.I64); case OperandType.V128: context.Assembler.Movdqu(value, address); break;
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: default: Debug.Assert(false); break;
Debug.Assert(false);
break;
} }
} }
@@ -1641,25 +1627,13 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: case OperandType.I32: context.Assembler.Mov (address, value, OperandType.I32); break;
context.Assembler.Mov(address, value, OperandType.I32); case OperandType.I64: context.Assembler.Mov (address, value, OperandType.I64); break;
break; case OperandType.FP32: context.Assembler.Movd (address, value); break;
case OperandType.I64: case OperandType.FP64: context.Assembler.Movq (address, value); break;
context.Assembler.Mov(address, value, OperandType.I64); case OperandType.V128: context.Assembler.Movdqu(address, value); break;
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: default: Debug.Assert(false); break;
Debug.Assert(false);
break;
} }
} }
@@ -1748,7 +1722,7 @@ namespace ARMeilleure.CodeGen.X86
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new(); List<UnwindPushEntry> pushEntries = new List<UnwindPushEntry>();
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
@@ -1853,9 +1827,9 @@ namespace ARMeilleure.CodeGen.X86
// that the OS will map all pages that we'll use. We do that by // that the OS will map all pages that we'll use. We do that by
// doing a dummy read on those pages, forcing a page fault and // doing a dummy read on those pages, forcing a page fault and
// the OS to map them. If they are already mapped, nothing happens. // the OS to map them. If they are already mapped, nothing happens.
const int PageMask = PageSize - 1; const int pageMask = PageSize - 1;
size = (size + PageMask) & ~PageMask; size = (size + pageMask) & ~pageMask;
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
Operand temp = Register(CallingConvention.GetIntReturnRegister()); Operand temp = Register(CallingConvention.GetIntReturnRegister());

View File

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

View File

@@ -5,13 +5,12 @@ namespace ARMeilleure.CodeGen.X86
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static readonly IntrinsicInfo[] _intrinTable; private static 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));
@@ -186,7 +185,6 @@ namespace ARMeilleure.CodeGen.X86
Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm)); Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary)); Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary));
Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary)); Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.X86
Less = 0xc, Less = 0xc,
GreaterOrEqual = 0xd, GreaterOrEqual = 0xd,
LessOrEqual = 0xe, LessOrEqual = 0xe,
Greater = 0xf, Greater = 0xf
} }
static class ComparisonX86Extensions static class ComparisonX86Extensions
@@ -29,7 +29,6 @@ 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,
@@ -40,9 +39,8 @@ namespace ARMeilleure.CodeGen.X86
Comparison.Less => X86Condition.Less, Comparison.Less => X86Condition.Less,
Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual, Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual,
Comparison.LessUI => X86Condition.Below, Comparison.LessUI => X86Condition.Below,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)), _ => throw new ArgumentException(null, nameof(comp))
}; };
} }
} }

View File

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

View File

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

View File

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

View File

@@ -82,10 +82,8 @@ 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);
} }
@@ -108,7 +106,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[^1].Pointer); NativeAllocator.Instance.Free(_pages[_pages.Count - 1].Pointer);
_pages.RemoveAt(_pages.Count - 1); _pages.RemoveAt(_pages.Count - 1);
} }
@@ -127,13 +125,12 @@ namespace ARMeilleure.Common
// If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time. // If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time.
int now = Environment.TickCount; int now = Environment.TickCount;
int count = (now - _lastReset) switch int count = (now - _lastReset) switch {
{
>= 5000 => 0, >= 5000 => 0,
>= 2500 => 50, >= 2500 => 50,
>= 1000 => 100, >= 1000 => 100,
>= 10 => 1500, >= 10 => 1500,
_ => 5000, _ => 5000
}; };
for (int i = _pages.Count - 1; i >= 0; i--) for (int i = _pages.Count - 1; i >= 0; i--)

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,11 +20,11 @@ namespace ARMeilleure.Decoders
public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode) public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
{ {
List<Block> blocks = new(); List<Block> blocks = new List<Block>();
Queue<Block> workQueue = new(); Queue<Block> workQueue = new Queue<Block>();
Dictionary<ulong, Block> visited = new(); Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
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 not OpCode32 op) if (!(opCode is OpCode32 op))
{ {
return false; return false;
} }
@@ -304,9 +304,9 @@ namespace ARMeilleure.Decoders
} }
else if (opCode is IOpCode32MemMult opMemMult) else if (opCode is IOpCode32MemMult opMemMult)
{ {
const int PCMask = 1 << RegisterAlias.Aarch32Pc; const int pcMask = 1 << RegisterAlias.Aarch32Pc;
rt = (opMemMult.RegisterMask & PCMask) != 0 ? RegisterAlias.Aarch32Pc : 0; rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
rn = opMemMult.Rn; rn = opMemMult.Rn;
wBack = opMemMult.PostOffset != 0; wBack = opMemMult.PostOffset != 0;
isLoad = opMemMult.IsLoad; isLoad = opMemMult.IsLoad;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,15 +14,9 @@
// 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: case 1: Size = 0; break;
Size = 0; case 2: Size = 1; break;
break; case 4: Size = 2; break;
case 2:
Size = 1;
break;
case 4:
Size = 2;
break;
} }
U = ((opCode >> (isThumb ? 28 : 24)) & 0x1) != 0; U = ((opCode >> (isThumb ? 28 : 24)) & 0x1) != 0;

View File

@@ -4,12 +4,12 @@ namespace ARMeilleure.Decoders
{ {
class OpCode32SimdMemPair : OpCode32, IOpCode32Simd class OpCode32SimdMemPair : OpCode32, IOpCode32Simd
{ {
private static readonly int[] _regsMap = private static int[] _regsMap =
{ {
1, 1, 4, 2, 1, 1, 4, 2,
1, 1, 3, 1, 1, 1, 3, 1,
1, 1, 2, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1
}; };
public int Vd { get; } public int Vd { get; }

View File

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

View File

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

View File

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

View File

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

View File

@@ -52,20 +52,17 @@
else if ((modeHigh & 0b110) == 0b100) else if ((modeHigh & 0b110) == 0b100)
{ {
// 16-bits shifted Immediate. // 16-bits shifted Immediate.
size = 1; size = 1; imm <<= (modeHigh & 1) << 3;
imm <<= (modeHigh & 1) << 3;
} }
else if ((modeHigh & 0b100) == 0b000) else if ((modeHigh & 0b100) == 0b000)
{ {
// 32-bits shifted Immediate. // 32-bits shifted Immediate.
size = 2; size = 2; imm <<= modeHigh << 3;
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; size = 2; imm = ShlOnes(imm, 8 << modeLow);
imm = ShlOnes(imm, 8 << modeLow);
} }
else else
{ {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -29,17 +29,16 @@ namespace ARMeilleure.Decoders
} }
} }
private static readonly List<InstInfo> _allInstA32 = new(); private static List<InstInfo> AllInstA32 = new();
private static readonly List<InstInfo> _allInstT32 = new(); private static List<InstInfo> AllInstT32 = new();
private static readonly List<InstInfo> _allInstA64 = new(); private static List<InstInfo> AllInstA64 = new();
private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][]; private static InstInfo[][] InstA32FastLookup = new InstInfo[FastLookupSize][];
private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][]; private static InstInfo[][] InstT32FastLookup = new InstInfo[FastLookupSize][];
private static readonly InstInfo[][] _instA64FastLookup = new InstInfo[FastLookupSize][]; private static 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);
@@ -918,7 +917,6 @@ 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);
@@ -1301,13 +1299,12 @@ 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];
@@ -1318,8 +1315,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++)
{ {
@@ -1338,21 +1335,22 @@ 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)}";
OpCode ReversedMakeOp(InstDescriptor inst, ulong address, int opCode) MakeOp reversedMakeOp =
(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)
@@ -1397,7 +1395,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)
@@ -1441,7 +1439,7 @@ namespace ARMeilleure.Decoders
} }
else if (chr != '0') else if (chr != '0')
{ {
throw new ArgumentException($"Invalid encoding: {encoding}", nameof(encoding)); throw new ArgumentException(nameof(encoding));
} }
} }
@@ -1472,17 +1470,17 @@ namespace ARMeilleure.Decoders
public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode)
{ {
return GetInstFromList(_instA32FastLookup[ToFastLookupIndexA(opCode)], opCode); return GetInstFromList(InstA32FastLookup[ToFastLookupIndexA(opCode)], opCode);
} }
public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode)
{ {
return GetInstFromList(_instT32FastLookup[ToFastLookupIndexT(opCode)], opCode); return GetInstFromList(InstT32FastLookup[ToFastLookupIndexT(opCode)], opCode);
} }
public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode) public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode)
{ {
return GetInstFromList(_instA64FastLookup[ToFastLookupIndexA(opCode)], opCode); return GetInstFromList(InstA64FastLookup[ToFastLookupIndexA(opCode)], opCode);
} }
private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode) private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode)

View File

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

View File

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

View File

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

View File

@@ -34,9 +34,7 @@ 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
} }
} }
@@ -112,18 +110,10 @@ namespace ARMeilleure.Diagnostics
switch (reg.Type) switch (reg.Type)
{ {
case RegisterType.Flag: case RegisterType.Flag: _builder.Append('b'); break;
_builder.Append('b'); case RegisterType.FpFlag: _builder.Append('f'); break;
break; case RegisterType.Integer: _builder.Append('r'); break;
case RegisterType.FpFlag: case RegisterType.Vector: _builder.Append('v'); break;
_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);
@@ -155,15 +145,9 @@ namespace ARMeilleure.Diagnostics
switch (memOp.Scale) switch (memOp.Scale)
{ {
case Multiplier.x2: case Multiplier.x2: _builder.Append("*2"); break;
_builder.Append("*2"); case Multiplier.x4: _builder.Append("*4"); break;
break; case Multiplier.x8: _builder.Append("*8"); break;
case Multiplier.x4:
_builder.Append("*4");
break;
case Multiplier.x8:
_builder.Append("*8");
break;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,7 +8,6 @@ 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,
@@ -26,7 +25,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[]
@@ -46,7 +45,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[]
@@ -66,7 +65,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[]
@@ -86,7 +85,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[]
@@ -106,7 +105,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[]
@@ -126,7 +125,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[]
@@ -146,7 +145,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[]
@@ -166,19 +165,18 @@ namespace ARMeilleure.Instructions
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
}; };
private static ReadOnlySpan<byte> _srPerm => new byte[] private static ReadOnlySpan<byte> _srPerm => new byte[]
{ {
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
}; };
private static ReadOnlySpan<byte> _isrPerm => new byte[] private static ReadOnlySpan<byte> _isrPerm => new byte[]
{ {
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
}; };
#pragma warning restore IDE1006
#endregion #endregion
public static V128 AesInvMixColumns(V128 op) public static V128 AesInvMixColumns(V128 op)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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