示例#1
0
        public void Emit(OpcodeEncoder opcode, Operand symbolOperand, int symbolOffset)
        {
            int pos = (int)codeStream.Position + symbolOffset;

            Emit(opcode);

            if (symbolOperand.IsLabel)
            {
                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, MethodName, SectionKind.Text, pos, 0, symbolOperand.Name, SectionKind.ROData, 0);
            }
            else if (symbolOperand.IsField)
            {
                var section = symbolOperand.Field.Data != null ? SectionKind.ROData : SectionKind.BSS;

                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, MethodName, SectionKind.Text, pos, 0, symbolOperand.Field.FullName, section, (int)symbolOperand.Displacement);
            }
            else if (symbolOperand.IsSymbol)
            {
                var section = symbolOperand.Method != null ? SectionKind.Text : SectionKind.ROData;

                var symbol = linker.GetSymbol(symbolOperand.Name, section);

                if (symbol == null)
                {
                    symbol = linker.FindSymbol(symbolOperand.Name);
                }

                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, MethodName, SectionKind.Text, pos, 0, symbol, 0);
            }
        }
示例#2
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);
        }
示例#3
0
        private static void MovImmediateToFixedMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);
            Debug.Assert(node.Operand2.IsConstantZero);
            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(Bits.b00)                                            // 2:mod (000)
                .Append3Bits(Bits.b000)                                         // 3:source (000)
                .AppendRM(node.Operand1)                                        // 3:r/m (destination)
                .AppendConditionalDisplacement(node.Operand1, !linkreference)   // 32:displacement value
                .AppendConditionalIntegerValue(0, linkreference)                // 32:memory
                .AppendInteger(node.Operand3, node.Size);                       // 8/16/32:immediate

            if (linkreference)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - (int)node.Size) / 8);
            else
                emitter.Emit(opcode);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
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);
        }
示例#8
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);
        }
示例#9
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);
        }
示例#10
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);
        }
示例#11
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);
        }
示例#12
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);
        }
示例#13
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);
        }
示例#14
0
        public void Emit(OpcodeEncoder opcode, Operand symbolOperand, int patchOffset, int referenceOffset = 0)
        {
            int pos = (int)codeStream.Position + patchOffset;

            Emit(opcode);

            if (symbolOperand.IsLabel)
            {
                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, pos, SectionKind.ROData, symbolOperand.Name, referenceOffset);
            }
            else if (symbolOperand.IsStaticField)
            {
                var section = symbolOperand.Field.Data != null ? SectionKind.ROData : SectionKind.BSS;

                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, pos, section, symbolOperand.Field.FullName, referenceOffset);
            }
            else if (symbolOperand.IsSymbol)
            {
                var section = symbolOperand.Method != null ? SectionKind.Text : SectionKind.ROData;

                // First try finding the symbol in the expected section
                var symbol = linker.FindSymbol(symbolOperand.Name, section);

                // If no symbol found, look in all sections
                if (symbol == null)
                {
                    symbol = linker.FindSymbol(symbolOperand.Name);
                }

                // Otherwise create the symbol in the expected section
                if (symbol == null)
                {
                    symbol = linker.GetSymbol(symbolOperand.Name, section);
                }

                linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, pos, symbol, referenceOffset);
            }
        }
示例#15
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);
        }
示例#16
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);
        }
示例#17
0
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Result.IsCPURegister);
            Debug.Assert(node.Operand1.IsCPURegister);

            // 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);
        }
示例#18
0
        private static void MovImmediateToMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsConstant);

            // immediate to memory	1100 011w: mod 000 r/m : immediate data
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66)  // 8:prefix: 16bit
                .AppendNibble(Bits.b1100)                                       // 4:opcode
                .Append3Bits(Bits.b011)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)             // 1:width
                .ModRegRMSIBDisplacement(true, node.Operand1, node.Operand3, node.Operand2) // Mod-Reg-RM-?SIB-?Displacement
                .AppendInteger(node.Operand3, node.Size)                        // 8/16/32:immediate
                .AppendConditionalIntegerValue(node.Operand3.IsLinkerResolved, 0); // 32:memory

            if (node.Operand3.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand3, 24 / 8, node.Operand2.ConstantSignedInteger);
            else
                emitter.Emit(opcode);
        }
示例#19
0
        private static void MovRegToFixedMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsCPURegister);
            Debug.Assert(!node.Operand3.IsConstant);
            Debug.Assert(node.Operand1.IsConstant);

            // reg to memory	1000 100w: mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66)  // 8:prefix: 16bit
                .AppendNibble(Bits.b1000)                                       // 4:opcode
                .Append3Bits(Bits.b100)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)             // 1:width

                .AppendMod(Bits.b00)                                            // 2:mod (00)
                .AppendRegister(node.Operand3)                                  // 3:source
                .AppendRegister(Bits.b101)                                      // 3:r/m (101=Fixed Displacement)

                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0)  // 32:memory
                .AppendConditionalIntegerValue(!node.Operand1.IsLinkerResolved, node.Operand1.ConstantUnsignedInteger);   // 32:memory

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8, node.Operand2.ConstantSignedInteger);
            else
                emitter.Emit(opcode);
        }
示例#20
0
        private static void MovRegToMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand3.IsCPURegister);
            Debug.Assert(!node.Operand3.IsConstant);

            // reg to memory	1000 100w: mod reg r/m
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66)  // 8:prefix: 16bit

                .AppendNibble(Bits.b1000)                                       // 4:opcode
                .Append3Bits(Bits.b100)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)             // 1:width

                // 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:displacement

            if (node.Operand1.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, (opcode.Size - 32) / 8);
            else
                emitter.Emit(opcode);
        }
示例#21
0
        private static void MovImmediateToFixedMemory(InstructionNode node, MachineCodeEmitter emitter)
        {
            Debug.Assert(node.Operand1.IsConstant);
            Debug.Assert(node.Operand2.IsResolvedConstant);
            Debug.Assert(node.Operand3.IsConstant);

            // immediate to memory	1100 011w: mod 000 r/m : immediate data
            var opcode = new OpcodeEncoder()
                .AppendConditionalPrefix(node.Size == InstructionSize.Size16, 0x66)  // 8:prefix: 16bit
                .AppendNibble(Bits.b1100)                                       // 4:opcode
                .Append3Bits(Bits.b011)                                         // 3:opcode
                .AppendWidthBit(node.Size != InstructionSize.Size8)             // 1:width

                .AppendMod(Bits.b00)                                            // 2:mod (00)
                .Append3Bits(Bits.b000)                                         // 3:source (000)
                .AppendRM(node.Operand1)                                        // 3:r/m (destination)

                .AppendConditionalDisplacement(!node.Operand1.IsLinkerResolved, node.Operand1)   // 32:displacement value

                .AppendConditionalIntegerValue(node.Operand1.IsLinkerResolved, 0)  // 32:memory
                .AppendInteger(node.Operand3, node.Size);                       // 8/16/32:immediate

            if (node.Operand1.IsLinkerResolved && !node.Operand3.IsLinkerResolved)
                emitter.Emit(opcode, node.Operand1, 2, node.Operand2.ConstantSignedInteger);
            else if (node.Operand1.IsLinkerResolved && node.Operand3.IsLinkerResolved)
            {
                // fixme: trouble!
                throw new NotImplementCompilerException("not here");
            }
            else
                emitter.Emit(opcode);
        }
示例#22
0
 /// <summary>
 /// Emits the specified opcode.
 /// </summary>
 /// <param name="opcode">The opcode.</param>
 public void Emit(OpcodeEncoder opcode)
 {
     opcode.WriteTo(codeStream);
 }
示例#23
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);
        }