Commits

Iain Buclaw committed ab99d67

Merge preliminary vector support from DMD 304af22b62

Comments (0)

Files changed (14)

             }
             break;
         }
+        case VECTOR_TYPE:
+        {
+            d = gcc_type_to_d_type(TREE_TYPE(t));
+            if (d)
+            {
+                d = new TypeSArray(d, new IntegerExp(0, TYPE_VECTOR_SUBPARTS(t), Type::tindex));
+
+                // For now, only support 128bit vectors... what about 64bit?
+                if (d->size() != 16 || d->nextOf()->isTypeBasic() == NULL)
+                    break;
+
+                d = new TypeVector(0, d);
+                d = d->semantic(0, NULL);
+                return d;
+            }
+            break;
+        }
         case RECORD_TYPE:
         {
             for (size_t i = 0; i < builtin_converted_types.dim; i += 2)
     return RETstack;
 }
 
+#if V2
+type *
+TypeVector::toCtype()
+{
+    if (! ctype)
+    {
+        int nunits = ((TypeSArray *) basetype)->dim->toUInteger();
+        tree inner = TREE_TYPE(basetype->toCtype());
+
+        ctype = build_vector_type (inner, nunits);
+        layout_type(ctype);
+
+        /* Give a graceful error if the backend does not support the vector type
+           we are creating.  If backend has support for the inner type mode,
+           then it can safely emulate the vector.  */
+        if (! targetm.vector_mode_supported_p(TYPE_MODE(ctype))
+                && ! targetm.scalar_mode_supported_p(TYPE_MODE(inner)))
+            ::error("vector type %s is not supported on this architechture", toChars());
+    }
+    return ctype;
+}
+#endif
+
 type *
 TypeSArray::toCtype()
 {

d/dmd2/argtypes.c

     return t;
 }
 
+TypeTuple *TypeVector::toArgTypes()
+{
+    return new TypeTuple(Type::tfloat64);
+}
+
 TypeTuple *TypeSArray::toArgTypes()
 {
 #if DMDV2

d/dmd2/cppmangle.c

 }
 
 
+void TypeVector::toCppMangle(OutBuffer *buf, CppMangleState *cms)
+{
+    if (!cms->substitute(buf, this))
+    {   buf->writestring("U8__vector");
+        basetype->toCppMangle(buf, cms);
+    }
+}
+
 void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
 {
     if (!cms->substitute(buf, this))

d/dmd2/declaration.c

     type = Type::typeinfoassociativearray->type;
 }
 
+/***************************** TypeInfoVectorDeclaration ***********************/
+
+TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+    if (!Type::typeinfoarray)
+    {
+        ObjectNotFound(Id::TypeInfo_Vector);
+    }
+    type = Type::typeinfovector->type;
+}
+
 /***************************** TypeInfoEnumDeclaration ***********************/
 
 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)

d/dmd2/declaration.h

 
     void toDt(dt_t **pdt);
 };
+
+struct TypeInfoVectorDeclaration : TypeInfoDeclaration
+{
+    TypeInfoVectorDeclaration(Type *tinfo);
+
+    void toDt(dt_t **pdt);
+};
 #endif
 
 /**************************************************************/
     { "TypeInfo_Enum" },
     { "TypeInfo_Typedef" },
     { "TypeInfo_Pointer" },
+    { "TypeInfo_Vector" },
     { "TypeInfo_Array" },
     { "TypeInfo_StaticArray" },
     { "TypeInfo_AssociativeArray" },
     {   "__thread",     TOKtls          },
     {   "__gshared",    TOKgshared      },
     {   "__traits",     TOKtraits       },
+    {   "__vector",     TOKvector       },
     {   "__overloadset", TOKoverloadset },
     {   "__FILE__",     TOKfile         },
     {   "__LINE__",     TOKline         },
 }
 
 void Lexer::initKeywords()
-{   StringValue *sv;
-    unsigned u;
-    enum TOK v;
+{
     unsigned nkeywords = sizeof(keywords) / sizeof(keywords[0]);
 
     stringtable.init();
 
     cmtable_init();
 
-    for (u = 0; u < nkeywords; u++)
-    {   const char *s;
-
+    for (unsigned u = 0; u < nkeywords; u++)
+    {
         //printf("keyword[%d] = '%s'\n",u, keywords[u].name);
-        s = keywords[u].name;
-        v = keywords[u].value;
-        sv = stringtable.insert(s, strlen(s));
+        const char *s = keywords[u].name;
+        enum TOK v = keywords[u].value;
+        StringValue *sv = stringtable.insert(s, strlen(s));
         sv->ptrvalue = (void *) new Identifier(sv->lstring.string,v);
 
         //printf("tochars[%d] = '%s'\n",v, s);
         TOKat,
         TOKpow,
         TOKpowass,
+        TOKvector,
 #endif
 
         TOKMAX
 ClassDeclaration *Type::typeinfoarray;
 ClassDeclaration *Type::typeinfostaticarray;
 ClassDeclaration *Type::typeinfoassociativearray;
+ClassDeclaration *Type::typeinfovector;
 ClassDeclaration *Type::typeinfoenum;
 ClassDeclaration *Type::typeinfofunction;
 ClassDeclaration *Type::typeinfodelegate;
     mangleChar[Ttuple] = 'B';
     mangleChar[Tslice] = '@';
     mangleChar[Treturn] = '@';
+    mangleChar[Tvector] = '@';
 
     mangleChar[Tnull] = 'n';    // same as TypeNone
 
     return (TypeBasic *)this;
 }
 
+/* ============================= TypeVector =========================== */
+
+/* The basetype must be one of:
+ *   byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
+ */
+TypeVector::TypeVector(Loc loc, Type *basetype)
+        : Type(Tvector)
+{
+    this->basetype = basetype;
+}
+
+Type *TypeVector::syntaxCopy()
+{
+    return this;
+}
+
+Type *TypeVector::semantic(Loc loc, Scope *sc)
+{
+    int errors = global.errors;
+    basetype = basetype->semantic(loc, sc);
+    if (errors != global.errors)
+        return terror;
+    basetype = basetype->toBasetype()->mutableOf();
+    if (basetype->ty != Tsarray || basetype->size() != 16)
+    {   error(loc, "base type of __vector must be a 16 byte static array, not %s", basetype->toChars());
+        return terror;
+    }
+    TypeSArray *t = (TypeSArray *)basetype;
+    TypeBasic *tb = t->nextOf()->isTypeBasic();
+    if (!tb)
+    {   error(loc, "base type of __vector must be a static array of an arithmetic type, not %s", t->toChars());
+        return terror;
+    }
+    return merge();
+}
+
+char *TypeVector::toChars()
+{
+    return Type::toChars();
+}
+
+void TypeVector::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
+{
+    //printf("TypeVector::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
+    if (mod != this->mod)
+    {   toCBuffer3(buf, hgs, mod);
+        return;
+    }
+    buf->writestring("__vector(");
+    basetype->toCBuffer2(buf, hgs, this->mod);
+    buf->writestring(")");
+}
+
+void TypeVector::toDecoBuffer(OutBuffer *buf, int flag)
+{
+    if (flag != mod && flag != 0x100)
+    {
+        MODtoDecoBuffer(buf, mod);
+    }
+    buf->writestring("Nh");
+    basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
+}
+
+d_uns64 TypeVector::size(Loc loc)
+{
+    return 16;
+}
+
+unsigned TypeVector::alignsize()
+{
+    return 16;
+}
+
+Expression *TypeVector::getProperty(Loc loc, Identifier *ident)
+{
+    return basetype->getProperty(loc, ident);
+}
+
+Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident)
+{
+#if LOGDOTEXP
+    printf("TypeVector::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars());
+#endif
+    return basetype->dotExp(sc, e, ident);
+}
+
+Expression *TypeVector::defaultInit(Loc loc)
+{
+    return basetype->defaultInit(loc);
+}
+
+int TypeVector::isZeroInit(Loc loc)
+{
+    return basetype->isZeroInit(loc);
+}
+
+int TypeVector::isintegral()
+{
+    //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
+    return basetype->nextOf()->isintegral();
+}
+
+int TypeVector::isfloating()
+{
+    return basetype->nextOf()->isfloating();
+}
+
+int TypeVector::isunsigned()
+{
+    return basetype->nextOf()->isunsigned();
+}
+
+int TypeVector::isscalar()
+{
+    return TRUE;        // I should hope so
+}
+
+MATCH TypeVector::implicitConvTo(Type *to)
+{
+    //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
+    if (this == to)
+        return MATCHexact;
+    if (ty == to->ty)
+        return MATCHconvert;
+    return MATCHnomatch;
+}
+
 /***************************** TypeArray *****************************/
 
 TypeArray::TypeArray(TY ty, Type *next)
 
     Treturn,
     Tnull,
+    Tvector,
     TMAX
 };
 typedef unsigned char TY;       // ENUMTY
     static ClassDeclaration *typeinfoarray;
     static ClassDeclaration *typeinfostaticarray;
     static ClassDeclaration *typeinfoassociativearray;
+    static ClassDeclaration *typeinfovector;
     static ClassDeclaration *typeinfoenum;
     static ClassDeclaration *typeinfofunction;
     static ClassDeclaration *typeinfodelegate;
     TypeBasic *isTypeBasic();
 };
 
+struct TypeVector : Type
+{
+    Type *basetype;
+
+    TypeVector(Loc loc, Type *basetype);
+    Type *syntaxCopy();
+    Type *semantic(Loc loc, Scope *sc);
+    d_uns64 size(Loc loc);
+    unsigned alignsize();
+    Expression *getProperty(Loc loc, Identifier *ident);
+    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
+    char *toChars();
+    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
+    void toDecoBuffer(OutBuffer *buf, int flag);
+#if CPP_MANGLE
+    void toCppMangle(OutBuffer *buf, CppMangleState *cms);
+#endif
+    int isintegral();
+    int isfloating();
+    int isscalar();
+    int isunsigned();
+    MATCH implicitConvTo(Type *to);
+    Expression *defaultInit(Loc loc);
+    int isZeroInit(Loc loc);
+    TypeInfoDeclaration *getTypeInfoDeclaration();
+    TypeTuple *toArgTypes();
+
+#if IN_GCC
+    type *toCtype();
+#endif
+};
+
 struct TypeArray : TypeNext
 {
     TypeArray(TY ty, Type *next);
             case TOKsuper:
             case TOKtypeof:
             case TOKdot:
+            case TOKvector:
             Ldeclaration:
                 a = parseDeclarations(STCundefined, NULL);
                 decldefs->append(a);
 #endif
 
 /***********************************
+ * Parse __vector(type).
+ * Current token is on the '__vector'.
+ */
+
+#if DMDV2
+Type *Parser::parseVector()
+{
+    Loc loc = this->loc;
+    nextToken();
+    check(TOKlparen);
+    Type *tb = parseType();
+    check(TOKrparen);
+    return new TypeVector(loc, tb);
+}
+#endif
+
+/***********************************
  * Parse extern (linkage)
  * The parser is on the 'extern' token.
  */
             tqual = parseTypeof();
             check(TOKdot);
         }
+        else if (token.value == TOKvector)
+        {
+            tqual = parseVector();
+            check(TOKdot);
+        }
         if (token.value != TOKidentifier)
         {
             error("identifier expected, not %s", token.toChars());
             ta = new TypeIdentifier(loc, token.ident);
             goto LabelX;
 
+        case TOKvector:
+            ta = parseVector();
+            goto LabelX;
+
         case BASIC_TYPES_X(ta):
             tiargs->push(ta);
             nextToken();
             tid = parseTypeof();
             goto Lident2;
 
+        case TOKvector:
+            t = parseVector();
+            break;
+
         case TOKconst:
             // const(type)
             nextToken();
             // fallthrough to TOKdot
         case TOKdot:
         case TOKtypeof:
+        case TOKvector:
             if (isDeclaration(&token, 2, TOKreserved, NULL))
                 goto Ldeclaration;
             else
         case TOKgshared:
         case TOKat:
 #endif
-//      case TOKtypeof:
         Ldeclaration:
         {   Dsymbols *a;
 
             goto Ldot;
 
         case TOKtypeof:
+        case TOKvector:
             /* typeof(exp).identifier...
              */
             t = peek(t);
             break;
         }
 
+        case TOKvector:
+        {
+            t = parseVector();
+            e = new TypeExp(loc, t);
+            break;
+        }
+
         case TOKtypeid:
         {
             nextToken();
                     case TOKfunction:
                     case TOKdelegate:
                     case TOKtypeof:
+                    case TOKvector:
 #if DMDV2
                     case TOKfile:
                     case TOKline:
     Objects *parseTemplateArgument();
     StaticAssert *parseStaticAssert();
     TypeQualified *parseTypeof();
+    Type *parseVector();
     enum LINK parseLinkage();
     Condition *parseDebugCondition();
     Condition *parseVersionCondition();
         return new TypeInfoClassDeclaration(this);
 }
 
+TypeInfoDeclaration *TypeVector::getTypeInfoDeclaration()
+{
+    return new TypeInfoVectorDeclaration(this);
+}
+
 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
 {
     return new TypeInfoEnumDeclaration(this);
     dtsize_t(pdt, tc->dim->toInteger());         // length
 }
 
+void TypeInfoVectorDeclaration::toDt(dt_t **pdt)
+{
+    //printf("TypeInfoVectorDeclaration::toDt()\n");
+    dtxoff(pdt, Type::typeinfovector->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Vector
+    dtsize_t(pdt, 0);                        // monitor
+
+    assert(tinfo->ty == Tvector);
+
+    TypeVector *tc = (TypeVector *)tinfo;
+
+    tc->basetype->getTypeInfo(NULL);
+    dtxoff(pdt, tc->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for equivalent static array
+}
+
 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
 {
     //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");