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 #2
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)
        {
            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);
        }
        internal IIROperand Translate(IILASTNode node)
        {
            if (node is ILASTExpression expr)
            {
                try
                {
                    if (!handlers.TryGetValue(expr.ILCode, out ITranslationHandler handler))
                    {
                        throw new NotSupportedException(expr.ILCode.ToString());
                    }

                    int        i       = this.Instructions.Count;
                    IIROperand operand = handler.Translate(expr, this);
                    while (i < this.Instructions.Count)
                    {
                        this.Instructions[i].ILAST = expr;
                        i++;
                    }
                    return(operand);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Failed to translate expr {expr.CILInstr} @ {expr.CILInstr.GetOffset():x4}.", ex);
                }
            }
            if (node is ILASTVariable)
            {
                return(this.Context.ResolveVRegister((ILASTVariable)node));
            }
            throw new NotSupportedException();
        }
 public IRInstruction(IROpCode opCode, IIROperand op1, IIROperand op2, object annotation)
 {
     OpCode     = opCode;
     Operand1   = op1;
     Operand2   = op2;
     Annotation = annotation;
 }
        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 static void PopOperand(this ILTranslator tr, IIROperand operand)
 {
     if (operand is IRRegister)
     {
         var reg = ILRegister.LookupRegister(((IRRegister)operand).Register);
         tr.Instructions.Add(new ILInstruction(ILOpCode.POP, reg));
     }
     else if (operand is IRPointer pointer)
     {
         var reg = ILRegister.LookupRegister(pointer.Register.Register);
         tr.Instructions.Add(new ILInstruction(pointer.Register.GetPUSHR(), reg));
         if (pointer.Offset != 0)
         {
             tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, ILImmediate.Create(pointer.Offset, ASTType.I4)));
             if (pointer.Register.Type == ASTType.I4)
             {
                 tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_DWORD));
             }
             else
             {
                 tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_QWORD));
             }
         }
         tr.Instructions.Add(new ILInstruction(pointer.GetSIND()));
     }
     else
     {
         throw new NotSupportedException();
     }
 }
Beispiel #8
0
        private IIROperand AllocateOperand(IIROperand operand, RegisterPool pool)
        {
            if (operand is IRVariable)
            {
                var variable = (IRVariable)operand;

                StackSlot?slot;
                var       reg = AllocateVariable(pool, variable, out slot);
                if (reg != null)
                {
                    return new IRRegister(reg.Value)
                           {
                               SourceVariable = variable,
                               Type           = variable.Type
                           }
                }
                ;
                variable.Annotation = slot.Value;
                return(new IRPointer
                {
                    Register = IRRegister.BP,
                    Offset = slot.Value.Offset,
                    SourceVariable = variable,
                    Type = variable.Type
                });
            }
            return(operand);
        }
        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);
        }
Beispiel #10
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

            // TODO: no exception possible?
            return(value);
        }
 public IRInstruction(IROpCode opCode, IIROperand op1, IIROperand op2, IRInstruction origin)
 {
     OpCode     = opCode;
     Operand1   = op1;
     Operand2   = op2;
     Annotation = origin.Annotation;
     ILAST      = origin.ILAST;
 }
Beispiel #12
0
        private void AddTryStart(IRTransformer tr)
        {
            var tryStartInstrs = new List <IRInstruction>();

            for (var i = 0; i < thisScopes.Length; i++)
            {
                var scope = thisScopes[i];
                if (scope.Type != ScopeType.Try)
                {
                    continue;
                }
                if (scope.GetBasicBlocks().First() != tr.Block)
                {
                    continue;
                }

                // Search for handler/filter
                IBasicBlock handler = null, filter = null;
                SearchForHandlers(tr.RootScope, scope.ExceptionHandler, ref handler, ref filter);
                Debug.Assert(handler != null &&
                             (scope.ExceptionHandler.HandlerType != ExceptionHandlerType.Filter || filter != null));

                // Add instructions
                tryStartInstrs.Add(new IRInstruction(IROpCode.PUSH, new IRBlockTarget(handler)));

                IIROperand tryOperand = null;
                int        ehType;
                if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Catch)
                {
                    tryOperand = IRConstant.FromI4((int)tr.VM.Data.GetId(scope.ExceptionHandler.CatchType));
                    ehType     = tr.VM.Runtime.RTFlags.EH_CATCH;
                }
                else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Filter)
                {
                    tryOperand = new IRBlockTarget(filter);
                    ehType     = tr.VM.Runtime.RTFlags.EH_FILTER;
                }
                else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Fault)
                {
                    ehType = tr.VM.Runtime.RTFlags.EH_FAULT;
                }
                else if (scope.ExceptionHandler.HandlerType == ExceptionHandlerType.Finally)
                {
                    ehType = tr.VM.Runtime.RTFlags.EH_FINALLY;
                }
                else
                {
                    throw new InvalidProgramException();
                }

                tryStartInstrs.Add(new IRInstruction(IROpCode.TRY, IRConstant.FromI4(ehType), tryOperand)
                {
                    Annotation = new EHInfo(scope.ExceptionHandler)
                });
            }
            tr.Instructions.InsertRange(0, tryStartInstrs);
        }
Beispiel #13
0
		public static void EmitCompareEq(IRTranslator tr, ASTType type, IIROperand a, IIROperand b) {
			if (type == ASTType.O || type == ASTType.ByRef ||
			    type == ASTType.R4 || type == ASTType.R8) {
				tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
			}
			else {
				// I4/I8/Ptr
				Debug.Assert(type == ASTType.I4 || type == ASTType.I8 || type == ASTType.Ptr);
				tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
			}
		}
Beispiel #14
0
        IIROperand AllocateOperand(IIROperand operand, RegisterPool pool)
        {
            if (operand is IRVariable)
            {
                var variable = (IRVariable)operand;

                StackSlot?slot;
                var       reg = AllocateVariable(pool, variable, out slot);
                if (reg != null)
                {
                    return new IRRegister(reg.Value)
                           {
                               SourceVariable = variable,
                               Type           = variable.Type
                           }
                }
                ;
                variable.Annotation = slot.Value;
                return(new IRPointer {
                    Register = IRRegister.BP,
                    Offset = slot.Value.Offset,
                    SourceVariable = variable,
                    Type = variable.Type
                });
            }
            return(operand);
        }

        VMRegisters?AllocateVariable(RegisterPool pool, IRVariable var, out StackSlot?stackSlot)
        {
            stackSlot = pool.CheckSpill(var);
            if (stackSlot == null)
            {
                var allocReg = var.Annotation == null ? (VMRegisters?)null : (VMRegisters)var.Annotation;
                if (allocReg == null)
                {
                    allocReg = pool.Allocate(var);
                }
                if (allocReg != null)
                {
                    if (var.Annotation == null)
                    {
                        var.Annotation = allocReg.Value;
                    }
                    return(allocReg);
                }
                // Spill variable
                stackSlot = pool.SpillVariable(var);
            }
            return(null);
        }
    }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand val = tr.Translate(expr.Arguments[0]);

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

            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.Null()));
            tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, val));
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(fieldId)));
            return(null);
        }
Beispiel #16
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);

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

            tr.Instructions.Add(new IRInstruction(IROpCode.SWT)
            {
                Operand1 = new IRJumpTable((IBasicBlock[])expr.Operand),
                Operand2 = val
            });
            return(null);
        }
Beispiel #17
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 #18
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 2);
            IIROperand addr  = tr.Translate(expr.Arguments[0]);
            IIROperand value = tr.Translate(expr.Arguments[1]);

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

            return(null);
        }
Beispiel #19
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand addr = tr.Translate(expr.Arguments[0]);

            int typeId  = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand);
            int 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);
        }
Beispiel #20
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 #21
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) | 0x80000000);
            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);
        }
 private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.__LEA)
     {
         var        source = (IRPointer)instr.Operand2;
         IIROperand target = instr.Operand1;
         Debug.Assert(source.Register == IRRegister.BP);
         instrs.Replace(index, new[]
         {
             new IRInstruction(IROpCode.MOV, target, IRRegister.BP, instr),
             new IRInstruction(IROpCode.ADD, target, IRConstant.FromI4(source.Offset), instr)
         });
     }
 }
Beispiel #24
0
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value = tr.Translate(expr.Arguments[0]);

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

            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);
        }
Beispiel #25
0
 private IIROperand TransformMD(IIROperand operand, IRTransformer tr)
 {
     if (operand is IRMetaTarget target)
     {
         if (!target.LateResolve)
         {
             if (!(target.MetadataItem is IMemberRef))
             {
                 throw new NotSupportedException();
             }
             return(IRConstant.FromI4((int)tr.VM.Data.GetId((IMemberRef)target.MetadataItem)));
         }
     }
     return(operand);
 }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            Debug.Assert(expr.Arguments.Length == 1);
            IIROperand value   = tr.Translate(expr.Arguments[0]);
            int        ecallId = tr.VM.Runtime.VMCall.CKFINITE;

            if (value.Type == ASTType.R4)
            {
                tr.Instructions.Add(new IRInstruction(IROpCode.__SETF)
                {
                    Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED)
                });
            }
            tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), value));
            return(value);
        }
Beispiel #27
0
        public static void EmitCompareEq(IRTranslator tr, ASTType type, IIROperand a, IIROperand b)
        {
            switch (type)
            {
            case ASTType.O:
            case ASTType.ByRef:
            case ASTType.R4:
            case ASTType.R8:
                tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
                break;

            default:
                // I4/I8/Ptr
                Debug.Assert(type == ASTType.I4 || type == ASTType.I8 || type == ASTType.Ptr);
                tr.Instructions.Add(new IRInstruction(IROpCode.CMP, a, b));
                break;
            }
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            if (expr.Arguments.Length == 1)
            {
                IIROperand value = tr.Translate(expr.Arguments[0]);
                tr.Instructions.Add(new IRInstruction(IROpCode.MOV)
                {
                    Operand1 = new IRRegister(DarksVMRegisters.R0, value.Type),
                    Operand2 = value
                });
            }
            else
            {
                Debug.Assert(expr.Arguments.Length == 0);
            }
            tr.Instructions.Add(new IRInstruction(IROpCode.RET));

            return(null);
        }
        public IIROperand Translate(ILASTExpression expr, IRTranslator tr)
        {
            var callInfo = new InstrCallInfo("NEWOBJ")
            {
                Method = (IMethod)expr.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;


            var retVal = tr.Context.AllocateVRegister(expr.Type.Value);

            tr.Instructions.Add(new IRInstruction(IROpCode.__NEWOBJ)
            {
                Operand1   = new IRMetaTarget(callInfo.Method),
                Operand2   = retVal,
                Annotation = callInfo
            });
            callInfo.ReturnValue = retVal;

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

            return(retVal);
        }
Beispiel #30
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;

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

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

            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:
                IRVariable fl = tr.Context.AllocateVRegister(ASTType.I4);
                tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, retVar, 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));
                break;

            default:
                throw new NotSupportedException();
            }
            return(retVar);
        }