Fix SSE2 VectorInsert8 path, and other fixes

This commit is contained in:
gdkchan 2019-07-27 23:23:55 -03:00
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 dividend = operation.GetSource(0);
Operand divisor = operation.GetSource(1); Operand divisor = operation.GetSource(1);
ValidateBinOp(dest, dividend, divisor); if (!dest.Type.IsInteger())
{
ValidateBinOp(dest, dividend, divisor);
}
if (dest.Type.IsInteger()) if (dest.Type.IsInteger())
{ {

View file

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

View file

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