aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/CodeGen')
-rw-r--r--ARMeilleure/CodeGen/Optimizations/Optimizer.cs4
-rw-r--r--ARMeilleure/CodeGen/X86/Assembler.cs16
-rw-r--r--ARMeilleure/CodeGen/X86/CodeGenerator.cs28
-rw-r--r--ARMeilleure/CodeGen/X86/PreAllocator.cs6
-rw-r--r--ARMeilleure/CodeGen/X86/X86Instruction.cs1
5 files changed, 52 insertions, 3 deletions
diff --git a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
index 8b0c75fd..06118bfd 100644
--- a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
+++ b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
@@ -138,7 +138,9 @@ namespace ARMeilleure.CodeGen.Optimizations
{
return (node is Operation operation) && (operation.Instruction == Instruction.Call
|| operation.Instruction == Instruction.Tailcall
- || operation.Instruction == Instruction.CompareAndSwap);
+ || operation.Instruction == Instruction.CompareAndSwap
+ || operation.Instruction == Instruction.CompareAndSwap16
+ || operation.Instruction == Instruction.CompareAndSwap8);
}
private static bool IsPropagableCopy(Operation operation)
diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs
index d0ccd6f8..b855f1b1 100644
--- a/ARMeilleure/CodeGen/X86/Assembler.cs
+++ b/ARMeilleure/CodeGen/X86/Assembler.cs
@@ -101,6 +101,7 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Cmpss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc2, InstructionFlags.Vex | InstructionFlags.PrefixF3));
Add(X86Instruction.Cmpxchg, new InstructionInfo(0x00000fb1, BadOp, BadOp, BadOp, BadOp, InstructionFlags.None));
Add(X86Instruction.Cmpxchg16b, new InstructionInfo(0x01000fc7, BadOp, BadOp, BadOp, BadOp, InstructionFlags.RexW));
+ Add(X86Instruction.Cmpxchg8, new InstructionInfo(0x00000fb0, BadOp, BadOp, BadOp, BadOp, InstructionFlags.Reg8Src));
Add(X86Instruction.Comisd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2f, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Comiss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2f, InstructionFlags.Vex));
Add(X86Instruction.Cpuid, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fa2, InstructionFlags.RegOnly));
@@ -353,6 +354,14 @@ namespace ARMeilleure.CodeGen.X86
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
}
+ public void Cmpxchg16(MemoryOperand memOp, Operand src)
+ {
+ WriteByte(LockPrefix);
+ WriteByte(0x66);
+
+ WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
+ }
+
public void Cmpxchg16b(MemoryOperand memOp)
{
WriteByte(LockPrefix);
@@ -360,6 +369,13 @@ namespace ARMeilleure.CodeGen.X86
WriteInstruction(memOp, null, OperandType.None, X86Instruction.Cmpxchg16b);
}
+ public void Cmpxchg8(MemoryOperand memOp, Operand src)
+ {
+ WriteByte(LockPrefix);
+
+ WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg8);
+ }
+
public void Comisd(Operand src1, Operand src2)
{
WriteInstruction(src1, null, src2, X86Instruction.Comisd);
diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
index 5c9fcd89..f04be52d 100644
--- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs
+++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
@@ -39,6 +39,8 @@ namespace ARMeilleure.CodeGen.X86
Add(Instruction.Call, GenerateCall);
Add(Instruction.Clobber, GenerateClobber);
Add(Instruction.CompareAndSwap, GenerateCompareAndSwap);
+ Add(Instruction.CompareAndSwap16, GenerateCompareAndSwap16);
+ Add(Instruction.CompareAndSwap8, GenerateCompareAndSwap8);
Add(Instruction.CompareEqual, GenerateCompareEqual);
Add(Instruction.CompareGreater, GenerateCompareGreater);
Add(Instruction.CompareGreaterOrEqual, GenerateCompareGreaterOrEqual);
@@ -587,6 +589,32 @@ namespace ARMeilleure.CodeGen.X86
}
}
+ private static void GenerateCompareAndSwap16(CodeGenContext context, Operation operation)
+ {
+ Operand src1 = operation.GetSource(0);
+ Operand src2 = operation.GetSource(1);
+ Operand src3 = operation.GetSource(2);
+
+ EnsureSameType(src2, src3);
+
+ MemoryOperand memOp = MemoryOp(src3.Type, src1);
+
+ context.Assembler.Cmpxchg16(memOp, src3);
+ }
+
+ private static void GenerateCompareAndSwap8(CodeGenContext context, Operation operation)
+ {
+ Operand src1 = operation.GetSource(0);
+ Operand src2 = operation.GetSource(1);
+ Operand src3 = operation.GetSource(2);
+
+ EnsureSameType(src2, src3);
+
+ MemoryOperand memOp = MemoryOp(src3.Type, src1);
+
+ context.Assembler.Cmpxchg8(memOp, src3);
+ }
+
private static void GenerateCompareEqual(CodeGenContext context, Operation operation)
{
GenerateCompare(context, operation, X86Condition.Equal);
diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs
index dc7f3a75..b76e9416 100644
--- a/ARMeilleure/CodeGen/X86/PreAllocator.cs
+++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs
@@ -101,7 +101,7 @@ namespace ARMeilleure.CodeGen.X86
if (callConv == CallConvName.Windows)
{
HandleTailcallWindowsAbi(block.Operations, stackAlloc, node, operation);
- }
+ }
else
{
HandleTailcallSystemVAbi(block.Operations, stackAlloc, node, operation);
@@ -207,6 +207,8 @@ namespace ARMeilleure.CodeGen.X86
switch (operation.Instruction)
{
case Instruction.CompareAndSwap:
+ case Instruction.CompareAndSwap16:
+ case Instruction.CompareAndSwap8:
{
OperandType type = operation.GetSource(1).Type;
@@ -887,7 +889,7 @@ namespace ARMeilleure.CodeGen.X86
HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
sources.Add(argReg);
- }
+ }
else
{
throw new NotImplementedException("Spilling is not currently supported for tail calls. (too many arguments)");
diff --git a/ARMeilleure/CodeGen/X86/X86Instruction.cs b/ARMeilleure/CodeGen/X86/X86Instruction.cs
index 9ac17e5b..f9b35d37 100644
--- a/ARMeilleure/CodeGen/X86/X86Instruction.cs
+++ b/ARMeilleure/CodeGen/X86/X86Instruction.cs
@@ -30,6 +30,7 @@ namespace ARMeilleure.CodeGen.X86
Cmpss,
Cmpxchg,
Cmpxchg16b,
+ Cmpxchg8,
Comisd,
Comiss,
Cpuid,