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 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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace ARMeilleure.IntermediateRepresentation
|
namespace ARMeilleure.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
class Operation : Node
|
class Operation : Node
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue