|
@@ -329,12 +329,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Bswap(Operand dest)
|
|
public void Bswap(Operand dest)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, dest.Type, X86Instruction.Bswap);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Bswap);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Call(Operand dest)
|
|
public void Call(Operand dest)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, OperandType.None, X86Instruction.Call);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, OperandType.None, X86Instruction.Call);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Cdq()
|
|
public void Cdq()
|
|
@@ -346,7 +346,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
{
|
|
|
InstructionInfo info = _instTable[(int)X86Instruction.Cmovcc];
|
|
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)
|
|
public void Cmp(Operand src1, Operand src2, OperandType type)
|
|
@@ -360,30 +360,38 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
WriteByte(0x99);
|
|
WriteByte(0x99);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void Cmpxchg(MemoryOperand memOp, Operand src)
|
|
|
|
|
|
|
+ public void Cmpxchg(Operand memOp, Operand src)
|
|
|
{
|
|
{
|
|
|
|
|
+ Debug.Assert(memOp.Kind == OperandKind.Memory);
|
|
|
|
|
+
|
|
|
WriteByte(LockPrefix);
|
|
WriteByte(LockPrefix);
|
|
|
|
|
|
|
|
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
|
|
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(LockPrefix);
|
|
|
WriteByte(0x66);
|
|
WriteByte(0x66);
|
|
|
|
|
|
|
|
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg);
|
|
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);
|
|
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);
|
|
WriteByte(LockPrefix);
|
|
|
|
|
|
|
|
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg8);
|
|
WriteInstruction(memOp, src, src.Type, X86Instruction.Cmpxchg8);
|
|
@@ -391,12 +399,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Comisd(Operand src1, Operand src2)
|
|
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)
|
|
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)
|
|
public void Cvtsd2ss(Operand dest, Operand src1, Operand src2)
|
|
@@ -421,7 +429,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Div(Operand source)
|
|
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)
|
|
public void Divsd(Operand dest, Operand src1, Operand src2)
|
|
@@ -436,12 +444,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Idiv(Operand source)
|
|
public void Idiv(Operand source)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(null, source, source.Type, X86Instruction.Idiv);
|
|
|
|
|
|
|
+ WriteInstruction(default, source, source.Type, X86Instruction.Idiv);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Imul(Operand source)
|
|
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)
|
|
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)
|
|
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());
|
|
WriteByte(src2.AsByte());
|
|
|
}
|
|
}
|
|
|
else if (IsImm32(src2.Value, src2.Type) && info.OpRMImm32 != BadOp)
|
|
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());
|
|
WriteInt32(src2.AsInt32());
|
|
|
}
|
|
}
|
|
@@ -531,12 +539,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Jmp(Operand dest)
|
|
public void Jmp(Operand dest)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, OperandType.None, X86Instruction.Jmp);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, OperandType.None, X86Instruction.Jmp);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Ldmxcsr(Operand dest)
|
|
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)
|
|
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)
|
|
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
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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
|
|
else
|
|
|
{
|
|
{
|
|
@@ -645,7 +653,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Mul(Operand source)
|
|
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)
|
|
public void Mulsd(Operand dest, Operand src1, Operand src2)
|
|
@@ -660,12 +668,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Neg(Operand dest)
|
|
public void Neg(Operand dest)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, dest.Type, X86Instruction.Neg);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, dest.Type, X86Instruction.Neg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Not(Operand dest)
|
|
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)
|
|
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)
|
|
public void Pclmulqdq(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pclmulqdq);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pclmulqdq);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
@@ -687,28 +695,28 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
public void Pextrb(Operand dest, Operand source, byte imm)
|
|
public void Pextrb(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pextrb);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pextrb);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Pextrd(Operand dest, Operand source, byte imm)
|
|
public void Pextrd(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pextrd);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pextrd);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Pextrq(Operand dest, Operand source, byte imm)
|
|
public void Pextrq(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pextrq);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pextrq);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void Pextrw(Operand dest, Operand source, byte imm)
|
|
public void Pextrw(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pextrw);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pextrw);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
@@ -749,7 +757,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
}
|
|
|
else
|
|
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)
|
|
public void Pshufd(Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, X86Instruction.Pshufd);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, X86Instruction.Pshufd);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
@@ -773,7 +781,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
}
|
|
|
else
|
|
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];
|
|
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)
|
|
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)
|
|
public void Sub(Operand dest, Operand source, OperandType type)
|
|
@@ -850,7 +858,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
Operand source,
|
|
Operand source,
|
|
|
OperandType type = OperandType.None)
|
|
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)
|
|
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)
|
|
public void WriteInstruction(X86Instruction inst, Operand dest, Operand source, byte imm)
|
|
|
{
|
|
{
|
|
|
- WriteInstruction(dest, null, source, inst);
|
|
|
|
|
|
|
+ WriteInstruction(dest, default, source, inst);
|
|
|
|
|
|
|
|
WriteByte(imm);
|
|
WriteByte(imm);
|
|
|
}
|
|
}
|
|
@@ -917,11 +925,11 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
Debug.Assert(shiftReg == X86Register.Rcx, $"Invalid shift register \"{shiftReg}\".");
|
|
Debug.Assert(shiftReg == X86Register.Rcx, $"Invalid shift register \"{shiftReg}\".");
|
|
|
|
|
|
|
|
- source = null;
|
|
|
|
|
|
|
+ source = default;
|
|
|
}
|
|
}
|
|
|
else if (source.Kind == OperandKind.Constant)
|
|
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);
|
|
WriteInstruction(dest, source, type, inst);
|
|
@@ -931,7 +939,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
{
|
|
|
InstructionInfo info = _instTable[(int)inst];
|
|
InstructionInfo info = _instTable[(int)inst];
|
|
|
|
|
|
|
|
- if (source != null)
|
|
|
|
|
|
|
+ if (source != default)
|
|
|
{
|
|
{
|
|
|
if (source.Kind == OperandKind.Constant)
|
|
if (source.Kind == OperandKind.Constant)
|
|
|
{
|
|
{
|
|
@@ -939,29 +947,29 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
if (inst == X86Instruction.Mov8)
|
|
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);
|
|
WriteByte((byte)imm);
|
|
|
}
|
|
}
|
|
|
else if (inst == X86Instruction.Mov16)
|
|
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);
|
|
WriteInt16((short)imm);
|
|
|
}
|
|
}
|
|
|
else if (IsImm8(imm, type) && info.OpRMImm8 != BadOp)
|
|
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);
|
|
WriteByte((byte)imm);
|
|
|
}
|
|
}
|
|
|
else if (!source.Relocatable && IsImm32(imm, type) && info.OpRMImm32 != BadOp)
|
|
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);
|
|
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);
|
|
int rexPrefix = GetRexPrefix(dest, source, type, rrm: false);
|
|
|
|
|
|
|
@@ -972,7 +980,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
WriteByte((byte)(info.OpRImm64 + (dest.GetRegister().Index & 0b111)));
|
|
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));
|
|
_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)
|
|
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)
|
|
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
|
|
else
|
|
|
{
|
|
{
|
|
@@ -999,11 +1007,11 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
}
|
|
|
else if (info.OpRRM != BadOp)
|
|
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)
|
|
else if (info.OpRMR != BadOp)
|
|
|
{
|
|
{
|
|
|
- WriteOpCode(dest, null, source, type, info.Flags, info.OpRMR);
|
|
|
|
|
|
|
+ WriteOpCode(dest, default, source, type, info.Flags, info.OpRMR);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -1020,7 +1028,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
{
|
|
|
InstructionInfo info = _instTable[(int)inst];
|
|
InstructionInfo info = _instTable[(int)inst];
|
|
|
|
|
|
|
|
- if (src2 != null)
|
|
|
|
|
|
|
+ if (src2 != default)
|
|
|
{
|
|
{
|
|
|
if (src2.Kind == OperandKind.Constant)
|
|
if (src2.Kind == OperandKind.Constant)
|
|
|
{
|
|
{
|
|
@@ -1028,7 +1036,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
if ((byte)imm == imm && info.OpRMImm8 != BadOp)
|
|
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);
|
|
WriteByte((byte)imm);
|
|
|
}
|
|
}
|
|
@@ -1082,9 +1090,10 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
int modRM = (opCode >> OpModRMBits) << 3;
|
|
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)
|
|
if (dest.Kind == OperandKind.Register)
|
|
|
{
|
|
{
|
|
@@ -1099,7 +1108,8 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
}
|
|
|
else if (dest.Kind == OperandKind.Memory)
|
|
else if (dest.Kind == OperandKind.Memory)
|
|
|
{
|
|
{
|
|
|
- memOp = dest as MemoryOperand;
|
|
|
|
|
|
|
+ memOp = dest.GetMemory();
|
|
|
|
|
+ hasMemOp = true;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -1107,7 +1117,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (src2 != null)
|
|
|
|
|
|
|
+ if (src2 != default)
|
|
|
{
|
|
{
|
|
|
if (src2.Kind == OperandKind.Register)
|
|
if (src2.Kind == OperandKind.Register)
|
|
|
{
|
|
{
|
|
@@ -1120,9 +1130,10 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
rexPrefix |= RexPrefix;
|
|
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
|
|
else
|
|
|
{
|
|
{
|
|
@@ -1135,14 +1146,14 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
|
|
int sib = 0;
|
|
int sib = 0;
|
|
|
|
|
|
|
|
- if (memOp != null)
|
|
|
|
|
|
|
+ if (hasMemOp)
|
|
|
{
|
|
{
|
|
|
// Either source or destination is a memory operand.
|
|
// Either source or destination is a memory operand.
|
|
|
Register baseReg = memOp.BaseAddress.GetRegister();
|
|
Register baseReg = memOp.BaseAddress.GetRegister();
|
|
|
|
|
|
|
|
X86Register baseRegLow = (X86Register)(baseReg.Index & 0b111);
|
|
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;
|
|
needsDisplacement = memOp.Displacement != 0 || baseRegLow == X86Register.Rbp;
|
|
|
|
|
|
|
|
if (needsDisplacement)
|
|
if (needsDisplacement)
|
|
@@ -1168,7 +1179,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
{
|
|
|
sib = (int)baseRegLow;
|
|
sib = (int)baseRegLow;
|
|
|
|
|
|
|
|
- if (memOp.Index != null)
|
|
|
|
|
|
|
+ if (memOp.Index != default)
|
|
|
{
|
|
{
|
|
|
int indexReg = memOp.Index.GetRegister().Index;
|
|
int indexReg = memOp.Index.GetRegister().Index;
|
|
|
|
|
|
|
@@ -1217,7 +1228,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
_ => 0
|
|
_ => 0
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- if (src1 != null)
|
|
|
|
|
|
|
+ if (src1 != default)
|
|
|
{
|
|
{
|
|
|
vexByte2 |= (src1.GetRegister().Index ^ 0xf) << 3;
|
|
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;
|
|
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);
|
|
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);
|
|
SetRegisterHighBit(source.GetRegister(), rrm ? 0 : 2);
|
|
|
}
|
|
}
|