Changeset 99

Show
Ignore:
Timestamp:
04/14/07 15:13:17 (1 year ago)
Author:
Don Clugston
Message:

Better comments. Added functions for counting temporaries.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/blade/Blade.d

    r98 r99  
    5959} 
    6060 
    61 char [] itoa(ulong x) 
     61char [] itoa(T)(T x) 
    6262{ 
    6363    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    } 
    6470    do { 
    6571        s = cast(char)('0' + (x%10)) ~ s; 
     
    6975} 
    7076 
    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 
    8178 
    8279// ------------------------------------------- 
     
    137134    alias operations ops; 
    138135    alias B ValueTuple; 
    139     B values; 
     136    ValueTuple values; 
    140137    alias knownlength len; 
    141138    // Append another tuple described by 'second', with operation 'op' 
     
    144141    } 
    145142    // 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]); 
    147146        VectorExpr!(BaseType, operations, knownlength, B) q; 
    148147        foreach (i, dummy; b) q.values[i] = b[i]; 
     
    153152    // All they do is update the expression string and the tuple, creating a new 
    154153    // 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); 
    168157    } 
    169158    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); 
    171160    } 
    172161    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); 
    174163    } 
    175164 
    176165    // The opAssign operations are only valid for single vectors, not for temporaries 
    177     // They actually perform the calculation. 
    178166  static if (operations=="#a") { 
    179167    void opAssign(A)(A expr) { 
     
    191179    } 
    192180private: 
     181    // Actually perform the calculation. 
    193182    void doAssign(char [] assignOperation, A)(A expr) { 
    194183        // Check for type mismatches and length mismatches when performing vector assignment. 
     
    239228  static if (isSSE2AsmPossible(tupstr, operations)) { 
    240229            const char [] q1 = generateCodeForAsmSSE2(knownlength, tupstr, makePostfixForX87(operations, tupstr), finaloperation); 
    241       pragma(msg, q1); 
     230      pragma(msg, "Generated SSE2 code: "\n ~ q1); 
    242231  } else static if (isX87AsmPossible(tupstr, operations)) { 
    243232 
    244233            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); 
    246235        } else pragma(msg, "Too complicated for x87 -- generating D code instead"); 
    247236          } 
     
    268257// Pure imaginary types are treated identically to pure reals, since they result in the 
    269258// 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't randomly index a tuple, so convert the type information 
     259template 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 
    285274// into a char[]. 
    286275template vectorTupleToString(X...) 
    287276{ 
    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..$]); 
    290279} 
    291280 
     
    438427    } 
    439428    return numVecs; 
     429} 
     430 
     431// Count the number of temporaries which occur in the postfix expression. 
     432int 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. 
     444int 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 
    440455} 
    441456 
     
    830845    auto w = Vec([2.0+17.0i, 0+28.1i, 8.1+1i]); 
    831846 
     847//    asm { int 3; } 
    832848    w*=(35.0 + 2.1i); 
    833849 
     
    839855 
    840856    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); 
    844859    q*=2.1; 
    845  
    846860/* 
    847861    p = r - q*2.0;