Fix SSE2 VectorInsert8 path, and other fixes

This commit is contained in:
gdkchan 2019-07-27 23:23:55 -03:00
parent 36be15fe6c
commit a3ea200444
4 changed files with 79 additions and 54 deletions

View file

@ -696,7 +696,10 @@ namespace ARMeilleure.CodeGen.X86
Operand dividend = operation.GetSource(0);
Operand divisor = operation.GetSource(1);
ValidateBinOp(dest, dividend, divisor);
if (!dest.Type.IsInteger())
{
ValidateBinOp(dest, dividend, divisor);
}
if (dest.Type.IsInteger())
{

View file

@ -502,36 +502,29 @@ namespace ARMeilleure.CodeGen.X86
LLNode currentNode = node;
Operand temp = Local(OperandType.I32);
Operand temp1 = Local(OperandType.I32);
Operand temp2 = Local(OperandType.I32);
Operation vextOp = new Operation(Instruction.VectorExtract16, temp, src1, Const(index >> 1));
node = nodes.AddAfter(node, new Operation(Instruction.Copy, temp2, src2));
Operation vextOp = new Operation(Instruction.VectorExtract16, temp1, src1, Const(index >> 1));
node = nodes.AddAfter(node, vextOp);
if ((index & 1) != 0)
{
Operand temp2 = Local(OperandType.I32);
Operation copyOp = new Operation(Instruction.Copy, temp2, src2);
Operation andOp = new Operation(Instruction.ZeroExtend8, temp, temp);
Operation shlOp = new Operation(Instruction.ShiftLeft, temp2, temp2, Const(8));
Operation orOp = new Operation(Instruction.BitwiseOr, temp, temp, temp2);
node = nodes.AddAfter(node, copyOp);
node = nodes.AddAfter(node, andOp);
node = nodes.AddAfter(node, shlOp);
node = nodes.AddAfter(node, orOp);
node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp1, temp1));
node = nodes.AddAfter(node, new Operation(Instruction.ShiftLeft, temp2, temp2, Const(8)));
node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2));
}
else
{
Operation andOp = new Operation(Instruction.BitwiseAnd, temp, temp, Const(0xff00));
Operation orOp = new Operation(Instruction.BitwiseOr, temp, temp, src2);
node = nodes.AddAfter(node, andOp);
node = nodes.AddAfter(node, orOp);
node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp2, temp2));
node = nodes.AddAfter(node, new Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00)));
node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2));
}
Operation vinsOp = new Operation(Instruction.VectorInsert16, dest, src1, temp, Const(index >> 1));
Operation vinsOp = new Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1));
node = nodes.AddAfter(node, vinsOp);

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
namespace ARMeilleure.IntermediateRepresentation
@ -43,7 +44,7 @@ namespace ARMeilleure.IntermediateRepresentation
public Node(Operand[] destinations, int sourcesCount)
{
SetDestinations(destinations);
SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations)));
_sources = new Operand[sourcesCount];
@ -62,69 +63,99 @@ namespace ARMeilleure.IntermediateRepresentation
public void SetDestination(int index, Operand destination)
{
Set(_destinations, _asgUseNodes, index, destination);
Operand oldOp = _destinations[index];
if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable)
{
oldOp.Assignments.Remove(_asgUseNodes[index]);
}
if (destination != null && destination.Kind == OperandKind.LocalVariable)
{
_asgUseNodes[index] = destination.Assignments.AddLast(this);
}
_destinations[index] = destination;
}
public void SetSource(int index, Operand source)
{
Set(_sources, _srcUseNodes, index, source);
}
private void Set(Operand[] ops, LinkedListNode<Node>[] uses, int index, Operand newOp)
{
Operand oldOp = ops[index];
Operand oldOp = _sources[index];
if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable)
{
oldOp.Uses.Remove(uses[index]);
oldOp.Uses.Remove(_srcUseNodes[index]);
}
if (newOp != null && newOp.Kind == OperandKind.LocalVariable)
if (source != null && source.Kind == OperandKind.LocalVariable)
{
uses[index] = newOp.Uses.AddLast(this);
_srcUseNodes[index] = source.Uses.AddLast(this);
}
ops[index] = newOp;
_sources[index] = source;
}
public void SetDestinations(Operand[] destinations)
{
Set(ref _destinations, ref _asgUseNodes, destinations);
if (_destinations != null)
{
for (int index = 0; index < _destinations.Length; index++)
{
Operand oldOp = _destinations[index];
if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable)
{
oldOp.Assignments.Remove(_asgUseNodes[index]);
}
}
_destinations = destinations;
}
else
{
_destinations = new Operand[destinations.Length];
}
_asgUseNodes = new LinkedListNode<Node>[destinations.Length];
for (int index = 0; index < destinations.Length; index++)
{
Operand newOp = destinations[index];
_destinations[index] = newOp;
if (newOp.Kind == OperandKind.LocalVariable)
{
_asgUseNodes[index] = newOp.Assignments.AddLast(this);
}
}
}
public void SetSources(Operand[] sources)
{
Set(ref _sources, ref _srcUseNodes, sources);
}
private void Set(ref Operand[] ops, ref LinkedListNode<Node>[] uses, Operand[] newOps)
{
if (ops != null)
for (int index = 0; index < _sources.Length; index++)
{
for (int index = 0; index < ops.Length; index++)
{
Operand oldOp = ops[index];
Operand oldOp = _sources[index];
if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable)
{
oldOp.Uses.Remove(uses[index]);
}
if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable)
{
oldOp.Uses.Remove(_srcUseNodes[index]);
}
}
ops = new Operand[newOps.Length];
_sources = new Operand[sources.Length];
uses = new LinkedListNode<Node>[newOps.Length];
_srcUseNodes = new LinkedListNode<Node>[sources.Length];
for (int index = 0; index < newOps.Length; index++)
for (int index = 0; index < sources.Length; index++)
{
Operand newOp = newOps[index];
Operand newOp = sources[index];
ops[index] = newOp;
_sources[index] = newOp;
if (newOp.Kind == OperandKind.LocalVariable)
{
uses[index] = newOp.Uses.AddLast(this);
_srcUseNodes[index] = newOp.Uses.AddLast(this);
}
}
}

View file

@ -1,5 +1,3 @@
using System.Collections.Generic;
namespace ARMeilleure.IntermediateRepresentation
{
class Operation : Node