Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Changeset 723:55f6c2e454d7

Show
Ignore:
Timestamp:
10/25/08 00:03:28 (3 months ago)
Author:
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
branch:
default
Message:

Implemented correct parameter order according to x86-32 ABI documentation.
Changed AA types to just a void* .

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dmd/attrib.c

    r716 r723  
    417417    case LINKwindows:   p = "Windows";      break; 
    418418    case LINKpascal:    p = "Pascal";       break; 
     419 
     420    // LDC 
     421    case LINKintrinsic: p = "Intrinsic"; break; 
     422 
    419423    default: 
    420424        assert(0); 
     
    10041008                fd->llvmInternal = llvm_internal; 
    10051009                fd->intrinsicName = arg1str; 
     1010                fd->linkage = LINKintrinsic; 
     1011                ((TypeFunction*)fd->type)->linkage = LINKintrinsic; 
    10061012            } 
    10071013            else if (TemplateDeclaration* td = s->isTemplateDeclaration()) 
  • dmd/expression.c

    r717 r723  
    685685        } 
    686686 
     687// LDC we don't want this! 
     688#if !IN_LLVM 
    687689        // Convert static arrays to pointers 
    688690        tb = arg->type->toBasetype(); 
     
    691693        arg = arg->checkToPointer(); 
    692694        } 
     695#endif 
     696 
    693697 
    694698        // Convert lazy argument to a delegate 
     
    702706 
    703707        // If not D linkage, do promotions 
    704         if (tf->linkage != LINKd) 
     708        // LDC: don't do promotions on intrinsics 
     709        if (tf->linkage != LINKd && tf->linkage != LINKintrinsic) 
    705710        { 
    706711        // Promote bytes, words, etc., to ints 
  • dmd/mangle.c

    r321 r723  
    105105            break; 
    106106 
     107        // LDC 
     108        case LINKintrinsic: 
     109 
    107110        case LINKc: 
    108111        case LINKwindows: 
  • dmd/mars.h

    r708 r723  
    310310    LINKwindows, 
    311311    LINKpascal, 
     312 
     313    // LDC 
     314    LINKintrinsic, 
    312315}; 
    313316 
  • dmd/mtype.c

    r720 r723  
    26742674    this->retAttrs = 0; 
    26752675    this->thisAttrs = 0; 
     2676    this->reverseParams = false; 
     2677    this->reverseIndex = 0; 
    26762678} 
    26772679 
     
    26862688    t->retAttrs = retAttrs; 
    26872689    t->thisAttrs = thisAttrs; 
     2690    t->reverseParams = reverseParams; 
     2691    t->reverseIndex = reverseIndex; 
    26882692    return t; 
    26892693} 
     
    27952799    case LINKpascal:    mc = 'V';   break; 
    27962800    case LINKcpp:       mc = 'R';   break; 
     2801 
     2802    // LDC 
     2803    case LINKintrinsic: mc = 'Q';   break; 
     2804 
    27972805    default: 
    27982806        assert(0); 
     
    28272835        case LINKpascal:    p = "Pascal ";  break; 
    28282836        case LINKcpp:   p = "C++ "; break; 
     2837 
     2838        // LDC 
     2839        case LINKintrinsic: p = "Intrinsic"; break; 
     2840 
    28292841        default: 
    28302842        assert(0); 
     
    28622874        case LINKpascal:    p = "Pascal ";  break; 
    28632875        case LINKcpp:   p = "C++ "; break; 
     2876 
     2877        // LDC 
     2878        case LINKintrinsic: p = "Intrinsic"; break; 
     2879 
    28642880        default: 
    28652881        assert(0); 
  • dmd/mtype.h

    r720 r723  
    441441    unsigned retAttrs; 
    442442    unsigned thisAttrs; // also used for nest 
     443 
     444    bool reverseParams; 
     445    size_t reverseIndex; 
    443446}; 
    444447 
  • gen/functions.cpp

    r720 r723  
    2121#include "gen/classes.h" 
    2222#include "gen/dvalue.h" 
     23 
     24#include <algorithm> 
    2325 
    2426const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, const LLType* nesttype, bool ismain) 
     
    112114    } 
    113115 
     116    // number of formal params 
    114117    size_t n = Argument::dim(f->parameters); 
     118 
     119    // on x86 we need to reverse the formal params in some cases to match the ABI 
     120    if (global.params.cpu == ARCHx86) 
     121    { 
     122        // more than one formal arg, 
     123        // extern(D) linkage 
     124        // not a D-style vararg 
     125        if (n > 1 && f->linkage == LINKd && !typesafeVararg) 
     126        { 
     127            f->reverseParams = true; 
     128            f->reverseIndex = paramvec.size(); 
     129        } 
     130    } 
     131 
    115132 
    116133    for (int i=0; i < n; ++i) { 
     
    168185    } 
    169186 
     187    // reverse params? 
     188    if (f->reverseParams) 
     189    { 
     190        std::reverse(paramvec.begin() + f->reverseIndex, paramvec.end()); 
     191    } 
     192 
    170193    // construct function type 
    171194    bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; 
     
    190213            else 
    191214            { 
     215                int inreg = f->reverseParams ? n - 1 : 0; 
    192216                Argument* arg = Argument::getNth(f->parameters, 0); 
    193217                Type* t = arg->type->toBasetype(); 
     
    341365            fdecl->llvmInternal = LLVMintrinsic; 
    342366            DtoOverloadedIntrinsicName(tinst, tempdecl, fdecl->intrinsicName); 
     367            fdecl->linkage = LINKintrinsic; 
     368            ((TypeFunction*)fdecl->type)->linkage = LINKintrinsic; 
    343369        } 
    344370    } 
     
    355381static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) 
    356382{ 
    357     int llidx = 1
     383    int llidx = 0
    358384    if (f->retInPtr) ++llidx; 
    359385    if (f->usesThis) ++llidx; 
     
    363389 
    364390    int funcNumArgs = func->getArgumentList().size(); 
    365     std::vector<llvm::AttributeWithIndex> attrs; 
    366     int k = 0; 
    367  
     391 
     392    LLSmallVector<llvm::AttributeWithIndex, 9> attrs; 
    368393    llvm::AttributeWithIndex PAWI; 
    369394 
     
    393418 
    394419    // set attrs on the rest of the arguments 
    395     for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) 
     420    size_t n = Argument::dim(f->parameters); 
     421    assert(funcNumArgs >= n); // main might mismatch, for the implicit char[][] arg 
     422 
     423    LLSmallVector<unsigned,8> attrptr(n, 0); 
     424 
     425    for (size_t k = 0; k < n; ++k) 
    396426    { 
    397427        Argument* fnarg = Argument::getNth(f->parameters, k); 
    398428        assert(fnarg); 
    399429 
    400         PAWI.Index = llidx; 
    401         PAWI.Attrs = fnarg->llvmAttrs; 
    402  
    403         if (PAWI.Attrs) 
     430        attrptr[k] = fnarg->llvmAttrs; 
     431    } 
     432 
     433    // reverse params? 
     434    if (f->reverseParams) 
     435    { 
     436        std::reverse(attrptr.begin(), attrptr.end()); 
     437    } 
     438 
     439    // build rest of attrs list 
     440    for (int i = 0; i < n; i++) 
     441    { 
     442        if (attrptr[i]) 
     443        { 
     444            PAWI.Index = llidx+i+1; 
     445            PAWI.Attrs = attrptr[i]; 
    404446            attrs.push_back(PAWI); 
    405     } 
    406  
    407     llvm::AttrListPtr palist = llvm::AttrListPtr::get(attrs.begin(), attrs.end()); 
    408     func->setAttributes(palist); 
     447        } 
     448    } 
     449 
     450    llvm::AttrListPtr attrlist = llvm::AttrListPtr::get(attrs.begin(), attrs.end()); 
     451    func->setAttributes(attrlist); 
    409452} 
    410453 
     
    504547        // name parameters 
    505548        llvm::Function::arg_iterator iarg = func->arg_begin(); 
    506         int k = 0; 
     549 
    507550        if (f->retInPtr) { 
    508551            iarg->setName(".sretarg"); 
     
    510553            ++iarg; 
    511554        } 
    512          
     555 
    513556        if (f->usesThis) { 
    514557            iarg->setName("this"); 
     
    533576        } 
    534577 
     578        int k = 0; 
     579 
    535580        for (; iarg != func->arg_end(); ++iarg) 
    536581        { 
    537582            if (fdecl->parameters && fdecl->parameters->dim > k) 
    538583            { 
    539                 Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++]; 
     584                Dsymbol* argsym; 
     585                if (f->reverseParams) 
     586                    argsym = (Dsymbol*)fdecl->parameters->data[fdecl->parameters->dim-k-1]; 
     587                else 
     588                    argsym = (Dsymbol*)fdecl->parameters->data[k]; 
     589 
    540590                VarDeclaration* argvd = argsym->isVarDeclaration(); 
    541591                assert(argvd); 
     
    544594                argvd->ir.irLocal->value = iarg; 
    545595                iarg->setName(argvd->ident->toChars()); 
     596 
     597                k++; 
    546598            } 
    547599            else 
     
    903955 
    904956    // ref/out arg 
    905     if (fnarg && ((fnarg->storageClass & STCref) || (fnarg->storageClass & STCout))) 
     957    if (fnarg && (fnarg->storageClass & (STCref | STCout))) 
    906958    { 
    907959        if (arg->isVar() || arg->isLRValue()) 
  • gen/tocall.cpp

    r720 r723  
    3535unsigned DtoCallingConv(LINK l) 
    3636{ 
    37     if (l == LINKc || l == LINKcpp
     37    if (l == LINKc || l == LINKcpp || l == LINKintrinsic
    3838        return llvm::CallingConv::C; 
    3939    else if (l == LINKd || l == LINKdefault) 
     
    112112////////////////////////////////////////////////////////////////////////////////////////// 
    113113 
    114 void DtoBuildDVarArgList(std::vector<LLValue*>& args, llvm::AttrListPtr& palist, TypeFunction* tf, Expressions* arguments, size_t argidx) 
     114void DtoBuildDVarArgList(std::vector<LLValue*>& args, std::vector<llvm::AttributeWithIndex>& attrs, TypeFunction* tf, Expressions* arguments, size_t argidx) 
    115115{ 
    116116    Logger::println("doing d-style variadic arguments"); 
     
    196196 
    197197        if (fnarg->llvmAttrs) 
    198             palist = palist.addAttr(argidx, fnarg->llvmAttrs); 
     198        { 
     199            llvm::AttributeWithIndex Attr; 
     200            Attr.Index = argidx; 
     201            Attr.Attrs = fnarg->llvmAttrs; 
     202            attrs.push_back(Attr); 
     203        } 
    199204 
    200205        ++argidx; 
     
    235240    assert(callableTy); 
    236241 
     242    if (Logger::enabled()) 
     243    { 
     244        Logger::cout() << "callable: " << *callable << '\n'; 
     245    } 
     246 
    237247    // get n arguments 
    238248    size_t n_arguments = arguments ? arguments->dim : 0; 
     
    243253 
    244254    // parameter attributes 
    245     llvm::AttrListPtr palist; 
     255    std::vector<llvm::AttributeWithIndex> attrs; 
     256    llvm::AttributeWithIndex Attr; 
    246257 
    247258    // return attrs 
    248259    if (tf->retAttrs) 
    249         palist = palist.addAttr(0, tf->retAttrs); 
     260    { 
     261        Attr.Index = 0; 
     262        Attr.Attrs = tf->retAttrs; 
     263        attrs.push_back(Attr); 
     264    } 
    250265 
    251266    // handle implicit arguments 
     
    260275 
    261276        // add attrs for hidden ptr 
    262         palist = palist.addAttr(1, llvm::Attribute::StructRet); 
     277        Attr.Index = 1; 
     278        Attr.Attrs = llvm::Attribute::StructRet; 
     279        attrs.push_back(Attr); 
    263280    } 
    264281 
     
    305322        // add attributes for context argument 
    306323        if (tf->thisAttrs) 
    307             palist = palist.addAttr(retinptr?2:1, tf->thisAttrs); 
     324        { 
     325            Attr.Index = retinptr ? 2 : 1; 
     326            Attr.Attrs = tf->thisAttrs; 
     327            attrs.push_back(Attr); 
     328        } 
    308329    } 
    309330 
     
    327348    else if (dvarargs) 
    328349    { 
    329         DtoBuildDVarArgList(args, palist, tf, arguments, argiter-argbegin+1); 
     350        DtoBuildDVarArgList(args, attrs, tf, arguments, argiter-argbegin+1); 
    330351    } 
    331352 
    332353    // otherwise we're looking at a normal function call 
     354    // or a C style vararg call 
    333355    else 
    334356    { 
    335357        Logger::println("doing normal arguments"); 
    336         for (int i=0; i<n_arguments; i++) { 
    337             int j = argiter-argbegin; 
     358 
     359        size_t n = Argument::dim(tf->parameters); 
     360 
     361        LLSmallVector<unsigned, 10> attrptr(n, 0); 
     362 
     363        // do formal params 
     364        int beg = argiter-argbegin; 
     365        for (int i=0; i<n; i++) 
     366        { 
    338367            Argument* fnarg = Argument::getNth(tf->parameters, i); 
     368            assert(fnarg); 
    339369            DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); 
    340370            LLValue* arg = argval->getRVal(); 
    341             if (fnarg) // can fnarg ever be null in this block? 
    342             { 
     371 
     372            int j = tf->reverseParams ? beg + n - i - 1 : beg + i; 
     373 
     374            // parameter type mismatch, this is hard to get rid of 
     375            if (arg->getType() != callableTy->getParamType(j)) 
     376            { 
     377            #if 0 
    343378                if (Logger::enabled()) 
    344379                { 
     
    346381                    Logger::cout() << "expects: " << *callableTy->getParamType(j) << '\n'; 
    347382                } 
    348                 if (arg->getType() != callableTy->getParamType(j)) 
    349                     arg = DtoBitCast(arg, callableTy->getParamType(j)); 
    350                 if (fnarg->llvmAttrs) 
    351                     palist = palist.addAttr(j+1, fnarg->llvmAttrs); 
    352             } 
     383            #endif 
     384                arg = DtoBitCast(arg, callableTy->getParamType(j)); 
     385            } 
     386 
     387            // param attrs 
     388            attrptr[i] = fnarg->llvmAttrs; 
     389 
    353390            ++argiter; 
    354391            args.push_back(arg); 
     392        } 
     393 
     394        // reverse the relevant params as well as the param attrs 
     395        if (tf->reverseParams) 
     396        { 
     397            std::reverse(args.begin() + tf->reverseIndex, args.end()); 
     398            std::reverse(attrptr.begin(), attrptr.end()); 
     399        } 
     400 
     401        // add attributes 
     402        for (int i = 0; i < n; i++) 
     403        { 
     404            if (attrptr[i]) 
     405            { 
     406                Attr.Index = beg + i + 1; 
     407                Attr.Attrs = attrptr[i]; 
     408                attrs.push_back(Attr); 
     409            } 
     410        } 
     411 
     412        // do C varargs 
     413        if (n_arguments > n) 
     414        { 
     415            for (int i=n; i<n_arguments; i++) 
     416            { 
     417                Argument* fnarg = Argument::getNth(tf->parameters, i); 
     418                DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); 
     419                LLValue* arg = argval->getRVal(); 
     420 
     421                // FIXME: do we need any param attrs here ? 
     422 
     423                ++argiter; 
     424                args.push_back(arg); 
     425            } 
    355426        } 
    356427    } 
     
    406477 
    407478    // set calling convention and parameter attributes 
     479    llvm::AttrListPtr attrlist = llvm::AttrListPtr::get(attrs.begin(), attrs.end()); 
    408480    if (dfnval && dfnval->func) 
    409481    { 
    410482        LLFunction* llfunc = llvm::dyn_cast<LLFunction>(dfnval->val); 
    411         if (llfunc && llfunc->isIntrinsic()) 
    412             palist = llvm::Intrinsic::getAttributes((llvm::Intrinsic::ID)llfunc->getIntrinsicID()); 
     483        if (llfunc && llfunc->isIntrinsic()) // override intrinsic attrs 
     484            attrlist = llvm::Intrinsic::getAttributes((llvm::Intrinsic::ID)llfunc->getIntrinsicID()); 
    413485        else 
    414486            call->setCallingConv(callconv); 
     
    416488    else 
    417489        call->setCallingConv(callconv); 
    418     call->setAttributes(palist); 
     490    call->setAttributes(attrlist); 
    419491 
    420492    return new DImValue(resulttype, retllval); 
  • gen/tollvm.cpp

    r719 r723  
    164164    // associative arrays 
    165165    case Taarray: 
     166    #if 1 
     167        return getVoidPtrType(); 
     168    #else 
    166169    { 
    167170        TypeAArray* taa = (TypeAArray*)t; 
     
    169172        return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0)); 
    170173    } 
     174    #endif 
    171175 
    172176/* 
  • tests/mini/intrinsics.d

    r663 r723  
    2222    real r; 
    2323    printf("Enter real: "); 
    24     //scanf("%lf", &d); 
     24    //scanf("%llf", &r); 
    2525    r = 3.2311167891231231234754764576; 
    2626    version(X86) 
Copyright © 2008, LDC Development Team.