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);
        }
        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);
        }
Beispiel #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);
        }
        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);
        }
        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);
        }
Beispiel #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);
        }
Beispiel #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());
        }
        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);
        }
Beispiel #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);
        }
Beispiel #10
0
            public StackSlot SpillVariable(IRVariable var)
            {
                var slot = new StackSlot(SpillOffset++, var);

                spillVars[var] = slot;
                return(slot);
            }
Beispiel #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
                });
            }
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #14
0
            public StackSlot?CheckSpill(IRVariable var)
            {
                StackSlot ret;

                if (!spillVars.TryGetValue(var, out ret))
                {
                    return(null);
                }
                return(ret);
            }
Beispiel #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);
        }
        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);
        }
        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);
        }
Beispiel #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);
        }
Beispiel #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);
 }
        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);
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
        }
        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);
        }
Beispiel #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());
        }
Beispiel #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);
        }
Beispiel #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;
            }
            }
        }
Beispiel #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);
        }