public Operation(byte Op1,byte Op2,char Op) { op1=new Vector(); op2=new Vector(); op=Op; op1loc=Op1; op2loc=Op2; args=ArgsToUse.Both; }
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); }
public Operation(byte Op1,Vector Op2,char Op) { op1=new Vector(); op2=Op2; op=Op; op1loc=Op1; op2loc=255; args=ArgsToUse.Left; }
public Operation(Vector Op1,byte Op2,char Op) { op1=Op1; op2=new Vector(); op=Op; op1loc=255; op2loc=Op2; args=ArgsToUse.Right; }
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"); }
public Operation(Vector Op1,Vector Op2,char Op) { op1=Op1; op2=Op2; op=Op; op1loc=255; op2loc=255; args=ArgsToUse.None; }
public static byte v4MoveToRegister(Vector v) { for(byte x=0;x<8;x++) { if(!Registers[x]) { string r=x.ToString(); switch(v.Direction) { case VectorDirection.Up: if(aligned) { AsmFile.WriteLine("movaps xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); } else { AsmFile.WriteLine("movups xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); } Registers[x]=new RegisterState(VectorDirection.Up,operation); break; case VectorDirection.Down: AsmFile.WriteLine("movhps xmm"+r+",["+v.Register+ToHex(v.Offset-(v.Count-2)*4)+"]"); AsmFile.WriteLine("shufps xmm"+r+",["+v.Register+ToHex(v.Offset-v.Count*4)+"],0x1B"); Registers[x]=new RegisterState(VectorDirection.Down,operation); break; case VectorDirection.Static: AsmFile.WriteLine("movss xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); AsmFile.WriteLine("shufps xmm"+r+",xmm"+r+",0x00"); Registers[x]=new RegisterState(VectorDirection.Static,operation); break; } return x; } } throw new OptimizationException("Code generater: Ran out of registers"); }
public static byte v3MoveToRegister(Vector v) { for(byte x=0;x<8;x++) { if(!Registers[x]) { string r=x.ToString(); switch(v.Direction) { case VectorDirection.Up: if(aligned) { if(flipped) { AsmFile.WriteLine("movaps xmm"+r+",["+v.Register+ToHex(v.Offset-8)+"]"); } else { AsmFile.WriteLine("movaps xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); } } else { AsmFile.WriteLine("movss xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); if(flipped) { AsmFile.WriteLine("movhps xmm"+r+",["+v.Register+ToHex(v.Offset-8)+"]"); } else { AsmFile.WriteLine("movhps xmm"+r+",["+v.Register+ToHex(v.Offset+4)+"]"); } } Registers[x]=new RegisterState(VectorDirection.Up,operation); break; case VectorDirection.Down: throw new OptimizationException("Code generator: Haven't got reversed v3 input working yet"); case VectorDirection.Static: AsmFile.WriteLine("movss xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); AsmFile.WriteLine("shufps xmm"+r+",xmm"+r+",0x00"); Registers[x]=new RegisterState(VectorDirection.Static,operation); break; } return x; } } throw new OptimizationException("Code generater: Ran out of registers"); }
public static byte v2MoveToRegister(Vector v) { for(byte x=0;x<8;x++) { if(!Registers[x]) { string r=x.ToString(); switch(v.Direction) { case VectorDirection.Up: if(flipped) { AsmFile.WriteLine("movlps xmm"+r+",["+v.Register+ToHex(v.Offset-4)+"]"); } else { AsmFile.WriteLine("movlps xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); } Registers[x]=new RegisterState(VectorDirection.Up,operation); break; case VectorDirection.Down: throw new OptimizationException("Code generator: Code using flipped v2's doesn't fit"); case VectorDirection.Static: AsmFile.WriteLine("movss xmm"+r+",["+v.Register+ToHex(v.Offset)+"]"); AsmFile.WriteLine("shufps xmm"+r+",xmm"+r+",0x00"); Registers[x]=new RegisterState(VectorDirection.Static,operation); break; } return x; } } throw new OptimizationException("Code generater: Ran out of registers"); }
public static string MemLoc(Vector v,int offset) { return "["+v.Register+ToHex(v.Offset+offset)+"]"; }
public static string MemLoc(Vector v) { return MemLoc(v,0); }