Add a new JIT compiler for CPU code (#693)
* Start of the ARMeilleure project * Refactoring around the old IRAdapter, now renamed to PreAllocator * Optimize the LowestBitSet method * Add CLZ support and fix CLS implementation * Add missing Equals and GetHashCode overrides on some structs, misc small tweaks * Implement the ByteSwap IR instruction, and some refactoring on the assembler * Implement the DivideUI IR instruction and fix 64-bits IDIV * Correct constant operand type on CSINC * Move division instructions implementation to InstEmitDiv * Fix destination type for the ConditionalSelect IR instruction * Implement UMULH and SMULH, with new IR instructions * Fix some issues with shift instructions * Fix constant types for BFM instructions * Fix up new tests using the new V128 struct * Update tests * Move DIV tests to a separate file * Add support for calls, and some instructions that depends on them * Start adding support for SIMD & FP types, along with some of the related ARM instructions * Fix some typos and the divide instruction with FP operands * Fix wrong method call on Clz_V * Implement ARM FP & SIMD move instructions, Saddlv_V, and misc. fixes * Implement SIMD logical instructions and more misc. fixes * Fix PSRAD x86 instruction encoding, TRN, UABD and UABDL implementations * Implement float conversion instruction, merge in LDj3SNuD fixes, and some other misc. fixes * Implement SIMD shift instruction and fix Dup_V * Add SCVTF and UCVTF (vector, fixed-point) variants to the opcode table * Fix check with tolerance on tester * Implement FP & SIMD comparison instructions, and some fixes * Update FCVT (Scalar) encoding on the table to support the Half-float variants * Support passing V128 structs, some cleanup on the register allocator, merge LDj3SNuD fixes * Use old memory access methods, made a start on SIMD memory insts support, some fixes * Fix float constant passed to functions, save and restore non-volatile XMM registers, other fixes * Fix arguments count with struct return values, other fixes * More instructions * Misc. fixes and integrate LDj3SNuD fixes * Update tests * Add a faster linear scan allocator, unwinding support on windows, and other changes * Update Ryujinx.HLE * Update Ryujinx.Graphics * Fix V128 return pointer passing, RCX is clobbered * Update Ryujinx.Tests * Update ITimeZoneService * Stop using GetFunctionPointer as that can't be called from native code, misc. fixes and tweaks * Use generic GetFunctionPointerForDelegate method and other tweaks * Some refactoring on the code generator, assert on invalid operations and use a separate enum for intrinsics * Remove some unused code on the assembler * Fix REX.W prefix regression on float conversion instructions, add some sort of profiler * Add hardware capability detection * Fix regression on Sha1h and revert Fcm** changes * Add SSE2-only paths on vector extract and insert, some refactoring on the pre-allocator * Fix silly mistake introduced on last commit on CpuId * Generate inline stack probes when the stack allocation is too large * Initial support for the System-V ABI * Support multiple destination operands * Fix SSE2 VectorInsert8 path, and other fixes * Change placement of XMM callee save and restore code to match other compilers * Rename Dest to Destination and Inst to Instruction * Fix a regression related to calls and the V128 type * Add an extra space on comments to match code style * Some refactoring * Fix vector insert FP32 SSE2 path * Port over the ARM32 instructions * Avoid memory protection races on JIT Cache * Another fix on VectorInsert FP32 (thanks to LDj3SNuD * Float operands don't need to use the same register when VEX is supported * Add a new register allocator, higher quality code for hot code (tier up), and other tweaks * Some nits, small improvements on the pre allocator * CpuThreadState is gone * Allow changing CPU emulators with a config entry * Add runtime identifiers on the ARMeilleure project * Allow switching between CPUs through a config entry (pt. 2) * Change win10-x64 to win-x64 on projects * Update the Ryujinx project to use ARMeilleure * Ensure that the selected register is valid on the hybrid allocator * Allow exiting on returns to 0 (should fix test regression) * Remove register assignments for most used variables on the hybrid allocator * Do not use fixed registers as spill temp * Add missing namespace and remove unneeded using * Address PR feedback * Fix types, etc * Enable AssumeStrictAbiCompliance by default * Ensure that Spill and Fill don't load or store any more than necessary
This commit is contained in:
parent
1ba58e9942
commit
a731ab3a2a
310 changed files with 37389 additions and 2086 deletions
1358
ARMeilleure/CodeGen/X86/Assembler.cs
Normal file
1358
ARMeilleure/CodeGen/X86/Assembler.cs
Normal file
File diff suppressed because it is too large
Load diff
8
ARMeilleure/CodeGen/X86/CallConvName.cs
Normal file
8
ARMeilleure/CodeGen/X86/CallConvName.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum CallConvName
|
||||
{
|
||||
SystemV,
|
||||
Windows
|
||||
}
|
||||
}
|
159
ARMeilleure/CodeGen/X86/CallingConvention.cs
Normal file
159
ARMeilleure/CodeGen/X86/CallingConvention.cs
Normal file
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
static class CallingConvention
|
||||
{
|
||||
private const int RegistersMask = 0xffff;
|
||||
|
||||
public static int GetIntAvailableRegisters()
|
||||
{
|
||||
return RegistersMask & ~(1 << (int)X86Register.Rsp);
|
||||
}
|
||||
|
||||
public static int GetVecAvailableRegisters()
|
||||
{
|
||||
return RegistersMask;
|
||||
}
|
||||
|
||||
public static int GetIntCallerSavedRegisters()
|
||||
{
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
return (1 << (int)X86Register.Rax) |
|
||||
(1 << (int)X86Register.Rcx) |
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
}
|
||||
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
|
||||
{
|
||||
return (1 << (int)X86Register.Rax) |
|
||||
(1 << (int)X86Register.Rcx) |
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.Rsi) |
|
||||
(1 << (int)X86Register.Rdi) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetVecCallerSavedRegisters()
|
||||
{
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
return (1 << (int)X86Register.Xmm0) |
|
||||
(1 << (int)X86Register.Xmm1) |
|
||||
(1 << (int)X86Register.Xmm2) |
|
||||
(1 << (int)X86Register.Xmm3) |
|
||||
(1 << (int)X86Register.Xmm4) |
|
||||
(1 << (int)X86Register.Xmm5);
|
||||
}
|
||||
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
|
||||
{
|
||||
return RegistersMask;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetIntCalleeSavedRegisters()
|
||||
{
|
||||
return GetIntCallerSavedRegisters() ^ RegistersMask;
|
||||
}
|
||||
|
||||
public static int GetVecCalleeSavedRegisters()
|
||||
{
|
||||
return GetVecCallerSavedRegisters() ^ RegistersMask;
|
||||
}
|
||||
|
||||
public static int GetArgumentsOnRegsCount()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static int GetIntArgumentsOnRegsCount()
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
public static int GetVecArgumentsOnRegsCount()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public static X86Register GetIntArgumentRegister(int index)
|
||||
{
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return X86Register.Rcx;
|
||||
case 1: return X86Register.Rdx;
|
||||
case 2: return X86Register.R8;
|
||||
case 3: return X86Register.R9;
|
||||
}
|
||||
}
|
||||
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return X86Register.Rdi;
|
||||
case 1: return X86Register.Rsi;
|
||||
case 2: return X86Register.Rdx;
|
||||
case 3: return X86Register.Rcx;
|
||||
case 4: return X86Register.R8;
|
||||
case 5: return X86Register.R9;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public static X86Register GetVecArgumentRegister(int index)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
count = 4;
|
||||
}
|
||||
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
|
||||
{
|
||||
count = 8;
|
||||
}
|
||||
|
||||
if ((uint)index < count)
|
||||
{
|
||||
return X86Register.Xmm0 + index;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public static X86Register GetIntReturnRegister()
|
||||
{
|
||||
return X86Register.Rax;
|
||||
}
|
||||
|
||||
public static X86Register GetIntReturnRegisterHigh()
|
||||
{
|
||||
return X86Register.Rdx;
|
||||
}
|
||||
|
||||
public static X86Register GetVecReturnRegister()
|
||||
{
|
||||
return X86Register.Xmm0;
|
||||
}
|
||||
|
||||
public static CallConvName GetCurrentCallConv()
|
||||
{
|
||||
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
||||
? CallConvName.Windows
|
||||
: CallConvName.SystemV;
|
||||
}
|
||||
}
|
||||
}
|
305
ARMeilleure/CodeGen/X86/CodeGenContext.cs
Normal file
305
ARMeilleure/CodeGen/X86/CodeGenContext.cs
Normal file
|
@ -0,0 +1,305 @@
|
|||
using ARMeilleure.CodeGen.RegisterAllocators;
|
||||
using ARMeilleure.Common;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
class CodeGenContext
|
||||
{
|
||||
private const int ReservedBytesForJump = 1;
|
||||
|
||||
private Stream _stream;
|
||||
|
||||
public int StreamOffset => (int)_stream.Length;
|
||||
|
||||
public AllocationResult AllocResult { get; }
|
||||
|
||||
public Assembler Assembler { get; }
|
||||
|
||||
public BasicBlock CurrBlock { get; private set; }
|
||||
|
||||
public int CallArgsRegionSize { get; }
|
||||
public int XmmSaveRegionSize { get; }
|
||||
|
||||
private long[] _blockOffsets;
|
||||
|
||||
private struct Jump
|
||||
{
|
||||
public bool IsConditional { get; }
|
||||
|
||||
public X86Condition Condition { get; }
|
||||
|
||||
public BasicBlock Target { get; }
|
||||
|
||||
public long JumpPosition { get; }
|
||||
|
||||
public long RelativeOffset { get; set; }
|
||||
|
||||
public int InstSize { get; set; }
|
||||
|
||||
public Jump(BasicBlock target, long jumpPosition)
|
||||
{
|
||||
IsConditional = false;
|
||||
Condition = 0;
|
||||
Target = target;
|
||||
JumpPosition = jumpPosition;
|
||||
|
||||
RelativeOffset = 0;
|
||||
|
||||
InstSize = 0;
|
||||
}
|
||||
|
||||
public Jump(X86Condition condition, BasicBlock target, long jumpPosition)
|
||||
{
|
||||
IsConditional = true;
|
||||
Condition = condition;
|
||||
Target = target;
|
||||
JumpPosition = jumpPosition;
|
||||
|
||||
RelativeOffset = 0;
|
||||
|
||||
InstSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Jump> _jumps;
|
||||
|
||||
private X86Condition _jNearCondition;
|
||||
|
||||
private long _jNearPosition;
|
||||
private int _jNearLength;
|
||||
|
||||
public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount)
|
||||
{
|
||||
_stream = stream;
|
||||
|
||||
AllocResult = allocResult;
|
||||
|
||||
Assembler = new Assembler(stream);
|
||||
|
||||
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize);
|
||||
XmmSaveRegionSize = xmmSaveRegionSize;
|
||||
|
||||
_blockOffsets = new long[blocksCount];
|
||||
|
||||
_jumps = new List<Jump>();
|
||||
}
|
||||
|
||||
private int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize)
|
||||
{
|
||||
// We need to add 8 bytes to the total size, as the call to this
|
||||
// function already pushed 8 bytes (the return address).
|
||||
int intMask = CallingConvention.GetIntCalleeSavedRegisters() & allocResult.IntUsedRegisters;
|
||||
int vecMask = CallingConvention.GetVecCalleeSavedRegisters() & allocResult.VecUsedRegisters;
|
||||
|
||||
xmmSaveRegionSize = BitUtils.CountBits(vecMask) * 16;
|
||||
|
||||
int calleeSaveRegionSize = BitUtils.CountBits(intMask) * 8 + xmmSaveRegionSize + 8;
|
||||
|
||||
int argsCount = maxCallArgs;
|
||||
|
||||
if (argsCount < 0)
|
||||
{
|
||||
// When the function has no calls, argsCount is -1.
|
||||
// In this case, we don't need to allocate the shadow space.
|
||||
argsCount = 0;
|
||||
}
|
||||
else if (argsCount < 4)
|
||||
{
|
||||
// The ABI mandates that the space for at least 4 arguments
|
||||
// is reserved on the stack (this is called shadow space).
|
||||
argsCount = 4;
|
||||
}
|
||||
|
||||
int frameSize = calleeSaveRegionSize + allocResult.SpillRegionSize;
|
||||
|
||||
// TODO: Instead of always multiplying by 16 (the largest possible size of a variable,
|
||||
// since a V128 has 16 bytes), we should calculate the exact size consumed by the
|
||||
// arguments passed to the called functions on the stack.
|
||||
int callArgsAndFrameSize = frameSize + argsCount * 16;
|
||||
|
||||
// Ensure that the Stack Pointer will be aligned to 16 bytes.
|
||||
callArgsAndFrameSize = (callArgsAndFrameSize + 0xf) & ~0xf;
|
||||
|
||||
return callArgsAndFrameSize - frameSize;
|
||||
}
|
||||
|
||||
public void EnterBlock(BasicBlock block)
|
||||
{
|
||||
_blockOffsets[block.Index] = _stream.Position;
|
||||
|
||||
CurrBlock = block;
|
||||
}
|
||||
|
||||
public void JumpTo(BasicBlock target)
|
||||
{
|
||||
_jumps.Add(new Jump(target, _stream.Position));
|
||||
|
||||
WritePadding(ReservedBytesForJump);
|
||||
}
|
||||
|
||||
public void JumpTo(X86Condition condition, BasicBlock target)
|
||||
{
|
||||
_jumps.Add(new Jump(condition, target, _stream.Position));
|
||||
|
||||
WritePadding(ReservedBytesForJump);
|
||||
}
|
||||
|
||||
public void JumpToNear(X86Condition condition)
|
||||
{
|
||||
_jNearCondition = condition;
|
||||
_jNearPosition = _stream.Position;
|
||||
_jNearLength = Assembler.GetJccLength(0);
|
||||
|
||||
_stream.Seek(_jNearLength, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
public void JumpHere()
|
||||
{
|
||||
long currentPosition = _stream.Position;
|
||||
|
||||
_stream.Seek(_jNearPosition, SeekOrigin.Begin);
|
||||
|
||||
long offset = currentPosition - (_jNearPosition + _jNearLength);
|
||||
|
||||
Debug.Assert(_jNearLength == Assembler.GetJccLength(offset), "Relative offset doesn't fit on near jump.");
|
||||
|
||||
Assembler.Jcc(_jNearCondition, offset);
|
||||
|
||||
_stream.Seek(currentPosition, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
private void WritePadding(int size)
|
||||
{
|
||||
while (size-- > 0)
|
||||
{
|
||||
_stream.WriteByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetCode()
|
||||
{
|
||||
// Write jump relative offsets.
|
||||
bool modified;
|
||||
|
||||
do
|
||||
{
|
||||
modified = false;
|
||||
|
||||
for (int index = 0; index < _jumps.Count; index++)
|
||||
{
|
||||
Jump jump = _jumps[index];
|
||||
|
||||
long jumpTarget = _blockOffsets[jump.Target.Index];
|
||||
|
||||
long offset = jumpTarget - jump.JumpPosition;
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
for (int index2 = index - 1; index2 >= 0; index2--)
|
||||
{
|
||||
Jump jump2 = _jumps[index2];
|
||||
|
||||
if (jump2.JumpPosition < jumpTarget)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
offset -= jump2.InstSize - ReservedBytesForJump;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int index2 = index + 1; index2 < _jumps.Count; index2++)
|
||||
{
|
||||
Jump jump2 = _jumps[index2];
|
||||
|
||||
if (jump2.JumpPosition >= jumpTarget)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
offset += jump2.InstSize - ReservedBytesForJump;
|
||||
}
|
||||
|
||||
offset -= ReservedBytesForJump;
|
||||
}
|
||||
|
||||
if (jump.IsConditional)
|
||||
{
|
||||
jump.InstSize = Assembler.GetJccLength(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
jump.InstSize = Assembler.GetJmpLength(offset);
|
||||
}
|
||||
|
||||
// The jump is relative to the next instruction, not the current one.
|
||||
// Since we didn't know the next instruction address when calculating
|
||||
// the offset (as the size of the current jump instruction was not know),
|
||||
// we now need to compensate the offset with the jump instruction size.
|
||||
// It's also worth to note that:
|
||||
// - This is only needed for backward jumps.
|
||||
// - The GetJmpLength and GetJccLength also compensates the offset
|
||||
// internally when computing the jump instruction size.
|
||||
if (offset < 0)
|
||||
{
|
||||
offset -= jump.InstSize;
|
||||
}
|
||||
|
||||
if (jump.RelativeOffset != offset)
|
||||
{
|
||||
modified = true;
|
||||
}
|
||||
|
||||
jump.RelativeOffset = offset;
|
||||
|
||||
_jumps[index] = jump;
|
||||
}
|
||||
}
|
||||
while (modified);
|
||||
|
||||
// Write the code, ignoring the dummy bytes after jumps, into a new stream.
|
||||
_stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (MemoryStream codeStream = new MemoryStream())
|
||||
{
|
||||
Assembler assembler = new Assembler(codeStream);
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
for (int index = 0; index < _jumps.Count; index++)
|
||||
{
|
||||
Jump jump = _jumps[index];
|
||||
|
||||
buffer = new byte[jump.JumpPosition - _stream.Position];
|
||||
|
||||
_stream.Read(buffer, 0, buffer.Length);
|
||||
_stream.Seek(ReservedBytesForJump, SeekOrigin.Current);
|
||||
|
||||
codeStream.Write(buffer);
|
||||
|
||||
if (jump.IsConditional)
|
||||
{
|
||||
assembler.Jcc(jump.Condition, jump.RelativeOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
assembler.Jmp(jump.RelativeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
buffer = new byte[_stream.Length - _stream.Position];
|
||||
|
||||
_stream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
codeStream.Write(buffer);
|
||||
|
||||
return codeStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1661
ARMeilleure/CodeGen/X86/CodeGenerator.cs
Normal file
1661
ARMeilleure/CodeGen/X86/CodeGenerator.cs
Normal file
File diff suppressed because it is too large
Load diff
52
ARMeilleure/CodeGen/X86/HardwareCapabilities.cs
Normal file
52
ARMeilleure/CodeGen/X86/HardwareCapabilities.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
static class HardwareCapabilities
|
||||
{
|
||||
private delegate ulong GetFeatureInfo();
|
||||
|
||||
private static ulong _featureInfo;
|
||||
|
||||
public static bool SupportsSse3 => (_featureInfo & (1UL << 0)) != 0;
|
||||
public static bool SupportsPclmulqdq => (_featureInfo & (1UL << 1)) != 0;
|
||||
public static bool SupportsSsse3 => (_featureInfo & (1UL << 9)) != 0;
|
||||
public static bool SupportsFma => (_featureInfo & (1UL << 12)) != 0;
|
||||
public static bool SupportsCx16 => (_featureInfo & (1UL << 13)) != 0;
|
||||
public static bool SupportsSse41 => (_featureInfo & (1UL << 19)) != 0;
|
||||
public static bool SupportsSse42 => (_featureInfo & (1UL << 20)) != 0;
|
||||
public static bool SupportsPopcnt => (_featureInfo & (1UL << 23)) != 0;
|
||||
public static bool SupportsAesni => (_featureInfo & (1UL << 25)) != 0;
|
||||
public static bool SupportsAvx => (_featureInfo & (1UL << 28)) != 0;
|
||||
public static bool SupportsF16c => (_featureInfo & (1UL << 29)) != 0;
|
||||
|
||||
public static bool SupportsSse => (_featureInfo & (1UL << 32 + 25)) != 0;
|
||||
public static bool SupportsSse2 => (_featureInfo & (1UL << 32 + 26)) != 0;
|
||||
|
||||
public static bool ForceLegacySse { get; set; }
|
||||
|
||||
public static bool SupportsVexEncoding => !ForceLegacySse && SupportsAvx;
|
||||
|
||||
static HardwareCapabilities()
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
||||
Operand featureInfo = context.CpuId();
|
||||
|
||||
context.Return(featureInfo);
|
||||
|
||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||
|
||||
OperandType[] argTypes = new OperandType[0];
|
||||
|
||||
GetFeatureInfo getFeatureInfo = Compiler.Compile<GetFeatureInfo>(
|
||||
cfg,
|
||||
argTypes,
|
||||
OperandType.I64,
|
||||
CompilerOptions.HighCq);
|
||||
|
||||
_featureInfo = getFeatureInfo();
|
||||
}
|
||||
}
|
||||
}
|
14
ARMeilleure/CodeGen/X86/IntrinsicInfo.cs
Normal file
14
ARMeilleure/CodeGen/X86/IntrinsicInfo.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
struct IntrinsicInfo
|
||||
{
|
||||
public X86Instruction Inst { get; }
|
||||
public IntrinsicType Type { get; }
|
||||
|
||||
public IntrinsicInfo(X86Instruction inst, IntrinsicType type)
|
||||
{
|
||||
Inst = inst;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
160
ARMeilleure/CodeGen/X86/IntrinsicTable.cs
Normal file
160
ARMeilleure/CodeGen/X86/IntrinsicTable.cs
Normal file
|
@ -0,0 +1,160 @@
|
|||
using ARMeilleure.Common;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
static class IntrinsicTable
|
||||
{
|
||||
private const int BadOp = 0;
|
||||
|
||||
private static IntrinsicInfo[] _intrinTable;
|
||||
|
||||
static IntrinsicTable()
|
||||
{
|
||||
_intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))];
|
||||
|
||||
Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Addss, new IntrinsicInfo(X86Instruction.Addss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Andnpd, new IntrinsicInfo(X86Instruction.Andnpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Andnps, new IntrinsicInfo(X86Instruction.Andnps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Cmppd, new IntrinsicInfo(X86Instruction.Cmppd, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Cmpps, new IntrinsicInfo(X86Instruction.Cmpps, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Cmpsd, new IntrinsicInfo(X86Instruction.Cmpsd, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Cmpss, new IntrinsicInfo(X86Instruction.Cmpss, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Comisdeq, new IntrinsicInfo(X86Instruction.Comisd, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Comisdge, new IntrinsicInfo(X86Instruction.Comisd, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Comisdlt, new IntrinsicInfo(X86Instruction.Comisd, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Comisseq, new IntrinsicInfo(X86Instruction.Comiss, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Comissge, new IntrinsicInfo(X86Instruction.Comiss, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Comisslt, new IntrinsicInfo(X86Instruction.Comiss, IntrinsicType.Comis_));
|
||||
Add(Intrinsic.X86Cvtdq2pd, new IntrinsicInfo(X86Instruction.Cvtdq2pd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtdq2ps, new IntrinsicInfo(X86Instruction.Cvtdq2ps, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtpd2dq, new IntrinsicInfo(X86Instruction.Cvtpd2dq, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtpd2ps, new IntrinsicInfo(X86Instruction.Cvtpd2ps, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtps2dq, new IntrinsicInfo(X86Instruction.Cvtps2dq, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtps2pd, new IntrinsicInfo(X86Instruction.Cvtps2pd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Cvtsd2si, new IntrinsicInfo(X86Instruction.Cvtsd2si, IntrinsicType.UnaryToGpr));
|
||||
Add(Intrinsic.X86Cvtsd2ss, new IntrinsicInfo(X86Instruction.Cvtsd2ss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Cvtss2sd, new IntrinsicInfo(X86Instruction.Cvtss2sd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Divpd, new IntrinsicInfo(X86Instruction.Divpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Divps, new IntrinsicInfo(X86Instruction.Divps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Divsd, new IntrinsicInfo(X86Instruction.Divsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Divss, new IntrinsicInfo(X86Instruction.Divss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Haddpd, new IntrinsicInfo(X86Instruction.Haddpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Haddps, new IntrinsicInfo(X86Instruction.Haddps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Maxpd, new IntrinsicInfo(X86Instruction.Maxpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Maxps, new IntrinsicInfo(X86Instruction.Maxps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Maxsd, new IntrinsicInfo(X86Instruction.Maxsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Maxss, new IntrinsicInfo(X86Instruction.Maxss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Minpd, new IntrinsicInfo(X86Instruction.Minpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Minps, new IntrinsicInfo(X86Instruction.Minps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Minsd, new IntrinsicInfo(X86Instruction.Minsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Minss, new IntrinsicInfo(X86Instruction.Minss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Movhlps, new IntrinsicInfo(X86Instruction.Movhlps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Movlhps, new IntrinsicInfo(X86Instruction.Movlhps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Mulpd, new IntrinsicInfo(X86Instruction.Mulpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Mulps, new IntrinsicInfo(X86Instruction.Mulps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Mulsd, new IntrinsicInfo(X86Instruction.Mulsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Mulss, new IntrinsicInfo(X86Instruction.Mulss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Paddb, new IntrinsicInfo(X86Instruction.Paddb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Paddd, new IntrinsicInfo(X86Instruction.Paddd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Paddq, new IntrinsicInfo(X86Instruction.Paddq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Paddw, new IntrinsicInfo(X86Instruction.Paddw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pand, new IntrinsicInfo(X86Instruction.Pand, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pandn, new IntrinsicInfo(X86Instruction.Pandn, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pavgb, new IntrinsicInfo(X86Instruction.Pavgb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pavgw, new IntrinsicInfo(X86Instruction.Pavgw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pblendvb, new IntrinsicInfo(X86Instruction.Pblendvb, IntrinsicType.Ternary));
|
||||
Add(Intrinsic.X86Pcmpeqb, new IntrinsicInfo(X86Instruction.Pcmpeqb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpeqd, new IntrinsicInfo(X86Instruction.Pcmpeqd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpeqq, new IntrinsicInfo(X86Instruction.Pcmpeqq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpeqw, new IntrinsicInfo(X86Instruction.Pcmpeqw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpgtb, new IntrinsicInfo(X86Instruction.Pcmpgtb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpgtd, new IntrinsicInfo(X86Instruction.Pcmpgtd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpgtq, new IntrinsicInfo(X86Instruction.Pcmpgtq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pcmpgtw, new IntrinsicInfo(X86Instruction.Pcmpgtw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxsb, new IntrinsicInfo(X86Instruction.Pmaxsb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxsd, new IntrinsicInfo(X86Instruction.Pmaxsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxsw, new IntrinsicInfo(X86Instruction.Pmaxsw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxub, new IntrinsicInfo(X86Instruction.Pmaxub, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxud, new IntrinsicInfo(X86Instruction.Pmaxud, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmaxuw, new IntrinsicInfo(X86Instruction.Pmaxuw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminsb, new IntrinsicInfo(X86Instruction.Pminsb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminsd, new IntrinsicInfo(X86Instruction.Pminsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminsw, new IntrinsicInfo(X86Instruction.Pminsw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminub, new IntrinsicInfo(X86Instruction.Pminub, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminud, new IntrinsicInfo(X86Instruction.Pminud, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pminuw, new IntrinsicInfo(X86Instruction.Pminuw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmovsxbw, new IntrinsicInfo(X86Instruction.Pmovsxbw, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmovsxdq, new IntrinsicInfo(X86Instruction.Pmovsxdq, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmovsxwd, new IntrinsicInfo(X86Instruction.Pmovsxwd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmovzxbw, new IntrinsicInfo(X86Instruction.Pmovzxbw, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmovzxdq, new IntrinsicInfo(X86Instruction.Pmovzxdq, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmovzxwd, new IntrinsicInfo(X86Instruction.Pmovzxwd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Pmulld, new IntrinsicInfo(X86Instruction.Pmulld, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pmullw, new IntrinsicInfo(X86Instruction.Pmullw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Popcnt, new IntrinsicInfo(X86Instruction.Popcnt, IntrinsicType.PopCount));
|
||||
Add(Intrinsic.X86Por, new IntrinsicInfo(X86Instruction.Por, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pshufb, new IntrinsicInfo(X86Instruction.Pshufb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pslld, new IntrinsicInfo(X86Instruction.Pslld, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pslldq, new IntrinsicInfo(X86Instruction.Pslldq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psllq, new IntrinsicInfo(X86Instruction.Psllq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psllw, new IntrinsicInfo(X86Instruction.Psllw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psrad, new IntrinsicInfo(X86Instruction.Psrad, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psraw, new IntrinsicInfo(X86Instruction.Psraw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psrld, new IntrinsicInfo(X86Instruction.Psrld, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psrlq, new IntrinsicInfo(X86Instruction.Psrlq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psrldq, new IntrinsicInfo(X86Instruction.Psrldq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psrlw, new IntrinsicInfo(X86Instruction.Psrlw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psubb, new IntrinsicInfo(X86Instruction.Psubb, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psubd, new IntrinsicInfo(X86Instruction.Psubd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psubq, new IntrinsicInfo(X86Instruction.Psubq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Psubw, new IntrinsicInfo(X86Instruction.Psubw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpckhbw, new IntrinsicInfo(X86Instruction.Punpckhbw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpckhdq, new IntrinsicInfo(X86Instruction.Punpckhdq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpckhqdq, new IntrinsicInfo(X86Instruction.Punpckhqdq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpckhwd, new IntrinsicInfo(X86Instruction.Punpckhwd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpcklbw, new IntrinsicInfo(X86Instruction.Punpcklbw, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpckldq, new IntrinsicInfo(X86Instruction.Punpckldq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpcklqdq, new IntrinsicInfo(X86Instruction.Punpcklqdq, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Punpcklwd, new IntrinsicInfo(X86Instruction.Punpcklwd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Pxor, new IntrinsicInfo(X86Instruction.Pxor, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Rcpps, new IntrinsicInfo(X86Instruction.Rcpps, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Rcpss, new IntrinsicInfo(X86Instruction.Rcpss, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Roundpd, new IntrinsicInfo(X86Instruction.Roundpd, IntrinsicType.BinaryImm));
|
||||
Add(Intrinsic.X86Roundps, new IntrinsicInfo(X86Instruction.Roundps, IntrinsicType.BinaryImm));
|
||||
Add(Intrinsic.X86Roundsd, new IntrinsicInfo(X86Instruction.Roundsd, IntrinsicType.BinaryImm));
|
||||
Add(Intrinsic.X86Roundss, new IntrinsicInfo(X86Instruction.Roundss, IntrinsicType.BinaryImm));
|
||||
Add(Intrinsic.X86Rsqrtps, new IntrinsicInfo(X86Instruction.Rsqrtps, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Rsqrtss, new IntrinsicInfo(X86Instruction.Rsqrtss, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Shufpd, new IntrinsicInfo(X86Instruction.Shufpd, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Shufps, new IntrinsicInfo(X86Instruction.Shufps, IntrinsicType.TernaryImm));
|
||||
Add(Intrinsic.X86Sqrtpd, new IntrinsicInfo(X86Instruction.Sqrtpd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Sqrtps, new IntrinsicInfo(X86Instruction.Sqrtps, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Sqrtsd, new IntrinsicInfo(X86Instruction.Sqrtsd, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Sqrtss, new IntrinsicInfo(X86Instruction.Sqrtss, IntrinsicType.Unary));
|
||||
Add(Intrinsic.X86Subpd, new IntrinsicInfo(X86Instruction.Subpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Subps, new IntrinsicInfo(X86Instruction.Subps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Subsd, new IntrinsicInfo(X86Instruction.Subsd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Subss, new IntrinsicInfo(X86Instruction.Subss, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Unpckhpd, new IntrinsicInfo(X86Instruction.Unpckhpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Unpckhps, new IntrinsicInfo(X86Instruction.Unpckhps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Unpcklpd, new IntrinsicInfo(X86Instruction.Unpcklpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Unpcklps, new IntrinsicInfo(X86Instruction.Unpcklps, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary));
|
||||
Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary));
|
||||
}
|
||||
|
||||
private static void Add(Intrinsic intrin, IntrinsicInfo info)
|
||||
{
|
||||
_intrinTable[(int)intrin] = info;
|
||||
}
|
||||
|
||||
public static IntrinsicInfo GetInfo(Intrinsic intrin)
|
||||
{
|
||||
return _intrinTable[(int)intrin];
|
||||
}
|
||||
}
|
||||
}
|
14
ARMeilleure/CodeGen/X86/IntrinsicType.cs
Normal file
14
ARMeilleure/CodeGen/X86/IntrinsicType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum IntrinsicType
|
||||
{
|
||||
Comis_,
|
||||
PopCount,
|
||||
Unary,
|
||||
UnaryToGpr,
|
||||
Binary,
|
||||
BinaryImm,
|
||||
Ternary,
|
||||
TernaryImm
|
||||
}
|
||||
}
|
1280
ARMeilleure/CodeGen/X86/PreAllocator.cs
Normal file
1280
ARMeilleure/CodeGen/X86/PreAllocator.cs
Normal file
File diff suppressed because it is too large
Load diff
22
ARMeilleure/CodeGen/X86/X86Condition.cs
Normal file
22
ARMeilleure/CodeGen/X86/X86Condition.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum X86Condition
|
||||
{
|
||||
Overflow = 0x0,
|
||||
NotOverflow = 0x1,
|
||||
Below = 0x2,
|
||||
AboveOrEqual = 0x3,
|
||||
Equal = 0x4,
|
||||
NotEqual = 0x5,
|
||||
BelowOrEqual = 0x6,
|
||||
Above = 0x7,
|
||||
Sign = 0x8,
|
||||
NotSign = 0x9,
|
||||
ParityEven = 0xa,
|
||||
ParityOdd = 0xb,
|
||||
Less = 0xc,
|
||||
GreaterOrEqual = 0xd,
|
||||
LessOrEqual = 0xe,
|
||||
Greater = 0xf
|
||||
}
|
||||
}
|
190
ARMeilleure/CodeGen/X86/X86Instruction.cs
Normal file
190
ARMeilleure/CodeGen/X86/X86Instruction.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum X86Instruction
|
||||
{
|
||||
Add,
|
||||
Addpd,
|
||||
Addps,
|
||||
Addsd,
|
||||
Addss,
|
||||
And,
|
||||
Andnpd,
|
||||
Andnps,
|
||||
Bsr,
|
||||
Bswap,
|
||||
Call,
|
||||
Cmovcc,
|
||||
Cmp,
|
||||
Cmppd,
|
||||
Cmpps,
|
||||
Cmpsd,
|
||||
Cmpss,
|
||||
Cmpxchg16b,
|
||||
Comisd,
|
||||
Comiss,
|
||||
Cpuid,
|
||||
Cvtdq2pd,
|
||||
Cvtdq2ps,
|
||||
Cvtpd2dq,
|
||||
Cvtpd2ps,
|
||||
Cvtps2dq,
|
||||
Cvtps2pd,
|
||||
Cvtsd2si,
|
||||
Cvtsd2ss,
|
||||
Cvtsi2sd,
|
||||
Cvtsi2ss,
|
||||
Cvtss2sd,
|
||||
Div,
|
||||
Divpd,
|
||||
Divps,
|
||||
Divsd,
|
||||
Divss,
|
||||
Haddpd,
|
||||
Haddps,
|
||||
Idiv,
|
||||
Imul,
|
||||
Imul128,
|
||||
Insertps,
|
||||
Lea,
|
||||
Maxpd,
|
||||
Maxps,
|
||||
Maxsd,
|
||||
Maxss,
|
||||
Minpd,
|
||||
Minps,
|
||||
Minsd,
|
||||
Minss,
|
||||
Mov,
|
||||
Mov16,
|
||||
Mov8,
|
||||
Movd,
|
||||
Movdqu,
|
||||
Movhlps,
|
||||
Movlhps,
|
||||
Movq,
|
||||
Movsd,
|
||||
Movss,
|
||||
Movsx16,
|
||||
Movsx32,
|
||||
Movsx8,
|
||||
Movzx16,
|
||||
Movzx8,
|
||||
Mul128,
|
||||
Mulpd,
|
||||
Mulps,
|
||||
Mulsd,
|
||||
Mulss,
|
||||
Neg,
|
||||
Not,
|
||||
Or,
|
||||
Paddb,
|
||||
Paddd,
|
||||
Paddq,
|
||||
Paddw,
|
||||
Pand,
|
||||
Pandn,
|
||||
Pavgb,
|
||||
Pavgw,
|
||||
Pblendvb,
|
||||
Pcmpeqb,
|
||||
Pcmpeqd,
|
||||
Pcmpeqq,
|
||||
Pcmpeqw,
|
||||
Pcmpgtb,
|
||||
Pcmpgtd,
|
||||
Pcmpgtq,
|
||||
Pcmpgtw,
|
||||
Pextrb,
|
||||
Pextrd,
|
||||
Pextrq,
|
||||
Pextrw,
|
||||
Pinsrb,
|
||||
Pinsrd,
|
||||
Pinsrq,
|
||||
Pinsrw,
|
||||
Pmaxsb,
|
||||
Pmaxsd,
|
||||
Pmaxsw,
|
||||
Pmaxub,
|
||||
Pmaxud,
|
||||
Pmaxuw,
|
||||
Pminsb,
|
||||
Pminsd,
|
||||
Pminsw,
|
||||
Pminub,
|
||||
Pminud,
|
||||
Pminuw,
|
||||
Pmovsxbw,
|
||||
Pmovsxdq,
|
||||
Pmovsxwd,
|
||||
Pmovzxbw,
|
||||
Pmovzxdq,
|
||||
Pmovzxwd,
|
||||
Pmulld,
|
||||
Pmullw,
|
||||
Pop,
|
||||
Popcnt,
|
||||
Por,
|
||||
Pshufb,
|
||||
Pshufd,
|
||||
Pslld,
|
||||
Pslldq,
|
||||
Psllq,
|
||||
Psllw,
|
||||
Psrad,
|
||||
Psraw,
|
||||
Psrld,
|
||||
Psrlq,
|
||||
Psrldq,
|
||||
Psrlw,
|
||||
Psubb,
|
||||
Psubd,
|
||||
Psubq,
|
||||
Psubw,
|
||||
Punpckhbw,
|
||||
Punpckhdq,
|
||||
Punpckhqdq,
|
||||
Punpckhwd,
|
||||
Punpcklbw,
|
||||
Punpckldq,
|
||||
Punpcklqdq,
|
||||
Punpcklwd,
|
||||
Push,
|
||||
Pxor,
|
||||
Rcpps,
|
||||
Rcpss,
|
||||
Ror,
|
||||
Roundpd,
|
||||
Roundps,
|
||||
Roundsd,
|
||||
Roundss,
|
||||
Rsqrtps,
|
||||
Rsqrtss,
|
||||
Sar,
|
||||
Setcc,
|
||||
Shl,
|
||||
Shr,
|
||||
Shufpd,
|
||||
Shufps,
|
||||
Sqrtpd,
|
||||
Sqrtps,
|
||||
Sqrtsd,
|
||||
Sqrtss,
|
||||
Sub,
|
||||
Subpd,
|
||||
Subps,
|
||||
Subsd,
|
||||
Subss,
|
||||
Test,
|
||||
Unpckhpd,
|
||||
Unpckhps,
|
||||
Unpcklpd,
|
||||
Unpcklps,
|
||||
Vpblendvb,
|
||||
Xor,
|
||||
Xorpd,
|
||||
Xorps,
|
||||
|
||||
Count
|
||||
}
|
||||
}
|
41
ARMeilleure/CodeGen/X86/X86Register.cs
Normal file
41
ARMeilleure/CodeGen/X86/X86Register.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum X86Register
|
||||
{
|
||||
Invalid = -1,
|
||||
|
||||
Rax = 0,
|
||||
Rcx = 1,
|
||||
Rdx = 2,
|
||||
Rbx = 3,
|
||||
Rsp = 4,
|
||||
Rbp = 5,
|
||||
Rsi = 6,
|
||||
Rdi = 7,
|
||||
R8 = 8,
|
||||
R9 = 9,
|
||||
R10 = 10,
|
||||
R11 = 11,
|
||||
R12 = 12,
|
||||
R13 = 13,
|
||||
R14 = 14,
|
||||
R15 = 15,
|
||||
|
||||
Xmm0 = 0,
|
||||
Xmm1 = 1,
|
||||
Xmm2 = 2,
|
||||
Xmm3 = 3,
|
||||
Xmm4 = 4,
|
||||
Xmm5 = 5,
|
||||
Xmm6 = 6,
|
||||
Xmm7 = 7,
|
||||
Xmm8 = 8,
|
||||
Xmm9 = 9,
|
||||
Xmm10 = 10,
|
||||
Xmm11 = 11,
|
||||
Xmm12 = 12,
|
||||
Xmm13 = 13,
|
||||
Xmm14 = 14,
|
||||
Xmm15 = 15
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue