Implement inline memory load/store exclusive and ordered (#1413)
* Implement inline memory load/store exclusive * Fix missing REX prefix on 8-bits CMPXCHG * Increment PTC version due to bugfix * Remove redundant memory checks * Address PR feedback * Increment PPTC version
This commit is contained in:
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)");
|
||||
|
@ -30,6 +30,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Cmpss,
|
||||
Cmpxchg,
|
||||
Cmpxchg16b,
|
||||
Cmpxchg8,
|
||||
Comisd,
|
||||
Comiss,
|
||||
Cpuid,
|
||||
|
Reference in New Issue
Block a user