Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARMeilleure: replace else-ifs with switch statements #124

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1445,17 +1445,16 @@ private static bool TryPairMemoryOp(CodeGenContext context, Operation currentOp,
return false;
}

if (currentOp.Instruction == Instruction.Load)
switch (currentOp.Instruction)
{
context.Assembler.LdpRiUn(currentOp.Destination, nextOp.Destination, op1Base, op1Offset);
}
else if (currentOp.Instruction == Instruction.Store)
{
context.Assembler.StpRiUn(currentOp.GetSource(1), nextOp.GetSource(1), op1Base, op1Offset);
}
else
{
return false;
case Instruction.Load:
context.Assembler.LdpRiUn(currentOp.Destination, nextOp.Destination, op1Base, op1Offset);
break;
case Instruction.Store:
context.Assembler.StpRiUn(currentOp.GetSource(1), nextOp.GetSource(1), op1Base, op1Offset);
break;
default:
return false;
}

return true;
Expand Down
17 changes: 7 additions & 10 deletions src/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,17 +1099,14 @@ private void AddIntervalCallerSavedReg(int mask, int operationPos, RegisterType

private static int GetOperandId(Operand operand)
{
if (operand.Kind == OperandKind.LocalVariable)
switch (operand.Kind)
{
return operand.GetLocalNumber();
}
else if (operand.Kind == OperandKind.Register)
{
return GetRegisterId(operand.GetRegister());
}
else
{
throw new ArgumentException($"Invalid operand kind \"{operand.Kind}\".");
case OperandKind.LocalVariable:
return operand.GetLocalNumber();
case OperandKind.Register:
return GetRegisterId(operand.GetRegister());
default:
throw new ArgumentException($"Invalid operand kind \"{operand.Kind}\".");
}
}

Expand Down
17 changes: 7 additions & 10 deletions src/ARMeilleure/CodeGen/RegisterAllocators/RegisterMasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,14 @@ public RegisterMasks(

public int GetAvailableRegisters(RegisterType type)
{
if (type == RegisterType.Integer)
switch (type)
{
return IntAvailableRegisters;
}
else if (type == RegisterType.Vector)
{
return VecAvailableRegisters;
}
else
{
throw new ArgumentException($"Invalid register type \"{type}\".");
case RegisterType.Integer:
return IntAvailableRegisters;
case RegisterType.Vector:
return VecAvailableRegisters;
default:
throw new ArgumentException($"Invalid register type \"{type}\".");
}
}
}
Expand Down
233 changes: 125 additions & 108 deletions src/ARMeilleure/CodeGen/X86/Assembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -754,73 +754,79 @@ private void WriteInstruction(Operand dest, Operand source, OperandType type, X8

if (source != default)
{
if (source.Kind == OperandKind.Constant)
switch (source.Kind)
{
ulong imm = source.Value;
case OperandKind.Constant:
ulong imm = source.Value;

if (inst == X86Instruction.Mov8)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);
if (inst == X86Instruction.Mov8)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);

WriteByte((byte)imm);
}
else if (inst == X86Instruction.Mov16)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);
WriteByte((byte)imm);
}
else if (inst == X86Instruction.Mov16)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);

WriteInt16((short)imm);
}
else if (IsImm8(imm, type) && info.OpRMImm8 != BadOp)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);
WriteInt16((short)imm);
}
else if (IsImm8(imm, type) && info.OpRMImm8 != BadOp)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);

WriteByte((byte)imm);
}
else if (!source.Relocatable && IsImm32(imm, type) && info.OpRMImm32 != BadOp)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);
WriteByte((byte)imm);
}
else if (!source.Relocatable && IsImm32(imm, type) && info.OpRMImm32 != BadOp)
{
WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);

WriteInt32((int)imm);
}
else if (dest != default && dest.Kind == OperandKind.Register && info.OpRImm64 != BadOp)
{
int rexPrefix = GetRexPrefix(dest, source, type, rrm: false);
WriteInt32((int)imm);
}
else if (dest != default && dest.Kind == OperandKind.Register && info.OpRImm64 != BadOp)
{
int rexPrefix = GetRexPrefix(dest, source, type, rrm: false);

if (rexPrefix != 0)
{
WriteByte((byte)rexPrefix);
}

WriteByte((byte)(info.OpRImm64 + (dest.GetRegister().Index & 0b111)));

if (rexPrefix != 0)
if (HasRelocs && source.Relocatable)
{
_relocs.Add(new Reloc
{
JumpIndex = _jumps.Count - 1,
Position = (int)_stream.Position,
Symbol = source.Symbol,
});
}

WriteUInt64(imm);
}
else
{
WriteByte((byte)rexPrefix);
throw new ArgumentException($"Failed to encode constant 0x{imm:X}.");
}

WriteByte((byte)(info.OpRImm64 + (dest.GetRegister().Index & 0b111)));
break;

if (HasRelocs && source.Relocatable)
case OperandKind.Register when info.OpRMR != BadOp:
WriteOpCode(dest, default, source, type, info.Flags, info.OpRMR);
break;
default:
if (info.OpRRM != BadOp)
{
_relocs.Add(new Reloc
{
JumpIndex = _jumps.Count - 1,
Position = (int)_stream.Position,
Symbol = source.Symbol,
});
WriteOpCode(dest, default, source, type, info.Flags, info.OpRRM, rrm: true);
}
else
{
throw new ArgumentException($"Invalid source operand kind \"{source.Kind}\".");
}

WriteUInt64(imm);
}
else
{
throw new ArgumentException($"Failed to encode constant 0x{imm:X}.");
}
}
else if (source.Kind == OperandKind.Register && info.OpRMR != BadOp)
{
WriteOpCode(dest, default, source, type, info.Flags, info.OpRMR);
}
else if (info.OpRRM != BadOp)
{
WriteOpCode(dest, default, source, type, info.Flags, info.OpRRM, rrm: true);
}
else
{
throw new ArgumentException($"Invalid source operand kind \"{source.Kind}\".");
break;
}
}
else if (info.OpRRM != BadOp)
Expand Down Expand Up @@ -848,32 +854,39 @@ private void WriteInstruction(

if (src2 != default)
{
if (src2.Kind == OperandKind.Constant)
switch (src2.Kind)
{
ulong imm = src2.Value;
case OperandKind.Constant:
ulong imm = src2.Value;

if ((byte)imm == imm && info.OpRMImm8 != BadOp)
{
WriteOpCode(dest, src1, default, type, info.Flags, info.OpRMImm8);
if ((byte)imm == imm && info.OpRMImm8 != BadOp)
{
WriteOpCode(dest, src1, default, type, info.Flags, info.OpRMImm8);

WriteByte((byte)imm);
}
else
{
throw new ArgumentException($"Failed to encode constant 0x{imm:X}.");
}
}
else if (src2.Kind == OperandKind.Register && info.OpRMR != BadOp)
{
WriteOpCode(dest, src1, src2, type, info.Flags, info.OpRMR);
}
else if (info.OpRRM != BadOp)
{
WriteOpCode(dest, src1, src2, type, info.Flags, info.OpRRM, rrm: true);
}
else
{
throw new ArgumentException($"Invalid source operand kind \"{src2.Kind}\".");
WriteByte((byte)imm);
}
else
{
throw new ArgumentException($"Failed to encode constant 0x{imm:X}.");
}

break;

case OperandKind.Register when info.OpRMR != BadOp:
WriteOpCode(dest, src1, src2, type, info.Flags, info.OpRMR);
break;

default:
if (info.OpRRM != BadOp)
{
WriteOpCode(dest, src1, src2, type, info.Flags, info.OpRRM, rrm: true);
}
else
{
throw new ArgumentException($"Invalid source operand kind \"{src2.Kind}\".");
}

break;
}
}
else if (info.OpRRM != BadOp)
Expand Down Expand Up @@ -913,49 +926,53 @@ private void WriteOpCode(

if (dest != default)
{
if (dest.Kind == OperandKind.Register)
switch (dest.Kind)
{
int regIndex = dest.GetRegister().Index;
case OperandKind.Register:
int regIndex = dest.GetRegister().Index;

modRM |= (regIndex & 0b111) << (rrm ? 3 : 0);
modRM |= (regIndex & 0b111) << (rrm ? 3 : 0);

if ((flags & InstructionFlags.Reg8Dest) != 0 && regIndex >= 4)
{
rexPrefix |= RexPrefix;
}
}
else if (dest.Kind == OperandKind.Memory)
{
memOp = dest.GetMemory();
hasMemOp = true;
}
else
{
throw new ArgumentException("Invalid destination operand kind \"" + dest.Kind + "\".");
if ((flags & InstructionFlags.Reg8Dest) != 0 && regIndex >= 4)
{
rexPrefix |= RexPrefix;
}

break;

case OperandKind.Memory:
memOp = dest.GetMemory();
hasMemOp = true;
break;

default:
throw new ArgumentException("Invalid destination operand kind \"" + dest.Kind + "\".");
}
}

if (src2 != default)
{
if (src2.Kind == OperandKind.Register)
switch (src2.Kind)
{
int regIndex = src2.GetRegister().Index;
case OperandKind.Register:
int regIndex = src2.GetRegister().Index;

modRM |= (regIndex & 0b111) << (rrm ? 0 : 3);
modRM |= (regIndex & 0b111) << (rrm ? 0 : 3);

if ((flags & InstructionFlags.Reg8Src) != 0 && regIndex >= 4)
{
rexPrefix |= RexPrefix;
}
}
else if (src2.Kind == OperandKind.Memory && !hasMemOp)
{
memOp = src2.GetMemory();
hasMemOp = true;
}
else
{
throw new ArgumentException("Invalid source operand kind \"" + src2.Kind + "\".");
if ((flags & InstructionFlags.Reg8Src) != 0 && regIndex >= 4)
{
rexPrefix |= RexPrefix;
}

break;

case OperandKind.Memory when !hasMemOp:
memOp = src2.GetMemory();
hasMemOp = true;
break;

default:
throw new ArgumentException("Invalid source operand kind \"" + src2.Kind + "\".");
}
}

Expand Down
Loading
Loading