Ejemplo n.º 1
0
        private static void MovupsMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // mem to xmmreg1 0000 1111:0001 0000: mod xmmreg r/m
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b0000)                                                    // 4:opcode
                         .AppendNibble(Bits.b1111)                                                    // 4:opcode
                         .AppendNibble(Bits.b0001)                                                    // 4:opcode
                         .AppendNibble(Bits.b0000)                                                    // 4:opcode
                         .AppendMod(true, node.Operand2)                                              // 2:mod
                         .AppendRegister(node.Result.Register)                                        // 3:register (destination)
                         .AppendRM(node.Operand1)                                                     // 3:r/m (source)
                         .AppendConditionalDisplacement(node.Operand2, !node.Operand2.IsConstantZero) // 8/32:displacement value
                         .AppendConditionalIntegerValue(0, linkreference);                            // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Operand1 is ConstantOperand)
     {
         if (IsByte(ctx.Operand1))
             emitter.Emit(CONST8, ctx.Operand1, null);
         else if (IsShort(ctx.Operand1) || IsChar(ctx.Operand1))
             emitter.Emit(CONST16, ctx.Operand1, null);
         else if (IsInt(ctx.Operand1))
             emitter.Emit(CONST32, ctx.Operand1, null);
         return;
     }
     if (ctx.Operand1 is RegisterOperand)
     {
         if ((ctx.Operand1 as RegisterOperand).Register is SegmentRegister)
             switch (((ctx.Operand1 as RegisterOperand).Register as SegmentRegister).Segment)
             {
                 case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS, null, null); return;
                 case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS, null, null); return;
                 case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS, null, null); return;
                 case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES, null, null); return;
                 case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS, null, null); return;
                 case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS, null, null); return;
                 default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
             }
     }
     emitter.Emit(PUSH, ctx.Operand1, null, null);
 }
Ejemplo n.º 3
0
        private static void CmpXchg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);
            Debug.Assert(node.Operand2.IsRegister);
            Debug.Assert(node.GetOperand(3).IsRegister);
            Debug.Assert(node.Result.Register == GeneralPurposeRegister.EAX);
            Debug.Assert(node.Operand1.Register == GeneralPurposeRegister.EAX);
            Debug.Assert(node.ResultCount == 1);

            var linkreference = node.Operand2.IsLabel || node.Operand2.IsField || node.Operand2.IsSymbol;

            // Compare EAX with r/m32. If equal, ZF is set and r32 is loaded into r/m32.
            // Else, clear ZF and load r/m32 into EAX.

            // memory, register 0000 1111 : 1011 000w : mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(0x66, node.Size == InstructionSize.Size16)  // 8:prefix: 16bit
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b1011)                                       // 4:opcode
                .Append3Bits(Bits.b000)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)             // 1:width
                .ModRegRMSIBDisplacement(node.GetOperand(3), node.Operand2, node.Operand3) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(0, linkreference);               // 32:memory

            if (linkreference)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 4
0
        private static void LgdtMemoryConstant(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // LGDT – Load Global Descriptor Table Register 0000 1111 : 0000 0001 : modA 010 r / m
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b0000)                                                    // 4:opcode
                         .AppendNibble(Bits.b1111)                                                    // 4:opcode
                         .AppendNibble(Bits.b0000)                                                    // 4:opcode
                         .AppendNibble(Bits.b0001)                                                    // 4:opcode
                         .Append2Bits(Bits.b00)                                                       // 2:mod (must not be b11)
                         .Append3Bits(Bits.b010)                                                      // 3:reg
                         .AppendRM(node.Operand1)                                                     // 3:r/m (source, always b101)
                         .AppendConditionalDisplacement(node.Operand1, !node.Operand1.IsConstantZero) // 32:displacement value
                         .AppendConditionalIntegerValue(0, linkreference);                            // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 /// <exception cref="System.InvalidOperationException">@unable to emit opcode for segment register</exception>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     if (node.Operand1.IsConstant)
     {
         if (node.Operand1.IsByte)
             emitter.Emit(CONST8, node.Operand1);
         else if (node.Operand1.IsShort || node.Operand1.IsChar)
             emitter.Emit(CONST16, node.Operand1);
         else if (node.Operand1.IsInt)
             emitter.Emit(CONST32, node.Operand1);
         return;
     }
     if (node.Operand1.IsCPURegister)
     {
         if (node.Operand1.Register is SegmentRegister)
             switch ((node.Operand1.Register as SegmentRegister).Segment)
             {
                 case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS); return;
                 case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS); return;
                 case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS); return;
                 case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES); return;
                 case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS); return;
                 case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS); return;
                 default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
             }
     }
     emitter.Emit(PUSH, node.Operand1);
 }
Ejemplo n.º 6
0
        private static void MovRegToMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsRegister);
            Debug.Assert(node.ResultCount == 0);
            Debug.Assert(!node.Operand3.IsConstant);

            var size          = BaseMethodCompilerStage.GetInstructionSize(node.Size, node.Operand1.Type);
            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // reg to memory       1000 100w: mod reg r/m
            var opcode = new OpcodeEncoder()
                         .AppendConditionalPrefix(0x66, size == InstructionSize.Size16)         // 8:prefix: 16bit
                         .AppendNibble(Bits.b1000)                                              // 4:opcode
                         .Append3Bits(Bits.b100)                                                // 3:opcode
                         .AppendWidthBit(size != InstructionSize.Size8)                         // 1:width
                         .ModRegRMSIBDisplacement(node.Operand3, node.Operand1, node.Operand2)  // Mod-Reg-RM-?SIB-?Displacement
                         .AppendConditionalIntegerValue(0, linkreference);                      // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 7
0
        private static void MovImmediateToMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsConstant);
            Debug.Assert(node.ResultCount == 0);

            var linkreference = node.Operand3.IsLabel || node.Operand3.IsField || node.Operand3.IsSymbol;

            // immediate to memory 1100 011w: mod 000 r/m : immediate data
            var opcode = new OpcodeEncoder()
                         .AppendConditionalPrefix(0x66, node.Size == InstructionSize.Size16)          // 8:prefix: 16bit
                         .AppendNibble(Bits.b1100)                                                    // 4:opcode
                         .Append3Bits(Bits.b011)                                                      // 3:opcode
                         .AppendWidthBit(node.Size != InstructionSize.Size8)                          // 1:width
                         .AppendMod(true, node.Operand2)                                              // 2:mod
                         .Append3Bits(Bits.b000)                                                      // 3:000
                         .AppendRM(node.Operand1)                                                     // 3:r/m (destination)
                         .AppendConditionalDisplacement(node.Operand2, !node.Operand2.IsConstantZero) // 8/32:displacement value
                         .AppendInteger(node.Operand3, node.Size)                                     // 8/16/32:immediate
                         .AppendConditionalIntegerValue(0, linkreference);                            // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, 24 / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 8
0
        private static void CmpXchg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);
            Debug.Assert(node.Operand2.IsRegister);
            Debug.Assert(node.GetOperand(3).IsRegister);
            Debug.Assert(node.Result.Register == GeneralPurposeRegister.EAX);
            Debug.Assert(node.Operand1.Register == GeneralPurposeRegister.EAX);
            Debug.Assert(node.ResultCount == 1);

            var linkreference = node.Operand2.IsLabel || node.Operand2.IsField || node.Operand2.IsSymbol;

            // Compare EAX with r/m32. If equal, ZF is set and r32 is loaded into r/m32.
            // Else, clear ZF and load r/m32 into EAX.

            // memory, register 0000 1111 : 1011 000w : mod reg r/m
            var opcode = new OpcodeEncoder()
                         .AppendConditionalPrefix(0x66, node.Size == InstructionSize.Size16)        // 8:prefix: 16bit
                         .AppendNibble(Bits.b0000)                                                  // 4:opcode
                         .AppendNibble(Bits.b1111)                                                  // 4:opcode
                         .AppendNibble(Bits.b1011)                                                  // 4:opcode
                         .Append3Bits(Bits.b000)                                                    // 3:opcode
                         .AppendWidthBit(node.Size != InstructionSize.Size8)                        // 1:width
                         .ModRegRMSIBDisplacement(node.GetOperand(3), node.Operand2, node.Operand3) // Mod-Reg-RM-?SIB-?Displacement
                         .AppendConditionalIntegerValue(0, linkreference);                          // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 9
0
        private static void MovsdRegToMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsCPURegister);
            Debug.Assert(node.ResultCount == 0);
            Debug.Assert(!node.Operand3.IsConstant);

            // xmmreg1 to mem 1111 0010:0000 1111:0001 0001: mod xmmreg r/m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0010)                                       // 4:opcode
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0001)                                       // 4:opcode
                .AppendNibble(Bits.b0001)                                       // 4:opcode

                // This opcode has a directionality bit, and it is set to 0
                // This means we must swap around operand1 and operand3, and set offsetDestination to false
                .ModRegRMSIBDisplacement(false, node.Operand3, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);          // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 10
0
        private static void MovapsMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // mem to xmmreg 1111 0011:0000 1111:0101 1101: mod xmmreg r/m
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b1111)                                              // 4:opcode
                         .AppendNibble(Bits.b0011)                                              // 4:opcode
                         .AppendNibble(Bits.b0000)                                              // 4:opcode
                         .AppendNibble(Bits.b1111)                                              // 4:opcode
                         .AppendNibble(Bits.b0101)                                              // 4:opcode
                         .AppendNibble(Bits.b1101)                                              // 4:opcode
                         .ModRegRMSIBDisplacement(node.Result, node.Operand1, node.Operand2)    // Mod-Reg-RM-?SIB-?Displacement
                         .AppendConditionalIntegerValue(0, linkreference);                      // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     if (node.Operand3.IsConstant)
     {
         emitter.Emit(C, node.Operand2, node.Result, node.Operand3);
     }
     else
     {
         emitter.Emit(RM, node.Operand2, node.Result);
     }
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context context, MachineCodeEmitter emitter)
 {
     if (context.Operand3.IsConstant)
     {
         emitter.Emit(C, context.Operand2, context.Result, context.Operand3);
     }
     else
     {
         emitter.Emit(RM, context.Operand2, context.Result);
     }
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     if (node.Operand3.IsConstant)
     {
         emitter.Emit(C, node.Operand2, node.Result, node.Operand3);
     }
     else
     {
         emitter.Emit(RM, node.Operand2, node.Result);
     }
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context context, MachineCodeEmitter emitter)
 {
     OpCode opCode = ComputeOpCode(context.Result, context.Operand1, context.Operand2);
     if (context.Operand1.IsConstant)
     {
         // FIXME: Conversion not necessary if constant already byte.
         Operand op = Operand.CreateConstant(BuiltInSigType.Byte, context.Operand1.Value);
         emitter.Emit(opCode, context.Result, op);
     }
     else
         emitter.Emit(opCode, context.Operand1, null);
 }
Ejemplo n.º 15
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     OpCode opCode = ComputeOpCode(ctx.Result, ctx.Operand1, ctx.Operand2);
     if (ctx.Operand1 is ConstantOperand)
     {
         ConstantOperand op = ctx.Operand1 as ConstantOperand;
         op = new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(CilElementType.U1), op.Value);
         emitter.Emit(opCode, ctx.Result, op);
     }
     else
         emitter.Emit(opCode, ctx.Operand1, null);
 }
Ejemplo n.º 16
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="context"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context context, MachineCodeEmitter emitter)
 {
     OpCode opCode = ComputeOpCode(context.Result, context.Operand1, context.Operand2);
     if (context.Operand1 is ConstantOperand)
     {
         ConstantOperand op = context.Operand1 as ConstantOperand;
         op = new ConstantOperand(BuiltInSigType.Byte, op.Value);
         emitter.Emit(opCode, context.Result, op);
     }
     else
         emitter.Emit(opCode, context.Operand1, null);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            OpCode opCode = ComputeOpCode(node.Result, node.Operand1, null);

            if (node.Result.Register is ControlRegister)
            {
                emitter.Emit(opCode, node.Result, node.Operand1);
            }
            else
            {
                emitter.Emit(opCode, node.Operand1, node.Result);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            var opCode = ComputeOpCode(node.Size, node.Operand1, node.Operand2);

            if (node.Operand1.IsConstant)
            {
                emitter.Emit(opCode, node.Operand1, null);
            }
            else
            {
                emitter.Emit(opCode, null, null);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            var opCode = ComputeOpCode(node.Size, node.Operand1, node.Operand2);

            if (node.Operand1.IsConstant)
            {
                emitter.Emit(opCode, node.Operand1, null);
            }
            else
            {
                emitter.Emit(opCode, null, null);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            OpCode opCode = ComputeOpCode(node.Result, node.Operand1, null);

            if (node.Result.Register is ControlRegister)
            {
                emitter.Emit(opCode, node.Result, node.Operand1);
            }
            else
            {
                emitter.Emit(opCode, node.Operand1, node.Result);
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context context, MachineCodeEmitter emitter)
        {
            OpCode opCode = ComputeOpCode(context.Result, context.Operand1, context.Operand2);
            if (context.Operand2 is ConstantOperand)
            {
                // TODO/FIXME: Move these two lines into a stage
                ConstantOperand op = context.Operand2 as ConstantOperand;
                op = new ConstantOperand(BuiltInSigType.Byte, op.Value);

                emitter.Emit(opCode, context.Result, context.Operand1, op);
            }
            else
                emitter.Emit(opCode, context.Result, context.Operand1, context.Operand2);
        }
Ejemplo n.º 22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="emitter"></param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            OpCode opCode = ComputeOpCode(ctx.Result, ctx.Operand1, ctx.Operand2);

            if (ctx.Operand2 is ConstantOperand)
            {
                ConstantOperand op = ctx.Operand2 as ConstantOperand;
                op = new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.U1), op.Value);
                emitter.Emit(opCode, ctx.Result, ctx.Operand1, op);
            }
            else
            {
                emitter.Emit(opCode, ctx.Result, ctx.Operand1, ctx.Operand2);
            }
        }
Ejemplo n.º 23
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     emitter.Emit (new OpCode (new byte[] {
         0xf,
         0xa2
     }), null, null);
 }
Ejemplo n.º 24
0
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);
            Debug.Assert(node.Operand2.IsConstant);

            // reg from xmmreg, imm8
            // 0110 0110:0000 1111:0011 1010: 0001 0110:11 xmmreg reg: imm8
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b0110)                                       // 4:opcode
                .AppendNibble(Bits.b0110)                                       // 4:opcode

                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode

                .AppendNibble(Bits.b0011)                                       // 4:opcode
                .AppendNibble(Bits.b1010)                                       // 4:opcode

                .AppendNibble(Bits.b0001)                                       // 4:opcode
                .AppendNibble(Bits.b0110)                                       // 4:opcode

                .Append2Bits(Bits.b11)                                          // 2:opcode
                .AppendRM(node.Operand1)                                        // 3:r/m (source)
                .AppendRegister(node.Result.Register)                           // 3:register (destination)

                .AppendByteValue((byte)node.Operand2.ConstantUnsignedInteger);  // 8:memory

            emitter.Emit(opcode);
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Result is RegisterOperand)
         emitter.WriteByte ((byte)(0x58 + (ctx.Result as RegisterOperand).Register.RegisterCode));
     else
         emitter.Emit (POP.Code, 0, ctx.Result, null);
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        /// <exception cref="System.NotSupportedException"></exception>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            OpCode opcode;

            switch (node.ConditionCode)
            {
                case ConditionCode.Equal: opcode = E; break;
                case ConditionCode.LessThan: opcode = LT; break;
                case ConditionCode.LessOrEqual: opcode = LE; break;
                case ConditionCode.GreaterOrEqual: opcode = GE; break;
                case ConditionCode.GreaterThan: opcode = GT; break;
                case ConditionCode.NotEqual: opcode = NE; break;
                case ConditionCode.UnsignedGreaterOrEqual: opcode = UGE; break;
                case ConditionCode.UnsignedGreaterThan: opcode = UGT; break;
                case ConditionCode.UnsignedLessOrEqual: opcode = ULE; break;
                case ConditionCode.UnsignedLessThan: opcode = ULT; break;
                case ConditionCode.Parity: opcode = P; break;
                case ConditionCode.NoParity: opcode = NP; break;
                case ConditionCode.NoCarry: opcode = NC; break;
                case ConditionCode.Carry: opcode = C; break;
                case ConditionCode.Zero: opcode = Z; break;
                case ConditionCode.NotZero: opcode = NZ; break;
                default: throw new NotSupportedException();
            }

            emitter.Emit(opcode, node.Result, null);
        }
Ejemplo n.º 27
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     emitter.Emit(new OpCode(new byte[] {
         0xf,
         0xa2
     }), null, null);
 }
Ejemplo n.º 28
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result == node.Operand1, node.ToString());
            OpCode opCode = ComputeOpCode(node.Result, node.Operand1, node.Operand2);

            emitter.Emit(opCode, node.Result, node.Operand2);
        }
Ejemplo n.º 29
0
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);
            Debug.Assert(node.Operand2.IsConstant);

            // reg from xmmreg, imm8
            // 0110 0110:0000 1111:0011 1010: 0001 0110:11 xmmreg reg: imm8
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b0110)                                              // 4:opcode
                         .AppendNibble(Bits.b0110)                                              // 4:opcode

                         .AppendNibble(Bits.b0000)                                              // 4:opcode
                         .AppendNibble(Bits.b1111)                                              // 4:opcode

                         .AppendNibble(Bits.b0011)                                              // 4:opcode
                         .AppendNibble(Bits.b1010)                                              // 4:opcode

                         .AppendNibble(Bits.b0001)                                              // 4:opcode
                         .AppendNibble(Bits.b0110)                                              // 4:opcode

                         .Append2Bits(Bits.b11)                                                 // 2:opcode
                         .AppendRM(node.Operand1)                                               // 3:r/m (source)
                         .AppendRegister(node.Result.Register)                                  // 3:register (destination)

                         .AppendByteValue((byte)node.Operand2.ConstantUnsignedInteger);         // 8:memory

            emitter.Emit(opcode);
        }
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context context, MachineCodeEmitter emitter)
        {
            Debug.Assert(context.Result == null);

            OpCode opCode = ComputeOpCode(null, context.Operand1, context.Operand2);
            emitter.Emit(opCode, context.Operand1, context.Operand2);
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Operand1 is RegisterOperand)
         emitter.Emit(JmpReg, ctx.Operand1);
     else
         emitter.EmitBranch(JMP, ctx.Branch.Targets[0]);
 }
Ejemplo n.º 32
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result == null);

            OpCode opCode = ComputeOpCode(null, node.Operand1, node.Operand2);
            emitter.Emit(opCode, node.Operand1, node.Operand2);
        }
Ejemplo n.º 33
0
        private static void LeaAddress(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsCPURegister);

            // LEA – Load Effective Address 1000 1101 : modA reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66)  // 8:prefix: 16bit
                .AppendNibble(Bits.b1000)                                       // 4:opcode
                .AppendNibble(Bits.b1101)                                       // 3:opcode
                .ModRegRMSIBDisplacement(false, node.Result, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);               // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            if (ctx.Operand1 is ConstantOperand)
            {
                if (IsByte (ctx.Result))
                    emitter.Emit (Const_8.Code, null, ctx.Operand1, null);                else if (IsShort (ctx.Operand1) || IsChar (ctx.Operand1))
                {
                    emitter.Emit (Const_16.Code, null, ctx.Operand1, null);
                }
                else if (IsInt (ctx.Result))
                {
                    emitter.Emit (Const_32.Code, null, ctx.Operand1, null);
                }
            }

            else
                emitter.Emit (PUSH.Code, 6, ctx.Operand1, null);
        }
Ejemplo n.º 35
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context context, MachineCodeEmitter emitter)
 {
     if (context.Operand2.IsConstant)
     {
         if (context.Operand2.IsConstantOne)
         {
             emitter.Emit(C1, context.Result, null);
         }
         else
         {
             emitter.Emit(C, context.Result, context.Operand2);
         }
     }
     else
     {
         emitter.Emit(RM, context.Operand1, null);
     }
 }
Ejemplo n.º 36
0
        private static void MovsxMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsCPURegister);

            // memory to reg 0000 1111 : 1011 111w : mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b1011)                                       // 4:opcode
                .Append3Bits(Bits.b111)                                         // 4:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)                  // 1:width
                .ModRegRMSIBDisplacement(false, node.Result, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);               // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        /// <exception cref="System.InvalidOperationException">@unable to emit opcode for segment register</exception>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            if (node.Operand1.IsConstant)
            {
                if (node.Operand1.IsByte)
                {
                    emitter.Emit(CONST8, node.Operand1, null);
                }
                else if (node.Operand1.IsShort || node.Operand1.IsChar)
                {
                    emitter.Emit(CONST16, node.Operand1, null);
                }
                else if (node.Operand1.IsInt)
                {
                    emitter.Emit(CONST32, node.Operand1, null);
                }
                return;
            }
            if (node.Operand1.IsRegister)
            {
                if (node.Operand1.Register is SegmentRegister)
                {
                    switch ((node.Operand1.Register as SegmentRegister).Segment)
                    {
                    case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS, null, null); return;

                    case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS, null, null); return;

                    case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS, null, null); return;

                    case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES, null, null); return;

                    case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS, null, null); return;

                    case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS, null, null); return;

                    default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
                    }
                }
            }
            emitter.Emit(PUSH, node.Operand1);
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            if (ctx.Operand1 is ConstantOperand)
            {
                if (IsByte(ctx.Operand1))
                {
                    emitter.Emit(CONST8, ctx.Operand1, null);
                }
                else if (IsShort(ctx.Operand1) || IsChar(ctx.Operand1))
                {
                    emitter.Emit(CONST16, ctx.Operand1, null);
                }
                else if (IsInt(ctx.Operand1))
                {
                    emitter.Emit(CONST32, ctx.Operand1, null);
                }
                return;
            }
            if (ctx.Operand1 is RegisterOperand)
            {
                if ((ctx.Operand1 as RegisterOperand).Register is SegmentRegister)
                {
                    switch (((ctx.Operand1 as RegisterOperand).Register as SegmentRegister).Segment)
                    {
                    case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS, null, null); return;

                    case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS, null, null); return;

                    case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS, null, null); return;

                    case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES, null, null); return;

                    case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS, null, null); return;

                    case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS, null, null); return;

                    default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
                    }
                }
            }
            emitter.Emit(PUSH, ctx.Operand1, null, null);
        }
Ejemplo n.º 39
0
        private static void MovMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // memory to reg 1000 101w: mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(0x66, node.Size == InstructionSize.Size16)  // 8:prefix: 16bit
                .AppendNibble(Bits.b1000)                                       // 4:opcode
                .Append3Bits(Bits.b101)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)                  // 1:width
                .ModRegRMSIBDisplacement(node.Result, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(0, linkreference);               // 32:memory

            if (linkreference)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 40
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Result is RegisterOperand)
     {
         emitter.WriteByte((byte)(0x58 + (ctx.Result as RegisterOperand).Register.RegisterCode));
     }
     else
     {
         emitter.Emit(POP.Code, 0, ctx.Result, null);
     }
 }
Ejemplo n.º 41
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Operand1 is RegisterOperand)
     {
         emitter.Emit(JmpReg, ctx.Operand1);
     }
     else
     {
         emitter.EmitBranch(JMP, ctx.Branch.Targets[0]);
     }
 }
Ejemplo n.º 42
0
        private static void InvlpgMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);

            // INVLPG – Invalidate TLB Entry 0000 1111 : 0000 0001 : mod 111 r/m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b0001)                                       // 4:opcode
                .Append2Bits(Bits.b00)                                          // 2:mod (must not be b11)
                .Append3Bits(Bits.b010)                                         // 3:reg
                .AppendRM(node.Operand1)                                        // 3:r/m (source, always b101)
                .AppendConditionalDisplacement(!node.Operand1.IsConstantZero, node.Operand1)    // 32:displacement value
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);               // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 43
0
        private static void LgdtMemoryConstant(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);

            // LGDT – Load Global Descriptor Table Register 0000 1111 : 0000 0001 : modA 010 r / m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b0001)                                       // 4:opcode
                .Append2Bits(Bits.b00)                                          // 2:mod (must not be b11)
                .Append3Bits(Bits.b010)                                         // 3:reg
                .AppendRM(node.Operand1)                                        // 3:r/m (source, always b101)
                .AppendConditionalDisplacement(!node.Operand1.IsConstantZero, node.Operand1)    // 32:displacement value
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);               // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 44
0
        private static void MovFixedMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsCPURegister);
            Debug.Assert(node.Operand1.IsLinkerResolved);

            // memory to reg 1000 101w: mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66) // 8:prefix: 16bit
                .AppendNibble(Bits.b1000)                                           // 4:opcode
                .Append3Bits(Bits.b101)                                             // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)                 // 1:width
                .AppendMod(Bits.b00)                                                // 2:mod
                .AppendRegister(node.Result.Register)                               // 3:register (destination)
                .AppendRM(Bits.b101)                                                // 3:r/m (source)
                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0);  // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8, node.Operand2.ConstantSignedInteger);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 45
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        /// <exception cref="System.InvalidOperationException">@unable to emit opcode for segment register</exception>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            if (node.Result.IsRegister)
            {
                if (node.Result.Register is SegmentRegister)
                {
                    switch ((node.Result.Register as SegmentRegister).Segment)
                    {
                    case SegmentRegister.SegmentType.DS: emitter.Emit(POP_DS, null, null); return;

                    case SegmentRegister.SegmentType.ES: emitter.Emit(POP_ES, null, null); return;

                    case SegmentRegister.SegmentType.FS: emitter.Emit(POP_FS, null, null); return;

                    case SegmentRegister.SegmentType.GS: emitter.Emit(POP_GS, null, null); return;

                    case SegmentRegister.SegmentType.SS: emitter.Emit(POP_SS, null, null); return;

                    default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
                    }
                }
                else
                {
                    emitter.WriteByte((byte)(0x58 + node.Result.Register.RegisterCode));
                }
            }
            else
            {
                emitter.Emit(POP, node.Result, null);
            }
        }
Ejemplo n.º 46
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            if (ctx.Result is RegisterOperand)
            {
                if ((ctx.Result as RegisterOperand).Register is SegmentRegister)
                {
                    switch (((ctx.Result as RegisterOperand).Register as SegmentRegister).Segment)
                    {
                    case SegmentRegister.SegmentType.DS: emitter.Emit(POP_DS, null, null); return;

                    case SegmentRegister.SegmentType.ES: emitter.Emit(POP_ES, null, null); return;

                    case SegmentRegister.SegmentType.FS: emitter.Emit(POP_FS, null, null); return;

                    case SegmentRegister.SegmentType.GS: emitter.Emit(POP_GS, null, null); return;

                    case SegmentRegister.SegmentType.SS: emitter.Emit(POP_SS, null, null); return;

                    default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
                    }
                }
                else
                {
                    emitter.WriteByte((byte)(0x58 + (ctx.Result as RegisterOperand).Register.RegisterCode));
                }
            }
            else
            {
                emitter.Emit(POP, ctx.Result, null);
            }
        }
Ejemplo n.º 47
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            OpCode opcode;

            switch (ctx.ConditionCode)
            {
            case IR.ConditionCode.Equal:
                opcode = E;
                break;

            case IR.ConditionCode.LessThan:
                opcode = LT;
                break;

            case IR.ConditionCode.LessOrEqual:
                opcode = LE;
                break;

            case IR.ConditionCode.GreaterOrEqual:
                opcode = GE;
                break;

            case IR.ConditionCode.GreaterThan:
                opcode = GT;
                break;

            case IR.ConditionCode.NotEqual:
                opcode = NE;
                break;

            case IR.ConditionCode.UnsignedGreaterOrEqual:
                opcode = UGE;
                break;

            case IR.ConditionCode.UnsignedGreaterThan:
                opcode = UGT;
                break;

            case IR.ConditionCode.UnsignedLessOrEqual:
                opcode = ULE;
                break;

            case IR.ConditionCode.UnsignedLessThan:
                opcode = ULT;
                break;

            default:
                throw new NotSupportedException();
            }

            emitter.Emit(opcode, ctx.Result, null, null);
        }
Ejemplo n.º 48
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context context, MachineCodeEmitter emitter)
        {
            OpCode opCode = ComputeOpCode(context.Result, context.Operand1, null);

            if (context.Result.Register is ControlRegister)
            {
                emitter.Emit(opCode, context.Result, context.Operand1);
            }
            else
            {
                emitter.Emit(opCode, context.Operand1, context.Result);
            }
        }
Ejemplo n.º 49
0
        private static void MovapsMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // mem to xmmreg 1111 0011:0000 1111:0101 1101: mod xmmreg r/m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0011)                                       // 4:opcode
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0101)                                       // 4:opcode
                .AppendNibble(Bits.b1101)                                       // 4:opcode
                .ModRegRMSIBDisplacement(node.Result, node.Operand1, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendConditionalIntegerValue(0, linkreference);               // 32:memory

            if (linkreference)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 50
0
        private static readonly OpCode CMOVG  = new OpCode(new byte[] { 0x0F, 0x4F });          // GreaterThan (ZF = 0 and SF = OF)

        #endregion Data Members

        #region Methods

        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        /// <exception cref="System.NotSupportedException"></exception>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            OpCode opcode = null;

            switch (node.ConditionCode)
            {
            case ConditionCode.Equal: opcode = CMOVO; break;

            case ConditionCode.NotEqual: opcode = CMOVNE; break;

            case ConditionCode.Zero: opcode = CMOVZ; break;

            case ConditionCode.NotZero: opcode = CMOVNZ; break;

            case ConditionCode.GreaterOrEqual: opcode = CMOVGE; break;

            case ConditionCode.GreaterThan: opcode = CMOVG; break;

            case ConditionCode.LessOrEqual: opcode = CMOVLE; break;

            case ConditionCode.LessThan: opcode = CMOVL; break;

            case ConditionCode.UnsignedGreaterOrEqual: opcode = CMOVNB; break;

            case ConditionCode.UnsignedGreaterThan: opcode = CMOVA; break;

            case ConditionCode.UnsignedLessOrEqual: opcode = CMOVBE; break;

            case ConditionCode.UnsignedLessThan: opcode = CMOVB; break;

            case ConditionCode.Signed: opcode = CMOVS; break;

            case ConditionCode.NotSigned: opcode = CMOVNS; break;

            case ConditionCode.Carry: opcode = CMOVC; break;

            case ConditionCode.NoCarry: opcode = CMOVNC; break;

            case ConditionCode.Overflow: opcode = CMOVO; break;

            case ConditionCode.NoOverflow: opcode = CMOVNO; break;

            case ConditionCode.Parity: opcode = CMOVP; break;

            case ConditionCode.NoParity: opcode = CMOVNP; break;

            default: throw new NotSupportedException();
            }

            emitter.Emit(opcode, node.Result, node.Operand1);
        }
Ejemplo n.º 51
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            if (ctx.Operand1 is ConstantOperand)
            {
                if (IsByte(ctx.Result))
                {
                    emitter.Emit(Const_8.Code, null, ctx.Operand1, null);
                }
                else if (IsShort(ctx.Operand1) || IsChar(ctx.Operand1))
                {
                    emitter.Emit(Const_16.Code, null, ctx.Operand1, null);
                }
                else if (IsInt(ctx.Result))
                {
                    emitter.Emit(Const_32.Code, null, ctx.Operand1, null);
                }
            }

            else
            {
                emitter.Emit(PUSH.Code, 6, ctx.Operand1, null);
            }
        }
Ejemplo n.º 52
0
        private static void LidtMemoryConstant(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // LIDT – Load Interrupt Descriptor Table Register 0000 1111 : 0000 0001 : modA 011 r/m
            var opcode = new OpcodeEncoder()
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b1111)                                       // 4:opcode
                .AppendNibble(Bits.b0000)                                       // 4:opcode
                .AppendNibble(Bits.b0001)                                       // 4:opcode
                .Append2Bits(Bits.b00)                                          // 2:mod (must not be b11)
                .Append3Bits(Bits.b011)                                         // 3:reg
                .AppendRM(node.Operand1)                                        // 3:r/m (source, always b101)
                .AppendConditionalDisplacement(node.Operand1, !node.Operand1.IsConstantZero)    // 32:displacement value
                .AppendConditionalIntegerValue(0, linkreference);               // 32:memory

            if (linkreference)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
Ejemplo n.º 53
0
        private static void MovMemoryToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);

            var linkreference = node.Operand1.IsLabel || node.Operand1.IsField || node.Operand1.IsSymbol;

            // memory to reg 1000 101w: mod reg r/m
            var opcode = new OpcodeEncoder()
                         .AppendConditionalPrefix(0x66, node.Size == InstructionSize.Size16)    // 8:prefix: 16bit
                         .AppendNibble(Bits.b1000)                                              // 4:opcode
                         .Append3Bits(Bits.b101)                                                // 3:opcode
                         .AppendWidthBit(node.Size != InstructionSize.Size8)                    // 1:width
                         .ModRegRMSIBDisplacement(node.Result, node.Operand1, node.Operand2)    // Mod-Reg-RM-?SIB-?Displacement
                         .AppendConditionalIntegerValue(0, linkreference);                      // 32:memory

            if (linkreference)
            {
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            }
            else
            {
                emitter.Emit(opcode);
            }
        }
Ejemplo n.º 54
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            Operand       destinationOperand = ctx.Operand1;
            SymbolOperand destinationSymbol  = destinationOperand as SymbolOperand;

            if (destinationSymbol != null)
            {
                emitter.WriteByte(0xE8);
                emitter.Call(destinationSymbol);
            }
            else
            {
                RegisterOperand registerOperand = destinationOperand as RegisterOperand;
                emitter.Emit(RegCall, registerOperand);
            }
        }
Ejemplo n.º 55
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            if (node.OperandCount == 0)
            {
                emitter.EmitRelativeBranch(CALL, node.BranchTargets[0].Label);
                return;
            }

            if (node.Operand1.IsSymbol)
            {
                emitter.WriteByte(0xE8);
                emitter.EmitCallSite(node.Operand1);
            }
            else
            {
                emitter.Emit(RegCall, node.Operand1);
            }
        }
Ejemplo n.º 56
0
        private static void MovsxRegToReg(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);

            // register2 to register1 0000 1111 : 1011 111w : 11 reg1 reg2
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b0000)                                  // 4:opcode
                         .AppendNibble(Bits.b1111)                                  // 4:opcode
                         .AppendNibble(Bits.b1011)                                  // 4:opcode
                         .Append3Bits(Bits.b111)                                    // 4:opcode
                         .AppendWidthBit(node.Size != InstructionSize.Size8)        // 1:width
                         .AppendMod(Bits.b11)                                       // 2:mod
                         .AppendRegister(node.Result)                               // 3:register (destination)
                         .AppendRM(node.Operand1);                                  // 3:r/m (source)

            emitter.Emit(opcode);
        }
Ejemplo n.º 57
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        /// <exception cref="System.NotSupportedException"></exception>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            OpCode opcode;

            switch (node.ConditionCode)
            {
            case ConditionCode.Equal: opcode = E; break;

            case ConditionCode.LessThan: opcode = LT; break;

            case ConditionCode.LessOrEqual: opcode = LE; break;

            case ConditionCode.GreaterOrEqual: opcode = GE; break;

            case ConditionCode.GreaterThan: opcode = GT; break;

            case ConditionCode.NotEqual: opcode = NE; break;

            case ConditionCode.UnsignedGreaterOrEqual: opcode = UGE; break;

            case ConditionCode.UnsignedGreaterThan: opcode = UGT; break;

            case ConditionCode.UnsignedLessOrEqual: opcode = ULE; break;

            case ConditionCode.UnsignedLessThan: opcode = ULT; break;

            case ConditionCode.Parity: opcode = P; break;

            case ConditionCode.NoParity: opcode = NP; break;

            case ConditionCode.NoCarry: opcode = NC; break;

            case ConditionCode.Carry: opcode = C; break;

            case ConditionCode.Zero: opcode = Z; break;

            case ConditionCode.NotZero: opcode = NZ; break;

            default: throw new NotSupportedException();
            }

            emitter.Emit(opcode, node.Result, null);
        }
Ejemplo n.º 58
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     if (node.Operand1 == null)
     {
         emitter.EmitRelativeBranch(JMP, node.BranchTargets[0].Label);
     }
     else
     {
         if (node.Operand1.IsSymbol)
         {
             emitter.WriteByte(0xE9);
             emitter.EmitCallSite(node.Operand1);
         }
         else if (node.Operand1.IsRegister)
         {
             emitter.Emit(JMP_R, node.Operand1);
         }
     }
 }
Ejemplo n.º 59
0
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsRegister);
            Debug.Assert(node.Operand1.IsRegister);

            // reg from mmxreg
            // 0000 1111:0111 1110: 11 mmxreg reg
            var opcode = new OpcodeEncoder()
                         .AppendNibble(Bits.b0110)                                              // 4:opcode
                         .AppendNibble(Bits.b0110)                                              // 4:opcode

                         .AppendNibble(Bits.b0000)                                              // 4:opcode
                         .AppendNibble(Bits.b1111)                                              // 4:opcode

                         .Append3Bits(Bits.b011)                                                // 3:opcode
                         .AppendBit(node.Result.Register.Width != 128)                          // 1:direction
                         .AppendNibble(Bits.b1110)                                              // 4:opcode

                         .Append2Bits(Bits.b11)                                                 // 2:opcode
                         .AppendRM(node.Operand1)                                               // 3:r/m (source)
                         .AppendRegister(node.Result.Register);                                 // 3:register (destination)

            emitter.Emit(opcode);
        }
Ejemplo n.º 60
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     emitter.Emit(opcode, node.Operand3, null);
 }