Пример #1
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            var     targetType = ((ITypeDefOrRef)expr.Operand).ToTypeSig();
            TypeDef boxType    = ((ITypeDefOrRef)expr.Operand).ResolveTypeDef();

            if (!targetType.GetElementType().IsPrimitive() && (boxType == null || !boxType.IsEnum))
            {
                if (targetType.ElementType != ElementType.String) // Box is used to resolve string ID
                {
                    return(value);
                }
            }

            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        typeId  = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand);
            int        ecallId = tr.VM.Runtime.VMCall.BOX;

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, value));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId)));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));

            return(retVar);
        }
Пример #2
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.R8);

            switch (valueType)
            {
            case ASTType.I4:
                IRVariable tmpVar = tr.Context.AllocateVRegister(ASTType.I8);
                tr.Instructions.Add(new IRInstruction(IROpCode.SX, tmpVar, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, tmpVar));
                break;

            case ASTType.I8:
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, value));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Пример #3
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            // TODO: overflow?

            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType valueType = value.Type;

            if (valueType == ASTType.Ptr || valueType == ASTType.I4) // no conversion needed.
            {
                return(value);
            }
            IRVariable retVar = tr.Context.AllocateVRegister(ASTType.Ptr);

            switch (valueType)
            {
            case ASTType.I8:
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value));
                break;

            case ASTType.R4:
            case ASTType.R8:
                IRVariable tmp = tr.Context.AllocateVRegister(ASTType.I8);
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, tmp));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Пример #4
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.I4);

            retVar.RawType = tr.Context.Method.Module.CorLibTypes.Byte;
            switch (valueType)
            {
            case ASTType.I4:
            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value));
                break;

            case ASTType.R4:
            case ASTType.R8:
                IRVariable tmp = tr.Context.AllocateVRegister(ASTType.I8);
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, tmp));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Пример #5
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            IRVariable retVar = tr.Context.AllocateVRegister(expr.Type.Value);

            MethodDef method = ((IMethod)expr.Operand).ResolveMethodDef();

            bool intraLinking = method != null && tr.VM.Settings.IsVirtualized(method);
            int  ecallId      = tr.VM.Runtime.VMCall.LDFTN;

            if (intraLinking)
            {
                int  sigId    = (int)tr.VM.Data.GetId(method.DeclaringType, method.MethodSig);
                uint entryKey = tr.VM.Data.LookupInfo(method).EntryKey;
                entryKey = ((uint)tr.VM.Random.Next() & 0xffffff00) | entryKey;
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4((int)entryKey)));
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4(sigId)));
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, new IRMetaTarget(method)
                {
                    LateResolve = true
                }));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId)));
            }
            else
            {
                int methodId = (int)tr.VM.Data.GetId((IMethod)expr.Operand);
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4(0)));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(methodId)));
            }
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));
            return(retVar);
        }
Пример #6
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            IRVariable ret = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
            {
                Operand1 = ret,
                Operand2 = tr.Translate(expr.Arguments[0])
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
            {
                Operand1 = ret,
                Operand2 = tr.Translate(expr.Arguments[1])
            });

            int        ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW;
            IRVariable fl      = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = fl,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.CARRY)
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), fl));
            return(ret);
        }
Пример #7
0
        public override void SubstituteUse(IRVariable variable, IRExpression expression)
        {
            if (ReferenceEquals(Address, variable))
            {
                Address = expression.CloneComplete();
            }
            else
            {
                Address.Substitute(variable, expression);
            }

            Uses.Clear();
            Uses.UnionWith(Address.GetAllVariables());

            if (ReferenceEquals(Operand, variable))
            {
                Operand = expression.CloneComplete();
            }
            else
            {
                Operand.Substitute(variable, expression);
            }

            Uses.UnionWith(Operand.GetAllVariables());
        }
Пример #8
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 0);

            ScopeBlock[] parentScopes = tr.RootScope.SearchBlock(tr.Block);
            ScopeBlock   catchScope   = parentScopes[parentScopes.Length - 1];

            if (catchScope.Type != ScopeType.Handler ||
                catchScope.ExceptionHandler.HandlerType != ExceptionHandlerType.Catch)
            {
                throw new InvalidProgramException();
            }

            IRVariable exVar = tr.Context.ResolveExceptionVar(catchScope.ExceptionHandler);

            Debug.Assert(exVar != null);

            int ecallId = tr.VM.Runtime.VMCall.THROW;

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, exVar));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL)
            {
                Operand1 = IRConstant.FromI4(ecallId),
                Operand2 = IRConstant.FromI4(1)
            });
            return(null);
        }
Пример #9
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);

            tr.Instructions.Add(new IRInstruction(IROpCode.CMP)
            {
                Operand1 = tr.Translate(expr.Arguments[0]),
                Operand2 = tr.Translate(expr.Arguments[1])
            });
            // CF=0 & ZF=0
            IRVariable ret = tr.Context.AllocateVRegister(ASTType.I4);

            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = ret,
                Operand2 = IRConstant.FromI4((1 << tr.Arch.Flags.CARRY) | (1 << tr.Arch.Flags.ZERO))
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__OR)
            {
                Operand1 = ret,
                Operand2 = ret
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = ret,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO)
            });
            return(ret);
        }
Пример #10
0
            public StackSlot SpillVariable(IRVariable var)
            {
                var slot = new StackSlot(SpillOffset++, var);

                spillVars[var] = slot;
                return(slot);
            }
Пример #11
0
        public IRContext(MethodDef method, CilBody body)
        {
            Method    = method;
            IsRuntime = false;

            locals = new IRVariable[body.Variables.Count];
            for (var i = 0; i < locals.Length; i++)
            {
                if (body.Variables[i].Type.IsPinned)
                {
                    throw new NotSupportedException("Pinned variables are not supported.");
                }

                locals[i] = new IRVariable
                {
                    Id           = i,
                    Name         = "local_" + i,
                    Type         = TypeInference.ToASTType(body.Variables[i].Type),
                    RawType      = body.Variables[i].Type,
                    VariableType = IRVariableType.Local
                };
            }

            args = new IRVariable[method.Parameters.Count];
            for (var i = 0; i < args.Length; i++)
            {
                args[i] = new IRVariable
                {
                    Id           = i,
                    Name         = "arg_" + i,
                    Type         = TypeInference.ToASTType(method.Parameters[i].Type),
                    RawType      = method.Parameters[i].Type,
                    VariableType = IRVariableType.Argument
                }
            }
            ;

            ehVars = new Dictionary <ExceptionHandler, IRVariable>();
            var id = -1;

            foreach (var eh in body.ExceptionHandlers)
            {
                id++;
                if (eh.HandlerType == ExceptionHandlerType.Fault ||
                    eh.HandlerType == ExceptionHandlerType.Finally)
                {
                    continue;
                }
                var type = eh.CatchType.ToTypeSig();
                ehVars.Add(eh, new IRVariable
                {
                    Id           = id,
                    Name         = "ex_" + id,
                    Type         = TypeInference.ToASTType(type),
                    RawType      = type,
                    VariableType = IRVariableType.VirtualRegister
                });
            }
        }
Пример #12
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            IRVariable ret = tr.Context.AllocateVRegister(expr.Type.Value);

            if (expr.Type != null && (expr.Type.Value == ASTType.R4 || expr.Type.Value == ASTType.R8))
            {
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.SUB)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[1])
                });
            }
            else
            {
                // A - B = A + (-B) = A + (~B + 1) = A + ~B + 1
                IRVariable tmp = tr.Context.AllocateVRegister(expr.Type.Value);
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = tmp,
                    Operand2 = tr.Translate(expr.Arguments[1])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.__NOT)
                {
                    Operand1 = tmp
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
                {
                    Operand1 = ret,
                    Operand2 = tmp
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
                {
                    Operand1 = ret,
                    Operand2 = IRConstant.FromI4(1)
                });
            }

            int        ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW;
            IRVariable fl      = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = fl,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.CARRY)
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), fl));
            return(ret);
        }
Пример #13
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            IRVariable local = tr.Context.ResolveLocal((Local)expr.Operand);
            IRVariable ret   = tr.Context.AllocateVRegister(ASTType.ByRef);

            tr.Instructions.Add(new IRInstruction(IROpCode.__LEA, ret, local));
            return(ret);
        }
Пример #14
0
            public StackSlot?CheckSpill(IRVariable var)
            {
                StackSlot ret;

                if (!spillVars.TryGetValue(var, out ret))
                {
                    return(null);
                }
                return(ret);
            }
Пример #15
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            int        typeId  = (int)tr.Runtime.Descriptor.Data.GetId((ITypeDefOrRef)expr.Operand);
            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        ecallId = tr.VM.Runtime.VMCall.SIZEOF;

            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId)));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));

            return(retVar);
        }
Пример #16
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        fieldId = (int)(tr.VM.Data.GetId((IField)expr.Operand) | 0x80000000);
            int        ecallId = tr.VM.Runtime.VMCall.LDFLD;

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.Null()));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(fieldId)));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));
            return(retVar);
        }
Пример #17
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        refId   = (int)tr.VM.Data.GetId((IMemberRef)expr.Operand);
            int        ecallId = tr.VM.Runtime.VMCall.TOKEN;

            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(refId)));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));

            return(retVar);
        }
Пример #18
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);

            tr.Instructions.Add(new IRInstruction(IROpCode.CMP)
            {
                Operand1 = tr.Translate(expr.Arguments[0]),
                Operand2 = tr.Translate(expr.Arguments[1])
            });
            // SF<>OF
            // !((FL=S|O) or (FL=0)), FL=S|O
            IRVariable ret = tr.Context.AllocateVRegister(ASTType.I4);
            IRVariable fl  = tr.Context.AllocateVRegister(ASTType.I4);

            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = fl,
                Operand2 = IRConstant.FromI4((1 << tr.Arch.Flags.OVERFLOW) | (1 << tr.Arch.Flags.SIGN))
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
            {
                Operand1 = ret,
                Operand2 = fl
            });
            TranslationHelpers.EmitCompareEq(tr, ASTType.I4,
                                             ret, IRConstant.FromI4((1 << tr.Arch.Flags.OVERFLOW) | (1 << tr.Arch.Flags.SIGN)));
            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = ret,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO)
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__AND)
            {
                Operand1 = fl,
                Operand2 = fl
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = fl,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO)
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__OR)
            {
                Operand1 = ret,
                Operand2 = fl
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = ret,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO)
            });
            return(ret);
        }
Пример #19
0
 public VMRegisters?Allocate(IRVariable var)
 {
     for (var i = 0; i < regAlloc.Length; i++)
     {
         if (regAlloc[i] == null)
         {
             regAlloc[i] = var;
             return(ToRegister(i));
         }
     }
     return(null);
 }
Пример #20
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IRVariable ret = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
            {
                Operand1 = ret,
                Operand2 = tr.Translate(expr.Arguments[0])
            });
            return(ret);
        }
Пример #21
0
        public IRVariable AllocateVRegister(ASTType type)
        {
            var vReg = new IRVariable {
                Id           = vRegs.Count,
                Name         = "vreg_" + vRegs.Count,
                Type         = type,
                VariableType = IRVariableType.VirtualRegister
            };

            vRegs.Add(vReg);
            return(vReg);
        }
Пример #22
0
        public IRVariable AllocateVRegister(ASTType type)
        {
            var vReg = new IRVariable
            {
                Id           = this.vRegs.Count,
                Name         = $"vreg_{this.vRegs.Count}",
                Type         = type,
                VariableType = IRVariableType.VirtualRegister
            };

            this.vRegs.Add(vReg);
            return(vReg);
        }
Пример #23
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand addr   = tr.Translate(expr.Arguments[0]);
            IRVariable retVar = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.__LDOBJ, addr, retVar)
            {
                Annotation = new PointerInfo("LDOBJ", (ITypeDefOrRef)expr.Operand)
            });

            return(retVar);
        }
Пример #24
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand size = tr.Translate(expr.Arguments[0]);

            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        ecallId = tr.VM.Runtime.VMCall.LOCALLOC;

            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), size));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));

            return(retVar);
        }
Пример #25
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType    valueType = value.Type;
            IRVariable t         = tr.Context.AllocateVRegister(ASTType.I4);
            IRVariable retVar    = tr.Context.AllocateVRegister(ASTType.I4);

            t.RawType = tr.Context.Method.Module.CorLibTypes.Int16;

            int rangechk = tr.VM.Runtime.VMCall.RANGECHK;
            int ckovf    = tr.VM.Runtime.VMCall.CKOVERFLOW;

            switch (valueType)
            {
            case ASTType.I4:
            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI8(ushort.MinValue)));
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI8(short.MaxValue)));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(rangechk), value));
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ckovf)));

                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, t, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.SX, retVar, t));
                break;

            case ASTType.R4:
            case ASTType.R8:
                IRVariable tmpVar = tr.Context.AllocateVRegister(ASTType.I8);
                IRVariable fl     = tr.Context.AllocateVRegister(ASTType.I4);
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmpVar, value));
                tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
                {
                    Operand1 = fl,
                    Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.OVERFLOW)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ckovf), fl));
                value = tmpVar;
                goto case ASTType.I8;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Пример #26
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand obj = tr.Translate(expr.Arguments[0]);

            IRVariable retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            int        fieldId = (int)tr.VM.Data.GetId((IField)expr.Operand);
            int        ecallId = tr.VM.Runtime.VMCall.LDFLD;

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, obj));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(fieldId)));
            tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar));
            return(retVar);
        }
Пример #27
0
        public override void SubstituteUse(IRVariable variable, IRExpression expression)
        {
            if (ReferenceEquals(ReturnValue, variable))
            {
                ReturnValue = expression.CloneComplete();
            }
            else
            {
                ReturnValue.Substitute(variable, expression);
            }

            Uses.Clear();
            Uses.UnionWith(ReturnValue.GetAllVariables());
        }
Пример #28
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            IRVariable ret = tr.Context.AllocateVRegister(ASTType.I4);

            TranslationHelpers.EmitCompareEq(tr, expr.Arguments[0].Type.Value,
                                             tr.Translate(expr.Arguments[0]), tr.Translate(expr.Arguments[1]));
            tr.Instructions.Add(new IRInstruction(IROpCode.__GETF)
            {
                Operand1 = ret,
                Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO)
            });
            return(ret);
        }
Пример #29
0
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            switch (instr.OpCode)
            {
            case IROpCode.__NOT:
                instrs.Replace(index, new[]
                {
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
                });
                break;

            case IROpCode.__AND:
            {
                IRVariable tmp = tr.Context.AllocateVRegister(instr.Operand2.Type);
                instrs.Replace(index, new[]
                    {
                        new IRInstruction(IROpCode.MOV, tmp, instr.Operand2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp, tmp, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp, instr)
                    });
                break;
            }

            case IROpCode.__OR:
                instrs.Replace(index, new[]
                {
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand2, instr),
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
                });
                break;

            case IROpCode.__XOR:
            {
                IRVariable tmp1 = tr.Context.AllocateVRegister(instr.Operand2.Type);
                IRVariable tmp2 = tr.Context.AllocateVRegister(instr.Operand2.Type);
                instrs.Replace(index, new[]
                    {
                        new IRInstruction(IROpCode.MOV, tmp1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp1, instr.Operand2, instr),
                        new IRInstruction(IROpCode.MOV, tmp2, instr.Operand2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp2, tmp2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp1, instr)
                    });
                break;
            }
            }
        }
Пример #30
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            IRVariable ret = tr.Context.AllocateVRegister(expr.Type.Value);

            if (expr.Type != null && (expr.Type.Value == ASTType.R4 || expr.Type.Value == ASTType.R8))
            {
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.SUB)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[1])
                });
            }
            else
            {
                // A - B = A + (-B) = A + (~B + 1) = A + ~B + 1
                IRVariable tmp = tr.Context.AllocateVRegister(expr.Type.Value);
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = tmp,
                    Operand2 = tr.Translate(expr.Arguments[1])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.__NOT)
                {
                    Operand1 = tmp
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
                {
                    Operand1 = ret,
                    Operand2 = tmp
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
                {
                    Operand1 = ret,
                    Operand2 = IRConstant.FromI4(1)
                });
            }
            return(ret);
        }