Пример #1
0
        public static void AddCodes(NodeBase caller, BlockBase parent, NodeBase target, OpModule codes, string op, Addr32 dest)
        {
            if (target is TypeOf) target = (target as TypeOf).Target;

            var v = target as Variant;
            if (v != null && parent.GetFunction(v.Name) == null)
            {
                var fpname = (target as Variant).Name;
                var fpt = Types.GetType(parent, fpname);
                if (fpt == null || !fpt.Check())
                    throw caller.Abort("undefined type: {0}", fpname);
                codes.AddCodesV(op, dest, codes.GetTypeObject(fpt));
                return;
            }

            var tt = target.Type;
            var tr = tt as TypeReference;
            var tts = tt.Type as TypeStruct;
            if (tr != null && (tr.IsArray || (tts != null && tts.IsClass)))
            {
                target.AddCodesV(codes, "mov", null);
                var label = new OpCode();
                codes.Add(I386.Test(Reg32.EAX, Reg32.EAX));
                codes.Add(I386.Jcc(Cc.Z, label.Address));
                codes.Add(I386.MovRA(Reg32.EAX, Addr32.NewRO(Reg32.EAX, -16)));
                codes.Add(label);
                codes.AddCodes(op, dest);
            }
            else
                codes.AddCodesV(op, dest, codes.GetTypeObject(tt));
        }
Пример #2
0
 public void AddOperatorCodes(TypeBase tb, string op, Addr32 dest, NodeBase arg, bool pushf)
 {
     arg.AddCodesV(this, "mov", null);
     var cleanup = NeedsDtor(arg);
     if (cleanup)
     {
         Add(I386.Push(Reg32.EAX));
         if (dest.Register == Reg32.ESP)
             dest = Addr32.NewRO(dest.Register, dest.Disp + 4);
     }
     tb.AddOpCodes(op, this, dest);
     if (cleanup)
     {
         if (pushf)
         {
             Add(I386.Pop(Reg32.EAX));
             Add(I386.Pushf());
             Add(I386.Push(Reg32.EAX));
         }
         AddDtorCodes(arg.Type);
         if (pushf) Add(I386.Popf());
     }
 }
Пример #3
0
 private void Simd(OpModule codes, string op, NodeBase m1, NodeBase m2)
 {
     var m1m = GetMm(m1);
     var m2m = GetMm(m2);
     var m1x = GetXmm(m1);
     var m2x = GetXmm(m2);
     var op2 = op.Substring(2);
     if (m1m != -1)
     {
         if (m2m != -1)
             codes.Add(MMX.FromName(op2, (Mm)m1m, (Mm)m2m));
         else
         {
             m2.AddCodesV(codes, "mov", null);
             codes.Add(MMX.FromNameA(op2, (Mm)m1m, Addr32.New(Reg32.EAX)));
         }
     }
     else if (m1x != -1)
     {
         if (m2x != -1)
             codes.Add(SSE2.FromName(op2, (Xmm)m1x, (Xmm)m2x));
         else
         {
             m2.AddCodesV(codes, "mov", null);
             codes.Add(SSE2.FromNameA(op2, (Xmm)m1x, Addr32.New(Reg32.EAX)));
         }
     }
     else
         throw Abort("{0}: invalid argument 1", op);
 }
Пример #4
0
 private void Movq(OpModule codes, NodeBase m1, NodeBase m2)
 {
     var m1m = GetMm(m1);
     var m2m = GetMm(m2);
     var m1x = GetXmm(m1);
     var m2x = GetXmm(m2);
     if (m1m != -1 && m2m != -1)
         codes.Add(MMX.MovQ((Mm)m1m, (Mm)m2m));
     else if (m1x != -1 && m2x != -1)
         codes.Add(SSE2.MovQ((Xmm)m1x, (Xmm)m2x));
     else if (m1m != -1)
     {
         m2.AddCodesV(codes, "mov", null);
         codes.Add(MMX.MovQA((Mm)m1m, Addr32.New(Reg32.EAX)));
     }
     else if (m2m != -1)
     {
         m1.AddCodesV(codes, "mov", null);
         codes.Add(MMX.MovQAM(Addr32.New(Reg32.EAX), (Mm)m2m));
     }
     else if (m1x != -1)
     {
         m2.AddCodesV(codes, "mov", null);
         codes.Add(SSE2.MovQA((Xmm)m1x, Addr32.New(Reg32.EAX)));
     }
     else if (m2x != -1)
     {
         m1.AddCodesV(codes, "mov", null);
         codes.Add(SSE2.MovQAX(Addr32.New(Reg32.EAX), (Xmm)m2x));
     }
     else
         throw Abort("__movq: invalid arguments");
 }
Пример #5
0
 private void Movdq(OpModule codes, string op, NodeBase m1, NodeBase m2)
 {
     var m1x = GetXmm(m1);
     var m2x = GetXmm(m2);
     var op2 = op.Substring(2);
     if (m1x != -1 && m2x != -1)
         codes.Add(SSE2.FromName(op2, (Xmm)m1x, (Xmm)m2x));
     else if (m1x != -1)
     {
         m2.AddCodesV(codes, "mov", null);
         codes.Add(SSE2.FromNameA(op2, (Xmm)m1x, Addr32.New(Reg32.EAX)));
     }
     else if (m2x != -1)
     {
         m1.AddCodesV(codes, "mov", null);
         codes.Add(SSE2.FromNameAX(op2, Addr32.New(Reg32.EAX), (Xmm)m2x));
     }
     else
         throw Abort("{0}: invalid arguments", op);
 }
Пример #6
0
        private void Movd(OpModule codes, NodeBase m1, NodeBase m2)
        {
            var m1m = GetMm(m1);
            var m2m = GetMm(m2);
            var m1x = GetXmm(m1);
            var m2x = GetXmm(m2);
            if (m1m != -1)
            {
                if (m2 is Var && m2.Type is TypeIntBase)
                {
                    var ad = (m2 as Var).GetAddress(codes);
                    codes.Add(MMX.MovDA((Mm)m1m, ad));
                }
                else if (m2 is IntValue)
                {
                    m2.AddCodesV(codes, "mov", null);
                    codes.Add(MMX.MovD((Mm)m1m, Reg32.EAX));
                }
                else
                {
                    m2.AddCodesV(codes, "mov", null);
                    codes.Add(MMX.MovDA((Mm)m1m, Addr32.New(Reg32.EAX)));
                }
                return;
            }
            else if (m1x != -1)
            {
                if (m2 is Var && m2.Type is TypeIntBase)
                {
                    var m2a = (m2 as Var).GetAddress(codes);
                    codes.Add(SSE2.MovDA((Xmm)m1x, m2a));
                }
                else if (m2 is IntValue)
                {
                    m2.AddCodesV(codes, "mov", null);
                    codes.Add(SSE2.MovD((Xmm)m1x, Reg32.EAX));
                }
                else
                {
                    m2.AddCodesV(codes, "mov", null);
                    codes.Add(SSE2.MovDA((Xmm)m1x, Addr32.New(Reg32.EAX)));
                }
                return;
            }

            var v = Var.Get(m1);
            if (v == null)
                throw Abort("__movd: invalid argument 1");
            if (m2m != -1)
            {
                if (v.Type is TypeIntBase)
                {
                    var ad = v.GetAddress(codes);
                    codes.Add(MMX.MovDAM(ad, (Mm)m2m));
                }
                else
                {
                    v.AddCodesV(codes, "mov", null);
                    codes.Add(MMX.MovDAM(Addr32.New(Reg32.EAX), (Mm)m2m));
                }
            }
            else if (m2x != -1)
            {
                if (v.Type is TypeIntBase)
                {
                    var ad = v.GetAddress(codes);
                    codes.Add(SSE2.MovDAX(ad, (Xmm)m2x));
                }
                else
                {
                    v.AddCodesV(codes, "mov", null);
                    codes.Add(SSE2.MovDAX(Addr32.New(Reg32.EAX), (Xmm)m2x));
                }
            }
            else
                throw Abort("__movd: invalid argument 2");
        }