aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/X86/Assembler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/CodeGen/X86/Assembler.cs')
-rw-r--r--ARMeilleure/CodeGen/X86/Assembler.cs141
1 files changed, 76 insertions, 65 deletions
diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs
index 39aeb7c9..044f6047 100644
--- a/ARMeilleure/CodeGen/X86/Assembler.cs
+++ b/ARMeilleure/CodeGen/X86/Assembler.cs
@@ -329,12 +329,12 @@ namespace ARMeilleure.CodeGen.X86
public void Bswap(Operand dest)
{
- WriteInstruction(dest, null, dest.Type, X86Instruction.Bswap);
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Bswap);
}
public void Call(Operand dest)
{
- WriteInstruction(dest, null, OperandType.None, X86Instruction.Call);
+ WriteInstruction(dest, default, OperandType.None, X86Instruction.Call);
}
public void Cdq()
@@ -346,7 +346,7 @@ namespace ARMeilleure.CodeGen.X86
{
InstructionInfo info = _instTable[(int)X86Instruction.Cmovcc];
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRRM | (int)condition, rrm: true);
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRRM | (int)condition, rrm: true);
}
public void Cmp(Operand src1, Operand src2, OperandType type)
@@ -360,30 +360,38 @@ namespace ARMeilleure.CodeGen.X86
WriteByte(0x99);
}
- public void Cmpxchg(MemoryOperand memOp, Operand src)
+ public void Cmpxchg(Operand memOp, Operand src)
{
+ Debug.Assert(memOp.Kind == OperandKind.Memory);
+
WriteByte(LockPrefix);
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
}
- public void Cmpxchg16(MemoryOperand memOp, Operand src)
+ public void Cmpxchg16(Operand memOp, Operand src)
{
+ Debug.Assert(memOp.Kind == OperandKind.Memory);
+
WriteByte(LockPrefix);
WriteByte(0x66);
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
}
- public void Cmpxchg16b(MemoryOperand memOp)
+ public void Cmpxchg16b(Operand memOp)
{
+ Debug.Assert(memOp.Kind == OperandKind.Memory);
+
WriteByte(LockPrefix);
- WriteInstruction(memOp, null, OperandType.None, X86Instruction.Cmpxchg16b);
+ WriteInstruction(memOp, default, OperandType.None, X86Instruction.Cmpxchg16b);
}
- public void Cmpxchg8(MemoryOperand memOp, Operand src)
+ public void Cmpxchg8(Operand memOp, Operand src)
{
+ Debug.Assert(memOp.Kind == OperandKind.Memory);
+
WriteByte(LockPrefix);
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg8);
@@ -391,12 +399,12 @@ namespace ARMeilleure.CodeGen.X86
public void Comisd(Operand src1, Operand src2)
{
- WriteInstruction(src1, null, src2, X86Instruction.Comisd);
+ WriteInstruction(src1, default, src2, X86Instruction.Comisd);
}
public void Comiss(Operand src1, Operand src2)
{
- WriteInstruction(src1, null, src2, X86Instruction.Comiss);
+ WriteInstruction(src1, default, src2, X86Instruction.Comiss);
}
public void Cvtsd2ss(Operand dest, Operand src1, Operand src2)
@@ -421,7 +429,7 @@ namespace ARMeilleure.CodeGen.X86
public void Div(Operand source)
{
- WriteInstruction(null, source, source.Type, X86Instruction.Div);
+ WriteInstruction(default, source, source.Type, X86Instruction.Div);
}
public void Divsd(Operand dest, Operand src1, Operand src2)
@@ -436,12 +444,12 @@ namespace ARMeilleure.CodeGen.X86
public void Idiv(Operand source)
{
- WriteInstruction(null, source, source.Type, X86Instruction.Idiv);
+ WriteInstruction(default, source, source.Type, X86Instruction.Idiv);
}
public void Imul(Operand source)
{
- WriteInstruction(null, source, source.Type, X86Instruction.Imul128);
+ WriteInstruction(default, source, source.Type, X86Instruction.Imul128);
}
public void Imul(Operand dest, Operand source, OperandType type)
@@ -465,13 +473,13 @@ namespace ARMeilleure.CodeGen.X86
if (IsImm8(src2.Value, src2.Type) && info.OpRMImm8 != BadOp)
{
- WriteOpCode(dest, null, src1, type, info.Flags, info.OpRMImm8, rrm: true);
+ WriteOpCode(dest, default, src1, type, info.Flags, info.OpRMImm8, rrm: true);
WriteByte(src2.AsByte());
}
else if (IsImm32(src2.Value, src2.Type) && info.OpRMImm32 != BadOp)
{
- WriteOpCode(dest, null, src1, type, info.Flags, info.OpRMImm32, rrm: true);
+ WriteOpCode(dest, default, src1, type, info.Flags, info.OpRMImm32, rrm: true);
WriteInt32(src2.AsInt32());
}
@@ -531,12 +539,12 @@ namespace ARMeilleure.CodeGen.X86
public void Jmp(Operand dest)
{
- WriteInstruction(dest, null, OperandType.None, X86Instruction.Jmp);
+ WriteInstruction(dest, default, OperandType.None, X86Instruction.Jmp);
}
public void Ldmxcsr(Operand dest)
{
- WriteInstruction(dest, null, OperandType.I32, X86Instruction.Ldmxcsr);
+ WriteInstruction(dest, default, OperandType.I32, X86Instruction.Ldmxcsr);
}
public void Lea(Operand dest, Operand source, OperandType type)
@@ -565,17 +573,17 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type.IsInteger() || source.Kind == OperandKind.Memory)
{
- WriteOpCode(dest, null, source, OperandType.None, info.Flags, info.OpRRM, rrm: true);
+ WriteOpCode(dest, default, source, OperandType.None, info.Flags, info.OpRRM, rrm: true);
}
else
{
- WriteOpCode(dest, null, source, OperandType.None, info.Flags, info.OpRMR);
+ WriteOpCode(dest, default, source, OperandType.None, info.Flags, info.OpRMR);
}
}
public void Movdqu(Operand dest, Operand source)
{
- WriteInstruction(dest, null, source, X86Instruction.Movdqu);
+ WriteInstruction(dest, default, source, X86Instruction.Movdqu);
}
public void Movhlps(Operand dest, Operand src1, Operand src2)
@@ -596,11 +604,11 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type.IsInteger() || source.Kind == OperandKind.Memory)
{
- WriteOpCode(dest, null, source, OperandType.None, flags, info.OpRRM, rrm: true);
+ WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRRM, rrm: true);
}
else if (dest.Type.IsInteger() || dest.Kind == OperandKind.Memory)
{
- WriteOpCode(dest, null, source, OperandType.None, flags, info.OpRMR);
+ WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRMR);
}
else
{
@@ -645,7 +653,7 @@ namespace ARMeilleure.CodeGen.X86
public void Mul(Operand source)
{
- WriteInstruction(null, source, source.Type, X86Instruction.Mul128);
+ WriteInstruction(default, source, source.Type, X86Instruction.Mul128);
}
public void Mulsd(Operand dest, Operand src1, Operand src2)
@@ -660,12 +668,12 @@ namespace ARMeilleure.CodeGen.X86
public void Neg(Operand dest)
{
- WriteInstruction(dest, null, dest.Type, X86Instruction.Neg);
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Neg);
}
public void Not(Operand dest)
{
- WriteInstruction(dest, null, dest.Type, X86Instruction.Not);
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Not);
}
public void Or(Operand dest, Operand source, OperandType type)
@@ -675,7 +683,7 @@ namespace ARMeilleure.CodeGen.X86
public void Pclmulqdq(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pclmulqdq);
+ WriteInstruction(dest, default, source, X86Instruction.Pclmulqdq);
WriteByte(imm);
}
@@ -687,28 +695,28 @@ namespace ARMeilleure.CodeGen.X86
public void Pextrb(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pextrb);
+ WriteInstruction(dest, default, source, X86Instruction.Pextrb);
WriteByte(imm);
}
public void Pextrd(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pextrd);
+ WriteInstruction(dest, default, source, X86Instruction.Pextrd);
WriteByte(imm);
}
public void Pextrq(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pextrq);
+ WriteInstruction(dest, default, source, X86Instruction.Pextrq);
WriteByte(imm);
}
public void Pextrw(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pextrw);
+ WriteInstruction(dest, default, source, X86Instruction.Pextrw);
WriteByte(imm);
}
@@ -749,7 +757,7 @@ namespace ARMeilleure.CodeGen.X86
}
else
{
- WriteInstruction(dest, null, dest.Type, X86Instruction.Pop);
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Pop);
}
}
@@ -760,7 +768,7 @@ namespace ARMeilleure.CodeGen.X86
public void Pshufd(Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, X86Instruction.Pshufd);
+ WriteInstruction(dest, default, source, X86Instruction.Pshufd);
WriteByte(imm);
}
@@ -773,7 +781,7 @@ namespace ARMeilleure.CodeGen.X86
}
else
{
- WriteInstruction(null, source, source.Type, X86Instruction.Push);
+ WriteInstruction(default, source, source.Type, X86Instruction.Push);
}
}
@@ -806,12 +814,12 @@ namespace ARMeilleure.CodeGen.X86
{
InstructionInfo info = _instTable[(int)X86Instruction.Setcc];
- WriteOpCode(dest, null, null, OperandType.None, info.Flags, info.OpRRM | (int)condition);
+ WriteOpCode(dest, default, default, OperandType.None, info.Flags, info.OpRRM | (int)condition);
}
public void Stmxcsr(Operand dest)
{
- WriteInstruction(dest, null, OperandType.I32, X86Instruction.Stmxcsr);
+ WriteInstruction(dest, default, OperandType.I32, X86Instruction.Stmxcsr);
}
public void Sub(Operand dest, Operand source, OperandType type)
@@ -850,7 +858,7 @@ namespace ARMeilleure.CodeGen.X86
Operand source,
OperandType type = OperandType.None)
{
- WriteInstruction(dest, null, source, inst, type);
+ WriteInstruction(dest, default, source, inst, type);
}
public void WriteInstruction(X86Instruction inst, Operand dest, Operand src1, Operand src2)
@@ -877,7 +885,7 @@ namespace ARMeilleure.CodeGen.X86
public void WriteInstruction(X86Instruction inst, Operand dest, Operand source, byte imm)
{
- WriteInstruction(dest, null, source, inst);
+ WriteInstruction(dest, default, source, inst);
WriteByte(imm);
}
@@ -917,11 +925,11 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(shiftReg == X86Register.Rcx, $"Invalid shift register \"{shiftReg}\".");
- source = null;
+ source = default;
}
else if (source.Kind == OperandKind.Constant)
{
- source = source.With((int)source.Value & (dest.Type == OperandType.I32 ? 0x1f : 0x3f));
+ source = Operand.Factory.Const((int)source.Value & (dest.Type == OperandType.I32 ? 0x1f : 0x3f));
}
WriteInstruction(dest, source, type, inst);
@@ -931,7 +939,7 @@ namespace ARMeilleure.CodeGen.X86
{
InstructionInfo info = _instTable[(int)inst];
- if (source != null)
+ if (source != default)
{
if (source.Kind == OperandKind.Constant)
{
@@ -939,29 +947,29 @@ namespace ARMeilleure.CodeGen.X86
if (inst == X86Instruction.Mov8)
{
- WriteOpCode(dest, null, null, type, info.Flags, info.OpRMImm8);
+ WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);
WriteByte((byte)imm);
}
else if (inst == X86Instruction.Mov16)
{
- WriteOpCode(dest, null, null, type, info.Flags, info.OpRMImm32);
+ WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);
WriteInt16((short)imm);
}
else if (IsImm8(imm, type) && info.OpRMImm8 != BadOp)
{
- WriteOpCode(dest, null, null, type, info.Flags, info.OpRMImm8);
+ WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm8);
WriteByte((byte)imm);
}
else if (!source.Relocatable && IsImm32(imm, type) && info.OpRMImm32 != BadOp)
{
- WriteOpCode(dest, null, null, type, info.Flags, info.OpRMImm32);
+ WriteOpCode(dest, default, default, type, info.Flags, info.OpRMImm32);
WriteInt32((int)imm);
}
- else if (dest?.Kind == OperandKind.Register && info.OpRImm64 != BadOp)
+ else if (dest != default && dest.Kind == OperandKind.Register && info.OpRImm64 != BadOp)
{
int rexPrefix = GetRexPrefix(dest, source, type, rrm: false);
@@ -972,7 +980,7 @@ namespace ARMeilleure.CodeGen.X86
WriteByte((byte)(info.OpRImm64 + (dest.GetRegister().Index & 0b111)));
- if (_ptcInfo != null && source.Relocatable)
+ if (_ptcInfo != default && source.Relocatable)
{
_ptcInfo.WriteRelocEntry(new RelocEntry((int)_stream.Position, source.Symbol));
}
@@ -986,11 +994,11 @@ namespace ARMeilleure.CodeGen.X86
}
else if (source.Kind == OperandKind.Register && info.OpRMR != BadOp)
{
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRMR);
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRMR);
}
else if (info.OpRRM != BadOp)
{
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRRM, rrm: true);
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRRM, rrm: true);
}
else
{
@@ -999,11 +1007,11 @@ namespace ARMeilleure.CodeGen.X86
}
else if (info.OpRRM != BadOp)
{
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRRM, rrm: true);
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRRM, rrm: true);
}
else if (info.OpRMR != BadOp)
{
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRMR);
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRMR);
}
else
{
@@ -1020,7 +1028,7 @@ namespace ARMeilleure.CodeGen.X86
{
InstructionInfo info = _instTable[(int)inst];
- if (src2 != null)
+ if (src2 != default)
{
if (src2.Kind == OperandKind.Constant)
{
@@ -1028,7 +1036,7 @@ namespace ARMeilleure.CodeGen.X86
if ((byte)imm == imm && info.OpRMImm8 != BadOp)
{
- WriteOpCode(dest, src1, null, type, info.Flags, info.OpRMImm8);
+ WriteOpCode(dest, src1, default, type, info.Flags, info.OpRMImm8);
WriteByte((byte)imm);
}
@@ -1082,9 +1090,10 @@ namespace ARMeilleure.CodeGen.X86
int modRM = (opCode >> OpModRMBits) << 3;
- MemoryOperand memOp = null;
+ MemoryOperand memOp = default;
+ bool hasMemOp = false;
- if (dest != null)
+ if (dest != default)
{
if (dest.Kind == OperandKind.Register)
{
@@ -1099,7 +1108,8 @@ namespace ARMeilleure.CodeGen.X86
}
else if (dest.Kind == OperandKind.Memory)
{
- memOp = dest as MemoryOperand;
+ memOp = dest.GetMemory();
+ hasMemOp = true;
}
else
{
@@ -1107,7 +1117,7 @@ namespace ARMeilleure.CodeGen.X86
}
}
- if (src2 != null)
+ if (src2 != default)
{
if (src2.Kind == OperandKind.Register)
{
@@ -1120,9 +1130,10 @@ namespace ARMeilleure.CodeGen.X86
rexPrefix |= RexPrefix;
}
}
- else if (src2.Kind == OperandKind.Memory && memOp == null)
+ else if (src2.Kind == OperandKind.Memory && !hasMemOp)
{
- memOp = src2 as MemoryOperand;
+ memOp = src2.GetMemory();
+ hasMemOp = true;
}
else
{
@@ -1135,14 +1146,14 @@ namespace ARMeilleure.CodeGen.X86
int sib = 0;
- if (memOp != null)
+ if (hasMemOp)
{
// Either source or destination is a memory operand.
Register baseReg = memOp.BaseAddress.GetRegister();
X86Register baseRegLow = (X86Register)(baseReg.Index & 0b111);
- needsSibByte = memOp.Index != null || baseRegLow == X86Register.Rsp;
+ needsSibByte = memOp.Index != default || baseRegLow == X86Register.Rsp;
needsDisplacement = memOp.Displacement != 0 || baseRegLow == X86Register.Rbp;
if (needsDisplacement)
@@ -1168,7 +1179,7 @@ namespace ARMeilleure.CodeGen.X86
{
sib = (int)baseRegLow;
- if (memOp.Index != null)
+ if (memOp.Index != default)
{
int indexReg = memOp.Index.GetRegister().Index;
@@ -1217,7 +1228,7 @@ namespace ARMeilleure.CodeGen.X86
_ => 0
};
- if (src1 != null)
+ if (src1 != default)
{
vexByte2 |= (src1.GetRegister().Index ^ 0xf) << 3;
}
@@ -1284,7 +1295,7 @@ namespace ARMeilleure.CodeGen.X86
}
}
- if (dest != null && (flags & InstructionFlags.RegOnly) != 0)
+ if (dest != default && (flags & InstructionFlags.RegOnly) != 0)
{
opCode += dest.GetRegister().Index & 7;
}
@@ -1353,12 +1364,12 @@ namespace ARMeilleure.CodeGen.X86
}
}
- if (dest != null && dest.Kind == OperandKind.Register)
+ if (dest != default && dest.Kind == OperandKind.Register)
{
SetRegisterHighBit(dest.GetRegister(), rrm ? 2 : 0);
}
- if (source != null && source.Kind == OperandKind.Register)
+ if (source != default && source.Kind == OperandKind.Register)
{
SetRegisterHighBit(source.GetRegister(), rrm ? 0 : 2);
}