[RFC] [i386] Test program for ms_abi to sysv_abi function calls
Daniel Santos
daniel.santos@pobox.com
Fri Feb 3 23:30:00 GMT 2017
This is a test program designed to test 64-bit Microsoft ABI functions
that call System V functions in a multitude of permutations to attempt
to discover flaws in the generation of prologues and epilogues and the
optimizationsand features that can affect them, specifically
shrink-wrapping, sibling calls and DRAP. This is an accompaniment to
the below patch sets (and was instrumental in finding and fixingflaws!),
but is not an ancestor.
Use aligned SSE movs for re-aligned MS ABI pro/epilogues -
https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01859.html
Use out-of-line stubs for ms_abi pro/epilogues- (v3 to be posted
shortly! Old v2: https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02293.html)
Summary
=======
A C++ generator program (gen.cc) is built and run to generate an
unguarded C header file, which is included by msabi.c. This header
defines a number of ms_abi functions that call sysv_abi functions with
various conditions. The generator has a CLI for test selection and
currently used arguments (in msabi.exp) generates about 19k tests. The
results of msabi.c and do_test.S are linked to create the test program.
Build time for msabi.c is takes 200-ish seconds on an old Phenom, but
execution is nearly instantaneous.
Each test function is called via an assembly stub (do_test_aligned or
do_test_unaligned) that:
1. Saves non-volatile registers to a global buffer,
2. Fills non-volatile registers with random data,
3. Calls the test function,
4. Saves resulting non-volatile registers for later comparison, and
5. Restores non-volatile registers to original values.
Upon completion, the resulting register values are compared to the
original random values to verify correctness. The return value is also
verified against what is expected to validate the correctness of both
the generated code as well as the test its self.
What Is Tested
==============
The test permutations consists of:
A. A number of extra long parametersfor the function (0-5 being used now).
B. A mask of additional non-volatile registers to explicitly clobber
(aside from RDI, RSI and XMM6-15, which are always clobbered):
enum optional_regs
{
OPTIONAL_REG_RBX = 0x01,
OPTIONAL_REG_RBP = 0x02,
OPTIONAL_REG_R12 = 0x04,
OPTIONAL_REG_R13 = 0x08,
OPTIONAL_REG_R14 = 0x10,
OPTIONAL_REG_R15 = 0x20,
OPTIONAL_REG_ALL = 0x3f,
OPTIONAL_REG_HFP_ALL = OPTIONAL_REG_ALL & (~OPTIONAL_REG_RBP)
};
B. A collection of variants:
enum fn_variants {
FN_VAR_MSABI = 0x01,/* This value is an implementation detail
and NOT a test permutation. */
FN_VAR_HFP = 0x02,
FN_VAR_REALIGN = 0x04,
FN_VAR_ALLOCA = 0x08,
FN_VAR_VARARGS = 0x10,
FN_VAR_SIBCALL = 0x20,
FN_VAR_SHRINK_WRAP = 0x40,
FN_VAR_HFP_OR_REALIGN = FN_VAR_HFP | FN_VAR_REALIGN,
FN_VAR_MASK = 0x7f,
FN_VAR_COUNT = 7
};
The variants deserve a little more explanation.
* FN_VAR_MSABI (implementation detail) Adds__attribute__((ms_abi)).
* FN_VAR_HFP Adds
__attribute__((optimize("no-omit-frame-pointer"))). FN_VAR_HFPand
FN_VAR_REALIGNare mutually exclusive.
* FN_VAR_REALIGN Adds __attribute__((__force_align_arg_pointer__)). The
test will call this function twice -- with an aligned and misaligned stack.
* FN_VAR_ALLOCA The ms_abi function calls alloca and passes the
pointer to the sysv_abi function.
* FN_VAR_VARARGS The ms_abi function takes varargs, but only passes
the argptr to the sysv_abi function.
* FN_VAR_SIBCALL The ms_abi function returns in a way that enables
the sibling call optimization (skipped if FN_VAR_REALIGN | FN_VAR_HFP
are enabled).
* FN_VAR_SHRINK_WRAP Tests a global variable and uses a branch that
enables the use shrink wrapping. Both the fast and slow path are tested.
The following nomenclature is used for function names:
(msabi|sysv)_<xx>_[r|f][a][v][s][w]<n>
| | | | | | | |
| | | | | | | Number of extra parameters (longs)
| | | | | | shrink wrap
| | | | | sibling call
| | | | varargs
| | | alloca
| | Forced realignment or hard frame pointer
| Explicit clobbers (hexadecimalmask)
Calling Convention
Examples
========
The function msabi_25_ra2looks like this:
__attribute__ ((noinline, ms_abi, __force_align_arg_pointer__))
long msabi_25_ra2 (long a, long b)
{
void *alloca_mem;
alloca_mem = alloca (8 + a);
*(long*)alloca_mem = FLAG_ALLOCA;
__asm__ __volatile__ ("" :::"rbx", "r12", "r15");
return sysv_a2_noinfo (alloca_mem, a, b);
}
And the tests (both aligned and misaligned) looks something like this:
void init_test (void *fn, const char *name, enum alignment_option alignment,
enum shrink_wrap_option shrink_wrap, long ret_expected);
void do_tests ()
{
long ret;
long a = 1;
long b = 2;
...
init_test (msabi_25_ra2, "msabi_25_ra2", ALIGNMENT_ALIGNED,
SHRINK_WRAP_NONE, a + b + FLAG_ALLOCA);
ret = do_test_2 (a, b);
check_results (ret);
init_test (msabi_25_ra2, "msabi_25_ra2", ALIGNMENT_MISALIGNED,
SHRINK_WRAP_NONE, a + b + FLAG_ALLOCA);
__asm__ __volatile__ ("subq $8,%%rsp":::"cc");
ret = do_test_u2 (a, b);
__asm__ __volatile__ ("addq $8,%%rsp":::"cc");
check_results (ret);
...
}
gcc/Makefile.in | 2 +
gcc/testsuite/gcc.target/i386/msabi/do_test.S | 162 ++++++
gcc/testsuite/gcc.target/i386/msabi/gen.cc | 788
++++++++++++++++++++++++++
gcc/testsuite/gcc.target/i386/msabi/msabi.c | 379 +++++++++++++
gcc/testsuite/gcc.target/i386/msabi/msabi.exp | 125 ++++
5 files changed, 1456 insertions(+)
Daniel Santos
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-i386-Test-program-for-ms_abi-functions.patch
Type: text/x-patch
Size: 42166 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20170203/e020db4e/attachment.bin>
More information about the Gcc
mailing list