Fix SSE2 VectorInsert8 path, and other fixes
This commit is contained in:
parent
36be15fe6c
commit
a3ea200444
4 changed files with 79 additions and 54 deletions
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
class Operation : Node
|
||||
|
|
Loading…
Add table
Reference in a new issue