diff options
Diffstat (limited to 'ARMeilleure/CodeGen')
-rw-r--r-- | ARMeilleure/CodeGen/Optimizations/Optimizer.cs | 4 | ||||
-rw-r--r-- | ARMeilleure/CodeGen/X86/Assembler.cs | 16 | ||||
-rw-r--r-- | ARMeilleure/CodeGen/X86/CodeGenerator.cs | 28 | ||||
-rw-r--r-- | ARMeilleure/CodeGen/X86/PreAllocator.cs | 6 | ||||
-rw-r--r-- | ARMeilleure/CodeGen/X86/X86Instruction.cs | 1 |
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, |