Changeset 101

Show
Ignore:
Timestamp:
04/23/07 22:53:16 (1 year ago)
Author:
Don Clugston
Message:

Now uses a char [][] array to record type information -- this is much more flexible.

Files:

Legend:

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

    r100 r101  
    205205ReturnType performOperation(ReturnType, char [] operations, char [] finaloperation, int knownlength, X...)(X expr) 
    206206{ 
    207   const char [] tuplestr = vectorTupleToString!(X); 
     207  const char [][] tuplestr = splitTuple(vectorTupleToString!(X)); 
    208208  const char [] rettypestr="real"; 
    209209  static if (is(RetType: ireal)){ rettypestr="ireal";} 
     
    213213 
    214214  version(BladeDebug) { 
    215     pragma(msg, finaloperation ~ " " ~ operations ~ "\nTuple: " ~ tuplestr); 
     215    pragma(msg, finaloperation ~ " " ~ operations ~ "\nTuple: " ~ vectorTupleToString!(X)); 
    216216    static if (knownlength!=0) pragma(msg, "Length is known!"); 
    217217    pragma(msg, "Generated Code: "\n ~ generateCode(rettypestr, tuplestr, operations, finaloperation, knownlength)); 
     
    220220} 
    221221 
    222 char [] generateCode(char [] rettypestr, char [] tuplestr, char [] operations, char [] finaloperation, int knownlength) 
     222char [] generateCode(char [] rettypestr, char [][] tuplestr, char [] operations, char [] finaloperation, int knownlength) 
    223223{ 
    224224    char [] a=""; 
     225//    char [][] tuplestr = splitTuple(rawtuplestr); 
    225226  // Decide which code generator to use, based on expression complexity and 
    226227  // assembler availability. 
     
    242243// of the types in the tuple. 
    243244 
    244 // Create a single-character string representing the type A. 
     245// Create a string representing the type A. 
    245246// Pure imaginary types are treated identically to pure reals, since they result in the 
    246247// same asm code. 
     
    263264template vectorTupleToString(X...) 
    264265{ 
    265     static if (X.length==1) const char [] vectorTupleToString = singleTypeToString!(X[0]); 
    266     else  const char [] vectorTupleToString = singleTypeToString!(X[0]) ~ vectorTupleToString!(X[1..$]); 
     266//    static if (X.length==1) const char [] vectorTupleToString = singleTypeToString!(X[0])~\0; 
     267//    else  const char [] vectorTupleToString = singleTypeToString!(X[0]) ~ \0 ~ vectorTupleToString!(X[1..$]); 
     268    static if (X.length==1) const char [] vectorTupleToString = X[0].stringof ~\0; 
     269    else  const char [] vectorTupleToString = X[0].stringof ~ \0 ~ vectorTupleToString!(X[1..$]); 
     270
     271 
     272// Encode the types in the array. For each entry, format is: 
     273//  first char = category. V for real/imag vector, Z for complex vector, S for scalar. 
     274//  second char = size. F for float, D for double, R for real. 
     275char[][] splitTuple(char [] raw) 
     276
     277    char [][] s; 
     278    int start=0; 
     279    for(int i=0;i<raw.length;++i) { 
     280        if (raw[i]=='\0') { 
     281            char [] a; 
     282            switch(raw[start..i]) { 
     283                case (ifloat[]).stringof: 
     284                case (float[]).stringof: a="VF"; break; 
     285                case (idouble[]).stringof: 
     286                case (double[]).stringof: a="VD"; break; 
     287                case (ireal[]).stringof: 
     288                case (real[]).stringof: a="VR"; break; 
     289                case ireal.stringof: 
     290                case real.stringof: a="SR"; break; 
     291                case idouble.stringof: 
     292                case double.stringof: a="SD"; break; 
     293                case ifloat.stringof: 
     294                case float.stringof: a="SF"; break; 
     295                case cfloat.stringof: 
     296                case cdouble.stringof: 
     297                case creal.stringof: a="SZ"; break; 
     298                case (cfloat[]).stringof: a="ZF"; break; 
     299                case (cdouble[]).stringof: a="ZD"; break; 
     300                case (creal[]).stringof: a="ZZ"; break; 
     301//                default: 
     302//                  a = "??" ~ raw[start..i]; break; 
     303            } 
     304             s~=a; start=i+1; } 
     305    } 
     306    return s; 
    267307} 
    268308 
     
    273313// Return a string to mixed in, which asserts that all vectors are of 
    274314// equal length. 
    275 char [] generateVectorLengthChecks(char [] typelist) 
     315char [] generateVectorLengthChecks(char [][] typelist) 
    276316{ 
    277317    int firstvec = findFirstVector(typelist); 
     
    289329 * 
    290330 */ 
    291 char [] generateCodeForD(char [] rettypestr, int knownlength, char [] typelist, char [] finalop, char [] operation) 
     331char [] generateCodeForD(char [] rettypestr, int knownlength, char [][] typelist, char [] finalop, char [] operation) 
    292332{ 
    293333    char [] iter=""; 
  • trunk/blade/BladeParse.d

    r100 r101  
    2222 
    2323// Return the first index in the tuple which is of vector type 
    24 int findFirstVector(char [] typelist) 
     24int findFirstVector(char [][] typelist) 
    2525{ 
    2626    for (int i=0; i< typelist.length;++i) { 
    2727        if (isVector(typelist[i])) return i; 
    2828    } 
    29     assert(0, typelist); 
    3029} 
    3130 
    32 bool isVector(char var) 
     31bool isVector(char [] typestr) 
    3332{ 
    34     return (var=='R' || var=='D' || var=='F' || var=='Z'); 
     33    return (typestr[0]=='V' || typestr[0]=='Z'); 
    3534} 
     35 
     36// Count the number of vectors in the typestring 
     37int countVectors(char [][] typelist) 
     38{ 
     39    int numVecs=0; 
     40    for (int i=0; i<typelist.length; ++i) { 
     41        if (isVector(typelist[i])) ++numVecs; 
     42    } 
     43    return numVecs; 
     44} 
     45 
  • trunk/blade/CodegenX87.d

    r100 r101  
    2222// Converts an infix string into postfix. Also strips off the # symbols. 
    2323// Apply x87-specific optimisations during the conversion. 
    24 char [] makePostfixForX87(char [] operations, char [] typelist) 
     24char [] makePostfixForX87(char [] operations, char [][] typelist) 
    2525{ 
    2626//    if (operations.length==1) return operations; 
     
    3131    char [] second = operations[x+2..$]; 
    3232    if (first[0]=='(') { 
    33         first = makePostfixForX87(first[1..$-1], typelist); 
     33        first = makePostfixForX87(first[1..first.length-1], typelist); 
    3434    } else if (first[0]=='#') first = operations[1..x+1]; 
    3535    if (second[0]=='(') { 
    36         second = makePostfixForX87(second[1..$-1], typelist); 
     36        second = makePostfixForX87(second[1..second.length-1], typelist); 
    3737    } else if (second[0]=='#') second = operations[x+3..$]; 
    3838 
     
    4747    // complexity of the mini-compiler.). 
    4848    if (operations[x+1]=='+') { 
    49         if (second[$-1]=='*' && first[$-1]!='*') { 
     49        if (second[second.length-1]=='*'&& first[first.length-1]!='*') { 
    5050           return second ~ first ~ operations[x+1..x+2]; 
    5151        } 
     
    5454    // instead of fsub. We use _ to mean reversed subtraction. 
    5555    if (operations[x+1]=='-') { 
    56         if (second[$-1]=='*' && first[$-1]!='*') { 
     56        if (second[second.length-1]=='*' && first[first.length-1]!='*') { 
    5757           return second ~ first ~ "_"; 
    5858        } 
     
    6161    // When an operation is performed between a real[] and a non-real[], 
    6262    // we want to have the real[] being the one which is loaded first. 
    63     if (second.length==1 && typelist[second[0]-'a']=='R' && operations[x+1]=='+') { 
     63    if (second.length==1 && typelist[second[0]-'a']=="VR" && operations[x+1]=='+') { 
    6464           return second ~ first ~ "+"; 
    6565    } 
    66     if (second.length==1 && typelist[second[0]-'a']=='R' && operations[x+1]=='-') { 
     66    if (second.length==1 && typelist[second[0]-'a']=="VR" && operations[x+1]=='-') { 
    6767           return second ~ first ~ "_"; 
    6868    } 
     
    7777{ 
    7878    return (op=='+' || op=='*' || op=='-'|| op=='.'|| op=='_'); 
    79 } 
    80  
    81 // Count the number of vectors in the typestring 
    82 int countVectors(char [] typelist) 
    83 { 
    84     int numVecs=0; 
    85     for (int i=0; i<typelist.length; ++i) { 
    86         if (typelist[i]=='R' || typelist[i]=='D' || typelist[i]=='F' || typelist[i]=='Z') ++numVecs; 
    87     } 
    88     return numVecs; 
    8979} 
    9080 
     
    115105} 
    116106 
    117 int vectorNum(char [] typelist, char var) 
     107int vectorNum(char [][] typelist, char var) 
    118108{ 
    119109    int numVecs=0; 
    120110    for (int i=0; i<var-'a'; ++i) { 
    121         if (typelist[i]=='R' || typelist[i]=='D' || typelist[i]=='F' || typelist[i]=='Z') ++numVecs; 
     111        if (typelist[i]=="VR" || typelist[i]=="VD" || typelist[i]=="VF") ++numVecs; 
    122112    } 
    123113    return numVecs; 
    124114} 
    125115 
    126 int realScalarNum(char [] typelist, char var) 
     116int realScalarNum(char [][] typelist, char var) 
    127117{ 
    128118    int k=0; 
    129119    for (int i=0; i<var-'a'; ++i) { 
    130         if (typelist[i]=='r') ++k; 
     120        if (typelist[i]=="SR") ++k; 
    131121    } 
    132122    return k; 
     
    134124 
    135125 
    136 char [] operandSize(char var) 
    137 { 
    138     switch(var) { 
    139         case 'r'
    140         case 'R': return "real ptr "; 
    141         case 'd'
    142         case 'D': return "double ptr "; 
    143         case 'f'
    144         case 'F': return "float ptr "; 
     126char [] operandSize(char [] typestr) 
     127{ 
     128    switch(typestr) { 
     129        case "SR"
     130        case "VR": return "real ptr "; 
     131        case "SD"
     132        case "VD": return "double ptr "; 
     133        case "SF"
     134        case "VF": return "float ptr "; 
    145135    } 
    146136} 
     
    161151else static if (real.sizeof==16) const char [] REALSIZE = "16"; 
    162152 
    163 char [] vectorSize(char vartype
    164 { 
    165     switch (vartype) { 
    166         case 'D': return "8"; 
    167         case 'F': return "4"; 
    168         case 'R': return REALSIZE; 
     153char [] vectorSize(char [] typestr
     154{ 
     155    switch (typestr) { 
     156        case "VD": return "8"; 
     157        case "VF": return "4"; 
     158        case "VR": return REALSIZE; 
    169159    } 
    170160} 
     
    175165 
    176166// Is this expression simple enough for the x87 code generator? 
    177 bool isX87AsmPossible(char [] typelist, char [] operations) { 
     167bool isX87AsmPossible(char [][] typelist, char [] operations) { 
    178168  version (D_InlineAsm_X86) { 
    179169        // Are there enough index registers? 
     
    182172        foreach(ch; typelist) { 
    183173            // can only do float, double, and 80-bit vectors, and scalars. 
    184             if (ch!='R' && ch!='D' && ch!='F' && ch!='r' && ch!='d' && ch!='s') return false; 
     174            if (ch!="VR" && ch!="VD" && ch!="VF" && ch!="SR" && ch!="SD" && ch!="SF") return false; 
    185175        } 
    186176        // BUG: should also check if it will overflow the FPU stack 
     
    193183 
    194184// Is this expression simple enough for the SSE2 code generator? 
    195 bool isSSE2AsmPossible(char [] typelist, char [] operations) 
     185bool isSSE2AsmPossible(char [][] typelist, char [] operations) 
    196186{ 
    197187  version (D_InlineAsm_X86) { 
     
    199189        foreach(ch; typelist) { 
    200190            // can only do double vectors and double scalars. 
    201             if (ch!='D' && ch!='d') return false; 
     191            if (ch!="VD" && ch!="SD") return false; 
    202192        } 
    203193        return false; // not yet implemented 
     
    224214} 
    225215 
    226 char [] indexedVector(char [] typelist, char var) 
    227 { 
    228     if (typelist[var-'a']=='R') return " real ptr [" ~ vectorRegister[vectorNum(typelist, var)] ~ "]"; 
     216char [] indexedVector(char [][] typelist, char var) 
     217{ 
     218    if (typelist[var-'a']=="VR") return " real ptr [" ~ vectorRegister[vectorNum(typelist, var)] ~ "]"; 
    229219    return operandSize(typelist[var-'a']) ~ "[" ~ 
    230220            vectorRegister[vectorNum(typelist, var)] ~ " + " ~ vectorSize(typelist[var-'a']) ~ "*ESI]"; 
    231221} 
    232222 
    233 char [] storeVector(char type, int vecnum) 
    234 { 
    235     char [] stride = " - " ~ vectorSize(type); 
    236     if (type=='R') { 
     223char [] storeVector(char [] typestr, int vecnum) 
     224{ 
     225    char [] stride = " - " ~ vectorSize(typestr); 
     226    if (typestr=="VR") { 
    237227        return "  fstp real ptr [" ~ vectorRegister[vecnum] ~ stride ~ "];"\n; 
    238228    } else { 
    239         return "  fstp " ~ operandSize(type) ~ " [" ~ vectorRegister[vecnum] ~ " + " ~ vectorSize(type)~ "*ESI" ~ stride ~ "];"\n; 
     229        return "  fstp " ~ operandSize(typestr) ~ " [" ~ vectorRegister[vecnum] ~ " + " ~ vectorSize(typestr)~ "*ESI" ~ stride ~ "];"\n; 
    240230    } 
    241231} 
     
    248238        case '+': return "addpd"; 
    249239        case '-': return "subpd"; 
    250         case '_': return "**BUG**"; // Non-existent! 
     240//        case '_': return "**BUG**"; // Non-existent! 
    251241    } 
    252242} 
     
    259249        case '+': return "addps"; 
    260250        case '-': return "subps"; 
    261         case '_': return "**BUG**"; // Non-existent! 
    262     } 
    263 } 
    264  
    265  
    266 char [] generateCodeForAsmSSE2(int knownlength, char [] typelist, char [] infixOperations, char [] finaloperation) 
     251//        case '_': return "**BUG**"; // Non-existent! 
     252    } 
     253} 
     254 
     255 
     256char [] generateCodeForAsmSSE2(int knownlength, char [][] typelist, char [] infixOperations, char [] finaloperation) 
    267257{ 
    268258// Use ESI as the index register. 
     
    312302 
    313303*/ 
    314 char [] generateCodeForAsmX87(int knownlength, char [] typelist, char [] infixOperations, char [] finaloperation) 
     304char [] generateCodeForAsmX87(int knownlength, char [][] typelist, char [] infixOperations, char [] finaloperation) 
    315305{ 
    316306    char [] operations = makePostfixForX87(infixOperations, typelist); 
     
    323313        if (isVector(typelist[i])){ 
    324314            result~= "  auto vec" ~ itoa(i) ~ " = expr[" ~itoa(i) ~"].ptr;\n"; 
    325             if (typelist[i]=='R') { 
     315            if (typelist[i]=="VR") { 
    326316                incrementRealVectors ~= "  add " ~ vectorRegister[vecnum] ~ ", " ~ REALSIZE ~ ";\n"; 
    327317            } 
     
    333323    } 
    334324 
    335     bool isDotProduct = (operations[$-1]=='.'); 
     325    bool isDotProduct = (operations[operations.length-1]=='.'); 
    336326    int numScalarsOnStack=0; 
    337327 
     
    347337    for (int i=0; i<typelist.length; ++i) { 
    348338      if (isVector(typelist[i])) { 
    349           if (typelist[i]=='R') { 
     339          if (typelist[i]=="VR") { 
    350340              result ~= "  mov " ~ vectorRegister[numvecs] ~ ", vec" ~ itoa(i) ~ ";"\n; 
    351341          } else  { 
     
    355345         } 
    356346        ++numvecs; 
    357       } else if (typelist[i]=='r') { 
     347      } else if (typelist[i]=="SR") { 
    358348          result ~= "  fld real ptr expr["~ itoa(i) ~"];\n"; 
    359349          ++numconsts; 
     
    405395         // If it's a float or double, we can combine the load+arithmetic op 
    406396         // into a single instruction. 
    407          if (typelist[operations[done]-'a']=='R') { 
     397         if (typelist[operations[done]-'a']=="VR") { 
    408398             // 80-bit vectors must be loaded onto the FPU stack first 
    409399            next = "  fld real ptr ["  ~ vectorRegister[vectorNum(typelist, operations[done])] ~ "];\n" 
     
    416406        done +=2; 
    417407      } else { // multiply by scalar. 
    418         if (typelist[operations[done]-'a']=='r') { 
     408        if (typelist[operations[done]-'a']=="SR") { 
    419409             // Multiply by real scalar, which is already on the stack. Note that there's an extra item on the stack when we're in the body of the loop. 
    420410            firstbody ~= "  fmul ST, ST(" ~ itoa(numOnStack + numScalarsOnStack - realScalarNum(typelist, operations[done]-'a')) ~ "); //var" ~ itoa(operations[done]-'a') ~ \n; 
     
    428418      } 
    429419    } 
    430 } else { // length = 1 
     420} else { // operations.length = 1 
    431421    char [] next; 
    432     if (typelist[$-1]=='R'
     422    if (typelist[typelist.length-1]=="VR"
    433423        next = "  fld real ptr ["  ~ vectorRegister[0] ~ "];\n"; 
    434     else next = "  fld "~ operandSize(typelist[$-1]) ~ " [" 
    435         ~ vectorRegister[0] ~ " + " ~ vectorSize(typelist[$-1]) ~ "*ESI];\n"; 
     424    else next = "  fld "~ operandSize(typelist[typelist.length-1]) ~ " [" 
     425        ~ vectorRegister[0] ~ " + " ~ vectorSize(typelist[typelist.length-1]) ~ "*ESI];\n"; 
    436426    mainbody ~=next; firstbody~=next; 
    437427    ++numOnStack; 
     
    448438            if (finaloperation[0]=='-') finalop="fsubr"; 
    449439            char [] next; 
    450              if (typelist[$-1]=='R') { 
     440             if (typelist[typelist.length-1]=="VR") { 
    451441                 // 80-bit vectors must be loaded onto the FPU stack first 
    452442                next = "  fld real ptr ["  ~ vectorRegister[numvecs-1] ~ "];"\n; 
    453443                next ~= "  " ~ finalop ~ "p ST(1), ST;\n"; 
    454444             } else { 
    455                 next = "  " ~ finalop ~ " " ~ operandSize(typelist[$-1]) ~ " [" ~ vectorRegister[numvecs-1] ~ " + " 
    456                 ~ vectorSize(typelist[$-1]) ~ "*ESI];"\n; 
     445                next = "  " ~ finalop ~ " " ~ operandSize(typelist[typelist.length-1]) ~ " [" ~ vectorRegister[numvecs-1] ~ " + " 
     446                ~ vectorSize(typelist[typelist.length-1]) ~ "*ESI];"\n; 
    457447            } 
    458448            mainbody ~=next; firstbody~=next; 
     
    465455    if (isDotProduct) result ~= "  faddp ST(2), ST;"\n; 
    466456    else { 
    467         result ~= storeVector(typelist[$-1], numvecs-1); 
     457        result ~= storeVector(typelist[typelist.length-1], numvecs-1); 
    468458    } 
    469459 
     
    475465    // Store the result from the final iteration 
    476466    if (isDotProduct) result ~= "  faddp ST(1), ST;"\n; 
    477     else result ~= storeVector(typelist[$-1], numvecs-1); 
     467    else result ~= storeVector(typelist[typelist.length-1], numvecs-1); 
    478468 
    479469    // Discard any scalars that are left on the stack