Beispiel #1
0
        private static void VectorMatchSplit(VectorMatch vm)
        {
            int tempofset = vm.Offset;

            string[] calcs  = new string[vm.Count];
            string[] rcalcs = new string[vm.Count];
            //Generate calcs and rcalcs
            for (int i = 0; i < vm.Count; i++)
            {
                calcs[i]  = ParseScalarCalc(((UnwrappedElement)elements[vm.Start + i]).stuff);
                rcalcs[i] = ParseScalarCalcWithReg(((UnwrappedElement)elements[vm.Start + i]).stuff);
            }
            //Rotate the registers to try and match up rcalcs
            RotateUnmatchedRegisters(ref rcalcs[0], (UnwrappedElement)elements[vm.Start]);
            for (int i = 1; i < vm.Count; i++)
            {
                if (calcs[i] == calcs[i - 1])
                {
                    if (rcalcs[i] != rcalcs[i - 1])
                    {
                        if (!RotateDeepRegisters(ref rcalcs[i], rcalcs[i - 1], (UnwrappedElement)elements[vm.Start + i]))
                        {
                            RotateUnmatchedRegisters(ref rcalcs[i], (UnwrappedElement)elements[vm.Start + i]);
                        }
                    }
                }
            }
            //Split vectors wherever rcalcs dont match up
            int start = 0;

            for (int i = 1; i < vm.Count; i++)
            {
                if (rcalcs[i] != rcalcs[i - 1])
                {
                    if (i > start + 1)
                    {
                        UnwrappedElement[] o = new UnwrappedElement[i - start + 1];
                        elements.CopyTo(start + vm.Start, o, 0, i - start + 1);
                        FoundVectors.Add(new VectorMatch(start + vm.Start, i - start + 1, vm.Upward, o, vm.Offset, vm.Reg));
                    }
                    start  = i;
                    Offset = ((UnwrappedElement)elements[i + vm.Start]).Offset;
                }
            }
            if (start < vm.Count - 1)
            {
                UnwrappedElement[] o = new UnwrappedElement[vm.Count - start];
                elements.CopyTo(start + vm.Start, o, 0, vm.Count - start);
                FoundVectors.Add(new VectorMatch(start + vm.Start, vm.Count - start, vm.Upward, o, Offset, vm.Reg));
            }
        }
Beispiel #2
0
 public VectorMatch(VectorMatch vm, int arg, int start, int count, VectorDirection dir)
 {
     Offset = vm.Offset + 4 * start;;
     Reg    = vm.Reg;
     Start  = start + vm.Start;
     Count  = count;
     Upward = vm.Upward;
     calc   = vm.calc;
     if (dir == VectorDirection.Unknown)
     {
         throw new OptimizationException("VectorMatch: Unknown vector direction");
     }
     fpulines = new int[Count][];
     for (int i = Start; i < count + Start; i++)
     {
         fpulines[i - Start] = ((UnwrappedElement)vectorizer.elements[i]).FpuLines;
     }
     arguments = new Element[count][];
     Array.Copy(vm.arguments, start, arguments, 0, count);
     if (vm.pArguments != null)
     {
         pArguments = new Vector[vm.pArguments.Length + 1];
         vm.pArguments.CopyTo(pArguments, 0);
         for (int i = 0; i < vm.pArguments.Length - 1; i++)
         {
             pArguments[i].Count = count;
             if (start > 0)
             {
                 if (pArguments[i].Direction == VectorDirection.Up)
                 {
                     pArguments[i].Offset += 4 * start;
                 }
                 else if (pArguments[i].Direction == VectorDirection.Down)
                 {
                     pArguments[i].Offset -= 4 * start;
                 }
             }
         }
     }
     else
     {
         pArguments = new Vector[1];
     }
     pArguments[arg] = new Vector(arguments[0][arg].Offset, arguments[0][arg].Register, count, dir);
 }
Beispiel #3
0
 public VectorMatch(VectorMatch vm,int arg,int start,int count,VectorDirection dir)
 {
     Offset=vm.Offset+4*start; ;
     Reg=vm.Reg;
     Start=start+vm.Start;
     Count=count;
     Upward=vm.Upward;
     calc=vm.calc;
     if(dir==VectorDirection.Unknown) throw new OptimizationException("VectorMatch: Unknown vector direction");
     fpulines=new int[Count][];
     for(int i=Start;i<count+Start;i++) {
         fpulines[i-Start]=((UnwrappedElement)vectorizer.elements[i]).FpuLines;
     }
     arguments=new Element[count][];
     Array.Copy(vm.arguments,start,arguments,0,count);
     if(vm.pArguments!=null) {
         pArguments=new Vector[vm.pArguments.Length+1];
         vm.pArguments.CopyTo(pArguments,0);
         for(int i=0;i<vm.pArguments.Length-1;i++) {
             pArguments[i].Count=count;
             if(start>0) {
                 if(pArguments[i].Direction==VectorDirection.Up) {
                     pArguments[i].Offset+=4*start;
                 } else if(pArguments[i].Direction==VectorDirection.Down) {
                     pArguments[i].Offset-=4*start;
                 }
             }
         }
     } else {
         pArguments=new Vector[1];
     }
     pArguments[arg]=new Vector(arguments[0][arg].Offset,arguments[0][arg].Register,count,dir);
 }
Beispiel #4
0
 private static void VectorMatchSplit(VectorMatch vm)
 {
     int tempofset=vm.Offset;
     string[] calcs=new string[vm.Count];
     string[] rcalcs=new string[vm.Count];
     //Generate calcs and rcalcs
     for(int i=0;i<vm.Count;i++) {
         calcs[i]=ParseScalarCalc(((UnwrappedElement)elements[vm.Start+i]).stuff);
         rcalcs[i]=ParseScalarCalcWithReg(((UnwrappedElement)elements[vm.Start+i]).stuff);
     }
     //Rotate the registers to try and match up rcalcs
     RotateUnmatchedRegisters(ref rcalcs[0],(UnwrappedElement)elements[vm.Start]);
     for(int i=1;i<vm.Count;i++) {
         if(calcs[i]==calcs[i-1]) {
             if(rcalcs[i]!=rcalcs[i-1]) {
                 if(!RotateDeepRegisters(ref rcalcs[i],rcalcs[i-1],(UnwrappedElement)elements[vm.Start+i])) {
                     RotateUnmatchedRegisters(ref rcalcs[i],(UnwrappedElement)elements[vm.Start+i]);
                 }
             }
         }
     }
     //Split vectors wherever rcalcs dont match up
     int start=0;
     for(int i=1;i<vm.Count;i++) {
         if(rcalcs[i]!=rcalcs[i-1]) {
             if(i>start+1) {
                 UnwrappedElement[] o=new UnwrappedElement[i-start+1];
                 elements.CopyTo(start+vm.Start,o,0,i-start+1);
                 FoundVectors.Add(new VectorMatch(start+vm.Start,i-start+1,vm.Upward,o,vm.Offset,vm.Reg));
             }
             start=i;
             Offset=((UnwrappedElement)elements[i+vm.Start]).Offset;
         }
     }
     if(start<vm.Count-1) {
         UnwrappedElement[] o=new UnwrappedElement[vm.Count-start];
         elements.CopyTo(start+vm.Start,o,0,vm.Count-start);
         FoundVectors.Add(new VectorMatch(start+vm.Start,vm.Count-start,vm.Upward,o,Offset,vm.Reg));
     }
 }
Beispiel #5
0
 private static VectorMatch[] ProcessSplit(VectorMatch vm,int arg)
 {
     int Offset=-1;
     int ExpectedOffset=-1;
     string Reg="";
     int VectorStart=0;
     VectorDirection dir=VectorDirection.Unknown;
     ArrayList matches=new ArrayList();
     for(int i=0;i<vm.arguments.Length;i++) {
         if(i==0||Offset==-1) {
             Offset=vm.arguments[i][arg].Offset;
             Reg=vm.arguments[i][arg].Register;
             VectorStart=i;
         } else if(ExpectedOffset==-1) {
             if(vm.arguments[i][arg].Register==Reg&&vm.arguments[i][arg].Offset==Offset+4) {
                 ExpectedOffset=vm.arguments[i][arg].Offset+4;
                 dir=VectorDirection.Up;
             } else if(vm.arguments[i][arg].Register==Reg&&vm.arguments[i][arg].Offset==Offset-4) {
                 ExpectedOffset=vm.arguments[i][arg].Offset-4;
                 dir=VectorDirection.Down;
             } else if(vm.arguments[i][arg].Register==Reg&&vm.arguments[i][arg].Offset==Offset) {
                 ExpectedOffset=vm.arguments[i][arg].Offset;
                 dir=VectorDirection.Static;
             } else {
                 Offset=vm.arguments[i][arg].Offset;
                 VectorStart=i;
                 Reg=vm.arguments[i][arg].Register;
                 ExpectedOffset=-1;
             }
         } else {
             if((!(i-VectorStart==4))&&vm.arguments[i][arg].Register==Reg&&ExpectedOffset==vm.arguments[i][arg].Offset) {
                 if(dir==VectorDirection.Up) {
                     ExpectedOffset+=4;
                 } else if(dir==VectorDirection.Down) {
                     ExpectedOffset-=4;
                 }
             } else {
                 matches.Add(new VectorMatch(vm,arg,VectorStart,i-VectorStart,dir));
                 Offset=vm.arguments[i][arg].Offset;
                 VectorStart=i;
                 Reg=vm.arguments[i][arg].Register;
                 ExpectedOffset=-1;
             }
         }
     }
     if(Offset!=-1&&ExpectedOffset!=-1) {
         matches.Add(new VectorMatch(vm,arg,VectorStart,vm.arguments.Length-VectorStart,dir));
     }
     return (VectorMatch[])matches.ToArray(typeof(VectorMatch));
 }
Beispiel #6
0
        private static VectorMatch[] ProcessSplit(VectorMatch vm, int arg)
        {
            int             Offset         = -1;
            int             ExpectedOffset = -1;
            string          Reg            = "";
            int             VectorStart    = 0;
            VectorDirection dir            = VectorDirection.Unknown;
            ArrayList       matches        = new ArrayList();

            for (int i = 0; i < vm.arguments.Length; i++)
            {
                if (i == 0 || Offset == -1)
                {
                    Offset      = vm.arguments[i][arg].Offset;
                    Reg         = vm.arguments[i][arg].Register;
                    VectorStart = i;
                }
                else if (ExpectedOffset == -1)
                {
                    if (vm.arguments[i][arg].Register == Reg && vm.arguments[i][arg].Offset == Offset + 4)
                    {
                        ExpectedOffset = vm.arguments[i][arg].Offset + 4;
                        dir            = VectorDirection.Up;
                    }
                    else if (vm.arguments[i][arg].Register == Reg && vm.arguments[i][arg].Offset == Offset - 4)
                    {
                        ExpectedOffset = vm.arguments[i][arg].Offset - 4;
                        dir            = VectorDirection.Down;
                    }
                    else if (vm.arguments[i][arg].Register == Reg && vm.arguments[i][arg].Offset == Offset)
                    {
                        ExpectedOffset = vm.arguments[i][arg].Offset;
                        dir            = VectorDirection.Static;
                    }
                    else
                    {
                        Offset         = vm.arguments[i][arg].Offset;
                        VectorStart    = i;
                        Reg            = vm.arguments[i][arg].Register;
                        ExpectedOffset = -1;
                    }
                }
                else
                {
                    if ((!(i - VectorStart == 4)) && vm.arguments[i][arg].Register == Reg && ExpectedOffset == vm.arguments[i][arg].Offset)
                    {
                        if (dir == VectorDirection.Up)
                        {
                            ExpectedOffset += 4;
                        }
                        else if (dir == VectorDirection.Down)
                        {
                            ExpectedOffset -= 4;
                        }
                    }
                    else
                    {
                        matches.Add(new VectorMatch(vm, arg, VectorStart, i - VectorStart, dir));
                        Offset         = vm.arguments[i][arg].Offset;
                        VectorStart    = i;
                        Reg            = vm.arguments[i][arg].Register;
                        ExpectedOffset = -1;
                    }
                }
            }
            if (Offset != -1 && ExpectedOffset != -1)
            {
                matches.Add(new VectorMatch(vm, arg, VectorStart, vm.arguments.Length - VectorStart, dir));
            }
            return((VectorMatch[])matches.ToArray(typeof(VectorMatch)));
        }
Beispiel #7
0
 public static Operation DeepOp(ref VectorMatch vm,byte depth)
 {
     if(depth>254) throw new OptimizationException("Code generater: Too deep recursion");
     int count=0; int maxcount=0; int pos=0;
     string s=vm.calc;
     for(int i=0;i<s.Length;i++) {
         switch(s[i]) {
             case '(':
                 count++;
                 if(count>maxcount) maxcount=count;
                 break;
             case ')': count--; break;
         }
     }
     for(int i=0;i<s.Length;i++) {
         switch(s[i]) {
             case '(':
                 count++;
                 if(count==maxcount) {
                     ArgsToUse atu=ArgsToUse.None;
                     int b=2;
                     if(s[i+1]!='$') { atu|=ArgsToUse.Left; b--; }
                     if(s[i+3]!='$') { atu|=ArgsToUse.Right; b--; }
                     Operation o=new Operation();
                     switch(atu) {
                         case ArgsToUse.None:
                             o=new Operation(vm.pArguments[pos],vm.pArguments[pos+1],s[i+2]);
                             break;
                         case ArgsToUse.Left:
                             o=new Operation(GetRegister(s[i+1]),vm.pArguments[pos],s[i+2]);
                             //Registers[GetRegister(s[i+1])].contains=depth;
                             break;
                         case ArgsToUse.Right:
                             o=new Operation(vm.pArguments[pos],GetRegister(s[i+3]),s[i+2]);
                             break;
                         case ArgsToUse.Both:
                             o=new Operation(GetRegister(s[i+3]),GetRegister(s[i+1]),s[i+2]);
                             //Registers[GetRegister(s[i+1])].contains=depth;
                             break;
                     }
                     Vector[] vs=new Vector[vm.pArguments.Length-b];
                     int c=0;
                     for(int a=0;a<vm.pArguments.Length;a++) {
                         if(a==c&&b>0) continue;
                         if(a==c+1&&b>1) continue;
                         vs[c++]=vm.pArguments[a];
                     }
                     vm.pArguments=vs;
                     vm.calc=s.Remove(i,5);
                     vm.calc=vm.calc.Insert(i,""+(char)depth);
                     return o;
                 }
                 break;
             case ')': count--; break;
             case '$':
                 pos++;
                 break;
         }
     }
     throw new OptimizationException("Code generater: No operation to perform");
 }
Beispiel #8
0
 public static void v4CreateCode(VectorMatch function)
 {
     byte a=0;
     while(function.calc.Length>1) {
         Operation op=DeepOp(ref function,a++);
         if(op.args==ArgsToUse.None) {
             op.op1loc=v4MoveToRegister(op.op1);
             op.args=ArgsToUse.Left;
         }
         if((op.args&ArgsToUse.Left)==0) {
             op.op1loc=v4MoveToRegister(op.op1);
             op.args|=ArgsToUse.Left;
         }
         if((op.args&ArgsToUse.Right)==0&&(!aligned||op.op2.Direction!=VectorDirection.Up)) {
             op.op2loc=v4MoveToRegister(op.op2);
             op.args|=ArgsToUse.Right;
         }
         Registers[op.op1loc].contains=(byte)(a-1);
         string s=null;
         switch(op.op) {
             case '+': s="addps "; break;
             case '-': s="subps "; break;
             case '*': s="mulps "; break;
             case '/': s="divps "; break;
         }
         if((op.args&ArgsToUse.Left)==0) {
             s+="["+op.op1.Register+ToHex(op.op1.Offset)+"],";
         } else {
             s+="xmm"+op.op1loc+",";
         }
         if((op.args&ArgsToUse.Right)==0) {
             s+="["+op.op2.Register+ToHex(op.op2.Offset)+"]";
         } else {
             s+="xmm"+op.op2loc;
         }
         AsmFile.WriteLine(s);
     }
     if(!function.Upward) {
         AsmFile.WriteLine("shufps xmm"+(byte)function.calc[0]+",xmm"+GetRegister(function.calc[0])+",0x1B");
     }
     if(aligned) {
         AsmFile.WriteLine("movaps ["+function.Reg+ToHex(function.Offset)+"],xmm"+GetRegister(function.calc[0]));
     } else {
         AsmFile.WriteLine("movups ["+function.Reg+ToHex(function.Offset)+"],xmm"+GetRegister(function.calc[0]));
     }
 }
Beispiel #9
0
 public static void v3CreateCode(VectorMatch function)
 {
     byte a=0;
     //If the function is reversed, flip all the arguments
     if(!function.Upward) {
         flipped=true;
         for(int i=0;i<function.pArguments.Length;i++) {
             if(function.pArguments[i].Direction==VectorDirection.Up) {
                 function.pArguments[i].Direction=VectorDirection.Down;
             } else if(function.pArguments[i].Direction==VectorDirection.Down) {
                 function.pArguments[i].Direction=VectorDirection.Up;
             }
         }
     }
     while(function.calc.Length>1) {
         Operation op=DeepOp(ref function,a++);
         if(op.args==ArgsToUse.None) {
             op.op1loc=v3MoveToRegister(op.op1);
             op.args=ArgsToUse.Left;
         }
         if((op.args&ArgsToUse.Left)==0) {
             op.op1loc=v3MoveToRegister(op.op1);
             op.args|=ArgsToUse.Left;
         }
         if((op.args&ArgsToUse.Right)==0&&(!aligned||op.op2.Direction!=VectorDirection.Up)) {
             op.op2loc=v3MoveToRegister(op.op2);
             op.args|=ArgsToUse.Right;
         }
         Registers[op.op1loc].contains=(byte)(a-1);
         string s=null;
         switch(op.op) {
             case '+': s="addps "; break;
             case '-': s="subps "; break;
             case '*': s="mulps "; break;
             case '/': s="divps "; break;
         }
         if((op.args&ArgsToUse.Left)==0) {
             s+="["+op.op1.Register+ToHex(op.op1.Offset)+"],";
         } else {
             s+="xmm"+op.op1loc+",";
         }
         if((op.args&ArgsToUse.Right)==0) {
             s+="["+op.op2.Register+ToHex(op.op2.Offset)+"]";
         } else {
             s+="xmm"+op.op2loc;
         }
         AsmFile.WriteLine(s);
     }
     if(aligned) {
         AsmFile.WriteLine("movhlps xmm7,xmm"+GetRegister(function.calc[0]));
         if(flipped) {
             AsmFile.WriteLine("movlps ["+function.Reg+ToHex(function.Offset-4)+"],xmm"+GetRegister(function.calc[0]));
             AsmFile.WriteLine("movss ["+function.Reg+ToHex(function.Offset-8)+"],xmm7");
         } else {
             AsmFile.WriteLine("movlps ["+function.Reg+ToHex(function.Offset)+"],xmm"+GetRegister(function.calc[0]));
             AsmFile.WriteLine("movss ["+function.Reg+ToHex(function.Offset+8)+"],xmm7");
         }
     } else {
         if(flipped) {
             AsmFile.WriteLine("movhps ["+function.Reg+ToHex(function.Offset-8)+"],xmm"+GetRegister(function.calc[0]));
         } else {
             AsmFile.WriteLine("movhps ["+function.Reg+ToHex(function.Offset+4)+"],xmm"+GetRegister(function.calc[0]));
         }
         AsmFile.WriteLine("movss ["+function.Reg+ToHex(function.Offset)+"],xmm"+GetRegister(function.calc[0]));
     }
 }
Beispiel #10
0
 public static void FindFpuLines(VectorMatch[] function)
 {
     ArrayList al=new ArrayList();
     foreach(VectorMatch vm in function) {
         for(int i=0;i<vm.fpulines.Length;i++) {
             al.AddRange(vm.fpulines[i]);
         }
     }
     al.Sort();
     //Remove duplicate references from fxch instructions
     int last=-1;
     for(int i=0;i<al.Count;i++) {
         if((int)al[i]==last) {
             al.RemoveAt(i--);
         } else {
             last=(int)al[i];
         }
     }
     FpuLines=(int[])al.ToArray(typeof(int));
 }
Beispiel #11
0
        public static Operation DeepOp(ref VectorMatch vm, byte depth)
        {
            if (depth > 254)
            {
                throw new OptimizationException("Code generater: Too deep recursion");
            }
            int    count = 0; int maxcount = 0; int pos = 0;
            string s = vm.calc;

            for (int i = 0; i < s.Length; i++)
            {
                switch (s[i])
                {
                case '(':
                    count++;
                    if (count > maxcount)
                    {
                        maxcount = count;
                    }
                    break;

                case ')': count--; break;
                }
            }
            for (int i = 0; i < s.Length; i++)
            {
                switch (s[i])
                {
                case '(':
                    count++;
                    if (count == maxcount)
                    {
                        ArgsToUse atu = ArgsToUse.None;
                        int       b   = 2;
                        if (s[i + 1] != '$')
                        {
                            atu |= ArgsToUse.Left; b--;
                        }
                        if (s[i + 3] != '$')
                        {
                            atu |= ArgsToUse.Right; b--;
                        }
                        Operation o = new Operation();
                        switch (atu)
                        {
                        case ArgsToUse.None:
                            o = new Operation(vm.pArguments[pos], vm.pArguments[pos + 1], s[i + 2]);
                            break;

                        case ArgsToUse.Left:
                            o = new Operation(GetRegister(s[i + 1]), vm.pArguments[pos], s[i + 2]);
                            //Registers[GetRegister(s[i+1])].contains=depth;
                            break;

                        case ArgsToUse.Right:
                            o = new Operation(vm.pArguments[pos], GetRegister(s[i + 3]), s[i + 2]);
                            break;

                        case ArgsToUse.Both:
                            o = new Operation(GetRegister(s[i + 3]), GetRegister(s[i + 1]), s[i + 2]);
                            //Registers[GetRegister(s[i+1])].contains=depth;
                            break;
                        }
                        Vector[] vs = new Vector[vm.pArguments.Length - b];
                        int      c  = 0;
                        for (int a = 0; a < vm.pArguments.Length; a++)
                        {
                            if (a == c && b > 0)
                            {
                                continue;
                            }
                            if (a == c + 1 && b > 1)
                            {
                                continue;
                            }
                            vs[c++] = vm.pArguments[a];
                        }
                        vm.pArguments = vs;
                        vm.calc       = s.Remove(i, 5);
                        vm.calc       = vm.calc.Insert(i, "" + (char)depth);
                        return(o);
                    }
                    break;

                case ')': count--; break;

                case '$':
                    pos++;
                    break;
                }
            }
            throw new OptimizationException("Code generater: No operation to perform");
        }
Beispiel #12
0
        public static void v4CreateCode(VectorMatch function)
        {
            byte a = 0;

            while (function.calc.Length > 1)
            {
                Operation op = DeepOp(ref function, a++);
                if (op.args == ArgsToUse.None)
                {
                    op.op1loc = v4MoveToRegister(op.op1);
                    op.args   = ArgsToUse.Left;
                }
                if ((op.args & ArgsToUse.Left) == 0)
                {
                    op.op1loc = v4MoveToRegister(op.op1);
                    op.args  |= ArgsToUse.Left;
                }
                if ((op.args & ArgsToUse.Right) == 0 && (!aligned || op.op2.Direction != VectorDirection.Up))
                {
                    op.op2loc = v4MoveToRegister(op.op2);
                    op.args  |= ArgsToUse.Right;
                }
                Registers[op.op1loc].contains = (byte)(a - 1);
                string s = null;
                switch (op.op)
                {
                case '+': s = "addps "; break;

                case '-': s = "subps "; break;

                case '*': s = "mulps "; break;

                case '/': s = "divps "; break;
                }
                if ((op.args & ArgsToUse.Left) == 0)
                {
                    s += "[" + op.op1.Register + ToHex(op.op1.Offset) + "],";
                }
                else
                {
                    s += "xmm" + op.op1loc + ",";
                }
                if ((op.args & ArgsToUse.Right) == 0)
                {
                    s += "[" + op.op2.Register + ToHex(op.op2.Offset) + "]";
                }
                else
                {
                    s += "xmm" + op.op2loc;
                }
                AsmFile.WriteLine(s);
            }
            if (!function.Upward)
            {
                AsmFile.WriteLine("shufps xmm" + (byte)function.calc[0] + ",xmm" + GetRegister(function.calc[0]) + ",0x1B");
            }
            if (aligned)
            {
                AsmFile.WriteLine("movaps [" + function.Reg + ToHex(function.Offset) + "],xmm" + GetRegister(function.calc[0]));
            }
            else
            {
                AsmFile.WriteLine("movups [" + function.Reg + ToHex(function.Offset) + "],xmm" + GetRegister(function.calc[0]));
            }
        }
Beispiel #13
0
        public static void v3CreateCode(VectorMatch function)
        {
            byte a = 0;

            //If the function is reversed, flip all the arguments
            if (!function.Upward)
            {
                flipped = true;
                for (int i = 0; i < function.pArguments.Length; i++)
                {
                    if (function.pArguments[i].Direction == VectorDirection.Up)
                    {
                        function.pArguments[i].Direction = VectorDirection.Down;
                    }
                    else if (function.pArguments[i].Direction == VectorDirection.Down)
                    {
                        function.pArguments[i].Direction = VectorDirection.Up;
                    }
                }
            }
            while (function.calc.Length > 1)
            {
                Operation op = DeepOp(ref function, a++);
                if (op.args == ArgsToUse.None)
                {
                    op.op1loc = v3MoveToRegister(op.op1);
                    op.args   = ArgsToUse.Left;
                }
                if ((op.args & ArgsToUse.Left) == 0)
                {
                    op.op1loc = v3MoveToRegister(op.op1);
                    op.args  |= ArgsToUse.Left;
                }
                if ((op.args & ArgsToUse.Right) == 0 && (!aligned || op.op2.Direction != VectorDirection.Up))
                {
                    op.op2loc = v3MoveToRegister(op.op2);
                    op.args  |= ArgsToUse.Right;
                }
                Registers[op.op1loc].contains = (byte)(a - 1);
                string s = null;
                switch (op.op)
                {
                case '+': s = "addps "; break;

                case '-': s = "subps "; break;

                case '*': s = "mulps "; break;

                case '/': s = "divps "; break;
                }
                if ((op.args & ArgsToUse.Left) == 0)
                {
                    s += "[" + op.op1.Register + ToHex(op.op1.Offset) + "],";
                }
                else
                {
                    s += "xmm" + op.op1loc + ",";
                }
                if ((op.args & ArgsToUse.Right) == 0)
                {
                    s += "[" + op.op2.Register + ToHex(op.op2.Offset) + "]";
                }
                else
                {
                    s += "xmm" + op.op2loc;
                }
                AsmFile.WriteLine(s);
            }
            if (aligned)
            {
                AsmFile.WriteLine("movhlps xmm7,xmm" + GetRegister(function.calc[0]));
                if (flipped)
                {
                    AsmFile.WriteLine("movlps [" + function.Reg + ToHex(function.Offset - 4) + "],xmm" + GetRegister(function.calc[0]));
                    AsmFile.WriteLine("movss [" + function.Reg + ToHex(function.Offset - 8) + "],xmm7");
                }
                else
                {
                    AsmFile.WriteLine("movlps [" + function.Reg + ToHex(function.Offset) + "],xmm" + GetRegister(function.calc[0]));
                    AsmFile.WriteLine("movss [" + function.Reg + ToHex(function.Offset + 8) + "],xmm7");
                }
            }
            else
            {
                if (flipped)
                {
                    AsmFile.WriteLine("movhps [" + function.Reg + ToHex(function.Offset - 8) + "],xmm" + GetRegister(function.calc[0]));
                }
                else
                {
                    AsmFile.WriteLine("movhps [" + function.Reg + ToHex(function.Offset + 4) + "],xmm" + GetRegister(function.calc[0]));
                }
                AsmFile.WriteLine("movss [" + function.Reg + ToHex(function.Offset) + "],xmm" + GetRegister(function.calc[0]));
            }
        }
Beispiel #14
0
        public static void GenerateCode(ArrayList function)
        {
            Reset();
            AsmFile.WriteLine("bits 32");
            for (int i = 0; i < function.Count; i++)
            {
                PartialReset();
                VectorMatch vm    = (VectorMatch)function[i];
                int         index = vm.Count - 2;
                if (Program.Mod[index])
                {
                    switch (Program.Align[index])
                    {
                    case 3: aligned = true; break;

                    case 2:
                        if (vm.Offset % 16 == 0)
                        {
                            aligned = true;
                            for (int j = 0; j < vm.pArguments.Length; j++)
                            {
                                if (vm.pArguments[j].Direction != VectorDirection.Static &&
                                    vm.pArguments[j].Offset % 16 != 0)
                                {
                                    aligned = false;
                                }
                            }
                        }
                        else
                        {
                            aligned = false;
                        }
                        break;

                    case 1:
                        if (vm.Offset == 0)
                        {
                            goto case 0;
                        }
                        for (int j = 0; j < Program.CurrentFpu.Pre.Length; j++)
                        {
                            if (Program.CurrentFpu.Pre[j].instruction == "push" || Program.CurrentFpu.Pre[j].instruction == "pop")
                            {
                                aligned = false;
                                goto case 0;
                            }
                        }
                        goto case 2;

                    case 0: aligned = false; break;
                    }
                    switch (vm.Count)
                    {
                    case 2: v2CreateCode(vm); break;

                    case 3: v3CreateCode(vm); break;

                    case 4: v4CreateCode(vm); break;
                    }
                }
                else
                {
                    function.RemoveAt(i--);
                }
            }
            //Copy any leftover fpu lines to the asm file so the esp pointers get updated
            if (function.Count == 0)
            {
                throw new OptimizationException("Code generator: Unable to generate any code");
            }
            FindFpuLines((VectorMatch[])function.ToArray(typeof(VectorMatch)));
            for (int i = 0; i < Program.CurrentFpu.Lines.Length; i++)
            {
                if (Array.IndexOf(FpuLines, i) == -1)
                {
                    AsmFile.WriteLine(Program.CurrentFpu.Lines[i].instruction + " " + Program.CurrentFpu.Lines[i].StoredOperands);
                }
            }
            //Return
            AsmFile.Close();
        }