Пример #1
0
 /// <summary>
 /// Convert the given instruction into 1 or more dex instructions.
 /// </summary>
 internal static IEnumerable<Instruction> Convert(RL.Instruction source, RegisterMapper regMapper)
 {
     var dexIns = new Instruction(source.Code.ToDex(), source.Operand) { SequencePoint = source.SequencePoint };
     var dexRegisters = dexIns.Registers;
     dexRegisters.AddRange(source.Registers.Select(x => regMapper[x]));
     if (!AllRegistersFit(dexIns) || dexIns.RequiresInvokeRange())
     {
         // At least 1 register does not fit.
         // Insert a NOP first so we do not have to re-route when we insert spilling code.
         yield return new Instruction(OpCodes.Nop);
     }
     yield return dexIns;
 }
Пример #2
0
        /// <summary>
        /// Convert the given instruction into 1 or more dex instructions.
        /// </summary>
        internal static IEnumerable <Instruction> Convert(RL.Instruction source, RegisterMapper regMapper)
        {
            var dexIns = new Instruction(source.Code.ToDex(), source.Operand)
            {
                SequencePoint = source.SequencePoint
            };
            var dexRegisters = dexIns.Registers;

            dexRegisters.AddRange(source.Registers.Select(x => regMapper[x]));
            if (!AllRegistersFit(dexIns) || dexIns.RequiresInvokeRange())
            {
                // At least 1 register does not fit.
                // Insert a NOP first so we do not have to re-route when we insert spilling code.
                yield return(new Instruction(OpCodes.Nop));
            }
            yield return(dexIns);
        }
Пример #3
0
            /// <summary>
            /// Convert a normal invoke_x to invoke_x_range.
            /// </summary>
            private void ConvertInvoke(Instruction ins)
            {
                var registers = ins.Registers;
                var count     = registers.Count;

                if (count == 0)
                {
                    return;
                }

                // Replace all registers with their "spill" variant (if any)
                for (var i = 0; i < count; i++)
                {
                    Register         sReg;
                    LowRegisterState state;
                    if (TryGetLowRegister(registers[i], out sReg, out state))
                    {
                        ReplaceRegister(ins, registers[i], sReg);
                    }
                }

                // By replacing the registers, it it possible to avoid the invoke_x_range opcodes?
                if (!ins.RequiresInvokeRange())
                {
                    return;
                }

                if (!IsValidInvokeRange(registers))
                {
                    // Use invoke frame
                    for (var i = 0; i < count; i++)
                    {
                        var type = GetType(registers[i]);
                        block.InsertBefore(ins, CreateMove(registers[i], invokeFrame[i], type));
                        registers[i] = invokeFrame[i];
                    }
                }
                // Change opcode
                ins.OpCode = ins.OpCode.InvokeToRange();
            }
Пример #4
0
            /// <summary>
            /// Convert a normal invoke_x to invoke_x_range.
            /// </summary>
            private void ConvertInvoke(Instruction ins)
            {
                var registers = ins.Registers;
                var count = registers.Count;
                if (count == 0)
                    return;

                // Replace all registers with their "spill" variant (if any)
                for (var i = 0; i < count; i++)
                {
                    Register sReg;
                    LowRegisterState state;
                    if (TryGetLowRegister(registers[i], out sReg, out state))
                    {
                        ReplaceRegister(ins, registers[i], sReg);
                    }
                }

                // By replacing the registers, it it possible to avoid the invoke_x_range opcodes?
                if (!ins.RequiresInvokeRange())
                    return;

                if (!IsValidInvokeRange(registers))
                {
                    // Use invoke frame
                    for (var i = 0; i < count; i++)
                    {
                        var type = GetType(registers[i]);
                        block.InsertBefore(ins, CreateMove(registers[i], invokeFrame[i], type));
                        registers[i] = invokeFrame[i];
                    }
                }
                // Change opcode
                ins.OpCode = ins.OpCode.InvokeToRange();
            }