# HG changeset patch # User Leonard Ritter # Date 1520981269 -3600 # Tue Mar 13 23:47:49 2018 +0100 # Node ID 91df6ee890163fc01d2e5e6d2c669d72efc5c083 # Parent 621dc0a9ccff14bb7076f4c67cf3cf2180aeee8a * fixed test_abi for windows diff --git a/src/scopes.cpp b/src/scopes.cpp --- a/src/scopes.cpp +++ b/src/scopes.cpp @@ -7775,12 +7775,15 @@ // support in the front-end, particularly whether an argument is passed by // value or not. -// based on x86-64 PS ABI +// based on x86-64 PS ABI (SystemV) #define DEF_ABI_CLASS_NAMES \ /* This class consists of integral types that fit into one of the general */ \ /* purpose registers. */ \ T(INTEGER) \ T(INTEGERSI) \ + /* special types for windows, not used anywhere else */ \ + T(INTEGERSI16) \ + T(INTEGERSI8) \ /* The class consists of types that fit into a vector register. */ \ T(SSE) \ T(SSESF) \ @@ -8046,12 +8049,35 @@ T = cast(T)->return_type; } classes[0] = ABI_CLASS_NO_CLASS; - if (T == TYPE_Void) + if (is_opaque(T)) return 1; - if (size_of(T) > 8) + T = storage_type(T); + size_t sz = size_of(T); + if (sz > 8) return 0; - else + switch(T->kind()) { + case TK_Array: + case TK_Union: + case TK_Tuple: + if (sz <= 1) + classes[0] = ABI_CLASS_INTEGERSI8; + else if (sz <= 2) + classes[0] = ABI_CLASS_INTEGERSI16; + else if (sz <= 4) + classes[0] = ABI_CLASS_INTEGERSI; + else + classes[0] = ABI_CLASS_INTEGER; return 1; + case TK_Integer: + case TK_Extern: + case TK_Pointer: + case TK_Real: + case TK_ReturnLabel: + case TK_Typename: + case TK_Vector: + default: + return 1; + } #else size_t sz = classify(T, classes, 0); #if 0 @@ -8070,7 +8096,7 @@ static bool is_memory_class(const Type *T) { ABIClass classes[MAX_ABI_CLASSES]; - return !classify(T, classes, 0); + return !abi_classify(T, classes); } //------------------------------------------------------------------------------ @@ -10158,7 +10184,7 @@ static LLVMTypeRef abi_struct_type(const ABIClass *classes, size_t sz) { LLVMTypeRef types[sz]; - int k = 0; + size_t k = 0; for (size_t i = 0; i < sz; ++i) { ABIClass cls = classes[i]; switch(cls) { @@ -10177,6 +10203,12 @@ case ABI_CLASS_INTEGERSI: { types[i] = i32T; k++; } break; + case ABI_CLASS_INTEGERSI16: { + types[i] = i16T; k++; + } break; + case ABI_CLASS_INTEGERSI8: { + types[i] = i8T; k++; + } break; default: { // do nothing #if 0 @@ -10198,8 +10230,6 @@ LLVMValueRef val = LLVMGetParam(func, k++); return LLVMBuildLoad(builder, val, ""); } -#ifdef SCOPES_WIN32 -#else LLVMTypeRef T = type_to_llvm_type(param->type); auto tk = LLVMGetTypeKind(T); if (tk == LLVMStructTypeKind) { @@ -10219,7 +10249,6 @@ return LLVMBuildLoad(builder, ptr, ""); } } -#endif LLVMValueRef val = LLVMGetParam(func, k++); return val; } @@ -10234,64 +10263,52 @@ LLVMBuildStore(builder, val, ptrval); val = ptrval; memptrs.push_back(values.size()); - } else { -#ifdef SCOPES_WIN32 values.push_back(val); -#else - auto tk = LLVMGetTypeKind(LLVMTypeOf(val)); - if (tk == LLVMStructTypeKind) { - auto ST = abi_struct_type(classes, sz); - if (!ST) { - // as-is + return; + } + auto tk = LLVMGetTypeKind(LLVMTypeOf(val)); + if (tk == LLVMStructTypeKind) { + auto ST = abi_struct_type(classes, sz); + if (ST) { + // break into argument-sized bits + auto ptr = LLVMBuildAlloca(builder, LLVMTypeOf(val), ""); + auto zero = LLVMConstInt(i32T,0,false); + LLVMBuildStore(builder, val, ptr); + ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(ST, 0), ""); + for (size_t i = 0; i < sz; ++i) { + LLVMValueRef indices[] = { + zero, LLVMConstInt(i32T,i,false), + }; + auto val = LLVMBuildGEP(builder, ptr, indices, 2, ""); + val = LLVMBuildLoad(builder, val, ""); values.push_back(val); - } else { - // break into argument-sized bits - auto ptr = LLVMBuildAlloca(builder, LLVMTypeOf(val), ""); - auto zero = LLVMConstInt(i32T,0,false); - LLVMBuildStore(builder, val, ptr); - ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(ST, 0), ""); - for (size_t i = 0; i < sz; ++i) { - LLVMValueRef indices[] = { - zero, LLVMConstInt(i32T,i,false), - }; - auto val = LLVMBuildGEP(builder, ptr, indices, 2, ""); - val = LLVMBuildLoad(builder, val, ""); - values.push_back(val); - } - } - } else { - values.push_back(val); - } -#endif - } + } + return; + } + } + values.push_back(val); } static void abi_transform_parameter(const Type *AT, std::vector ¶ms) { ABIClass classes[MAX_ABI_CLASSES]; - size_t sz = classify(AT, classes, 0); + size_t sz = abi_classify(AT, classes); auto T = type_to_llvm_type(AT); if (!sz) { params.push_back(LLVMPointerType(T, 0)); - } else { - #ifdef SCOPES_WIN32 - params.push_back(T); - #elif 1 - auto tk = LLVMGetTypeKind(T); - if (tk == LLVMStructTypeKind) { - auto ST = abi_struct_type(classes, sz); - if (!ST) { - params.push_back(T); - } else { - for (size_t i = 0; i < sz; ++i) { - params.push_back(LLVMStructGetTypeAtIndex(ST, i)); - } - } - } else { - params.push_back(T); - } - #endif - } + return; + } + auto tk = LLVMGetTypeKind(T); + if (tk == LLVMStructTypeKind) { + auto ST = abi_struct_type(classes, sz); + if (ST) { + for (size_t i = 0; i < sz; ++i) { + params.push_back(LLVMStructGetTypeAtIndex(ST, i)); + } + return; + } + } + params.push_back(T); } static LLVMTypeRef create_llvm_type(const Type *type) { @@ -10708,8 +10725,12 @@ auto ret = LLVMBuildCall(builder, func, &values[0], values.size(), ""); for (auto idx : memptrs) { auto i = idx + 1; +#ifdef SCOPES_WIN32 + LLVMAddCallSiteAttribute(ret, i, attr_nonnull); +#else LLVMAddCallSiteAttribute(ret, i, attr_byval); LLVMAddCallSiteAttribute(ret, i, attr_nonnull); +#endif } auto rlt = cast(fi->return_type); multiple_return_values = rlt->has_multiple_return_values(); @@ -16863,10 +16884,10 @@ static void f_type_debug_abi(const Type *T) { ABIClass classes[MAX_ABI_CLASSES]; - size_t sz = classify(T, classes, 0); + size_t sz = abi_classify(T, classes); StyledStream ss(std::cout); ss << T << " -> " << sz; - for (int i = 0; i < sz; ++i) { + for (size_t i = 0; i < sz; ++i) { ss << " " << abi_class_to_string(classes[i]); } ss << std::endl; diff --git a/testing/test_abi.sc b/testing/test_abi.sc --- a/testing/test_abi.sc +++ b/testing/test_abi.sc @@ -85,8 +85,8 @@ lib.Vec3 1.0 2.0 3.0 lib.Vec3 4.0 5.0 6.0 -#compile - typify testf4 +compile + typify testf1 'dump-module assert (1 == (testf4))