Skip to content

Commit

Permalink
switch
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeWarnut committed Oct 31, 2024
1 parent b21740c commit ae82452
Show file tree
Hide file tree
Showing 20 changed files with 682 additions and 658 deletions.
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

0 comments on commit ae82452

Please sign in to comment.