Example #1
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
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var 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])
            });

            var ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW;
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var 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
                var 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)
                });
            }

            var ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW;
            var 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);
        }
Example #4
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
            var ret = tr.Context.AllocateVRegister(ASTType.I4);
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var addr  = tr.Translate(expr.Arguments[0]);
            var value = tr.Translate(expr.Arguments[1]);

            tr.Instructions.Add(new IRInstruction(IROpCode.__STOBJ, addr, value)
            {
                Annotation = new PointerInfo("STOBJ", (ITypeDefOrRef)expr.Operand)
            });

            return(null);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var obj = tr.Translate(expr.Arguments[0]);
            var val = tr.Translate(expr.Arguments[1]);

            var fieldId = (int)tr.VM.Data.GetId((IField)expr.Operand);
            var ecallId = tr.VM.Runtime.VMCall.STFLD;

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, obj));
            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, val));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(fieldId)));
            return(null);
        }
Example #7
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var 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
                var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            ASTType valueType = value.Type;

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

            switch (valueType)
            {
            case ASTType.I4:
            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.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Example #10
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);
        }
Example #11
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);
        }
Example #12
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

            var targetType = ((ITypeDefOrRef)expr.Operand).ToTypeSig();

            if (!targetType.GetElementType().IsPrimitive() &&
                targetType.ElementType != ElementType.Object &&
                !targetType.ToTypeDefOrRef().ResolveTypeDefThrow().IsEnum)
            {
                // Non-primitive types => already boxed in VM
                return(value);
            }

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

            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);
        }
Example #13
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

            var valueType = value.Type;
            var 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:
                var 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);
        }
Example #14
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

            var valueType = value.Type;

            if (valueType == ASTType.I8) // no conversion needed.
            {
                return(value);
            }
            var retVar = tr.Context.AllocateVRegister(ASTType.I8);

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

            case ASTType.Ptr:
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value));
                break;

            case ASTType.R4:
            case ASTType.R8:
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, retVar, value));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }
Example #15
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

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

            switch (valueType)
            {
            case ASTType.I4:
                var 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);
        }
Example #16
0
        // Just recalc Name.
        private void RecalcWorker2(string name)
        {
            if (_calcs.ContainsKey(name))
            {
                return; // already computed.
            }

            var fi = _parent.Formulas[name];

            // Now calculate this node. Will recalc any dependencies if needed.
            if (fi._binding != null)
            {
                var binding = fi._binding;

                (IntermediateNode irnode, ScopeSymbol ruleScopeSymbol) = IRTranslator.Translate(binding);

                var scope = this;
                var v     = new EvalVisitor(_cultureInfo);

                FormulaValue newValue = irnode.Accept(v, SymbolContext.New());

                var equal = fi._value != null &&  // null on initial run.
                            RuntimeHelpers.AreEqual(newValue, fi._value);

                if (!equal)
                {
                    _sendUpdates.Add(name);
                }

                fi._value = newValue;
            }

            _calcs[name] = fi._value;
        }
Example #17
0
 public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
 {
     Debug.Assert(expr.Arguments.Length == 1);
     tr.Instructions.Add(new IRInstruction(IROpCode.__EHRET, tr.Translate(expr.Arguments[0])));
     tr.Block.Flags |= BlockFlags.ExitEHReturn;
     return(null);
 }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            var callInfo = new InstrCallInfo("CALLVIRT")
            {
                Method = (IMethod)expr.Operand
            };

            if (expr.Prefixes != null && expr.Prefixes[0].OpCode == OpCodes.Constrained)
            {
                callInfo.ConstrainType = (ITypeDefOrRef)expr.Prefixes[0].Operand;
            }

            tr.Instructions.Add(new IRInstruction(IROpCode.__BEGINCALL)
            {
                Annotation = callInfo
            });

            var args = new IIROperand[expr.Arguments.Length];

            for (var i = 0; i < args.Length; i++)
            {
                args[i] = tr.Translate(expr.Arguments[i]);
                tr.Instructions.Add(new IRInstruction(IROpCode.PUSH)
                {
                    Operand1   = args[i],
                    Annotation = callInfo
                });
            }
            callInfo.Arguments = args;


            IIROperand retVal = null;

            if (expr.Type != null)
            {
                retVal = tr.Context.AllocateVRegister(expr.Type.Value);
                tr.Instructions.Add(new IRInstruction(IROpCode.__CALLVIRT)
                {
                    Operand1   = new IRMetaTarget(callInfo.Method),
                    Operand2   = retVal,
                    Annotation = callInfo
                });
            }
            else
            {
                tr.Instructions.Add(new IRInstruction(IROpCode.__CALLVIRT)
                {
                    Operand1   = new IRMetaTarget(callInfo.Method),
                    Annotation = callInfo
                });
            }
            callInfo.ReturnValue = retVal;

            tr.Instructions.Add(new IRInstruction(IROpCode.__ENDCALL)
            {
                Annotation = callInfo
            });

            return(retVal);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

            // TODO: no exception possible?
            return(value);
        }
Example #20
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            var 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.__XOR)
            {
                Operand1 = ret,
                Operand2 = tr.Translate(expr.Arguments[1])
            });
            return(ret);
        }
 public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
 {
     Debug.Assert(expr.Arguments.Length == 1);
     tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
     {
         Operand1 = tr.Context.ResolveParameter((Parameter)expr.Operand),
         Operand2 = tr.Translate(expr.Arguments[0])
     });
     return(null);
 }
        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.__SETF)
            {
                Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
            });
            tr.Instructions.Add(new IRInstruction(IROpCode.SHR)
            {
                Operand1 = ret,
                Operand2 = tr.Translate(expr.Arguments[1])
            });
            return(ret);
        }
Example #23
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);

            var val = tr.Translate(expr.Arguments[0]);

            tr.Instructions.Add(new IRInstruction(IROpCode.SWT)
            {
                Operand1 = new IRJumpTable((IBasicBlock[])expr.Operand),
                Operand2 = val
            });
            return(null);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var size = tr.Translate(expr.Arguments[0]);

            var retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var addr = tr.Translate(expr.Arguments[0]);

            var typeId  = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand);
            var ecallId = tr.VM.Runtime.VMCall.INITOBJ;

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

            return(null);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var addr   = tr.Translate(expr.Arguments[0]);
            var 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);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var value = tr.Translate(expr.Arguments[0]);

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

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

            var rangechk = tr.VM.Runtime.VMCall.RANGECHK;
            var 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:
                var tmpVar = tr.Context.AllocateVRegister(ASTType.I8);
                var 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);
        }
Example #28
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            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 = IRConstant.FromI4(0)
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.SUB)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
            }
            else
            {
                // -A = ~A + 1
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = ret,
                    Operand2 = tr.Translate(expr.Arguments[0])
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.__NOT)
                {
                    Operand1 = ret
                });
                tr.Instructions.Add(new IRInstruction(IROpCode.ADD)
                {
                    Operand1 = ret,
                    Operand2 = IRConstant.FromI4(1)
                });
            }
            return(ret);
        }
Example #29
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);

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

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, tr.Translate(expr.Arguments[0])));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL)
            {
                Operand1 = IRConstant.FromI4(ecallId),
                Operand2 = IRConstant.FromI4(0)
            });
            return(null);
        }
Example #30
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            var obj = tr.Translate(expr.Arguments[0]);

            var retVar  = tr.Context.AllocateVRegister(expr.Type.Value);
            var fieldId = (int)(tr.VM.Data.GetId((IField)expr.Operand) | 0x80000000);
            var 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);
        }