// This is an implementation of the x86-64 ABI as described in 'System V // Application Binary Interface, AMD64 Architecture Processor Supplement' // (http://www.x86-64.org/documentation/abi-0.95.pdf) // // The code in this file is a modification of src/x86/ffi64.c from libffi // (http://sources.redhat.com/libffi/) which is under the following license:
/* Register class used for passing given 64bit part of the argument. TheserepresentclassesasdocumentedbythePSABI,withtheexception ofSSESF,SSEDFclasses,thatarebasicallySSEclass,justgccwill useSForDFmodemoveinsteadofDImodetoavoidreformattingpenalties.
/* x86-64 register passing implementation. See x86-64 ABI for details. Goal ofthiscodeistoclassifyeach8bytesofincomingargumentbytheregister
class and assign registers accordingly. */
/* Return the union class of CLASS1 and CLASS2.
See the x86-64 PS ABI for details. */
staticenum x86_64_reg_class
merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
noexcept
{ /* Rule #1: If both classes are equal, this is the resulting class. */ if (class1 == class2) return class1;
/* Rule #2: If one of the classes is NO_CLASS, the resulting class is
the other class. */ if (class1 == X86_64_NO_CLASS) return class2; if (class2 == X86_64_NO_CLASS) return class1;
/* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) return X86_64_MEMORY_CLASS;
/* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
|| (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) return X86_64_INTEGERSI_CLASS; if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
|| class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) return X86_64_INTEGER_CLASS;
/* Rule #6: Otherwise class SSE is used. */ return X86_64_SSE_CLASS;
}
/* Classify a parameter/return type. CLASSESwillbefilledbytheregisterclassusedtopasseachword oftheoperand.Thenumberofwordsisreturned.Incasetheoperand shouldbepassedinmemory,0isreturned.
Seethex86-64PSABIfordetails.
*/ staticint
classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int byteOffset ) noexcept
{ switch ( pTypeRef->eTypeClass )
{ case typelib_TypeClass_CHAR: case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_ENUM: if ( ( byteOffset % 8 + pTypeRef->pType->nSize ) <= 4 )
classes[0] = X86_64_INTEGERSI_CLASS; else
classes[0] = X86_64_INTEGER_CLASS; return1; case typelib_TypeClass_FLOAT: if ( ( byteOffset % 8 ) == 0 )
classes[0] = X86_64_SSESF_CLASS; else
classes[0] = X86_64_SSE_CLASS; return1; case typelib_TypeClass_DOUBLE:
classes[0] = X86_64_SSE_CLASS; return1; case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_INTERFACE: return0; case typelib_TypeClass_STRUCT:
{
typelib_TypeDescription * pTypeDescr = nullptr;
TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
constint UNITS_PER_WORD = 8; int words = ( pTypeDescr->nSize + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD; enum x86_64_reg_class subclasses[MAX_CLASSES];
/* If the struct is larger than 16 bytes, pass it on the stack. */ if ( pTypeDescr->nSize > 16 )
{
TYPELIB_DANGER_RELEASE( pTypeDescr ); return0;
}
for ( int i = 0; i < words; i++ )
classes[i] = X86_64_NO_CLASS;
/* Merge the fields of structure. */ for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
{
typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ]; int offset = byteOffset + pStruct->pMemberOffsets[ nMember ];
int num = classify_argument( pTypeInStruct, subclasses, offset );
if ( num == 0 )
{
TYPELIB_DANGER_RELEASE( pTypeDescr ); return0;
}
for ( int i = 0; i < num; i++ )
{ int pos = offset / 8;
classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] ); if (classes[i + pos] == X86_64_MEMORY_CLASS) {
TYPELIB_DANGER_RELEASE( pTypeDescr ); return0;
}
}
}
TYPELIB_DANGER_RELEASE( pTypeDescr );
return words;
}
default:
O3TL_UNREACHABLE;
}
}
/* Examine the argument and return set number of register required in each
class. Return 0 iff parameter should be passed in memory. */ bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, int &nUsedGPR, int &nUsedSSE ) noexcept
{ enum x86_64_reg_class classes[MAX_CLASSES]; // coverity[uninit_use_in_call : FALSE] int n = classify_argument( pTypeRef, classes, 0 );
if ( n == 0 ) returnfalse;
nUsedGPR = 0;
nUsedSSE = 0; for ( n--; n >= 0; n-- ) switch ( classes[n] )
{ case X86_64_INTEGER_CLASS: case X86_64_INTEGERSI_CLASS:
nUsedGPR++; break; case X86_64_SSE_CLASS: case X86_64_SSESF_CLASS:
nUsedSSE++; break; default:
O3TL_UNREACHABLE;
} returntrue;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.38Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.