Changeset 99
- Timestamp:
- 04/14/07 15:13:17 (1 year ago)
- Files:
-
- trunk/blade/Blade.d (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r98 r99 59 59 } 60 60 61 char [] itoa( ulongx)61 char [] itoa(T)(T x) 62 62 { 63 63 char [] s=""; 64 static if (is(T==byte)||is(T==short)||is(T==int)||is(T==long)) { 65 if (x<0) { 66 s = "-"; 67 x = -x; 68 } 69 } 64 70 do { 65 71 s = cast(char)('0' + (x%10)) ~ s; … … 69 75 } 70 76 71 char [] itoa(long x) 72 { 73 if (x<0) return "-" ~ itoa(cast(ulong)(-x)); 74 return itoa(cast(ulong)(x)); 75 } 76 77 char [] itoa(int x) 78 { 79 return itoa(cast(long)(x)); 80 } 77 81 78 82 79 // ------------------------------------------- … … 137 134 alias operations ops; 138 135 alias B ValueTuple; 139 Bvalues;136 ValueTuple values; 140 137 alias knownlength len; 141 138 // Append another tuple described by 'second', with operation 'op' … … 144 141 } 145 142 // Construct a vector expression, with the given arguments. 146 static VectorExpr!(BaseType, operations, knownlength, B) opCall(B b) { 143 static VectorExpr!(BaseType, operations, knownlength, B) create(B b) { 144 // alias VectorExpr!(BaseType, operations, knownlength, B) Target; 145 // return *cast(Target *)cast(void *)(&b[0]); 147 146 VectorExpr!(BaseType, operations, knownlength, B) q; 148 147 foreach (i, dummy; b) q.values[i] = b[i]; … … 153 152 // All they do is update the expression string and the tuple, creating a new 154 153 // VectorExpr. The existing VectorExpr will not be used again. 155 static if (operations.length>2 && operations[$-2]=='*') { 156 // Optimisation: already a scalar multiply, so constant fold it. 157 VectorExpr!(BaseType, operations, knownlength, B) opMul(real x) { 158 return VectorExpr!(BaseType, operations, knownlength, B)(values[0..$-1], x*values[$-1]); 159 } 160 VectorExpr!(typeof(BaseType*1.0fi), operations, knownlength, B) opMul(ireal x) { 161 return VectorExpr!(typeof(BaseType*1.0fi), operations, knownlength, B)(values[0..$-1], x.im*values[$-1]); 162 } 163 } else { 164 JoinResult!(typeof(BaseType*C), "*", "#a", C) opMul(C)(C x) { 165 static assert(is(C: real) || is(C:ireal) || is(C:creal), "Can only multiply by scalars"); 166 return JoinResult!(typeof(BaseType*C), "*", "#a", C)(values, x); 167 } 154 JoinResult!(typeof(BaseType*C), "*", "#a", C) opMul(C)(C x) { 155 static assert(is(C: real) || is(C:ireal) || is(C:creal), "Can only multiply by scalars"); 156 return JoinResult!(typeof(BaseType*C), "*", "#a", C).create(values, x); 168 157 } 169 158 JoinResult!(typeof(BaseType+C.BaseType), "+", C.ops, C.ValueTuple) opAdd(C)(C x) { 170 return JoinResult!(typeof(BaseType+C.BaseType), "+", C.ops, C.ValueTuple) (values, x.values);159 return JoinResult!(typeof(BaseType+C.BaseType), "+", C.ops, C.ValueTuple).create(values, x.values); 171 160 } 172 161 JoinResult!(typeof(BaseType-C.BaseType), "-", C.ops, C.ValueTuple) opSub(C)(C x) { 173 return JoinResult!(typeof(BaseType-C.BaseType), "-", C.ops, C.ValueTuple) (values, x.values);162 return JoinResult!(typeof(BaseType-C.BaseType), "-", C.ops, C.ValueTuple).create(values, x.values); 174 163 } 175 164 176 165 // The opAssign operations are only valid for single vectors, not for temporaries 177 // They actually perform the calculation.178 166 static if (operations=="#a") { 179 167 void opAssign(A)(A expr) { … … 191 179 } 192 180 private: 181 // Actually perform the calculation. 193 182 void doAssign(char [] assignOperation, A)(A expr) { 194 183 // Check for type mismatches and length mismatches when performing vector assignment. … … 239 228 static if (isSSE2AsmPossible(tupstr, operations)) { 240 229 const char [] q1 = generateCodeForAsmSSE2(knownlength, tupstr, makePostfixForX87(operations, tupstr), finaloperation); 241 pragma(msg, q1);230 pragma(msg, "Generated SSE2 code: "\n ~ q1); 242 231 } else static if (isX87AsmPossible(tupstr, operations)) { 243 232 244 233 const char [] qqq = generateCodeForAsmX87(knownlength, tupstr, makePostfixForX87(operations, tupstr), finaloperation); 245 pragma(msg, "Generated code:"\n ~ qqq);234 pragma(msg, "Generated x87 code:"\n ~ qqq); 246 235 } else pragma(msg, "Too complicated for x87 -- generating D code instead"); 247 236 } … … 268 257 // Pure imaginary types are treated identically to pure reals, since they result in the 269 258 // same asm code. 270 template singleType (A)271 { 272 static if (is(A == real[]) || is(A == ireal[])) const char [] singleType= "R";273 else static if (is(A == double[])|| is(A == idouble[])) const char [] singleType= "D";274 else static if (is(A == float[]) || is(A == ifloat[])) const char [] singleType= "F";275 else static if (is(A == creal[]) || is(A == cdouble[]) || is(A==cfloat[])) const char [] singleType = "Z";276 277 else static if (is(A == real) || is (A == ireal)) const char [] singleType = "r";278 else static if (is(A == double) || is (A == idouble)) const char [] singleType = "d";279 else static if (is(A == float) || is (A == ifloat)) const char [] singleType = "f";280 else static if (is(A : creal)) const char [] singleType = "z";281 else const char [] singleType = "?";282 } 283 284 // A CTFE function can'trandomly index a tuple, so convert the type information259 template singleTypeToString(A) 260 { 261 static if (is(A == real[]) || is(A == ireal[])) const char [] singleTypeToString = "R"; 262 else static if (is(A == double[])|| is(A == idouble[])) const char [] singleTypeToString = "D"; 263 else static if (is(A == float[]) || is(A == ifloat[])) const char [] singleTypeToString = "F"; 264 else static if (is(A == creal[]) || is(A == cdouble[]) || is(A==cfloat[])) const char [] singleTypeToString = "Z"; 265 266 else static if (is(A == real) || is (A == ireal)) const char [] singleTypeToString = "r"; 267 else static if (is(A == double) || is (A == idouble)) const char [] singleTypeToString = "d"; 268 else static if (is(A == float) || is (A == ifloat)) const char [] singleTypeToString = "f"; 269 else static if (is(A : creal)) const char [] singleTypeToString = "z"; 270 else const char [] singleTypeToString = "?"; 271 } 272 273 // A CTFE function is not permitted to randomly index a tuple, so convert the type information 285 274 // into a char[]. 286 275 template vectorTupleToString(X...) 287 276 { 288 static if (X.length==1) const char [] vectorTupleToString = singleType !(X[0]);289 else const char [] vectorTupleToString = singleType !(X[0]) ~ vectorTupleToString!(X[1..$]);277 static if (X.length==1) const char [] vectorTupleToString = singleTypeToString!(X[0]); 278 else const char [] vectorTupleToString = singleTypeToString!(X[0]) ~ vectorTupleToString!(X[1..$]); 290 279 } 291 280 … … 438 427 } 439 428 return numVecs; 429 } 430 431 // Count the number of temporaries which occur in the postfix expression. 432 int countTemporaries(char [] postfix) 433 { 434 // A temporary occurs whenever we load two values without an operation performed on the 435 // first one. 436 int numTemps=0; 437 for (int i=1; i<postfix.length; ++i) { 438 if (!isInstruction(postfix[i-1]) && !isInstruction(postfix[i])) numTemps++; 439 } 440 return numTemps; 441 } 442 443 // The maximum number of simultaneous temporary values in the postfix expression. 444 int maxActiveTemporaries(char [] postfix) 445 { 446 int maxTemps=0; 447 int numTemps=0; 448 for (int i=1; i<postfix.length; ++i) { 449 if (!isInstruction(postfix[i-1]) && !isInstruction(postfix[i])) numTemps++; 450 if (isInstruction(postfix[i])) numTemps--; 451 if (maxTemps<numTemps) maxTemps=numTemps; 452 } 453 return maxTemps; 454 440 455 } 441 456 … … 830 845 auto w = Vec([2.0+17.0i, 0+28.1i, 8.1+1i]); 831 846 847 // asm { int 3; } 832 848 w*=(35.0 + 2.1i); 833 849 … … 839 855 840 856 q -= ((r+p)*18.0L*314.1L - (p-r))*35.0; 841 d = dot(r, p+r+r); 842 writefln(d, " ", e); 843 assert(d==2267.625); 857 real d2 = dot(r, p+r+r); 858 assert(d2==2267.625); 844 859 q*=2.1; 845 846 860 /* 847 861 p = r - q*2.0;
