ctypes-commit Mailing List for ctypes (Page 25)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2006-02-02 20:32:41
|
Update of /cvsroot/ctypes/ctypes/docs/manual In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1847 Modified Files: Tag: branch_1_0 manual.txt manual.html Added Files: Tag: branch_1_0 libraries.txt functions.txt Log Message: manual.txt now includes the sections. Added a 'functions' section. --- NEW FILE: functions.txt --- Functions --------- Functions exported from loaded shared libraries can be accessed in two ways. The easiest way is to access them as attributes of library obects by name:: libc = cdll.find("c") # posix libc = cdll.msvcrt # windows atoi = libc.atoi This creates an instance of a forein function object, using the calling convention specified by the library object ``cdll``, bound to the standard C library ``atoi`` function. The C function is assumed to return an integer (which is correct for ``atoi``), and the argument types are not specified (``atoi`` expects a single ``char *`` argument). If the library function returns a type different from ``int``, the ``restype`` attribute can be set to a ctypes type that describes to return type, or to ```None`` meaning no return value (``void``). The optional ``argtypes`` attribute can be set to a sequence of ctypes types that the function expects. The function can (as in C) be called with more arguments than the length of the argtypes sequence. The optional ``errcheck`` attribute can be set to a Python callable, it can be used to validate and/or process the library functions return value. ``errcheck`` will be called with three arguments, after the library function has returned:: errcheck(retval, function, arguments) ``retval`` is the value that the library function returned, comverted according to ``restype``. ``function`` is the ctypes function object (libc.atoi in this case), and ``arguments`` is a tuple containing the arguments that have been used to call ``function``. ``errcheck`` should validate the library function result, raise an error if it detects a failure, or return the needed return value otherwise. Prototypes ---------- Another way to access a function exported from shared libraries is to first create a prototype by calling a factory function, specifying the return type and the argument types. The factory function itself specifies the calling convention: ``CFUNCTYPE`` uses the standard C calling convention, ``WINFUNCTYPE`` (Windows only) uses the stdcall calling convention. The factory function must be called with the return type plus the argument types. For the C ``atoi`` function one would use ``CFUNCTYPE(c_int, c_char_p)``. This returns a function prototype, which is a ctypes type representing all functions that are compatible with the calling convention, return type, and argument types. The ``CFUNCTYPE`` and ``WINFUNCTYPE`` factory functions cache and reuse the types they create in internal caches, so is is cheap to call them over and over with the same or different arguments. An instance of this function prototype, bound to a foreign library function, can be created by calling the prototype with the name of the function, and a library object:: proto = CFUNCTYPE(c_int, c_char_p) atoi = proto("atoi", libc) It is possible to specify a third argument ``paramflags`` when calling the prototype. This is used to specify additional information for each argument: direction of data transfer, the name, and a default value. A tuple with the same length as ``argtypes`` (the second argument in the prototype call) must be used. Each item in this tuple must be a tuple, having either one, two, or three items. The first item is the direction flag, an integer specifying if this is an input (use ``1``) or an output (use ``2``) parameter. The optional second item is a string containing the parameter name, the optional third item is a default value for the parameter. If parameter names are specified, the function object created can be called with named arguments in the usual way. Arguments with default values do not need to be specified when the function is called. ``out`` parameter types must be pointer types. When the function object is called, ctypes will automatically create empty instances of them, pass them to the library function, retrieve the value from them, and return the value, if there is exactly one ``out`` parameter, or a tuple of values, if there is more than one ``out`` parameter. The original foreign function return value is lost in this case (but see below for how it can be retrieved). If ``paramflags`` have been used in the prototype call, and an ``errcheck`` attribuet is also present, the ``errcheck`` callable will be called with a fourth parameter ``outargs``:: errcheck(retval, function, arguments, outargs) ``outargs`` is a tuple containing all the ``out`` parameters that ctypes has created. Without the ``errcheck`` function ctypes would retrieve the values contained in these pointer objects, and return them. The ``errcheck`` function can let ctypes continue this processing by returning the ``outargs`` tuple. It could also return something else, or raise an error if it detects that the library function has failed. --- NEW FILE: libraries.txt --- Shared Libraries, DLLs ---------------------- Shared libraries are accessed when compiling/linking a program, and when the program is run. The purpose of the ``find`` method is to locate a library in a way similar to what the compiler does (on platforms with several versions of a shared library the most recent should be loaded), while ``load`` acts like when a program is run, and uses the runtime loader directly. ``load_version`` works like ``load`` but tries to be platform independent (for cases where this makes sense). Loading via attribute access is a shorthand notation especially usefull for interactive use, it is equivalent to calling ``load_version`` with no version specified. class LibraryLoader ------------------- Instances of this ``LibraryLoader`` are used to load shared libraries. They have the following methods: ``load(libname, mode=None)`` Load and return the library with the given libname. On most systems ``libname`` is the filename of the shared library; when it's not a pathname it will be searched in a system dependend list of locations (on many systems additional search paths can be specified by an environemtn variable). Sometimes the file extension (like ``.dll`` on Windows) can be omitted. ``mode`` allows to override the default flags passed to the ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are typical values. On Windows, ``mode`` is ignored. ``load_version(name, version=None, mode=None)`` Build a system dependend filename from ``name`` and optionally ``version``, then load and return it. ``name`` is the library name without any prefix like ``lib`` and suffix like ``.so`` or ``.dylib``. This method should be used if a library is available on different platforms, using the particular naming convention of each platform. ``mode`` allows to override the default flags passed to the ``dlopen()`` function, ignored on Windows. Example: calling ``loader.load_version('z', '1.1.3')`` would possibly load ``/usr/lib/libz.1.1.3.dylib`` on Mac OS X, and ``/lib/libz.so.1.1.3`` on a Linux system. ``find(name, mode=None)`` Try to find a library, load and return it. ``name`` is the library name without any prefix like ``lib``, suffix like ``.so``, ``.dylib`` or version number (this is the form used for the posix linker option ``-l``). ``mode`` allows to override the default flags passed to the ``dlopen()`` function, ignored on Windows. On Windows, this method does exactly the same as the ``load`` method. On other platforms, this function might call other programs like the compiler to find the library. When using ctypes to write a shared library wrapping, consider using ``load_version`` or ``load`` instead. Libaries can also be loaded by accessing them as attributes of the loader instance, internally this calls ``load_version`` without specifying ``version`` or ``mode``. Obviously this only works for libraries with names that are valid Python identifiers, and when the name does not start with a ``_`` character. Predefined library loaders -------------------------- ctypes provides some LibraryLoader instances, the differences are the calling conventions the functions will use, the default return type of the functions, and other stuff. All these loaders use the ``RTLD_LOCAL`` mode flag. Functions can be accessed as named attributes of loaded libraries. On Windows, structured exception handling is used around the function call to protect Python from crashing in case you pass invalid parameters to the function. ``cdll`` Functions provided by libraries loaded using the ``cdll`` loader will be called with the standard C calling convention, and have a default return type of ``int``. ctypes does release the Python global interpreter lock (GIL) just before calling the actual function, and reaquire it before returing, so a chance is given to other threads to run. ``windll`` Windows only. Functions provided by libraries loaded by ``windll`` will be called using the Windows ``__stdcall`` calling convention. ctypes can to detect the case that the wrong number of parameters have been passed to the function call by examining the stack pointer before and after the function call. If the wrong parameter count was used, an exception is raised (although the function really *has* been called). The return value of the function is lost in this case. Again, the GIL is released during the call. ``oledll`` Windows only. ``oledll`` behaves in the same way as ``windll``, except that the called function is expected to return a ``HRESULT`` value. These are long values containing error or success codes. In case the function return an error ``HRESULT`` value, a `WindowsError`` is raised. GIL released during the function call. ``pydll`` This loader allows to call functions in libraries using the *Python* calling convention, for example Python C API functions. The GIL is *not* released during the function call, and the state of the Python error flag is examined after the function returns. If the error flag is set, an exception is raised. ctypes provides a prefabricated instance of ``pydll`` exposing the Python C api as the ``pythonapi`` symbol, you should however make sure to set the correct ``restype`` for the functions you use. Index: manual.html =================================================================== RCS file: /cvsroot/ctypes/ctypes/docs/manual/Attic/manual.html,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** manual.html 27 Jan 2006 20:34:24 -0000 1.1.2.2 --- manual.html 2 Feb 2006 20:32:29 -0000 1.1.2.3 *************** *** 297,307 **** <p class="topic-title first"><a id="contents" name="contents">Contents</a></p> <ul class="simple"> ! <li><a class="reference" href="#loading-shared-libraries" id="id1" name="id1">Loading shared libraries</a></li> <li><a class="reference" href="#class-libraryloader" id="id2" name="id2">class LibraryLoader</a></li> <li><a class="reference" href="#predefined-library-loaders" id="id3" name="id3">Predefined library loaders</a></li> </ul> </div> <div class="section"> ! <h1><a class="toc-backref" href="#id1" id="loading-shared-libraries" name="loading-shared-libraries">Loading shared libraries</a></h1> <p>Shared libraries are accessed when compiling/linking a program, and when the program is run. The purpose of the <tt class="docutils literal"><span class="pre">find</span></tt> method is to --- 297,309 ---- <p class="topic-title first"><a id="contents" name="contents">Contents</a></p> <ul class="simple"> ! <li><a class="reference" href="#shared-libraries-dlls" id="id1" name="id1">Shared Libraries, DLLs</a></li> <li><a class="reference" href="#class-libraryloader" id="id2" name="id2">class LibraryLoader</a></li> <li><a class="reference" href="#predefined-library-loaders" id="id3" name="id3">Predefined library loaders</a></li> + <li><a class="reference" href="#functions" id="id4" name="id4">Functions</a></li> + <li><a class="reference" href="#prototypes" id="id5" name="id5">Prototypes</a></li> </ul> </div> <div class="section"> ! <h1><a class="toc-backref" href="#id1" id="shared-libraries-dlls" name="shared-libraries-dlls">Shared Libraries, DLLs</a></h1> <p>Shared libraries are accessed when compiling/linking a program, and when the program is run. The purpose of the <tt class="docutils literal"><span class="pre">find</span></tt> method is to *************** *** 326,330 **** of locations (on many systems additional search paths can be specified by an environemtn variable). Sometimes the file ! extension (like <tt class="docutils literal"><span class="pre">.dll</span></tt> pon Windows) can be omitted.</p> <p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the <tt class="docutils literal"><span class="pre">dlopen()</span></tt> function. <tt class="docutils literal"><span class="pre">RTLD_LOCAL</span></tt> and <tt class="docutils literal"><span class="pre">RTLD_GLOBAL</span></tt> are --- 328,332 ---- of locations (on many systems additional search paths can be specified by an environemtn variable). Sometimes the file ! extension (like <tt class="docutils literal"><span class="pre">.dll</span></tt> on Windows) can be omitted.</p> <p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the <tt class="docutils literal"><span class="pre">dlopen()</span></tt> function. <tt class="docutils literal"><span class="pre">RTLD_LOCAL</span></tt> and <tt class="docutils literal"><span class="pre">RTLD_GLOBAL</span></tt> are *************** *** 353,358 **** <p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the <tt class="docutils literal"><span class="pre">dlopen()</span></tt> function, ignored on Windows.</p> ! <blockquote> ! <p>On windows, this method does exactly the same as the <tt class="docutils literal"><span class="pre">load</span></tt> method.</p> <p>On other platforms, this function might call other programs like --- 355,359 ---- <p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the <tt class="docutils literal"><span class="pre">dlopen()</span></tt> function, ignored on Windows.</p> ! <p>On Windows, this method does exactly the same as the <tt class="docutils literal"><span class="pre">load</span></tt> method.</p> <p>On other platforms, this function might call other programs like *************** *** 361,365 **** <tt class="docutils literal"><span class="pre">load</span></tt> instead.</p> </blockquote> - </blockquote> <p>Libaries can also be loaded by accessing them as attributes of the loader instance, internally this calls <tt class="docutils literal"><span class="pre">load_version</span></tt> without --- 362,365 ---- *************** *** 417,420 **** --- 417,514 ---- </blockquote> </div> + <div class="section"> + <h1><a class="toc-backref" href="#id4" id="functions" name="functions">Functions</a></h1> + <p>Functions exported from loaded shared libraries can be accessed in two + ways. The easiest way is to access them as attributes of library + obects by name:</p> + <pre class="literal-block"> + libc = cdll.find("c") # posix + libc = cdll.msvcrt # windows + atoi = libc.atoi + </pre> + <p>This creates an instance of a forein function object, using the + calling convention specified by the library object <tt class="docutils literal"><span class="pre">cdll</span></tt>, bound to + the standard C library <tt class="docutils literal"><span class="pre">atoi</span></tt> function. The C function is assumed + to return an integer (which is correct for <tt class="docutils literal"><span class="pre">atoi</span></tt>), and the argument + types are not specified (<tt class="docutils literal"><span class="pre">atoi</span></tt> expects a single <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> + argument).</p> + <p>If the library function returns a type different from <tt class="docutils literal"><span class="pre">int</span></tt>, the + <tt class="docutils literal"><span class="pre">restype</span></tt> attribute can be set to a ctypes type that describes to + return type, or to <tt class="docutils literal"><span class="pre">`None</span></tt> meaning no return value (<tt class="docutils literal"><span class="pre">void</span></tt>).</p> + <p>The optional <tt class="docutils literal"><span class="pre">argtypes</span></tt> attribute can be set to a sequence of ctypes + types that the function expects. The function can (as in C) be called + with more arguments than the length of the argtypes sequence.</p> + <p>The optional <tt class="docutils literal"><span class="pre">errcheck</span></tt> attribute can be set to a Python callable, + it can be used to validate and/or process the library functions return + value. <tt class="docutils literal"><span class="pre">errcheck</span></tt> will be called with three arguments, after the + library function has returned:</p> + <pre class="literal-block"> + errcheck(retval, function, arguments) + </pre> + <p><tt class="docutils literal"><span class="pre">retval</span></tt> is the value that the library function returned, comverted + according to <tt class="docutils literal"><span class="pre">restype</span></tt>. <tt class="docutils literal"><span class="pre">function</span></tt> is the ctypes function object + (libc.atoi in this case), and <tt class="docutils literal"><span class="pre">arguments</span></tt> is a tuple containing the + arguments that have been used to call <tt class="docutils literal"><span class="pre">function</span></tt>. <tt class="docutils literal"><span class="pre">errcheck</span></tt> + should validate the library function result, raise an error if it + detects a failure, or return the needed return value otherwise.</p> + </div> + <div class="section"> + <h1><a class="toc-backref" href="#id5" id="prototypes" name="prototypes">Prototypes</a></h1> + <p>Another way to access a function exported from shared libraries is to + first create a prototype by calling a factory function, specifying the + return type and the argument types. The factory function itself + specifies the calling convention: <tt class="docutils literal"><span class="pre">CFUNCTYPE</span></tt> uses the standard C + calling convention, <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt> (Windows only) uses the stdcall + calling convention. The factory function must be called with the + return type plus the argument types. For the C <tt class="docutils literal"><span class="pre">atoi</span></tt> function one + would use <tt class="docutils literal"><span class="pre">CFUNCTYPE(c_int,</span> <span class="pre">c_char_p)</span></tt>.</p> + <p>This returns a function prototype, which is a ctypes type representing + all functions that are compatible with the calling convention, return + type, and argument types.</p> + <p>The <tt class="docutils literal"><span class="pre">CFUNCTYPE</span></tt> and <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt> factory functions cache and + reuse the types they create in internal caches, so is is cheap to call + them over and over with the same or different arguments.</p> + <p>An instance of this function prototype, bound to a foreign library + function, can be created by calling the prototype with the name of the + function, and a library object:</p> + <pre class="literal-block"> + proto = CFUNCTYPE(c_int, c_char_p) + atoi = proto("atoi", libc) + </pre> + <p>It is possible to specify a third argument <tt class="docutils literal"><span class="pre">paramflags</span></tt> when calling + the prototype. This is used to specify additional information for + each argument: direction of data transfer, the name, and a default + value.</p> + <p>A tuple with the same length as <tt class="docutils literal"><span class="pre">argtypes</span></tt> (the second argument in + the prototype call) must be used. Each item in this tuple must be a + tuple, having either one, two, or three items.</p> + <p>The first item is the direction flag, an integer specifying if this is + an input (use <tt class="docutils literal"><span class="pre">1</span></tt>) or an output (use <tt class="docutils literal"><span class="pre">2</span></tt>) parameter. The optional + second item is a string containing the parameter name, the optional + third item is a default value for the parameter.</p> + <p>If parameter names are specified, the function object created can be + called with named arguments in the usual way. Arguments with default + values do not need to be specified when the function is called.</p> + <p><tt class="docutils literal"><span class="pre">out</span></tt> parameter types must be pointer types. When the function + object is called, ctypes will automatically create empty instances of + them, pass them to the library function, retrieve the value from them, + and return the value, if there is exactly one <tt class="docutils literal"><span class="pre">out</span></tt> parameter, or a + tuple of values, if there is more than one <tt class="docutils literal"><span class="pre">out</span></tt> parameter. The + original foreign function return value is lost in this case (but see + below for how it can be retrieved).</p> + <p>If <tt class="docutils literal"><span class="pre">paramflags</span></tt> have been used in the prototype call, and an + <tt class="docutils literal"><span class="pre">errcheck</span></tt> attribuet is also present, the <tt class="docutils literal"><span class="pre">errcheck</span></tt> callable will + be called with a fourth parameter <tt class="docutils literal"><span class="pre">outargs</span></tt>:</p> + <pre class="literal-block"> + errcheck(retval, function, arguments, outargs) + </pre> + <p><tt class="docutils literal"><span class="pre">outargs</span></tt> is a tuple containing all the <tt class="docutils literal"><span class="pre">out</span></tt> parameters that + ctypes has created. Without the <tt class="docutils literal"><span class="pre">errcheck</span></tt> function ctypes would + retrieve the values contained in these pointer objects, and return + them. The <tt class="docutils literal"><span class="pre">errcheck</span></tt> function can let ctypes continue this + processing by returning the <tt class="docutils literal"><span class="pre">outargs</span></tt> tuple. It could also return + something else, or raise an error if it detects that the library + function has failed.</p> + </div> </div> </body> Index: manual.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes/docs/manual/Attic/manual.txt,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** manual.txt 27 Jan 2006 20:40:21 -0000 1.1.2.3 --- manual.txt 2 Feb 2006 20:32:29 -0000 1.1.2.4 *************** *** 7,137 **** .. contents:: ! Loading shared libraries ! ++++++++++++++++++++++++ ! ! Shared libraries are accessed when compiling/linking a program, and ! when the program is run. The purpose of the ``find`` method is to ! locate a library in a way similar to what the compiler does (on ! platforms with several versions of a shared library the most recent ! should be loaded), while ``load`` acts like when a program is run, and ! uses the runtime loader directly. ``load_version`` works like ``load`` ! but tries to be platform independent (for cases where this makes ! sense). Loading via attribute access is a shorthand notation ! especially usefull for interactive use, it is equivalent to calling ! ``load_version`` with no version specified. ! ! ! class LibraryLoader ! +++++++++++++++++++ ! ! Instances of this ``LibraryLoader`` are used to load shared libraries. ! They have the following methods: ! ! ``load(libname, mode=None)`` ! ! Load and return the library with the given libname. On most ! systems ``libname`` is the filename of the shared library; when ! it's not a pathname it will be searched in a system dependend list ! of locations (on many systems additional search paths can be ! specified by an environemtn variable). Sometimes the file ! extension (like ``.dll`` pon Windows) can be omitted. ! ! ``mode`` allows to override the default flags passed to the ! ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are ! typical values. On Windows, ``mode`` is ignored. ! ! ``load_version(name, version=None, mode=None)`` ! ! Build a system dependend filename from ``name`` and optionally ! ``version``, then load and return it. ``name`` is the library ! name without any prefix like ``lib`` and suffix like ``.so`` or ! ``.dylib``. This method should be used if a library is available ! on different platforms, using the particular naming convention of ! each platform. ! ! ``mode`` allows to override the default flags passed to the ! ``dlopen()`` function, ignored on Windows. ! ! Example: calling ``loader.load_version('z', '1.1.3')`` would ! possibly load ``/usr/lib/libz.1.1.3.dylib`` on Mac OS X, and ! ``/lib/libz.so.1.1.3`` on a Linux system. ! ! ``find(name, mode=None)`` ! ! Try to find a library, load and return it. ``name`` is the ! library name without any prefix like ``lib``, suffix like ``.so``, ! ``.dylib`` or version number (this is the form used for the posix ! linker option ``-l``). ! ! ``mode`` allows to override the default flags passed to the ! ``dlopen()`` function, ignored on Windows. ! ! On windows, this method does exactly the same as the ``load`` ! method. ! ! On other platforms, this function might call other programs like ! the compiler to find the library. When using ctypes to write a ! shared library wrapping, consider using ``load_version`` or ! ``load`` instead. ! ! Libaries can also be loaded by accessing them as attributes of the ! loader instance, internally this calls ``load_version`` without ! specifying ``version`` or ``mode``. Obviously this only works for ! libraries with names that are valid Python identifiers, and when the ! name does not start with a ``_`` character. ! ! Predefined library loaders ! ++++++++++++++++++++++++++ ! ! ctypes provides some LibraryLoader instances, the differences are the ! calling conventions the functions will use, the default return type of ! the functions, and other stuff. All these loaders use the ! ``RTLD_LOCAL`` mode flag. ! ! Functions can be accessed as named attributes of loaded libraries. ! ! On Windows, structured exception handling is used around the function ! call to protect Python from crashing in case you pass invalid ! parameters to the function. ! ! ``cdll`` ! ! Functions provided by libraries loaded using the ``cdll`` loader ! will be called with the standard C calling convention, and have a ! default return type of ``int``. ctypes does release the Python ! global interpreter lock (GIL) just before calling the actual ! function, and reaquire it before returing, so a chance is given to ! other threads to run. ! ! ``windll`` ! ! Windows only. Functions provided by libraries loaded by ! ``windll`` will be called using the Windows ``__stdcall`` calling ! convention. ctypes can to detect the case that the wrong number ! of parameters have been passed to the function call by examining ! the stack pointer before and after the function call. If the ! wrong parameter count was used, an exception is raised (although ! the function really *has* been called). The return value of the ! function is lost in this case. Again, the GIL is released during ! the call. ! ! ``oledll`` ! ! Windows only. ``oledll`` behaves in the same way as ``windll``, ! except that the called function is expected to return a ! ``HRESULT`` value. These are long values containing error or ! success codes. In case the function return an error ``HRESULT`` ! value, a `WindowsError`` is raised. GIL released during the ! function call. ! ! ``pydll`` ! ! This loader allows to call functions in libraries using the ! *Python* calling convention, for example Python C API functions. ! The GIL is *not* released during the function call, and the state ! of the Python error flag is examined after the function returns. ! If the error flag is set, an exception is raised. ! ! ctypes provides a prefabricated instance of ``pydll`` exposing the ! Python C api as the ``pythonapi`` symbol, you should however make ! sure to set the correct ``restype`` for the functions you use. --- 7,10 ---- .. contents:: ! .. include:: libraries.txt ! .. include:: functions.txt |
From: Hye-Shik C. <pe...@us...> - 2006-02-02 16:45:40
|
Update of /cvsroot/ctypes/ctypes/ctypes/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20967 Modified Files: Tag: branch_1_0 test_loading.py Log Message: Fix inconsistent use of tab/spaces Index: test_loading.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_loading.py,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -C2 -d -r1.1.2.5 -r1.1.2.6 *** test_loading.py 2 Feb 2006 01:37:39 -0000 1.1.2.5 --- test_loading.py 2 Feb 2006 16:45:29 -0000 1.1.2.6 *************** *** 8,32 **** def test_load(self): ! if os.name == "nt": ! name = "msvcrt" elif os.name == "ce": name = "coredll" ! elif sys.platform == "darwin": ! name = "libc.dylib" ! elif sys.platform.startswith("freebsd"): ! name = "libc.so" ! else: ! name = "libc.so.6" ! cdll.load(name) ! self.assertRaises(OSError, cdll.load, self.unknowndll) def test_load_version(self): ! version = "6" name = "c" ! if sys.platform == "linux2": cdll.load_version(name, version) ! # linux uses version, libc 9 should not exist ! self.assertRaises(OSError, cdll.load_version, name, "9") ! self.assertRaises(OSError, cdll.load_version, self.unknowndll, "") if os.name == "posix": --- 8,32 ---- def test_load(self): ! if os.name == "nt": ! name = "msvcrt" elif os.name == "ce": name = "coredll" ! elif sys.platform == "darwin": ! name = "libc.dylib" ! elif sys.platform.startswith("freebsd"): ! name = "libc.so" ! else: ! name = "libc.so.6" ! cdll.load(name) ! self.assertRaises(OSError, cdll.load, self.unknowndll) def test_load_version(self): ! version = "6" name = "c" ! if sys.platform == "linux2": cdll.load_version(name, version) ! # linux uses version, libc 9 should not exist ! self.assertRaises(OSError, cdll.load_version, name, "9") ! self.assertRaises(OSError, cdll.load_version, self.unknowndll, "") if os.name == "posix": |
From: Hye-Shik C. <pe...@us...> - 2006-02-02 01:37:50
|
Update of /cvsroot/ctypes/ctypes/ctypes/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15681/ctypes/test Modified Files: Tag: branch_1_0 test_loading.py Log Message: Fix test on FreeBSD. FreeBSD N has libc.so.N. Index: test_loading.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_loading.py,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** test_loading.py 26 Jan 2006 19:59:45 -0000 1.1.2.4 --- test_loading.py 2 Feb 2006 01:37:39 -0000 1.1.2.5 *************** *** 14,17 **** --- 14,19 ---- elif sys.platform == "darwin": name = "libc.dylib" + elif sys.platform.startswith("freebsd"): + name = "libc.so" else: name = "libc.so.6" |
From: Thomas H. <th...@us...> - 2006-02-01 20:53:03
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19341/source Modified Files: Tag: branch_1_0 _ctypes.c callproc.c cfield.c stgdict.c Log Message: Patch from perky: use WORDS_BIGENDIAN from pyconfig.h, instead of inventing our own mechanism ro determine the byte order. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.32.2.4 retrieving revision 1.32.2.5 diff -C2 -d -r1.32.2.4 -r1.32.2.5 *** stgdict.c 30 Nov 2005 09:34:21 -0000 1.32.2.4 --- stgdict.c 1 Feb 2006 20:52:50 -0000 1.32.2.5 *************** *** 194,198 **** return 0; ! #ifdef IS_BIG_ENDIAN big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; #else --- 194,198 ---- return 0; ! #ifdef WORDS_BIGENDIAN big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; #else Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.127.2.20 retrieving revision 1.127.2.21 diff -C2 -d -r1.127.2.20 -r1.127.2.21 *** callproc.c 12 Jan 2006 12:32:04 -0000 1.127.2.20 --- callproc.c 1 Feb 2006 20:52:49 -0000 1.127.2.21 *************** *** 938,942 **** goto cleanup; ! #if IS_BIG_ENDIAN /* libffi returns the result in a buffer with sizeof(ffi_arg). This causes problems on big endian machines, since the result buffer --- 938,942 ---- goto cleanup; ! #if WORDS_BIGENDIAN /* libffi returns the result in a buffer with sizeof(ffi_arg). This causes problems on big endian machines, since the result buffer Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.74.2.16 retrieving revision 1.74.2.17 diff -C2 -d -r1.74.2.16 -r1.74.2.17 *** cfield.c 30 Dec 2005 17:22:47 -0000 1.74.2.16 --- cfield.c 1 Feb 2006 20:52:50 -0000 1.74.2.17 *************** *** 916,920 **** return NULL; } ! #ifdef IS_BIG_ENDIAN if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) return NULL; --- 916,920 ---- return NULL; } ! #ifdef WORDS_BIGENDIAN if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) return NULL; *************** *** 929,933 **** d_get_sw(void *ptr, unsigned size) { ! #ifdef IS_BIG_ENDIAN return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); #else --- 929,933 ---- d_get_sw(void *ptr, unsigned size) { ! #ifdef WORDS_BIGENDIAN return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); #else *************** *** 970,974 **** return NULL; } ! #ifdef IS_BIG_ENDIAN if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) return NULL; --- 970,974 ---- return NULL; } ! #ifdef WORDS_BIGENDIAN if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) return NULL; *************** *** 983,987 **** f_get_sw(void *ptr, unsigned size) { ! #ifdef IS_BIG_ENDIAN return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); #else --- 983,987 ---- f_get_sw(void *ptr, unsigned size) { ! #ifdef WORDS_BIGENDIAN return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); #else Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226.2.44 retrieving revision 1.226.2.45 diff -C2 -d -r1.226.2.44 -r1.226.2.45 *** _ctypes.c 17 Jan 2006 14:55:59 -0000 1.226.2.44 --- _ctypes.c 1 Feb 2006 20:52:49 -0000 1.226.2.45 *************** *** 1247,1251 **** if (suffix == NULL) ! #ifdef IS_BIG_ENDIAN suffix = PyString_FromString("_le"); #else --- 1247,1251 ---- if (suffix == NULL) ! #ifdef WORDS_BIGENDIAN suffix = PyString_FromString("_le"); #else *************** *** 1417,1421 **** return NULL; } ! #ifdef IS_BIG_ENDIAN PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); --- 1417,1421 ---- return NULL; } ! #ifdef WORDS_BIGENDIAN PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); |
From: Thomas H. <th...@us...> - 2006-02-01 20:52:57
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19341 Modified Files: Tag: branch_1_0 setup.py Log Message: Patch from perky: use WORDS_BIGENDIAN from pyconfig.h, instead of inventing our own mechanism ro determine the byte order. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.122.2.12 retrieving revision 1.122.2.13 diff -C2 -d -r1.122.2.12 -r1.122.2.13 *** setup.py 1 Feb 2006 20:15:25 -0000 1.122.2.12 --- setup.py 1 Feb 2006 20:52:49 -0000 1.122.2.13 *************** *** 220,227 **** "source/malloc_closure.c"] - import struct, binascii - if "12345678" == binascii.hexlify(struct.pack("i", 0x12345678)): - kw["define_macros"] = [("IS_BIG_ENDIAN", "1")] - # common header file kw["depends"] = ["source/ctypes.h"] --- 220,223 ---- |
From: Thomas H. <th...@us...> - 2006-02-01 20:50:13
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18187 Modified Files: Tag: branch_1_0 ChangeLog Log Message: *** empty log message *** Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.86.2.35 retrieving revision 1.86.2.36 diff -C2 -d -r1.86.2.35 -r1.86.2.36 *** ChangeLog 27 Jan 2006 17:57:23 -0000 1.86.2.35 --- ChangeLog 1 Feb 2006 20:50:03 -0000 1.86.2.36 *************** *** 1,2 **** --- 1,23 ---- + 2006-02-01 Thomas Heller <th...@py...> + + * Hye-Shik Chang <pe...@us...> made these changes: + Update libffi to gcc head as of 2006/02/01. This fixes several + unittest failures on 64bit platforms. + + 2006-02-01 Thomas Heller <th...@py...> + + * Committed a patch from Hye-Shik Chang (perky). + + See http://mail.python.org/pipermail/python-dev/2006-January/060199.html, + where he wrote: + + I did some work to make ctypes+libffi compacter and liberal. I + removed sources/gcc and put sources/libffi copied from gcc 4.0.2. + And removed all automake-related build processes and integrated + them info setup.py. There's still aclocal.m4 in + sources/libffi. But it is just identical to libffi's acinclude.m4 + which looks liberal. + + 2006-01-26 Thomas Heller <th...@py...> |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:08
|
Update of /cvsroot/ctypes/ctypes/source/libffi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi Modified Files: Tag: branch_1_0 configure configure.ac fficonfig.h.in fficonfig.py.in Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: fficonfig.py.in =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/Attic/fficonfig.py.in,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** fficonfig.py.in 1 Feb 2006 20:15:26 -0000 1.1.2.4 --- fficonfig.py.in 1 Feb 2006 20:31:51 -0000 1.1.2.5 *************** *** 4,30 **** ffi_platforms = { ! 'MIPS_IRIX': 'src/mips/ffi.c src/mips/o32.S src/mips/n32.S', ! 'MIPS_LINUX': 'src/mips/ffi.c src/mips/o32.S', ! 'X86': 'src/x86/ffi.c src/x86/sysv.S', ! 'X86_WIN32': 'src/x86/ffi.c src/x86/win32.S', ! 'SPARC': 'src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S', ! 'ALPHA': 'src/alpha/ffi.c src/alpha/osf.S', ! 'IA64': 'src/ia64/ffi.c src/ia64/unix.S', ! 'M32R': 'src/m32r/sysv.S src/m32r/ffi.c', ! 'M68K': 'src/m68k/ffi.c src/m68k/sysv.S', ! 'POWERPC': 'src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S', ! 'POWERPC_AIX': 'src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S', ! 'POWERPC_DARWIN': 'src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S', ! 'ARM': 'src/arm/sysv.S src/arm/ffi.c', ! 'FRV': 'src/frv/eabi.S src/frv/ffi.c', ! 'S390': 'src/s390/sysv.S src/s390/ffi.c', ! 'X86_64': 'src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S', ! 'SH': 'src/sh/sysv.S src/sh/ffi.c', ! 'SH64': 'src/sh64/sysv.S src/sh64/ffi.c', ! 'PA': 'src/pa/linux.S src/pa/ffi.c', } ffi_srcdir = '@srcdir@' ! ffi_sources += ffi_platforms['@TARGET@'].split() ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] --- 4,32 ---- ffi_platforms = { ! 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'], ! 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'], ! 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'], ! 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'], ! 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'], ! 'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'], ! 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'], ! 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'], ! 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'], ! 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], ! 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'], ! 'POWERPC_DARWIN': ['src/powerpc/ffi_darwin.c', 'src/powerpc/darwin.S', 'src/powerpc/darwin_closure.S'], ! 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'], ! 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'], ! 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'], ! 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'], ! 'S390': ['src/s390/sysv.S', 'src/s390/ffi.c'], ! 'X86_64': ['src/x86/ffi64.c', 'src/x86/unix64.S', 'src/x86/ffi.c', 'src/x86/sysv.S'], ! 'SH': ['src/sh/sysv.S', 'src/sh/ffi.c'], ! 'SH64': ['src/sh64/sysv.S', 'src/sh64/ffi.c'], ! 'PA': ['src/pa/linux.S', 'src/pa/ffi.c'], } ffi_srcdir = '@srcdir@' ! ffi_sources += ffi_platforms['@TARGET@'] ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] Index: fficonfig.h.in =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/Attic/fficonfig.h.in,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** fficonfig.h.in 31 Jan 2006 20:14:15 -0000 1.1.2.3 --- fficonfig.h.in 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 12,24 **** #undef EH_FRAME_FLAGS - /* Define this if you want extra debugging. */ - #undef FFI_DEBUG - - /* Define this is you do not want support for the raw API. */ - #undef FFI_NO_RAW_API - - /* Define this is you do not want support for aggregate types. */ - #undef FFI_NO_STRUCTS - /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA --- 12,15 ---- *************** *** 35,38 **** --- 26,32 ---- #undef HAVE_AS_SPARC_UA_PCREL + /* Define if __attribute__((visibility("hidden"))) is supported. */ + #undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H *************** *** 118,126 **** #undef STDC_HEADERS - /* Define this if you are using Purify and want to suppress spurious messages. - */ - #undef USING_PURIFY - /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN --- 112,132 ---- #undef STDC_HEADERS /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN + + + #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE + #ifdef LIBFFI_ASM + #define FFI_HIDDEN(name) .hidden name + #else + #define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) + #endif + #else + #ifdef LIBFFI_ASM + #define FFI_HIDDEN(name) + #else + #define FFI_HIDDEN + #endif + #endif + Index: configure.ac =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/Attic/configure.ac,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** configure.ac 31 Jan 2006 20:14:15 -0000 1.1.2.3 --- configure.ac 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 29,32 **** --- 29,33 ---- i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; + i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; *************** *** 36,40 **** sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ! sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; --- 37,42 ---- sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ! sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; ! sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; *************** *** 48,58 **** --- 50,65 ---- powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; + powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; + powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; + arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; + cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; + sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; *************** *** 142,145 **** --- 149,184 ---- fi + AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], + libffi_cv_hidden_visibility_attribute, [ + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* + ]) + if test $libffi_cv_hidden_visibility_attribute = yes; then + AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, + [Define if __attribute__((visibility("hidden"))) is supported.]) + fi + + AH_BOTTOM([ + #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE + #ifdef LIBFFI_ASM + #define FFI_HIDDEN(name) .hidden name + #else + #define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) + #endif + #else + #ifdef LIBFFI_ASM + #define FFI_HIDDEN(name) + #else + #define FFI_HIDDEN + #endif + #endif + ]) + AC_SUBST(TARGET) AC_SUBST(TARGETDIR) *************** *** 147,174 **** AC_SUBST(SHELL) - AC_ARG_ENABLE(debug, - [ --enable-debug debugging mode], - if test "$enable_debug" = "yes"; then - AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.]) - fi) - - AC_ARG_ENABLE(structs, - [ --disable-structs omit code for struct support], - if test "$enable_structs" = "no"; then - AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.]) - fi) - - AC_ARG_ENABLE(raw-api, - [ --disable-raw-api make the raw api unavailable], - if test "$enable_raw_api" = "no"; then - AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.]) - fi) - - AC_ARG_ENABLE(purify-safety, - [ --enable-purify-safety purify-safe mode], - if test "$enable_purify_safety" = "yes"; then - AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.]) - fi) - AC_CONFIG_COMMANDS(include, [test -d include || mkdir include]) AC_CONFIG_COMMANDS(src, [ --- 186,189 ---- Index: configure =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/Attic/configure,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** configure 31 Jan 2006 20:14:15 -0000 1.1.2.3 --- configure 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 834,845 **** cat <<\_ACEOF - Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-debug debugging mode - --disable-structs omit code for struct support - --disable-raw-api make the raw api unavailable - --enable-purify-safety purify-safe mode - Some influential environment variables: CC C compiler command --- 834,837 ---- *************** *** 3499,3502 **** --- 3491,3495 ---- i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; + i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; *************** *** 3506,3510 **** sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ! sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; --- 3499,3504 ---- sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ! sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; ! sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; *************** *** 3518,3528 **** --- 3512,3527 ---- powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; + powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; + powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; + arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; + cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; + sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; *************** *** 5418,5473 **** fi ! ! ! ! # Check whether --enable-debug or --disable-debug was given. ! if test "${enable_debug+set}" = set; then ! enableval="$enable_debug" ! if test "$enable_debug" = "yes"; then cat >>confdefs.h <<\_ACEOF ! #define FFI_DEBUG 1 _ACEOF ! fi ! fi; - # Check whether --enable-structs or --disable-structs was given. - if test "${enable_structs+set}" = set; then - enableval="$enable_structs" - if test "$enable_structs" = "no"; then - cat >>confdefs.h <<\_ACEOF - #define FFI_NO_STRUCTS 1 - _ACEOF - fi - fi; - # Check whether --enable-raw-api or --disable-raw-api was given. - if test "${enable_raw_api+set}" = set; then - enableval="$enable_raw_api" - if test "$enable_raw_api" = "no"; then - cat >>confdefs.h <<\_ACEOF - #define FFI_NO_RAW_API 1 - _ACEOF - fi - fi; - # Check whether --enable-purify-safety or --disable-purify-safety was given. - if test "${enable_purify_safety+set}" = set; then - enableval="$enable_purify_safety" - if test "$enable_purify_safety" = "yes"; then - cat >>confdefs.h <<\_ACEOF - #define USING_PURIFY 1 - _ACEOF - - fi - fi; ac_config_commands="$ac_config_commands include" --- 5417,5458 ---- fi + echo "$as_me:$LINENO: checking for __attribute__((visibility(\"hidden\")))" >&5 + echo $ECHO_N "checking for __attribute__((visibility(\"hidden\")))... $ECHO_C" >&6 + if test "${libffi_cv_hidden_visibility_attribute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* ! fi ! echo "$as_me:$LINENO: result: $libffi_cv_hidden_visibility_attribute" >&5 ! echo "${ECHO_T}$libffi_cv_hidden_visibility_attribute" >&6 ! if test $libffi_cv_hidden_visibility_attribute = yes; then cat >>confdefs.h <<\_ACEOF ! #define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1 _ACEOF ! fi ac_config_commands="$ac_config_commands include" |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:05
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/cris In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/cris Added Files: Tag: branch_1_0 ffi.c ffitarget.h sysv.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. --- NEW FILE: sysv.S --- /* ----------------------------------------------------------------------- sysv.S - Copyright (c) 2004 Simon Posnjak Copyright (c) 2005 Axis Communications AB CRIS Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <ffi.h> #define CONCAT(x,y) x ## y #define XCONCAT(x,y) CONCAT (x, y) #define L(x) XCONCAT (__USER_LABEL_PREFIX__, x) .text ;; OK, when we get called we should have this (according to ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3). ;; ;; R10: ffi_prep_args (func. pointer) ;; R11: &ecif ;; R12: cif->bytes ;; R13: fig->flags ;; sp+0: ecif.rvalue ;; sp+4: fn (function pointer to the function that we need to call) .globl L(ffi_call_SYSV) .type L(ffi_call_SYSV),@function .hidden L(ffi_call_SYSV) L(ffi_call_SYSV): ;; Save the regs to the stack. push $srp ;; Used for stack pointer saving. push $r6 ;; Used for function address pointer. push $r7 ;; Used for stack pointer saving. push $r8 ;; We save fig->flags to stack we will need them after we ;; call The Function. push $r13 ;; Saving current stack pointer. move.d $sp,$r8 move.d $sp,$r6 ;; Move address of ffi_prep_args to r13. move.d $r10,$r13 ;; Make room on the stack for the args of fn. sub.d $r12,$sp ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are: ;; r10 <-- stack pointer ;; r11 <-- &ecif (already there) move.d $sp,$r10 ;; Call the function. jsr $r13 ;; Save the size of the structures which are passed on stack. move.d $r10,$r7 ;; Move first four args in to r10..r13. move.d [$sp+0],$r10 move.d [$sp+4],$r11 move.d [$sp+8],$r12 move.d [$sp+12],$r13 ;; Adjust the stack and check if any parameters are given on stack. addq 16,$sp sub.d $r7,$r6 cmp.d $sp,$r6 bpl go_on nop go_on_no_params_on_stack: move.d $r6,$sp go_on: ;; Discover if we need to put rval address in to r9. move.d [$r8+0],$r7 cmpq FFI_TYPE_STRUCT,$r7 bne call_now nop ;; Move rval address to $r9. move.d [$r8+20],$r9 call_now: ;; Move address of The Function in to r7. move.d [$r8+24],$r7 ;; Call The Function. jsr $r7 ;; Reset stack. move.d $r8,$sp ;; Load rval type (fig->flags) in to r13. pop $r13 ;; Detect rval type. cmpq FFI_TYPE_VOID,$r13 beq epilogue cmpq FFI_TYPE_STRUCT,$r13 beq epilogue cmpq FFI_TYPE_DOUBLE,$r13 beq return_double_or_longlong cmpq FFI_TYPE_UINT64,$r13 beq return_double_or_longlong cmpq FFI_TYPE_SINT64,$r13 beq return_double_or_longlong nop ;; Just return the 32 bit value. ba return nop return_double_or_longlong: ;; Load half of the rval to r10 and the other half to r11. move.d [$sp+16],$r13 move.d $r10,[$r13] addq 4,$r13 move.d $r11,[$r13] ba epilogue nop return: ;; Load the rval to r10. move.d [$sp+16],$r13 move.d $r10,[$r13] epilogue: pop $r8 pop $r7 pop $r6 Jump [$sp+] .size ffi_call_SYSV,.-ffi_call_SYSV /* Save R10..R13 into an array, somewhat like varargs. Copy the next argument too, to simplify handling of any straddling parameter. Save R9 and SP after those. Jump to function handling the rest. Since this is a template, copied and the main function filled in by the user. */ .globl L(ffi_cris_trampoline_template) .type L(ffi_cris_trampoline_template),@function .hidden L(ffi_cris_trampoline_template) L(ffi_cris_trampoline_template): 0: /* The value we get for "PC" is right after the prefix instruction, two bytes from the beginning, i.e. 0b+2. */ move.d $r10,[$pc+2f-(0b+2)] move.d $pc,$r10 1: addq 2f-1b+4,$r10 move.d $r11,[$r10+] move.d $r12,[$r10+] move.d $r13,[$r10+] move.d [$sp],$r11 move.d $r11,[$r10+] move.d $r9,[$r10+] move.d $sp,[$r10+] subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10 move.d 0,$r11 3: jump 0 2: .size ffi_cris_trampoline_template,.-0b /* This macro create a constant usable as "extern const int \name" in C from within libffi, when \name has no prefix decoration. */ .macro const name,value .globl \name .type \name,@object .hidden \name \name: .dword \value .size \name,4 .endm /* Constants for offsets within the trampoline. We could do this with just symbols, avoiding memory contents and memory accesses, but the C usage code would look a bit stranger. */ const L(ffi_cris_trampoline_fn_offset),2b-4-0b const L(ffi_cris_trampoline_closure_offset),3b-4-0b --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1998 Cygnus Solutions Copyright (c) 2004 Simon Posnjak Copyright (c) 2005 Axis Communications AB CRIS Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) static ffi_status initialize_aggregate_packed_struct (ffi_type * arg) { ffi_type **ptr; FFI_ASSERT (arg != NULL); FFI_ASSERT (arg->elements != NULL); FFI_ASSERT (arg->size == 0); FFI_ASSERT (arg->alignment == 0); ptr = &(arg->elements[0]); while ((*ptr) != NULL) { if (((*ptr)->size == 0) && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; FFI_ASSERT (ffi_type_test ((*ptr))); arg->size += (*ptr)->size; arg->alignment = (arg->alignment > (*ptr)->alignment) ? arg->alignment : (*ptr)->alignment; ptr++; } if (arg->size == 0) return FFI_BAD_TYPEDEF; else return FFI_OK; } int ffi_prep_args (char *stack, extended_cif * ecif) { unsigned int i; unsigned int struct_count = 0; void **p_argv; char *argp; ffi_type **p_arg; argp = stack; p_argv = ecif->avalue; for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); i--, p_arg++) { size_t z; switch ((*p_arg)->type) { case FFI_TYPE_STRUCT: { z = (*p_arg)->size; if (z <= 4) { memcpy (argp, *p_argv, z); z = 4; } else if (z <= 8) { memcpy (argp, *p_argv, z); z = 8; } else { unsigned int uiLocOnStack; z = sizeof (void *); uiLocOnStack = 4 * ecif->cif->nargs + struct_count; struct_count = struct_count + (*p_arg)->size; *(unsigned int *) argp = (unsigned int) (UINT32 *) (stack + uiLocOnStack); memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size); } break; } default: z = (*p_arg)->size; if (z < sizeof (int)) { switch ((*p_arg)->type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv); break; case FFI_TYPE_UINT8: *(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv); break; case FFI_TYPE_SINT16: *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv); break; case FFI_TYPE_UINT16: *(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv); break; default: FFI_ASSERT (0); } z = sizeof (int); } else if (z == sizeof (int)) *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv); else memcpy (argp, *p_argv, z); break; } p_argv++; argp += z; } return (struct_count); } ffi_status ffi_prep_cif (ffi_cif * cif, ffi_abi abi, unsigned int nargs, ffi_type * rtype, ffi_type ** atypes) { unsigned bytes = 0; unsigned int i; ffi_type **ptr; FFI_ASSERT (cif != NULL); FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); cif->abi = abi; cif->arg_types = atypes; cif->nargs = nargs; cif->rtype = rtype; cif->flags = 0; if ((cif->rtype->size == 0) && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; FFI_ASSERT_VALID_TYPE (cif->rtype); for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { if (((*ptr)->size == 0) && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; FFI_ASSERT_VALID_TYPE (*ptr); if (((*ptr)->alignment - 1) & bytes) bytes = ALIGN (bytes, (*ptr)->alignment); if ((*ptr)->type == FFI_TYPE_STRUCT) { if ((*ptr)->size > 8) { bytes += (*ptr)->size; bytes += sizeof (void *); } else { if ((*ptr)->size > 4) bytes += 8; else bytes += 4; } } else bytes += STACK_ARG_SIZE ((*ptr)->size); } cif->bytes = bytes; return ffi_prep_cif_machdep (cif); } ffi_status ffi_prep_cif_machdep (ffi_cif * cif) { switch (cif->rtype->type) { case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: cif->flags = (unsigned) cif->rtype->type; break; default: cif->flags = FFI_TYPE_INT; break; } return FFI_OK; } extern void ffi_call_SYSV (int (*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void (*fn) ()) __attribute__ ((__visibility__ ("hidden"))); void ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue) { extended_cif ecif; ecif.cif = cif; ecif.avalue = avalue; if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { ecif.rvalue = alloca (cif->rtype->size); } else ecif.rvalue = rvalue; switch (cif->abi) { case FFI_SYSV: ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; default: FFI_ASSERT (0); break; } } /* Because the following variables are not exported outside libffi, we mark them hidden. */ /* Assembly code for the jump stub. */ extern const char ffi_cris_trampoline_template[] __attribute__ ((__visibility__ ("hidden"))); /* Offset into ffi_cris_trampoline_template of where to put the ffi_prep_closure_inner function. */ extern const int ffi_cris_trampoline_fn_offset __attribute__ ((__visibility__ ("hidden"))); /* Offset into ffi_cris_trampoline_template of where to put the closure data. */ extern const int ffi_cris_trampoline_closure_offset __attribute__ ((__visibility__ ("hidden"))); /* This function is sibling-called (jumped to) by the closure trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at PARAMS[4] to simplify handling of a straddling parameter. A copy of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are put at the appropriate place in CLOSURE which is then executed and the return value is passed back to the caller. */ static unsigned long long ffi_prep_closure_inner (void **params, ffi_closure* closure) { char *register_args = (char *) params; void *struct_ret = params[5]; char *stack_args = params[6]; char *ptr = register_args; ffi_cif *cif = closure->cif; ffi_type **arg_types = cif->arg_types; /* Max room needed is number of arguments as 64-bit values. */ void **avalue = alloca (closure->cif->nargs * sizeof(void *)); int i; int doing_regs; long long llret = 0; /* Find the address of each argument. */ for (i = 0, doing_regs = 1; i < cif->nargs; i++) { /* Types up to and including 8 bytes go by-value. */ if (arg_types[i]->size <= 4) { avalue[i] = ptr; ptr += 4; } else if (arg_types[i]->size <= 8) { avalue[i] = ptr; ptr += 8; } else { FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT); /* Passed by-reference, so copy the pointer. */ avalue[i] = *(void **) ptr; ptr += 4; } /* If we've handled more arguments than fit in registers, start looking at the those passed on the stack. Step over the first one if we had a straddling parameter. */ if (doing_regs && ptr >= register_args + 4*4) { ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0); doing_regs = 0; } } /* Invoke the closure. */ (closure->fun) (cif, cif->rtype->type == FFI_TYPE_STRUCT /* The caller allocated space for the return structure, and passed a pointer to this space in R9. */ ? struct_ret /* We take advantage of being able to ignore that the high part isn't set if the return value is not in R10:R11, but in R10 only. */ : (void *) &llret, avalue, closure->user_data); return llret; } /* API function: Prepare the trampoline. */ ffi_status ffi_prep_closure (ffi_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif *, void *, void **, void*), void *user_data) { void *innerfn = ffi_prep_closure_inner; FFI_ASSERT (cif->abi == FFI_SYSV); closure->cif = cif; closure->user_data = user_data; closure->fun = fun; memcpy (closure->tramp, ffi_cris_trampoline_template, FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE); memcpy (closure->tramp + ffi_cris_trampoline_fn_offset, &innerfn, sizeof (void *)); memcpy (closure->tramp + ffi_cris_trampoline_closure_offset, &closure, sizeof (void *)); return FFI_OK; } --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for CRIS. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_SYSV, FFI_DEFAULT_ABI = FFI_SYSV, FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36 #define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4) #define FFI_TRAMPOLINE_SIZE \ (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE) #define FFI_NATIVE_RAW_API 0 #endif |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:05
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/x86 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/x86 Modified Files: Tag: branch_1_0 ffi.c ffi64.c sysv.S unix64.S win32.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: unix64.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/x86/Attic/unix64.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** unix64.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- unix64.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 32,36 **** /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, ! void *raddr, void (*fnaddr)()); Bit o trickiness here -- ARGS+BYTES is the base of the stack frame --- 32,36 ---- /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, ! void *raddr, void (*fnaddr)()); Bit o trickiness here -- ARGS+BYTES is the base of the stack frame *************** *** 40,44 **** .align 2 .globl ffi_call_unix64 ! .type ffi_call_unix64,@function ffi_call_unix64: --- 40,44 ---- .align 2 .globl ffi_call_unix64 ! .type ffi_call_unix64,@function ffi_call_unix64: *************** *** 54,57 **** --- 54,58 ---- movq %rdi, %r10 /* Save a copy of the register area. */ movq %r8, %r11 /* Save a copy of the target fn. */ + movl %r9d, %eax /* Set number of SSE registers. */ /* Load up all argument registers. */ *************** *** 62,73 **** movq 32(%r10), %r8 movq 40(%r10), %r9 ! movdqa 48(%r10), %xmm0 ! movdqa 64(%r10), %xmm1 ! movdqa 80(%r10), %xmm2 ! movdqa 96(%r10), %xmm3 ! movdqa 112(%r10), %xmm4 ! movdqa 128(%r10), %xmm5 ! movdqa 144(%r10), %xmm6 ! movdqa 160(%r10), %xmm7 /* Deallocate the reg arg area. */ --- 63,69 ---- movq 32(%r10), %r8 movq 40(%r10), %r9 ! testl %eax, %eax ! jnz .Lload_sse ! .Lret_from_load_sse: /* Deallocate the reg arg area. */ *************** *** 182,216 **** movq %rdx, 8(%rsi) ! /* Bits 11-31 contain the true size of the structure. Copy from the scratch area to the true destination. */ ! shrl $11, %ecx rep movsb ret .LUW3: .size ffi_call_unix64,.-ffi_call_unix64 .align 2 .globl ffi_closure_unix64 ! .type ffi_closure_unix64,@function ffi_closure_unix64: - .LUW4: - subq $200, %rsp .LUW5: ! movq %rdi, (%rsp) ! movq %rsi, 8(%rsp) ! movq %rdx, 16(%rsp) ! movq %rcx, 24(%rsp) ! movq %r8, 32(%rsp) ! movq %r9, 40(%rsp) ! movdqa %xmm0, 48(%rsp) ! movdqa %xmm1, 64(%rsp) ! movdqa %xmm2, 80(%rsp) ! movdqa %xmm3, 96(%rsp) ! movdqa %xmm4, 112(%rsp) ! movdqa %xmm5, 128(%rsp) ! movdqa %xmm6, 144(%rsp) ! movdqa %xmm7, 160(%rsp) movq %r10, %rdi --- 178,224 ---- movq %rdx, 8(%rsi) ! /* Bits 12-31 contain the true size of the structure. Copy from the scratch area to the true destination. */ ! shrl $12, %ecx rep movsb ret + + /* Many times we can avoid loading any SSE registers at all. + It's not worth an indirect jump to load the exact set of + SSE registers needed; zero or all is a good compromise. */ + .align 2 .LUW3: + .Lload_sse: + movdqa 48(%r10), %xmm0 + movdqa 64(%r10), %xmm1 + movdqa 80(%r10), %xmm2 + movdqa 96(%r10), %xmm3 + movdqa 112(%r10), %xmm4 + movdqa 128(%r10), %xmm5 + movdqa 144(%r10), %xmm6 + movdqa 160(%r10), %xmm7 + jmp .Lret_from_load_sse + + .LUW4: .size ffi_call_unix64,.-ffi_call_unix64 .align 2 .globl ffi_closure_unix64 ! .type ffi_closure_unix64,@function ffi_closure_unix64: .LUW5: ! /* The carry flag is set by the trampoline iff SSE registers ! are used. Don't clobber it before the branch instruction. */ ! leaq -200(%rsp), %rsp ! .LUW6: movq %rdi, (%rsp) ! movq %rsi, 8(%rsp) ! movq %rdx, 16(%rsp) ! movq %rcx, 24(%rsp) ! movq %r8, 32(%rsp) ! movq %r9, 40(%rsp) ! jc .Lsave_sse ! .Lret_from_save_sse: movq %r10, %rdi *************** *** 222,226 **** /* Deallocate stack frame early; return value is now in redzone. */ addq $200, %rsp ! .LUW6: /* The first byte of the return value contains the FFI_TYPE. */ --- 230,234 ---- /* Deallocate stack frame early; return value is now in redzone. */ addq $200, %rsp ! .LUW7: /* The first byte of the return value contains the FFI_TYPE. */ *************** *** 301,305 **** cmovnz %rdx, %rax ret ! .LUW7: .size ffi_closure_unix64,.-ffi_closure_unix64 --- 309,328 ---- cmovnz %rdx, %rax ret ! ! /* See the comment above .Lload_sse; the same logic applies here. */ ! .align 2 ! .LUW8: ! .Lsave_sse: ! movdqa %xmm0, 48(%rsp) ! movdqa %xmm1, 64(%rsp) ! movdqa %xmm2, 80(%rsp) ! movdqa %xmm3, 96(%rsp) ! movdqa %xmm4, 112(%rsp) ! movdqa %xmm5, 128(%rsp) ! movdqa %xmm6, 144(%rsp) ! movdqa %xmm7, 160(%rsp) ! jmp .Lret_from_save_sse ! ! .LUW9: .size ffi_closure_unix64,.-ffi_closure_unix64 *************** *** 328,332 **** .long .LASFDE1-.Lframe1 /* FDE CIE offset */ .long .LUW0-. /* FDE initial location */ ! .long .LUW3-.LUW0 /* FDE address range */ .uleb128 0x0 /* Augmentation size */ --- 351,355 ---- .long .LASFDE1-.Lframe1 /* FDE CIE offset */ .long .LUW0-. /* FDE initial location */ ! .long .LUW4-.LUW0 /* FDE address range */ .uleb128 0x0 /* Augmentation size */ *************** *** 334,344 **** .long .LUW1-.LUW0 ! /* New stack frame based off rbp. This is a itty bit of unwind ! trickery in that the CFA *has* changed. There is no easy way ! to describe it correctly on entry to the function. Fortunately, ! it doesn't matter too much since at all points we can correctly ! unwind back to ffi_call. Note that the location to which we ! moved the return address is (the new) CFA-8, so from the ! perspective of the unwind info, it hasn't moved. */ .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */ .uleb128 6 --- 357,367 ---- .long .LUW1-.LUW0 ! /* New stack frame based off rbp. This is a itty bit of unwind ! trickery in that the CFA *has* changed. There is no easy way ! to describe it correctly on entry to the function. Fortunately, ! it doesn't matter too much since at all points we can correctly ! unwind back to ffi_call. Note that the location to which we ! moved the return address is (the new) CFA-8, so from the ! perspective of the unwind info, it hasn't moved. */ .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */ .uleb128 6 *************** *** 346,349 **** --- 369,373 ---- .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */ .uleb128 2 + .byte 0xa /* DW_CFA_remember_state */ .byte 0x4 /* DW_CFA_advance_loc4 */ *************** *** 353,356 **** --- 377,385 ---- .uleb128 8 .byte 0xc0+6 /* DW_CFA_restore, %rbp */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LUW3-.LUW2 + .byte 0xb /* DW_CFA_restore_state */ + .align 8 .LEFDE1: *************** *** 359,373 **** .LASFDE3: .long .LASFDE3-.Lframe1 /* FDE CIE offset */ ! .long .LUW4-. /* FDE initial location */ ! .long .LUW7-.LUW4 /* FDE address range */ .uleb128 0x0 /* Augmentation size */ .byte 0x4 /* DW_CFA_advance_loc4 */ ! .long .LUW5-.LUW4 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 208 .byte 0x4 /* DW_CFA_advance_loc4 */ ! .long .LUW6-.LUW5 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 8 .align 8 .LEFDE3: --- 388,410 ---- .LASFDE3: .long .LASFDE3-.Lframe1 /* FDE CIE offset */ ! .long .LUW5-. /* FDE initial location */ ! .long .LUW9-.LUW5 /* FDE address range */ .uleb128 0x0 /* Augmentation size */ + .byte 0x4 /* DW_CFA_advance_loc4 */ ! .long .LUW6-.LUW5 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 208 + .byte 0xa /* DW_CFA_remember_state */ + .byte 0x4 /* DW_CFA_advance_loc4 */ ! .long .LUW7-.LUW6 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 8 + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LUW8-.LUW7 + .byte 0xb /* DW_CFA_restore_state */ + .align 8 .LEFDE3: Index: sysv.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/x86/Attic/sysv.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** sysv.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- sysv.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 1,4 **** /* ----------------------------------------------------------------------- ! sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc. X86 Foreign Function Interface --- 1,4 ---- /* ----------------------------------------------------------------------- ! sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. X86 Foreign Function Interface *************** *** 131,134 **** --- 131,263 ---- .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV + .align 4 + FFI_HIDDEN (ffi_closure_SYSV) + .globl ffi_closure_SYSV + .type ffi_closure_SYSV, @function + + ffi_closure_SYSV: + .LFB2: + pushl %ebp + .LCFI2: + movl %esp, %ebp + .LCFI3: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__ + call ffi_closure_SYSV_inner + #else + movl %ebx, 8(%esp) + .LCFI7: + call 1f + 1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx + #endif + movl -12(%ebp), %ecx + cmpl $FFI_TYPE_INT, %eax + je .Lcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lcls_retllong + .Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret + .Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue + .Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue + .Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue + .Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue + .Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue + .LFE2: + .size ffi_closure_SYSV, .-ffi_closure_SYSV + + #if !FFI_NO_RAW_API + + #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) + #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) + #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) + #define CIF_FLAGS_OFFSET 20 + + .align 4 + FFI_HIDDEN (ffi_closure_raw_SYSV) + .globl ffi_closure_raw_SYSV + .type ffi_closure_raw_SYSV, @function + + ffi_closure_raw_SYSV: + .LFB3: + pushl %ebp + .LCFI4: + movl %esp, %ebp + .LCFI5: + pushl %esi + .LCFI6: + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ + cmpl $FFI_TYPE_INT, %eax + je .Lrcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lrcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lrcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lrcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lrcls_retllong + .Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret + .Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + .Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue + .LFE3: + .size ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV + #endif + .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: *************** *** 181,184 **** --- 310,378 ---- .align 4 .LEFDE1: + .LSFDE2: + .long .LEFDE2-.LASFDE2 /* FDE Length */ + .LASFDE2: + .long .LASFDE2-.Lframe1 /* FDE CIE offset */ + #ifdef __PIC__ + .long .LFB2-. /* FDE initial location */ + #else + .long .LFB2 + #endif + .long .LFE2-.LFB2 /* FDE address range */ + #ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ + #endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI2-.LFB2 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ + .byte 0x2 /* .uleb128 0x2 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI3-.LCFI2 + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0x5 /* .uleb128 0x5 */ + #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI7-.LCFI3 + .byte 0x83 /* DW_CFA_offset, column 0x3 */ + .byte 0xa /* .uleb128 0xa */ + #endif + .align 4 + .LEFDE2: + + #if !FFI_NO_RAW_API + + .LSFDE3: + .long .LEFDE3-.LASFDE3 /* FDE Length */ + .LASFDE3: + .long .LASFDE3-.Lframe1 /* FDE CIE offset */ + #ifdef __PIC__ + .long .LFB3-. /* FDE initial location */ + #else + .long .LFB3 + #endif + .long .LFE3-.LFB3 /* FDE address range */ + #ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ + #endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI4-.LFB3 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ + .byte 0x2 /* .uleb128 0x2 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI5-.LCFI4 + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0x5 /* .uleb128 0x5 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI6-.LCFI5 + .byte 0x86 /* DW_CFA_offset, column 0x6 */ + .byte 0x3 /* .uleb128 0x3 */ + .align 4 + .LEFDE3: + + #endif #endif /* ifndef __x86_64__ */ Index: ffi64.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/x86/Attic/ffi64.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffi64.c 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- ffi64.c 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 43,47 **** extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, ! void *raddr, void (*fnaddr)()); /* All reference to register classes here is identical to the code in --- 43,47 ---- extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, ! void *raddr, void (*fnaddr)(), unsigned ssecount); /* All reference to register classes here is identical to the code in *************** *** 304,311 **** flags |= 1 << 10; /* Mark the true size of the structure. */ ! flags |= cif->rtype->size << 11; } } - cif->flags = flags; /* Go over all arguments and determine the way they should be passed. --- 304,310 ---- flags |= 1 << 10; /* Mark the true size of the structure. */ ! flags |= cif->rtype->size << 12; } } /* Go over all arguments and determine the way they should be passed. *************** *** 332,335 **** --- 331,337 ---- } } + if (ssecount) + flags |= 1 << 11; + cif->flags = flags; cif->bytes = bytes; *************** *** 354,358 **** VOID above in ffi_prep_cif_machdep. */ ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT ! && cif->flags == FFI_TYPE_VOID); if (rvalue == NULL && ret_in_memory) rvalue = alloca (cif->rtype->size); --- 356,360 ---- VOID above in ffi_prep_cif_machdep. */ ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT ! && (cif->flags & 0xff) == FFI_TYPE_VOID); if (rvalue == NULL && ret_in_memory) rvalue = alloca (cif->rtype->size); *************** *** 425,429 **** ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args), ! cif->flags, rvalue, fn); } --- 427,431 ---- ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args), ! cif->flags, rvalue, fn, ssecount); } *************** *** 440,450 **** tramp = (volatile unsigned short *) &closure->tramp[0]; tramp[0] = 0xbb49; /* mov <code>, %r11 */ - tramp[5] = 0xba49; /* mov <data>, %r10 */ - tramp[10] = 0xff49; /* jmp *%r11 */ - tramp[11] = 0x00e3; *(void * volatile *) &tramp[1] = ffi_closure_unix64; *(void * volatile *) &tramp[6] = closure; closure->cif = cif; closure->fun = fun; --- 442,457 ---- tramp = (volatile unsigned short *) &closure->tramp[0]; + tramp[0] = 0xbb49; /* mov <code>, %r11 */ *(void * volatile *) &tramp[1] = ffi_closure_unix64; + tramp[5] = 0xba49; /* mov <data>, %r10 */ *(void * volatile *) &tramp[6] = closure; + /* Set the carry bit iff the function uses any sse registers. + This is clc or stc, together with the first byte of the jmp. */ + tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8; + + tramp[11] = 0xe3ff; /* jmp *%r11 */ + closure->cif = cif; closure->fun = fun; Index: ffi.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/x86/Attic/ffi.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffi.c 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- ffi.c 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 242,265 **** static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); ! static void ffi_closure_SYSV (ffi_closure *) __attribute__ ((regparm(1))); ! static void ffi_closure_raw_SYSV (ffi_raw_closure *) __attribute__ ((regparm(1))); /* This function is jumped to by the trampoline */ ! static void ! ffi_closure_SYSV (closure) ffi_closure *closure; { - // this is our return value storage - long double res; - // our various things... ffi_cif *cif; void **arg_area; - unsigned short rtype; - void *resp = (void*)&res; - void *args = __builtin_dwarf_cfa (); cif = closure->cif; --- 242,263 ---- static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); ! void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) __attribute__ ((regparm(1))); ! unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) ! __attribute__ ((regparm(1))); ! void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) __attribute__ ((regparm(1))); /* This function is jumped to by the trampoline */ ! unsigned int FFI_HIDDEN ! ffi_closure_SYSV_inner (closure, respp, args) ffi_closure *closure; + void **respp; + void *args; { // our various things... ffi_cif *cif; void **arg_area; cif = closure->cif; *************** *** 272,315 **** * structure return address. */ ! ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); ! ! (closure->fun) (cif, resp, arg_area, closure->user_data); ! rtype = cif->flags; ! /* now, do a generic return based on the value of rtype */ ! if (rtype == FFI_TYPE_INT) ! { ! asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); ! } ! else if (rtype == FFI_TYPE_FLOAT) ! { ! asm ("flds (%0)" : : "r" (resp) : "st" ); ! } ! else if (rtype == FFI_TYPE_DOUBLE) ! { ! asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); ! } ! else if (rtype == FFI_TYPE_LONGDOUBLE) ! { ! asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); ! } ! else if (rtype == FFI_TYPE_SINT64) ! { ! asm ("movl 0(%0),%%eax;" ! "movl 4(%0),%%edx" ! : : "r"(resp) ! : "eax", "edx"); ! } ! #ifdef X86_WIN32 ! else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct */ ! { ! asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax"); ! } ! else if (rtype == FFI_TYPE_SINT16) /* 2-bytes struct */ ! { ! asm ("movswl (%0),%%eax" : : "r" (resp) : "eax"); ! } ! #endif } --- 270,278 ---- * structure return address. */ ! ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); ! (closure->fun) (cif, *respp, arg_area, closure->user_data); ! return cif->flags; } *************** *** 395,449 **** #if !FFI_NO_RAW_API - static void - ffi_closure_raw_SYSV (closure) - ffi_raw_closure *closure; - { - // this is our return value storage - long double res; - - // our various things... - ffi_raw *raw_args; - ffi_cif *cif; - unsigned short rtype; - void *resp = (void*)&res; - - /* get the cif */ - cif = closure->cif; - - /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */ - raw_args = (ffi_raw*) __builtin_dwarf_cfa (); - - (closure->fun) (cif, resp, raw_args, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } - } - - - - ffi_status ffi_prep_raw_closure (ffi_raw_closure* closure, --- 358,361 ---- Index: win32.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/x86/Attic/win32.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** win32.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- win32.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 258,259 **** --- 258,373 ---- .ffi_call_STDCALL_end: + + .globl _ffi_closure_SYSV + _ffi_closure_SYSV: + pushl %ebp + movl %esp, %ebp + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx + cmpl $FFI_TYPE_INT, %eax + je .Lcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lcls_retllong + cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */ + je .Lcls_retstruct1 + cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */ + je .Lcls_retstruct2 + .Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret + .Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue + .Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue + .Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue + .Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue + .Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue + .Lcls_retstruct1: + movsbl (%ecx), %eax + jmp .Lcls_epilogue + .Lcls_retstruct2: + movswl (%ecx), %eax + jmp .Lcls_epilogue + .ffi_closure_SYSV_end: + + #if !FFI_NO_RAW_API + + #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) + #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) + #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) + #define CIF_FLAGS_OFFSET 20 + + .balign 16 + .globl _ffi_closure_raw_SYSV + _ffi_closure_raw_SYSV: + pushl %ebp + movl %esp, %ebp + pushl %esi + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ + cmpl $FFI_TYPE_INT, %eax + je .Lrcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lrcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lrcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lrcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lrcls_retllong + .Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret + .Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + .Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue + .Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue + .ffi_closure_raw_SYSV_end: + + #endif |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:04
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/frv In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/frv Modified Files: Tag: branch_1_0 eabi.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:04
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/ia64 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/ia64 Modified Files: Tag: branch_1_0 ffitarget.h unix.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: unix.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/ia64/Attic/unix.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** unix.S 31 Jan 2006 20:17:41 -0000 1.1.2.3 --- unix.S 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 291,296 **** --- 291,301 ---- /* Retrieve closure pointer and real gp. */ + #ifdef _ILP32 + addp4 out0 = 0, gp + addp4 gp = 16, gp + #else mov out0 = gp add gp = 16, gp + #endif ;; ld8 gp = [gp] *************** *** 369,397 **** br.ret.sptk.many b0 ;; ! .Lld_int8: ! .body ! .copy_state 1 ! ld1 r8 = [r16] ! .restore sp ! add sp = FRAME_SIZE, sp ! br.ret.sptk.many b0 ! ;; ! .Lld_int16: ! .body ! .copy_state 1 ! ld2 r8 = [r16] ! .restore sp ! add sp = FRAME_SIZE, sp ! br.ret.sptk.many b0 ! ;; ! .Lld_int32: ! .body ! .copy_state 1 ! ld4 r8 = [r16] ! .restore sp ! add sp = FRAME_SIZE, sp ! br.ret.sptk.many b0 ! ;; ! .Lld_int64: .body .copy_state 1 --- 374,378 ---- br.ret.sptk.many b0 ;; ! .Lld_int: .body .copy_state 1 *************** *** 555,572 **** .Lld_table: data8 @pcrel(.Lld_void) // FFI_TYPE_VOID ! data8 @pcrel(.Lld_int32) // FFI_TYPE_INT data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE ! data8 @pcrel(.Lld_int8) // FFI_TYPE_UINT8 ! data8 @pcrel(.Lld_int8) // FFI_TYPE_SINT8 ! data8 @pcrel(.Lld_int16) // FFI_TYPE_UINT16 ! data8 @pcrel(.Lld_int16) // FFI_TYPE_SINT16 ! data8 @pcrel(.Lld_int32) // FFI_TYPE_UINT32 ! data8 @pcrel(.Lld_int32) // FFI_TYPE_SINT32 ! data8 @pcrel(.Lld_int64) // FFI_TYPE_UINT64 ! data8 @pcrel(.Lld_int64) // FFI_TYPE_SINT64 data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT ! data8 @pcrel(.Lld_int64) // FFI_TYPE_POINTER data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT --- 536,553 ---- .Lld_table: data8 @pcrel(.Lld_void) // FFI_TYPE_VOID ! data8 @pcrel(.Lld_int) // FFI_TYPE_INT data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE ! data8 @pcrel(.Lld_int) // FFI_TYPE_UINT8 ! data8 @pcrel(.Lld_int) // FFI_TYPE_SINT8 ! data8 @pcrel(.Lld_int) // FFI_TYPE_UINT16 ! data8 @pcrel(.Lld_int) // FFI_TYPE_SINT16 ! data8 @pcrel(.Lld_int) // FFI_TYPE_UINT32 ! data8 @pcrel(.Lld_int) // FFI_TYPE_SINT32 ! data8 @pcrel(.Lld_int) // FFI_TYPE_UINT64 ! data8 @pcrel(.Lld_int) // FFI_TYPE_SINT64 data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT ! data8 @pcrel(.Lld_int) // FFI_TYPE_POINTER data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT Index: ffitarget.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/ia64/Attic/ffitarget.h,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffitarget.h 31 Jan 2006 20:17:41 -0000 1.1.2.3 --- ffitarget.h 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 28,33 **** #ifndef LIBFFI_ASM ! typedef unsigned long ffi_arg; ! typedef signed long ffi_sarg; typedef enum ffi_abi { --- 28,33 ---- #ifndef LIBFFI_ASM ! typedef unsigned long long ffi_arg; ! typedef signed long long ffi_sarg; typedef enum ffi_abi { |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:04
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/sh64 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/sh64 Modified Files: Tag: branch_1_0 ffi.c sysv.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: sysv.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/sh64/Attic/sysv.S,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** sysv.S 31 Jan 2006 19:44:37 -0000 1.1.2.1 --- sysv.S 1 Feb 2006 20:31:52 -0000 1.1.2.2 *************** *** 1,4 **** /* ----------------------------------------------------------------------- ! sysv.S - Copyright (c) 2003 Kaz Kojima SuperH SHmedia Foreign Function Interface --- 1,4 ---- /* ----------------------------------------------------------------------- ! sysv.S - Copyright (c) 2003, 2004 Kaz Kojima SuperH SHmedia Foreign Function Interface *************** *** 65,70 **** st.l r15, 4, r18 st.l r15, 0, r14 - add.l r15, r63, r14 .LCFI1: # add r4, r63, r28 add r5, r63, r29 --- 65,71 ---- st.l r15, 4, r18 st.l r15, 0, r14 .LCFI1: + add.l r15, r63, r14 + .LCFI2: # add r4, r63, r28 add r5, r63, r29 *************** *** 253,260 **** --- 254,268 ---- beqi/l r29, FFI_TYPE_INT, tr0 + beqi/l r29, FFI_TYPE_UINT32, tr0 beqi/l r29, FFI_TYPE_SINT64, tr1 beqi/l r29, FFI_TYPE_UINT64, tr1 beqi/l r29, FFI_TYPE_DOUBLE, tr2 beqi/l r29, FFI_TYPE_FLOAT, tr3 + + pt/l .L_ret_q, tr0 + pt/l .L_ret_h, tr1 + + beqi/l r29, FFI_TYPE_UINT8, tr0 + beqi/l r29, FFI_TYPE_UINT16, tr1 blink tr4, r63 *************** *** 271,274 **** --- 279,290 ---- blink tr4, r63 + .L_ret_q: + st.b r31, 0, r2 + blink tr4, r63 + + .L_ret_h: + st.w r31, 0, r2 + blink tr4, r63 + .L_ret_i: st.l r31, 0, r2 *************** *** 298,307 **** .LFB2: addi.l r15, -136, r15 ! .LCFI2: st.l r15, 12, r18 st.l r15, 8, r14 st.l r15, 4, r12 add r15, r63, r14 ! .LCFI3: /* Stack layout: ... --- 314,324 ---- .LFB2: addi.l r15, -136, r15 ! .LCFI3: st.l r15, 12, r18 st.l r15, 8, r14 st.l r15, 4, r12 + .LCFI4: add r15, r63, r14 ! .LCFI5: /* Stack layout: ... *************** *** 419,428 **** .4byte 0x0 /* CIE Identifier Tag */ .byte 0x1 /* CIE Version */ .ascii "zR\0" /* CIE Augmentation */ .uleb128 0x1 /* CIE Code Alignment Factor */ .sleb128 -4 /* CIE Data Alignment Factor */ .byte 0x12 /* CIE RA Column */ .uleb128 0x1 /* Augmentation size */ ! .byte 0x1b /* FDE Encoding (pcrel sdata4) */ .byte 0xc /* DW_CFA_def_cfa */ .uleb128 0xf --- 436,451 ---- .4byte 0x0 /* CIE Identifier Tag */ .byte 0x1 /* CIE Version */ + #ifdef PIC .ascii "zR\0" /* CIE Augmentation */ + #else + .byte 0x0 /* CIE Augmentation */ + #endif .uleb128 0x1 /* CIE Code Alignment Factor */ .sleb128 -4 /* CIE Data Alignment Factor */ .byte 0x12 /* CIE RA Column */ + #ifdef PIC .uleb128 0x1 /* Augmentation size */ ! .byte 0x10 /* FDE Encoding (pcrel) */ ! #endif .byte 0xc /* DW_CFA_def_cfa */ .uleb128 0xf *************** *** 434,439 **** .LASFDE1: .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__ ! .4byte datalabel .LFB1-. /* FDE initial location */ .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */ .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte datalabel .LCFI0-datalabel .LFB1 --- 457,469 ---- .LASFDE1: .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__ ! #ifdef PIC ! .4byte .LFB1-. /* FDE initial location */ ! #else ! .4byte .LFB1 /* FDE initial location */ ! #endif .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */ + #ifdef PIC + .uleb128 0x0 /* Augmentation size */ + #endif .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte datalabel .LCFI0-datalabel .LFB1 *************** *** 456,459 **** --- 486,491 ---- .byte 0xa0 /* DW_CFA_offset, column 0x20 */ .uleb128 0x2 + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI2-datalabel .LCFI1 .byte 0xd /* DW_CFA_def_cfa_register */ .uleb128 0xe *************** *** 465,476 **** .LASFDE3: .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__ ! .4byte datalabel .LFB2-. /* FDE initial location */ .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */ .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte datalabel .LCFI2-datalabel .LFB2 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 0x88 .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte datalabel .LCFI3-datalabel .LCFI2 .byte 0x8c /* DW_CFA_offset, column 0xc */ .uleb128 0x21 --- 497,515 ---- .LASFDE3: .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__ ! #ifdef PIC ! .4byte .LFB2-. /* FDE initial location */ ! #else ! .4byte .LFB2 /* FDE initial location */ ! #endif .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */ + #ifdef PIC + .uleb128 0x0 /* Augmentation size */ + #endif .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte datalabel .LCFI3-datalabel .LFB2 .byte 0xe /* DW_CFA_def_cfa_offset */ .uleb128 0x88 .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte datalabel .LCFI4-datalabel .LCFI3 .byte 0x8c /* DW_CFA_offset, column 0xc */ .uleb128 0x21 *************** *** 479,482 **** --- 518,523 ---- .byte 0x92 /* DW_CFA_offset, column 0x12 */ .uleb128 0x1f + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte datalabel .LCFI5-datalabel .LCFI4 .byte 0xd /* DW_CFA_def_cfa_register */ .uleb128 0xe Index: ffi.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/sh64/Attic/ffi.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ffi.c 31 Jan 2006 19:44:37 -0000 1.1.2.1 --- ffi.c 1 Feb 2006 20:31:52 -0000 1.1.2.2 *************** *** 1,4 **** /* ----------------------------------------------------------------------- ! ffi.c - Copyright (c) 2003 Kaz Kojima SuperH SHmedia Foreign Function Interface --- 1,4 ---- /* ----------------------------------------------------------------------- ! ffi.c - Copyright (c) 2003, 2004 Kaz Kojima SuperH SHmedia Foreign Function Interface *************** *** 32,77 **** #define NFREGARG 12 - /* If the structure has essentialy an unique element, return its type. */ - static int - simple_type (ffi_type *arg) - { - if (arg->type != FFI_TYPE_STRUCT) - return arg->type; - else if (arg->elements[1]) - return FFI_TYPE_STRUCT; - - return simple_type (arg->elements[0]); - } - static int return_type (ffi_type *arg) { - unsigned short type; if (arg->type != FFI_TYPE_STRUCT) return arg->type; - type = simple_type (arg->elements[0]); - if (! arg->elements[1]) - { - switch (type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - return FFI_TYPE_UINT64; - - default: - return type; - } - } - /* gcc uses r2 if the result can be packed in on register. */ ! if (arg->size <= sizeof (UINT64)) return FFI_TYPE_UINT64; --- 32,50 ---- #define NFREGARG 12 static int return_type (ffi_type *arg) { if (arg->type != FFI_TYPE_STRUCT) return arg->type; /* gcc uses r2 if the result can be packed in on register. */ ! if (arg->size <= sizeof (UINT8)) ! return FFI_TYPE_UINT8; ! else if (arg->size <= sizeof (UINT16)) ! return FFI_TYPE_UINT16; ! else if (arg->size <= sizeof (UINT32)) ! return FFI_TYPE_UINT32; ! else if (arg->size <= sizeof (UINT64)) return FFI_TYPE_UINT64; *************** *** 106,111 **** --- 79,86 ---- { size_t z; + int align; z = (*p_arg)->size; + align = (*p_arg)->alignment; if (z < sizeof (UINT32)) { *************** *** 129,133 **** case FFI_TYPE_STRUCT: ! *(UINT64 *) argp = (UINT64) *(UINT32 *)(*p_argv); break; --- 104,108 ---- case FFI_TYPE_STRUCT: ! memcpy (argp, *p_argv, z); break; *************** *** 137,146 **** argp += sizeof (UINT64); } ! else if (z == sizeof (UINT32)) { ! *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv); argp += sizeof (UINT64); } ! else if (z == sizeof (UINT64)) { *(UINT64 *) argp = *(UINT64 *) (*p_argv); --- 112,140 ---- argp += sizeof (UINT64); } ! else if (z == sizeof (UINT32) && align == sizeof (UINT32)) { ! switch ((*p_arg)->type) ! { ! case FFI_TYPE_INT: ! case FFI_TYPE_SINT32: ! *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv); ! break; ! ! case FFI_TYPE_FLOAT: ! case FFI_TYPE_POINTER: ! case FFI_TYPE_UINT32: ! case FFI_TYPE_STRUCT: ! *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv); ! break; ! ! default: ! FFI_ASSERT(0); ! break; ! } argp += sizeof (UINT64); } ! else if (z == sizeof (UINT64) ! && align == sizeof (UINT64) ! && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0) { *(UINT64 *) argp = *(UINT64 *) (*p_argv); *************** *** 255,258 **** --- 249,253 ---- { extended_cif ecif; + UINT64 trvalue; ecif.cif = cif; *************** *** 262,266 **** /* value address then we need to make one */ ! if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { --- 257,264 ---- /* value address then we need to make one */ ! if (cif->rtype->type == FFI_TYPE_STRUCT ! && return_type (cif->rtype) != FFI_TYPE_STRUCT) ! ecif.rvalue = &trvalue; ! else if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { *************** *** 284,287 **** --- 282,290 ---- break; } + + if (rvalue + && cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + memcpy (rvalue, &trvalue, cif->rtype->size); } *************** *** 354,358 **** /* Copy the caller's structure return value address so that the closure returns the data directly to the caller. */ ! if (cif->rtype->type == FFI_TYPE_STRUCT) { rvalue = *pgr; --- 357,361 ---- /* Copy the caller's structure return value address so that the closure returns the data directly to the caller. */ ! if (return_type (cif->rtype) == FFI_TYPE_STRUCT) { rvalue = *pgr; *************** *** 444,448 **** /* Tell ffi_closure_SYSV how to perform return type promotions. */ ! return cif->rtype->type; } --- 447,451 ---- /* Tell ffi_closure_SYSV how to perform return type promotions. */ ! return return_type (cif->rtype); } |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:04
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/alpha In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/alpha Modified Files: Tag: branch_1_0 osf.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:03
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/powerpc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/powerpc Modified Files: Tag: branch_1_0 darwin.S darwin_closure.S ffi.c ffitarget.h linux64.S linux64_closure.S ppc_closure.S sysv.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: ffitarget.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/ffitarget.h,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffitarget.h 31 Jan 2006 20:27:40 -0000 1.1.2.3 --- ffitarget.h 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 63,66 **** --- 63,73 ---- #endif + #ifdef POWERPC_FREEBSD + FFI_SYSV, + FFI_GCC_SYSV, + FFI_LINUX64, + FFI_DEFAULT_ABI = FFI_SYSV, + #endif + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; *************** *** 72,75 **** --- 79,85 ---- #define FFI_NATIVE_RAW_API 0 + /* Needed for FFI_SYSV small structure returns. */ + #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) + #if defined(POWERPC64) || defined(POWERPC_AIX) #define FFI_TRAMPOLINE_SIZE 24 Index: linux64.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/linux64.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** linux64.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- linux64.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 121,127 **** .Lfp_return_value: bf 28, .Lfloat_return_value stfd %f1, 0(%r30) ! stfd %f2, 8(%r30) /* It might be a long double */ b .Ldone_return_value .Lfloat_return_value: --- 121,131 ---- .Lfp_return_value: + bt 27, .Lfd_return_value bf 28, .Lfloat_return_value stfd %f1, 0(%r30) ! b .Ldone_return_value ! .Lfd_return_value: ! stfd %f1, 0(%r30) ! stfd %f2, 8(%r30) b .Ldone_return_value .Lfloat_return_value: Index: darwin.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/darwin.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** darwin.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- darwin.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 25,28 **** --- 25,38 ---- ----------------------------------------------------------------------- */ + #if defined(__ppc64__) + #define MODE_CHOICE(x, y) y + #else + #define MODE_CHOICE(x, y) x + #endif + + #define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + + #define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ + #define LIBFFI_ASM #include <fficonfig.h> *************** *** 191,195 **** .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 ! .align 2 LECIE1: .globl _ffi_call_DARWIN.eh --- 201,205 ---- .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 ! .align LOG2_GPR_BYTES LECIE1: .globl _ffi_call_DARWIN.eh *************** *** 200,206 **** LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset ! .long LLFB0$non_lazy_ptr-. ; FDE initial location .set L$set$3,LFE1-LFB0 ! .long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size .byte 0x4 ; DW_CFA_advance_loc4 --- 210,216 ---- LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset ! .g_long LLFB0$non_lazy_ptr-. ; FDE initial location .set L$set$3,LFE1-LFB0 ! .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size .byte 0x4 ; DW_CFA_advance_loc4 *************** *** 228,235 **** .byte 0xd ; DW_CFA_def_cfa_register .byte 0x1c ; uleb128 0x1c ! .align 2 LEFDE1: .data ! .align 2 LLFB0$non_lazy_ptr: ! .long LFB0 --- 238,245 ---- .byte 0xd ; DW_CFA_def_cfa_register .byte 0x1c ; uleb128 0x1c ! .align LOG2_GPR_BYTES LEFDE1: .data ! .align LOG2_GPR_BYTES LLFB0$non_lazy_ptr: ! .g_long LFB0 Index: linux64_closure.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/linux64_closure.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** linux64_closure.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- linux64_closure.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 6,10 **** #ifdef __powerpc64__ ! .hidden ffi_closure_LINUX64, .ffi_closure_LINUX64 .globl ffi_closure_LINUX64, .ffi_closure_LINUX64 .section ".opd","aw" --- 6,11 ---- #ifdef __powerpc64__ ! FFI_HIDDEN (ffi_closure_LINUX64) ! FFI_HIDDEN (.ffi_closure_LINUX64) .globl ffi_closure_LINUX64, .ffi_closure_LINUX64 .section ".opd","aw" Index: ffi.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/ffi.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffi.c 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- ffi.c 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 30,48 **** #include <stdio.h> - #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) - # define hidden __attribute__ ((visibility ("hidden"))) - #else - # define hidden - #endif ! ! extern void ffi_closure_SYSV(void); [...1440 lines suppressed...] ! int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, ! unsigned long *, ffi_dblfl *); ! int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, unsigned long *pst, ffi_dblfl *pfr) *************** *** 1124,1128 **** default: ! FFI_ASSERT(0); } --- 1236,1240 ---- default: ! FFI_ASSERT (0); } Index: ppc_closure.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/ppc_closure.S,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ppc_closure.S 31 Jan 2006 19:44:36 -0000 1.1.2.1 --- ppc_closure.S 1 Feb 2006 20:31:52 -0000 1.1.2.2 *************** *** 58,62 **** # make the call ! bl JUMPTARGET(ffi_closure_helper_SYSV) # now r3 contains the return type --- 58,62 ---- # make the call ! bl ffi_closure_helper_SYSV@local # now r3 contains the return type *************** *** 66,70 **** # look up the proper starting point in table # by using return type as offset ! addi %r5,%r1,112 # get pointer to results area bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR mflr %r4 # move to r4 --- 66,70 ---- # look up the proper starting point in table # by using return type as offset ! addi %r6,%r1,112 # get pointer to results area bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR mflr %r4 # move to r4 *************** *** 95,99 **** # case FFI_TYPE_INT .Lret_type1: ! lwz %r3,0(%r5) b .Lfinish nop --- 95,99 ---- # case FFI_TYPE_INT .Lret_type1: ! lwz %r3,0(%r6) b .Lfinish nop *************** *** 102,106 **** # case FFI_TYPE_FLOAT .Lret_type2: ! lfs %f1,0(%r5) b .Lfinish nop --- 102,106 ---- # case FFI_TYPE_FLOAT .Lret_type2: ! lfs %f1,0(%r6) b .Lfinish nop *************** *** 109,113 **** # case FFI_TYPE_DOUBLE .Lret_type3: ! lfd %f1,0(%r5) b .Lfinish nop --- 109,113 ---- # case FFI_TYPE_DOUBLE .Lret_type3: ! lfd %f1,0(%r6) b .Lfinish nop *************** *** 116,120 **** # case FFI_TYPE_LONGDOUBLE .Lret_type4: ! lfd %f1,0(%r5) b .Lfinish nop --- 116,120 ---- # case FFI_TYPE_LONGDOUBLE .Lret_type4: ! lfd %f1,0(%r6) b .Lfinish nop *************** *** 123,127 **** # case FFI_TYPE_UINT8 .Lret_type5: ! lbz %r3,3(%r5) b .Lfinish nop --- 123,127 ---- # case FFI_TYPE_UINT8 .Lret_type5: ! lbz %r3,3(%r6) b .Lfinish nop *************** *** 130,134 **** # case FFI_TYPE_SINT8 .Lret_type6: ! lbz %r3,3(%r5) extsb %r3,%r3 b .Lfinish --- 130,134 ---- # case FFI_TYPE_SINT8 .Lret_type6: ! lbz %r3,3(%r6) extsb %r3,%r3 b .Lfinish *************** *** 137,141 **** # case FFI_TYPE_UINT16 .Lret_type7: ! lhz %r3,2(%r5) b .Lfinish nop --- 137,141 ---- # case FFI_TYPE_UINT16 .Lret_type7: ! lhz %r3,2(%r6) b .Lfinish nop *************** *** 144,148 **** # case FFI_TYPE_SINT16 .Lret_type8: ! lha %r3,2(%r5) b .Lfinish nop --- 144,148 ---- # case FFI_TYPE_SINT16 .Lret_type8: ! lha %r3,2(%r6) b .Lfinish nop *************** *** 151,155 **** # case FFI_TYPE_UINT32 .Lret_type9: ! lwz %r3,0(%r5) b .Lfinish nop --- 151,155 ---- # case FFI_TYPE_UINT32 .Lret_type9: ! lwz %r3,0(%r6) b .Lfinish nop *************** *** 158,162 **** # case FFI_TYPE_SINT32 .Lret_type10: ! lwz %r3,0(%r5) b .Lfinish nop --- 158,162 ---- # case FFI_TYPE_SINT32 .Lret_type10: ! lwz %r3,0(%r6) b .Lfinish nop *************** *** 165,170 **** # case FFI_TYPE_UINT64 .Lret_type11: ! lwz %r3,0(%r5) ! lwz %r4,4(%r5) b .Lfinish nop --- 165,170 ---- # case FFI_TYPE_UINT64 .Lret_type11: ! lwz %r3,0(%r6) ! lwz %r4,4(%r6) b .Lfinish nop *************** *** 172,177 **** # case FFI_TYPE_SINT64 .Lret_type12: ! lwz %r3,0(%r5) ! lwz %r4,4(%r5) b .Lfinish nop --- 172,177 ---- # case FFI_TYPE_SINT64 .Lret_type12: ! lwz %r3,0(%r6) ! lwz %r4,4(%r6) b .Lfinish nop *************** *** 186,194 **** # case FFI_TYPE_POINTER .Lret_type14: ! lwz %r3,0(%r5) b .Lfinish nop nop # case done .Lfinish: --- 186,259 ---- # case FFI_TYPE_POINTER .Lret_type14: ! lwz %r3,0(%r6) ! b .Lfinish ! nop ! nop ! ! # The return types below are only used when the ABI type is FFI_SYSV. ! # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. ! .Lret_type15: ! # fall through. ! lbz %r3,0(%r6) ! b .Lfinish ! nop ! nop ! ! # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. ! .Lret_type16: ! # fall through. ! lhz %r3,0(%r6) b .Lfinish nop nop + # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. + .Lret_type17: + # fall through. + lwz %r3,0(%r6) + srwi %r3,%r3,8 + b .Lfinish + nop + + # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. + .Lret_type18: + # this one handles the structs from above too. + lwz %r3,0(%r6) + b .Lfinish + nop + nop + + # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. + .Lret_type19: + # fall through. + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,24 + b .Lstruct567 + + # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. + .Lret_type20: + # fall through. + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,16 + b .Lstruct567 + + # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. + .Lret_type21: + # fall through. + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,8 + b .Lstruct567 + + # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. + .Lret_type22: + # this one handles the above unhandled structs. + lwz %r3,0(%r6) + lwz %r4,4(%r6) + b .Lfinish + nop + # case done .Lfinish: *************** *** 198,201 **** --- 263,274 ---- addi %r1,%r1,144 blr + + .Lstruct567: + subfic %r0,%r5,32 + srw %r4,%r4,%r5 + slw %r0,%r3,%r0 + srw %r3,%r3,%r5 + or %r4,%r0,%r4 + b .Lfinish END(ffi_closure_SYSV) *************** *** 242,248 **** .byte 0x4 # DW_CFA_advance_loc4 .4byte .LCFI1-.LCFI0 ! .byte 0x2f # DW_CFA_GNU_negative_offset_extended .uleb128 0x41 ! .uleb128 0x1 .align 2 .LEFDE1: --- 315,321 ---- .byte 0x4 # DW_CFA_advance_loc4 .4byte .LCFI1-.LCFI0 ! .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x41 ! .sleb128 -1 .align 2 .LEFDE1: Index: darwin_closure.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/darwin_closure.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** darwin_closure.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- darwin_closure.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 28,38 **** #define L(x) x .file "darwin_closure.S" .text ! .align 2 .globl _ffi_closure_ASM .text ! .align 2 _ffi_closure_ASM: LFB1: --- 28,50 ---- #define L(x) x + #if defined(__ppc64__) + #define MODE_CHOICE(x, y) y + #else + #define MODE_CHOICE(x, y) x + #endif + + #define lgu MODE_CHOICE(lwzu, ldu) + + #define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + + #define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ + .file "darwin_closure.S" .text ! .align LOG2_GPR_BYTES .globl _ffi_closure_ASM .text ! .align LOG2_GPR_BYTES _ffi_closure_ASM: LFB1: *************** *** 235,239 **** .data ! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms EH_frame1: .set L$set$0,LECIE1-LSCIE1 --- 247,251 ---- .data ! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 *************** *** 251,255 **** .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 ! .align 2 LECIE1: .globl _ffi_closure_ASM.eh --- 263,267 ---- .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 ! .align LOG2_GPR_BYTES LECIE1: .globl _ffi_closure_ASM.eh *************** *** 261,267 **** LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset ! .long LLFB1$non_lazy_ptr-. ; FDE initial location .set L$set$3,LFE1-LFB1 ! .long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size .byte 0x4 ; DW_CFA_advance_loc4 --- 273,279 ---- LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset ! .g_long LLFB1$non_lazy_ptr-. ; FDE initial location .set L$set$3,LFE1-LFB1 ! .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size .byte 0x4 ; DW_CFA_advance_loc4 *************** *** 276,287 **** .byte 0x41 ; uleb128 0x41 .byte 0x7e ; sleb128 -2 ! .align 2 LEFDE1: .data ! .align 2 LDFCM0: .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 ! .align 2 Lffi_closure_helper_DARWIN$stub: .indirect_symbol _ffi_closure_helper_DARWIN mflr r0 --- 288,300 ---- .byte 0x41 ; uleb128 0x41 .byte 0x7e ; sleb128 -2 ! .align LOG2_GPR_BYTES LEFDE1: .data ! .align LOG2_GPR_BYTES LDFCM0: .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 ! .align LOG2_GPR_BYTES Lffi_closure_helper_DARWIN$stub: + #if 1 .indirect_symbol _ffi_closure_helper_DARWIN mflr r0 *************** *** 291,304 **** addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) mtlr r0 ! lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) mtctr r12 bctr - .data .lazy_symbol_pointer L_ffi_closure_helper_DARWIN$lazy_ptr: .indirect_symbol _ffi_closure_helper_DARWIN ! .long dyld_stub_binding_helper .data ! .align 2 LLFB1$non_lazy_ptr: ! .long LFB1 --- 304,317 ---- addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) mtlr r0 ! lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) mtctr r12 bctr .lazy_symbol_pointer L_ffi_closure_helper_DARWIN$lazy_ptr: .indirect_symbol _ffi_closure_helper_DARWIN ! .g_long dyld_stub_binding_helper ! #endif .data ! .align LOG2_GPR_BYTES LLFB1$non_lazy_ptr: ! .g_long LFB1 Index: sysv.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/powerpc/Attic/sysv.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** sysv.S 31 Jan 2006 20:27:40 -0000 1.1.2.3 --- sysv.S 1 Feb 2006 20:31:52 -0000 1.1.2.4 *************** *** 61,65 **** /* Call ffi_prep_args_SYSV. */ mr %r4,%r1 ! bl JUMPTARGET(ffi_prep_args_SYSV) /* Now do the call. */ --- 61,65 ---- /* Call ffi_prep_args_SYSV. */ mr %r4,%r1 ! bl ffi_prep_args_SYSV@local /* Now do the call. */ *************** *** 100,103 **** --- 100,104 ---- /* Now, deal with the return value. */ mtcrf 0x01,%r31 + bt- 31,L(small_struct_return_value) bt- 30,L(done_return_value) bt- 29,L(fp_return_value) *************** *** 125,128 **** --- 126,156 ---- stfs %f1,0(%r30) b L(done_return_value) + + L(small_struct_return_value): + mtcrf 0x10,%r31 /* cr3 */ + bt- 15,L(smst_one_register) + mtcrf 0x08,%r31 /* cr4 */ + bt- 16,L(smst_two_register) + b L(done_return_value) + + L(smst_one_register): + rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ + slw %r3,%r3,%r5 + stw %r3,0(%r30) + b L(done_return_value) + L(smst_two_register): + rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ + cmpwi %r5,0 + subfic %r9,%r5,32 + slw %r29,%r3,%r5 + srw %r9,%r4,%r9 + beq- L(smst_8byte) + or %r3,%r9,%r29 + slw %r4,%r4,%r5 + L(smst_8byte): + stw %r3,0(%r30) + stw %r4,4(%r30) + b L(done_return_value) + .LFE1: END(ffi_call_SYSV) *************** *** 170,176 **** .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI5-.LCFI0 ! .byte 0x2f /* DW_CFA_GNU_negative_offset_extended */ .uleb128 0x41 ! .uleb128 0x1 .byte 0x9f /* DW_CFA_offset, column 0x1f */ .uleb128 0x1 --- 198,204 ---- .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI5-.LCFI0 ! .byte 0x11 /* DW_CFA_offset_extended_sf */ .uleb128 0x41 ! .sleb128 -1 .byte 0x9f /* DW_CFA_offset, column 0x1f */ .uleb128 0x1 |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:03
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/sh In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/sh Modified Files: Tag: branch_1_0 ffi.c sysv.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: sysv.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/sh/Attic/sysv.S,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** sysv.S 31 Jan 2006 19:44:37 -0000 1.1.2.1 --- sysv.S 1 Feb 2006 20:31:52 -0000 1.1.2.2 *************** *** 402,405 **** --- 402,408 ---- L_pass_i: + cmp/eq #FFI_TYPE_INT,r0 + bf L_call_it + mov #8,r0 cmp/hs r0,r2 *************** *** 493,504 **** ENTRY(ffi_closure_SYSV) .LFB2: ! mov.l r14,@-r15 .LCFI7: sts.l pr,@-r15 /* Stack layout: ! ... ! 32 bytes (floating register parameters, SH-4 only) 16 bytes (register parameters) 8 bytes (result) 4 bytes (pad) --- 496,517 ---- ENTRY(ffi_closure_SYSV) .LFB2: ! mov.l r7,@-r15 .LCFI7: + mov.l r6,@-r15 + .LCFI8: + mov.l r5,@-r15 + .LCFI9: + mov.l r4,@-r15 + .LCFIA: + mov.l r14,@-r15 + .LCFIB: sts.l pr,@-r15 /* Stack layout: ! xx bytes (on stack parameters) 16 bytes (register parameters) + 4 bytes (saved frame pointer) + 4 bytes (saved return address) + 32 bytes (floating register parameters, SH-4 only) 8 bytes (result) 4 bytes (pad) *************** *** 506,529 **** <- new stack pointer */ ! .LCFI8: #if defined(__SH4__) ! add #-64,r15 #else ! add #-32,r15 #endif ! .LCFI9: mov r15,r14 ! .LCFIA: ! mov r14,r1 ! add #32,r1 ! mov.l r7,@-r1 ! mov.l r6,@-r1 ! mov.l r5,@-r1 ! mov.l r4,@-r1 ! mov r1,r6 #if defined(__SH4__) mov r14,r1 ! add #64,r1 #ifdef __LITTLE_ENDIAN__ fmov.s fr10,@-r1 --- 519,535 ---- <- new stack pointer */ ! .LCFIC: #if defined(__SH4__) ! add #-48,r15 #else ! add #-16,r15 #endif ! .LCFID: mov r15,r14 ! .LCFIE: #if defined(__SH4__) mov r14,r1 ! add #48,r1 #ifdef __LITTLE_ENDIAN__ fmov.s fr10,@-r1 *************** *** 546,549 **** --- 552,560 ---- #endif mov r1,r7 + mov r14,r6 + add #56,r6 + #else + mov r14,r6 + add #24,r6 #endif *************** *** 679,689 **** L_case_v: #if defined(__SH4__) ! add #64,r15 #else ! add #32,r15 #endif lds.l @r15+,pr rts ! mov.l @r15+,r14 .LFE2: .ffi_closure_SYSV_end: --- 690,701 ---- L_case_v: #if defined(__SH4__) ! add #48,r15 #else ! add #16,r15 #endif lds.l @r15+,pr + mov.l @r15+,r14 rts ! add #16,r15 .LFE2: .ffi_closure_SYSV_end: *************** *** 789,807 **** .4byte .LCFI8-.LCFI7 .byte 0xe /* DW_CFA_def_cfa_offset */ ! .byte 0x8 /* uleb128 0x8 */ .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI9-.LCFI8 .byte 0xe /* DW_CFA_def_cfa_offset */ #if defined(__SH4__) ! .byte 8+64 /* uleb128 8+64 */ #else ! .byte 8+32 /* uleb128 8+32 */ #endif .byte 0x91 /* DW_CFA_offset, column 0x11 */ ! .byte 0x2 ! .byte 0x8e /* DW_CFA_offset, column 0xe */ ! .byte 0x1 .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte .LCFIA-.LCFI9 .byte 0xd /* DW_CFA_def_cfa_register */ .byte 0xe /* uleb128 0xe */ --- 801,843 ---- .4byte .LCFI8-.LCFI7 .byte 0xe /* DW_CFA_def_cfa_offset */ ! .byte 0x8 /* uleb128 0x4 */ .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI9-.LCFI8 .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0xc /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIA-.LCFI9 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x10 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIB-.LCFIA + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x14 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFIC-.LCFIB + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x18 /* uleb128 0x4 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte .LCFID-.LCFIC + .byte 0xe /* DW_CFA_def_cfa_offset */ #if defined(__SH4__) ! .byte 24+48 /* uleb128 24+48 */ #else ! .byte 24+16 /* uleb128 24+16 */ #endif .byte 0x91 /* DW_CFA_offset, column 0x11 */ ! .byte 0x6 /* uleb128 0x6 */ ! .byte 0x8e /* DW_CFA_offset, column 0xe */ ! .byte 0x5 /* uleb128 0x5 */ ! .byte 0x8b /* DW_CFA_offset, column 0xb */ ! .byte 0x4 /* uleb128 0x4 */ ! .byte 0x8a /* DW_CFA_offset, column 0xa */ ! .byte 0x3 /* uleb128 0x3 */ ! .byte 0x89 /* DW_CFA_offset, column 0x9 */ ! .byte 0x2 /* uleb128 0x2 */ ! .byte 0x88 /* DW_CFA_offset, column 0x8 */ ! .byte 0x1 /* uleb128 0x1 */ .byte 0x4 /* DW_CFA_advance_loc4 */ ! .4byte .LCFIE-.LCFID .byte 0xd /* DW_CFA_def_cfa_register */ .byte 0xe /* uleb128 0xe */ Index: ffi.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/sh/Attic/ffi.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ffi.c 31 Jan 2006 19:44:37 -0000 1.1.2.1 --- ffi.c 1 Feb 2006 20:31:52 -0000 1.1.2.2 *************** *** 1,4 **** /* ----------------------------------------------------------------------- ! ffi.c - Copyright (c) 2002, 2003, 2004 Kaz Kojima SuperH Foreign Function Interface --- 1,4 ---- /* ----------------------------------------------------------------------- ! ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima SuperH Foreign Function Interface *************** *** 211,223 **** if (greg + n - 1 >= NGREGARG) continue; - greg += n; #else if (greg >= NGREGARG) continue; - else if (greg + n - 1 >= NGREGARG) - greg = NGREGARG; - else - greg += n; #endif memcpy (argp, *p_argv, z); argp += n * sizeof (int); --- 211,219 ---- if (greg + n - 1 >= NGREGARG) continue; #else if (greg >= NGREGARG) continue; #endif + greg += n; memcpy (argp, *p_argv, z); argp += n * sizeof (int); *************** *** 381,387 **** continue; else if (greg + n - 1 >= NGREGARG) ! greg = NGREGARG; ! else ! greg += n; for (m = 0; m < n; m++) cif->flags += FFI_TYPE_INT << (2 * j++); --- 377,382 ---- continue; else if (greg + n - 1 >= NGREGARG) ! n = NGREGARG - greg; ! greg += n; for (m = 0; m < n; m++) cif->flags += FFI_TYPE_INT << (2 * j++); *************** *** 428,431 **** --- 423,427 ---- { extended_cif ecif; + UINT64 trvalue; ecif.cif = cif; *************** *** 435,439 **** /* value address then we need to make one */ ! if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { --- 431,438 ---- /* value address then we need to make one */ ! if (cif->rtype->type == FFI_TYPE_STRUCT ! && return_type (cif->rtype) != FFI_TYPE_STRUCT) ! ecif.rvalue = &trvalue; ! else if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { *************** *** 444,448 **** else ecif.rvalue = rvalue; - switch (cif->abi) --- 443,446 ---- *************** *** 458,461 **** --- 456,464 ---- break; } + + if (rvalue + && cif->rtype->type == FFI_TYPE_STRUCT + && return_type (cif->rtype) != FFI_TYPE_STRUCT) + memcpy (rvalue, &trvalue, cif->rtype->size); } *************** *** 621,633 **** if (greg + n - 1 >= NGREGARG) continue; - greg += n; #else if (greg >= NGREGARG) continue; - else if (greg + n - 1 >= NGREGARG) - greg = NGREGARG; - else - greg += n; #endif avalue[i] = pgr; pgr += n; --- 624,632 ---- if (greg + n - 1 >= NGREGARG) continue; #else if (greg >= NGREGARG) continue; #endif + greg += n; avalue[i] = pgr; pgr += n; *************** *** 713,717 **** else if (greg < NGREGARG) { ! greg = NGREGARG; continue; } --- 712,717 ---- else if (greg < NGREGARG) { ! greg += n; ! pst += greg - NGREGARG; continue; } |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:32:00
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/mips In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src/mips Modified Files: Tag: branch_1_0 ffi.c ffitarget.h o32.S Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: o32.S =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/mips/Attic/o32.S,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** o32.S 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- o32.S 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 36,40 **** #define flags a3 ! #define SIZEOF_FRAME ( 4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG ) .abicalls --- 36,43 ---- #define flags a3 ! #define SIZEOF_FRAME (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG) ! #define A3_OFF (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG) ! #define FP_OFF (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG) ! #define RA_OFF (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG) .abicalls *************** *** 46,91 **** $LFB0: # Prologue ! SUBU $sp, SIZEOF_FRAME # Frame size $LCFI0: ! REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer $LCFI1: ! REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address $LCFI2: move $fp, $sp $LCFI3: ! move t9, callback # callback function pointer ! REG_S flags, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # flags # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * FFI_SIZEOF_ARG, bigger LI v0, 4 * FFI_SIZEOF_ARG ! b sixteen ! bigger: ! ADDU t0, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned ! and v0, t0, -2 * FFI_SIZEOF_ARG # to an 8 byte boundry sixteen: ! SUBU $sp, $sp, v0 # move the stack pointer to reflect the # arg space ADDU a0, $sp, 4 * FFI_SIZEOF_ARG - ADDU a3, $fp, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG jalr t9 ! REG_L t0, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # load the flags word ! add t2, t0, 0 # and copy it into t2 ! and t0, ((1<<4)-1) # mask out the return type - SRL t2, 4 # shift our arg info ! ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args bnez t0, pass_d # make it quick for int ! REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the ! REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. REG_L a2, 2*FFI_SIZEOF_ARG($sp) REG_L a3, 3*FFI_SIZEOF_ARG($sp) --- 49,88 ---- $LFB0: # Prologue ! SUBU $sp, SIZEOF_FRAME # Frame size $LCFI0: ! REG_S $fp, FP_OFF($sp) # Save frame pointer $LCFI1: ! REG_S ra, RA_OFF($sp) # Save return address $LCFI2: move $fp, $sp $LCFI3: ! move t9, callback # callback function pointer ! REG_S flags, A3_OFF($fp) # flags # Allocate at least 4 words in the argstack LI v0, 4 * FFI_SIZEOF_ARG ! blt bytes, v0, sixteen ! ADDU v0, bytes, 7 # make sure it is aligned ! and v0, -8 # to an 8 byte boundry sixteen: ! SUBU $sp, v0 # move the stack pointer to reflect the # arg space ADDU a0, $sp, 4 * FFI_SIZEOF_ARG jalr t9 ! REG_L t0, A3_OFF($fp) # load the flags word ! SRL t2, t0, 4 # shift our arg info and t0, ((1<<4)-1) # mask out the return type ! ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args bnez t0, pass_d # make it quick for int ! REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the ! REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. REG_L a2, 2*FFI_SIZEOF_ARG($sp) REG_L a3, 3*FFI_SIZEOF_ARG($sp) *************** *** 177,183 **** epilogue: move $sp, $fp ! REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer ! REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address ! ADDU $sp, SIZEOF_FRAME # Fix stack pointer j ra --- 174,180 ---- epilogue: move $sp, $fp ! REG_L $fp, FP_OFF($sp) # Restore frame pointer ! REG_L ra, RA_OFF($sp) # Restore return address ! ADDU $sp, SIZEOF_FRAME # Fix stack pointer j ra *************** *** 210,214 **** */ ! #define SIZEOF_FRAME2 ( 14 * FFI_SIZEOF_ARG ) .text --- 207,225 ---- */ ! #define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG) ! #define A3_OFF2 (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG) ! #define A2_OFF2 (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG) ! #define A1_OFF2 (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG) ! #define A0_OFF2 (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG) ! #define RA_OFF2 (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG) ! #define FP_OFF2 (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG) ! #define S0_OFF2 (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG) ! #define GP_OFF2 (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG) ! #define V1_OFF2 (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG) ! #define V0_OFF2 (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG) ! #define FA_1_1_OFF2 (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG) ! #define FA_1_0_OFF2 (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG) ! #define FA_0_1_OFF2 (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG) ! #define FA_0_0_OFF2 (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG) .text *************** *** 219,232 **** $LFB1: # Prologue ! .frame $fp, SIZEOF_FRAME2, $31 .set noreorder ! .cpload $25 .set reorder SUBU $sp, SIZEOF_FRAME2 ! .cprestore SIZEOF_FRAME2 - 4*FFI_SIZEOF_ARG $LCFI4: ! REG_S $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Save s0 ! REG_S $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer ! REG_S ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Save return address $LCFI6: move $fp, $sp --- 230,243 ---- $LFB1: # Prologue ! .frame $fp, SIZEOF_FRAME2, ra .set noreorder ! .cpload t9 .set reorder SUBU $sp, SIZEOF_FRAME2 ! .cprestore GP_OFF2 $LCFI4: ! REG_S $16, S0_OFF2($sp) # Save s0 ! REG_S $fp, FP_OFF2($sp) # Save frame pointer ! REG_S ra, RA_OFF2($sp) # Save return address $LCFI6: move $fp, $sp *************** *** 234,244 **** $LCFI7: # Store all possible argument registers. If there are more than ! # four arguments, then they should be stored above where we put $7. ! REG_S $4, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG($fp) ! REG_S $5, SIZEOF_FRAME2 + 1*FFI_SIZEOF_ARG($fp) ! REG_S $6, SIZEOF_FRAME2 + 2*FFI_SIZEOF_ARG($fp) ! REG_S $7, SIZEOF_FRAME2 + 3*FFI_SIZEOF_ARG($fp) ! # Load ABI enum to $16 REG_L $16, 20($8) # cif pointer follows tramp. REG_L $16, 0($16) # abi is first member. --- 245,255 ---- $LCFI7: # Store all possible argument registers. If there are more than ! # four arguments, then they are stored above where we put a3. ! REG_S a0, A0_OFF2($fp) ! REG_S a1, A1_OFF2($fp) ! REG_S a2, A2_OFF2($fp) ! REG_S a3, A3_OFF2($fp) ! # Load ABI enum to s0 REG_L $16, 20($8) # cif pointer follows tramp. REG_L $16, 0($16) # abi is first member. *************** *** 248,261 **** # Store all possible float/double registers. ! s.d $f12, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG($fp) ! s.d $f14, SIZEOF_FRAME2 - 8*FFI_SIZEOF_ARG($fp) 1: # Call ffi_closure_mips_inner_O32 to do the work. ! la $25, ffi_closure_mips_inner_O32 ! move $4, $8 # Pointer to the ffi_closure ! addu $5, $fp, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG ! addu $6, $fp, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG ! addu $7, $fp, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG ! jalr $31, $25 # Load the return value into the appropriate register. --- 259,272 ---- # Store all possible float/double registers. ! s.d $f12, FA_0_0_OFF2($fp) ! s.d $f14, FA_1_0_OFF2($fp) 1: # Call ffi_closure_mips_inner_O32 to do the work. ! la t9, ffi_closure_mips_inner_O32 ! move a0, $8 # Pointer to the ffi_closure ! addu a1, $fp, V0_OFF2 ! addu a2, $fp, A0_OFF2 ! addu a3, $fp, FA_0_0_OFF2 ! jalr t9 # Load the return value into the appropriate register. *************** *** 268,293 **** li $9, FFI_TYPE_FLOAT ! l.s $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) beq $8, $9, closure_done li $9, FFI_TYPE_DOUBLE ! l.d $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) beq $8, $9, closure_done 1: ! li $9, FFI_TYPE_SINT64 ! REG_L $3, SIZEOF_FRAME2 - 5*FFI_SIZEOF_ARG($fp) ! beq $8, $9, integer ! li $9, FFI_TYPE_UINT64 ! beq $8, $9, integer ! ! integer: ! REG_L $2, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) closure_done: # Epilogue move $sp, $fp ! REG_L $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Restore s0 ! REG_L $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer ! REG_L ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Restore return address ADDU $sp, SIZEOF_FRAME2 j ra --- 279,298 ---- li $9, FFI_TYPE_FLOAT ! l.s $f0, V0_OFF2($fp) beq $8, $9, closure_done li $9, FFI_TYPE_DOUBLE ! l.d $f0, V0_OFF2($fp) beq $8, $9, closure_done 1: ! REG_L $3, V1_OFF2($fp) ! REG_L $2, V0_OFF2($fp) closure_done: # Epilogue move $sp, $fp ! REG_L $16, S0_OFF2($sp) # Restore s0 ! REG_L $fp, FP_OFF2($sp) # Restore frame pointer ! REG_L ra, RA_OFF2($sp) # Restore return address ADDU $sp, SIZEOF_FRAME2 j ra Index: ffi.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/mips/Attic/ffi.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffi.c 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- ffi.c 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 51,58 **** int flags) { ! register int i; ! register void **p_argv; ! register char *argp; ! register ffi_type **p_arg; #if _MIPS_SIM == _ABIN32 --- 51,58 ---- int flags) { ! int i; ! void **p_argv; ! char *argp; ! ffi_type **p_arg; #if _MIPS_SIM == _ABIN32 *************** *** 60,65 **** on the stack. We reorder stuff on the stack here to support this easily. */ ! if (bytes > 8 * FFI_SIZEOF_ARG) ! argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)]; else argp = stack; --- 60,65 ---- on the stack. We reorder stuff on the stack here to support this easily. */ ! if (bytes > 8 * sizeof(ffi_arg)) ! argp = &stack[bytes - (8 * sizeof(ffi_arg))]; else argp = stack; *************** *** 86,185 **** { size_t z; ! unsigned short a; ! /* Align if necessary */ a = (*p_arg)->alignment; ! if (a < FFI_SIZEOF_ARG) ! a = FFI_SIZEOF_ARG; ! if ((a - 1) & (unsigned) argp) { ! argp = (char *) ALIGN(argp, a); ! FIX_ARGP; ! } ! #if _MIPS_SIM == _ABIO32 ! #define OFFSET 0 ! #else ! #define OFFSET sizeof(int) ! #endif ! z = (*p_arg)->size; ! if (z < sizeof(ffi_arg)) { ! z = sizeof(ffi_arg); ! switch ((*p_arg)->type) ! { ! case FFI_TYPE_SINT8: ! *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); ! break; ! ! case FFI_TYPE_UINT8: ! *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); ! break; ! case FFI_TYPE_SINT16: ! *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); ! break; ! case FFI_TYPE_UINT16: ! *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); ! break; ! case FFI_TYPE_SINT32: ! *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); ! break; ! case FFI_TYPE_UINT32: ! case FFI_TYPE_POINTER: ! *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv); ! break; ! ! /* This can only happen with 64bit slots */ ! case FFI_TYPE_FLOAT: ! *(float *) argp = *(float *)(* p_argv); ! break; ! /* Handle small structures */ ! case FFI_TYPE_STRUCT: ! memcpy(argp, *p_argv, (*p_arg)->size); ! break; ! default: ! FFI_ASSERT(0); ! } } ! else ! { ! #if _MIPS_SIM == _ABIO32 ! memcpy(argp, *p_argv, z); #else ! { ! unsigned end = (unsigned) argp+z; ! unsigned cap = (unsigned) stack+bytes; ! /* Check if the data will fit within the register ! space. Handle it if it doesn't. */ ! if (end <= cap) ! memcpy(argp, *p_argv, z); ! else ! { ! unsigned portion = end - cap; ! memcpy(argp, *p_argv, portion); ! argp = stack; ! memcpy(argp, ! (void*)((unsigned)(*p_argv)+portion), z - portion); ! } } #endif ! } ! p_argv++; ! argp += z; ! FIX_ARGP; } - - return; } --- 86,176 ---- { size_t z; ! unsigned int a; ! /* Align if necessary. */ a = (*p_arg)->alignment; ! if (a < sizeof(ffi_arg)) ! a = sizeof(ffi_arg); ! if ((a - 1) & (unsigned int) argp) ! { ! argp = (char *) ALIGN(argp, a); ! FIX_ARGP; ! } ! z = (*p_arg)->size; ! if (z <= sizeof(ffi_arg)) ! { ! z = sizeof(ffi_arg); ! switch ((*p_arg)->type) { ! case FFI_TYPE_SINT8: ! *(ffi_arg *)argp = *(SINT8 *)(* p_argv); ! break; ! case FFI_TYPE_UINT8: ! *(ffi_arg *)argp = *(UINT8 *)(* p_argv); ! break; ! case FFI_TYPE_SINT16: ! *(ffi_arg *)argp = *(SINT16 *)(* p_argv); ! break; ! case FFI_TYPE_UINT16: ! *(ffi_arg *)argp = *(UINT16 *)(* p_argv); ! break; ! case FFI_TYPE_SINT32: ! *(ffi_arg *)argp = *(SINT32 *)(* p_argv); ! break; ! case FFI_TYPE_UINT32: ! case FFI_TYPE_POINTER: ! *(ffi_arg *)argp = *(UINT32 *)(* p_argv); ! break; ! /* This can only happen with 64bit slots. */ ! case FFI_TYPE_FLOAT: ! *(float *) argp = *(float *)(* p_argv); ! break; ! /* Handle small structures. */ ! case FFI_TYPE_STRUCT: ! default: ! memcpy(argp, *p_argv, (*p_arg)->size); ! break; } ! } ! else ! { ! #if _MIPS_SIM == _ABIO32 ! memcpy(argp, *p_argv, z); #else ! { ! unsigned end = (unsigned) argp+z; ! unsigned cap = (unsigned) stack+bytes; ! /* Check if the data will fit within the register space. ! Handle it if it doesn't. */ ! if (end <= cap) ! memcpy(argp, *p_argv, z); ! else ! { ! unsigned portion = end - cap; ! memcpy(argp, *p_argv, portion); ! argp = stack; ! memcpy(argp, ! (void*)((unsigned)(*p_argv)+portion), z - portion); } + } #endif ! } ! p_argv++; ! argp += z; ! FIX_ARGP; } } *************** *** 525,530 **** tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */ ! tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */ ! tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */ tramp[3] = 0x03200008; /* jr $25 */ tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */ --- 516,521 ---- tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */ ! tramp[1] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */ ! tramp[2] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */ tramp[3] = 0x03200008; /* jr $25 */ tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */ *************** *** 559,572 **** int ffi_closure_mips_inner_O32 (ffi_closure *closure, ! void *rvalue, unsigned long *ar, double *fpr) { ffi_cif *cif; ! void **avalue; ffi_type **arg_types; int i, avn, argn, seen_int; cif = closure->cif; ! avalue = alloca (cif->nargs * sizeof (void *)); seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); --- 550,565 ---- int ffi_closure_mips_inner_O32 (ffi_closure *closure, ! void *rvalue, ffi_arg *ar, double *fpr) { ffi_cif *cif; ! void **avaluep; ! ffi_arg *avalue; ffi_type **arg_types; int i, avn, argn, seen_int; cif = closure->cif; ! avalue = alloca (cif->nargs * sizeof (ffi_arg)); ! avaluep = alloca (cif->nargs * sizeof (ffi_arg)); seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); *************** *** 589,593 **** arg_types[i]->type == FFI_TYPE_DOUBLE)) { ! avalue[i] = ((char *) &fpr[i]); } else --- 582,591 ---- arg_types[i]->type == FFI_TYPE_DOUBLE)) { ! #ifdef __MIPSEB__ ! if (arg_types[i]->type == FFI_TYPE_FLOAT) ! avaluep[i] = ((char *) &fpr[i]) + sizeof (float); ! else ! #endif ! avaluep[i] = (char *) &fpr[i]; } else *************** *** 595,599 **** if (arg_types[i]->alignment == 8 && (argn & 0x1)) argn++; ! avalue[i] = ((char *) &ar[argn]); seen_int = 1; } --- 593,622 ---- if (arg_types[i]->alignment == 8 && (argn & 0x1)) argn++; ! switch (arg_types[i]->type) ! { ! case FFI_TYPE_SINT8: ! avaluep[i] = &avalue[i]; ! *(SINT8 *) &avalue[i] = (SINT8) ar[argn]; ! break; ! ! case FFI_TYPE_UINT8: ! avaluep[i] = &avalue[i]; ! *(UINT8 *) &avalue[i] = (UINT8) ar[argn]; ! break; ! ! case FFI_TYPE_SINT16: ! avaluep[i] = &avalue[i]; ! *(SINT16 *) &avalue[i] = (SINT16) ar[argn]; ! break; ! ! case FFI_TYPE_UINT16: ! avaluep[i] = &avalue[i]; ! *(UINT16 *) &avalue[i] = (UINT16) ar[argn]; ! break; ! ! default: ! avaluep[i] = (char *) &ar[argn]; ! break; ! } seen_int = 1; } *************** *** 603,607 **** /* Invoke the closure. */ ! (closure->fun) (cif, rvalue, avalue, closure->user_data); if (cif->abi == FFI_O32_SOFT_FLOAT) --- 626,630 ---- /* Invoke the closure. */ ! (closure->fun) (cif, rvalue, avaluep, closure->user_data); if (cif->abi == FFI_O32_SOFT_FLOAT) Index: ffitarget.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/mips/Attic/ffitarget.h,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** ffitarget.h 31 Jan 2006 20:17:42 -0000 1.1.2.3 --- ffitarget.h 1 Feb 2006 20:31:51 -0000 1.1.2.4 *************** *** 27,34 **** #define LIBFFI_TARGET_H - #ifndef LIBFFI_ASM - #include <sgidefs.h> - #endif - #if !defined(_MIPS_SIM) -- something is very wrong -- --- 27,30 ---- *************** *** 37,41 **** # define FFI_MIPS_N32 # else ! # if _MIPS_SIM==_ABIO32 && defined(_ABIO32) # define FFI_MIPS_O32 # else --- 33,37 ---- # define FFI_MIPS_N32 # else ! # if (_MIPS_SIM==_ABIO32 && defined(_ABIO32)) # define FFI_MIPS_O32 # else |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 20:31:59
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9598/source/libffi/src Modified Files: Tag: branch_1_0 prep_cif.c Log Message: Update libffi to gcc head as of 2006/02/01. This fixes several unittest failures on 64bit platforms. Index: prep_cif.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/src/Attic/prep_cif.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** prep_cif.c 31 Jan 2006 19:44:35 -0000 1.1.2.1 --- prep_cif.c 1 Feb 2006 20:31:51 -0000 1.1.2.2 *************** *** 82,85 **** --- 82,90 ---- } + #ifndef __CRIS__ + /* The CRIS ABI specifies structure elements to have byte + alignment only, so it completely overrides this functions, + which assumes "natural" alignment and padding. */ + /* Perform machine independent ffi_cif preparation, then call machine dependent routine. */ *************** *** 159,160 **** --- 164,166 ---- return ffi_prep_cif_machdep(cif); } + #endif /* not __CRIS__ */ |
From: Thomas H. <th...@us...> - 2006-02-01 20:15:36
|
Update of /cvsroot/ctypes/ctypes/source/libffi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3547/source/libffi Modified Files: Tag: branch_1_0 fficonfig.py.in Log Message: Fix include file not found problem, patch from Hye-Shik Chang. Index: fficonfig.py.in =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/libffi/Attic/fficonfig.py.in,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** fficonfig.py.in 31 Jan 2006 20:14:15 -0000 1.1.2.3 --- fficonfig.py.in 1 Feb 2006 20:15:26 -0000 1.1.2.4 *************** *** 25,28 **** --- 25,29 ---- } + ffi_srcdir = '@srcdir@' ffi_sources += ffi_platforms['@TARGET@'].split() ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] |
From: Thomas H. <th...@us...> - 2006-02-01 20:15:33
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3547 Modified Files: Tag: branch_1_0 setup.py Log Message: Fix include file not found problem, patch from Hye-Shik Chang. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.122.2.11 retrieving revision 1.122.2.12 diff -C2 -d -r1.122.2.11 -r1.122.2.12 *** setup.py 31 Jan 2006 19:44:35 -0000 1.122.2.11 --- setup.py 1 Feb 2006 20:15:25 -0000 1.122.2.12 *************** *** 146,149 **** --- 146,150 ---- fficonfig = {} execfile(fficonfigfile, globals(), fficonfig) + srcdir = os.path.join(fficonfig['ffi_srcdir'], 'src') for ext in self.extensions: *************** *** 151,154 **** --- 152,156 ---- ext.include_dirs.append(incdir) ext.include_dirs.append(incdir_2) + ext.include_dirs.append(srcdir) ext.sources.extend(fficonfig['ffi_sources']) if fficonfig['ffi_cflags'].strip(): |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 18:46:27
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/cris In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20665/cris Log Message: Directory /cvsroot/ctypes/ctypes/source/libffi/src/cris added to the repository --> Using per-directory sticky tag `branch_1_0' |
From: Hye-Shik C. <pe...@us...> - 2006-02-01 16:00:18
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13773 Modified Files: Tag: branch_1_0 MANIFEST.other.in Log Message: Update path to libffi sources: source/gcc -> source/libffi Index: MANIFEST.other.in =================================================================== RCS file: /cvsroot/ctypes/ctypes/MANIFEST.other.in,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -C2 -d -r1.2 -r1.2.4.1 *** MANIFEST.other.in 23 Jul 2004 13:19:03 -0000 1.2 --- MANIFEST.other.in 1 Feb 2006 16:00:08 -0000 1.2.4.1 *************** *** 4,8 **** include source/darwin/*.c source/darwin/*.h include ctypes/.CTYPES_DEVEL ! recursive-include source/gcc * include unittests/*.py --- 4,8 ---- include source/darwin/*.c source/darwin/*.h include ctypes/.CTYPES_DEVEL ! recursive-include source/libffi * include unittests/*.py *************** *** 13,15 **** include samples/rt recursive-include samples *.py ! prune samples/Windows \ No newline at end of file --- 13,15 ---- include samples/rt recursive-include samples *.py ! prune samples/Windows |
From: Thomas H. <th...@us...> - 2006-01-31 20:27:47
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/powerpc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32323/src/powerpc Added Files: Tag: branch_1_0 ffitarget.h sysv.S Log Message: Still some files were missing. --- NEW FILE: sysv.S --- /* ----------------------------------------------------------------------- sysv.h - Copyright (c) 1998 Geoffrey Keating PowerPC Assembly glue. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> #include <powerpc/asm.h> #ifndef __powerpc64__ .globl ffi_prep_args_SYSV ENTRY(ffi_call_SYSV) .LFB1: /* Save the old stack pointer as AP. */ mr %r8,%r1 .LCFI0: /* Allocate the stack space we need. */ stwux %r1,%r1,%r4 /* Save registers we use. */ mflr %r9 stw %r28,-16(%r8) .LCFI1: stw %r29,-12(%r8) .LCFI2: stw %r30, -8(%r8) .LCFI3: stw %r31, -4(%r8) .LCFI4: stw %r9, 4(%r8) .LCFI5: /* Save arguments over call... */ mr %r31,%r5 /* flags, */ mr %r30,%r6 /* rvalue, */ mr %r29,%r7 /* function address, */ mr %r28,%r8 /* our AP. */ .LCFI6: /* Call ffi_prep_args_SYSV. */ mr %r4,%r1 bl JUMPTARGET(ffi_prep_args_SYSV) /* Now do the call. */ /* Set up cr1 with bits 4-7 of the flags. */ mtcrf 0x40,%r31 /* Get the address to call into CTR. */ mtctr %r29 /* Load all those argument registers. */ lwz %r3,-16-(8*4)(%r28) lwz %r4,-16-(7*4)(%r28) lwz %r5,-16-(6*4)(%r28) lwz %r6,-16-(5*4)(%r28) bf- 5,1f nop lwz %r7,-16-(4*4)(%r28) lwz %r8,-16-(3*4)(%r28) lwz %r9,-16-(2*4)(%r28) lwz %r10,-16-(1*4)(%r28) nop 1: /* Load all the FP registers. */ bf- 6,2f lfd %f1,-16-(8*4)-(8*8)(%r28) lfd %f2,-16-(8*4)-(7*8)(%r28) lfd %f3,-16-(8*4)-(6*8)(%r28) lfd %f4,-16-(8*4)-(5*8)(%r28) nop lfd %f5,-16-(8*4)-(4*8)(%r28) lfd %f6,-16-(8*4)-(3*8)(%r28) lfd %f7,-16-(8*4)-(2*8)(%r28) lfd %f8,-16-(8*4)-(1*8)(%r28) 2: /* Make the call. */ bctrl /* Now, deal with the return value. */ mtcrf 0x01,%r31 bt- 30,L(done_return_value) bt- 29,L(fp_return_value) stw %r3,0(%r30) bf+ 28,L(done_return_value) stw %r4,4(%r30) /* Fall through... */ L(done_return_value): /* Restore the registers we used and return. */ lwz %r9, 4(%r28) lwz %r31, -4(%r28) mtlr %r9 lwz %r30, -8(%r28) lwz %r29,-12(%r28) lwz %r28,-16(%r28) lwz %r1,0(%r1) blr L(fp_return_value): bf 28,L(float_return_value) stfd %f1,0(%r30) b L(done_return_value) L(float_return_value): stfs %f1,0(%r30) b L(done_return_value) .LFE1: END(ffi_call_SYSV) .section ".eh_frame",EH_FRAME_FLAGS,@progbits .Lframe1: .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ .LSCIE1: .4byte 0x0 /* CIE Identifier Tag */ .byte 0x1 /* CIE Version */ #if defined _RELOCATABLE || defined __PIC__ .ascii "zR\0" /* CIE Augmentation */ #else .ascii "\0" /* CIE Augmentation */ #endif .uleb128 0x1 /* CIE Code Alignment Factor */ .sleb128 -4 /* CIE Data Alignment Factor */ .byte 0x41 /* CIE RA Column */ #if defined _RELOCATABLE || defined __PIC__ .uleb128 0x1 /* Augmentation size */ .byte 0x1b /* FDE Encoding (pcrel sdata4) */ #endif .byte 0xc /* DW_CFA_def_cfa */ .uleb128 0x1 .uleb128 0x0 .align 2 .LECIE1: .LSFDE1: .4byte .LEFDE1-.LASFDE1 /* FDE Length */ .LASFDE1: .4byte .LASFDE1-.Lframe1 /* FDE CIE offset */ #if defined _RELOCATABLE || defined __PIC__ .4byte .LFB1-. /* FDE initial location */ #else .4byte .LFB1 /* FDE initial location */ #endif .4byte .LFE1-.LFB1 /* FDE address range */ #if defined _RELOCATABLE || defined __PIC__ .uleb128 0x0 /* Augmentation size */ #endif .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI0-.LFB1 .byte 0xd /* DW_CFA_def_cfa_register */ .uleb128 0x08 .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI5-.LCFI0 .byte 0x2f /* DW_CFA_GNU_negative_offset_extended */ .uleb128 0x41 .uleb128 0x1 .byte 0x9f /* DW_CFA_offset, column 0x1f */ .uleb128 0x1 .byte 0x9e /* DW_CFA_offset, column 0x1e */ .uleb128 0x2 .byte 0x9d /* DW_CFA_offset, column 0x1d */ .uleb128 0x3 .byte 0x9c /* DW_CFA_offset, column 0x1c */ .uleb128 0x4 .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFI6-.LCFI5 .byte 0xd /* DW_CFA_def_cfa_register */ .uleb128 0x1c .align 2 .LEFDE1: #endif --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for PowerPC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H /* ---- System specific configurations ----------------------------------- */ #if defined (POWERPC) && defined (__powerpc64__) #define POWERPC64 #endif #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, #ifdef POWERPC FFI_SYSV, FFI_GCC_SYSV, FFI_LINUX64, # ifdef POWERPC64 FFI_DEFAULT_ABI = FFI_LINUX64, # else FFI_DEFAULT_ABI = FFI_GCC_SYSV, # endif #endif #ifdef POWERPC_AIX FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_AIX, #endif #ifdef POWERPC_DARWIN FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_DARWIN, #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 #if defined(POWERPC64) || defined(POWERPC_AIX) #define FFI_TRAMPOLINE_SIZE 24 #else /* POWERPC || POWERPC_AIX */ #define FFI_TRAMPOLINE_SIZE 40 #endif #ifndef LIBFFI_ASM #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) struct ffi_aix_trampoline_struct { void * code_pointer; /* Pointer to ffi_closure_ASM */ void * toc; /* TOC */ void * static_chain; /* Pointer to closure */ }; #endif #endif #endif |
From: Thomas H. <th...@us...> - 2006-01-31 20:17:54
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/mips In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28311/src/mips Added Files: Tag: branch_1_0 ffi.c ffitarget.h n32.S o32.S Log Message: Hm, somehow pcl-cvs managed to first add, then remove the files again ;-( --- NEW FILE: n32.S --- /* ----------------------------------------------------------------------- n32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc. MIPS Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> /* Only build this code if we are compiling for n32 */ #if defined(FFI_MIPS_N32) #define callback a0 #define bytes a2 #define flags a3 #define raddr a4 #define fn a5 #define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG ) .abicalls .text .align 2 .globl ffi_call_N32 .ent ffi_call_N32 ffi_call_N32: # Prologue SUBU $sp, SIZEOF_FRAME # Frame size REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address move $fp, $sp move t9, callback # callback function pointer REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags REG_S raddr, 4*FFI_SIZEOF_ARG($fp) # raddr REG_S fn, 5*FFI_SIZEOF_ARG($fp) # fn # Allocate at least 4 words in the argstack move v0, bytes bge bytes, 4 * FFI_SIZEOF_ARG, bigger LI v0, 4 * FFI_SIZEOF_ARG b sixteen bigger: ADDU t4, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned and v0, t4, -2 * FFI_SIZEOF_ARG # to a proper boundry. sixteen: SUBU $sp, $sp, v0 # move the stack pointer to reflect the # arg space ADDU a0, $sp, 0 # 4 * FFI_SIZEOF_ARG ADDU a3, $fp, 3 * FFI_SIZEOF_ARG # Call ffi_prep_args jal t9 # ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args # Copy the stack pointer to t9 move t9, $sp # Fix the stack if there are more than 8 64bit slots worth # of arguments. # Load the number of bytes REG_L t6, 2*FFI_SIZEOF_ARG($fp) # Is it bigger than 8 * FFI_SIZEOF_ARG? dadd t7, $0, 8 * FFI_SIZEOF_ARG dsub t8, t6, t7 bltz t8, loadregs add t9, t9, t8 loadregs: REG_L t4, 3*FFI_SIZEOF_ARG($fp) # load the flags word add t6, t4, 0 # and copy it into t6 and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg1_floatp REG_L a0, 0*FFI_SIZEOF_ARG(t9) b arg1_next arg1_floatp: bne t4, FFI_TYPE_FLOAT, arg1_doublep l.s $f12, 0*FFI_SIZEOF_ARG(t9) b arg1_next arg1_doublep: l.d $f12, 0*FFI_SIZEOF_ARG(t9) arg1_next: add t4, t6, 0 SRL t4, 1*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg2_floatp REG_L a1, 1*FFI_SIZEOF_ARG(t9) b arg2_next arg2_floatp: bne t4, FFI_TYPE_FLOAT, arg2_doublep l.s $f13, 1*FFI_SIZEOF_ARG(t9) b arg2_next arg2_doublep: l.d $f13, 1*FFI_SIZEOF_ARG(t9) arg2_next: add t4, t6, 0 SRL t4, 2*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg3_floatp REG_L a2, 2*FFI_SIZEOF_ARG(t9) b arg3_next arg3_floatp: bne t4, FFI_TYPE_FLOAT, arg3_doublep l.s $f14, 2*FFI_SIZEOF_ARG(t9) b arg3_next arg3_doublep: l.d $f14, 2*FFI_SIZEOF_ARG(t9) arg3_next: add t4, t6, 0 SRL t4, 3*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg4_floatp REG_L a3, 3*FFI_SIZEOF_ARG(t9) b arg4_next arg4_floatp: bne t4, FFI_TYPE_FLOAT, arg4_doublep l.s $f15, 3*FFI_SIZEOF_ARG(t9) b arg4_next arg4_doublep: l.d $f15, 3*FFI_SIZEOF_ARG(t9) arg4_next: add t4, t6, 0 SRL t4, 4*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg5_floatp REG_L a4, 4*FFI_SIZEOF_ARG(t9) b arg5_next arg5_floatp: bne t4, FFI_TYPE_FLOAT, arg5_doublep l.s $f16, 4*FFI_SIZEOF_ARG(t9) b arg5_next arg5_doublep: l.d $f16, 4*FFI_SIZEOF_ARG(t9) arg5_next: add t4, t6, 0 SRL t4, 5*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg6_floatp REG_L a5, 5*FFI_SIZEOF_ARG(t9) b arg6_next arg6_floatp: bne t4, FFI_TYPE_FLOAT, arg6_doublep l.s $f17, 5*FFI_SIZEOF_ARG(t9) b arg6_next arg6_doublep: l.d $f17, 5*FFI_SIZEOF_ARG(t9) arg6_next: add t4, t6, 0 SRL t4, 6*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg7_floatp REG_L a6, 6*FFI_SIZEOF_ARG(t9) b arg7_next arg7_floatp: bne t4, FFI_TYPE_FLOAT, arg7_doublep l.s $f18, 6*FFI_SIZEOF_ARG(t9) b arg7_next arg7_doublep: l.d $f18, 6*FFI_SIZEOF_ARG(t9) arg7_next: add t4, t6, 0 SRL t4, 7*FFI_FLAG_BITS and t4, ((1<<FFI_FLAG_BITS)-1) bnez t4, arg8_floatp REG_L a7, 7*FFI_SIZEOF_ARG(t9) b arg8_next arg8_floatp: bne t4, FFI_TYPE_FLOAT, arg8_doublep l.s $f19, 7*FFI_SIZEOF_ARG(t9) b arg8_next arg8_doublep: l.d $f19, 7*FFI_SIZEOF_ARG(t9) arg8_next: callit: # Load the function pointer REG_L t9, 5*FFI_SIZEOF_ARG($fp) # If the return value pointer is NULL, assume no return value. REG_L t5, 4*FFI_SIZEOF_ARG($fp) beqz t5, noretval # Shift the return type flag over SRL t6, 8*FFI_FLAG_BITS bne t6, FFI_TYPE_INT, retfloat jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) REG_S v0, 0(t4) b epilogue retfloat: bne t6, FFI_TYPE_FLOAT, retdouble jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.s $f0, 0(t4) b epilogue retdouble: bne t6, FFI_TYPE_DOUBLE, retstruct_d jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.d $f0, 0(t4) b epilogue retstruct_d: bne t6, FFI_TYPE_STRUCT_D, retstruct_f jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.d $f0, 0(t4) b epilogue retstruct_f: bne t6, FFI_TYPE_STRUCT_F, retstruct_d_d jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.s $f0, 0(t4) b epilogue retstruct_d_d: bne t6, FFI_TYPE_STRUCT_DD, retstruct_f_f jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.d $f0, 0(t4) s.d $f2, 8(t4) b epilogue retstruct_f_f: bne t6, FFI_TYPE_STRUCT_FF, retstruct_d_f jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.s $f0, 0(t4) s.s $f2, 4(t4) b epilogue retstruct_d_f: bne t6, FFI_TYPE_STRUCT_DF, retstruct_f_d jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.d $f0, 0(t4) s.s $f2, 8(t4) b epilogue retstruct_f_d: bne t6, FFI_TYPE_STRUCT_FD, retstruct_small jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) s.s $f0, 0(t4) s.d $f2, 8(t4) b epilogue retstruct_small: bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2 jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) REG_S v0, 0(t4) b epilogue retstruct_small2: bne t6, FFI_TYPE_STRUCT_SMALL2, retstruct jal t9 REG_L t4, 4*FFI_SIZEOF_ARG($fp) REG_S v0, 0(t4) REG_S v1, 8(t4) b epilogue retstruct: noretval: jal t9 # Epilogue epilogue: move $sp, $fp REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address ADDU $sp, SIZEOF_FRAME # Fix stack pointer j ra .end ffi_call_N32 #endif --- NEW FILE: o32.S --- /* ----------------------------------------------------------------------- o32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc. MIPS Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> /* Only build this code if we are compiling for o32 */ #if defined(FFI_MIPS_O32) #define callback a0 #define bytes a2 #define flags a3 #define SIZEOF_FRAME ( 4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG ) .abicalls .text .align 2 .globl ffi_call_O32 .ent ffi_call_O32 ffi_call_O32: $LFB0: # Prologue SUBU $sp, SIZEOF_FRAME # Frame size $LCFI0: REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer $LCFI1: REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address $LCFI2: move $fp, $sp $LCFI3: move t9, callback # callback function pointer REG_S flags, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # flags # Allocate at least 4 words in the argstack move v0, bytes bge bytes, 4 * FFI_SIZEOF_ARG, bigger LI v0, 4 * FFI_SIZEOF_ARG b sixteen bigger: ADDU t0, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned and v0, t0, -2 * FFI_SIZEOF_ARG # to an 8 byte boundry sixteen: SUBU $sp, $sp, v0 # move the stack pointer to reflect the # arg space ADDU a0, $sp, 4 * FFI_SIZEOF_ARG ADDU a3, $fp, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG jalr t9 REG_L t0, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # load the flags word add t2, t0, 0 # and copy it into t2 and t0, ((1<<4)-1) # mask out the return type SRL t2, 4 # shift our arg info ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args bnez t0, pass_d # make it quick for int REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. REG_L a2, 2*FFI_SIZEOF_ARG($sp) REG_L a3, 3*FFI_SIZEOF_ARG($sp) b call_it pass_d: bne t0, FFI_ARGS_D, pass_f l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args REG_L a2, 2*FFI_SIZEOF_ARG($sp) # passing a double REG_L a3, 3*FFI_SIZEOF_ARG($sp) b call_it pass_f: bne t0, FFI_ARGS_F, pass_d_d l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args REG_L a1, 1*FFI_SIZEOF_ARG($sp) # passing a float REG_L a2, 2*FFI_SIZEOF_ARG($sp) REG_L a3, 3*FFI_SIZEOF_ARG($sp) b call_it pass_d_d: bne t0, FFI_ARGS_DD, pass_f_f l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing two doubles b call_it pass_f_f: bne t0, FFI_ARGS_FF, pass_d_f l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args l.s $f14, 1*FFI_SIZEOF_ARG($sp) # passing two floats REG_L a2, 2*FFI_SIZEOF_ARG($sp) REG_L a3, 3*FFI_SIZEOF_ARG($sp) b call_it pass_d_f: bne t0, FFI_ARGS_DF, pass_f_d l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args l.s $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float REG_L a3, 3*FFI_SIZEOF_ARG($sp) b call_it pass_f_d: # assume that the only other combination must be float then double # bne t0, FFI_ARGS_F_D, call_it l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float call_it: # Load the function pointer REG_L t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp) # If the return value pointer is NULL, assume no return value. REG_L t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) beqz t1, noretval bne t2, FFI_TYPE_INT, retlonglong jalr t9 REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) REG_S v0, 0(t0) b epilogue retlonglong: # Really any 64-bit int, signed or not. bne t2, FFI_TYPE_UINT64, retfloat jalr t9 REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) REG_S v1, 4(t0) REG_S v0, 0(t0) b epilogue retfloat: bne t2, FFI_TYPE_FLOAT, retdouble jalr t9 REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) s.s $f0, 0(t0) b epilogue retdouble: bne t2, FFI_TYPE_DOUBLE, noretval jalr t9 REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) s.d $f0, 0(t0) b epilogue noretval: jalr t9 # Epilogue epilogue: move $sp, $fp REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address ADDU $sp, SIZEOF_FRAME # Fix stack pointer j ra $LFE0: .end ffi_call_O32 /* ffi_closure_O32. Expects address of the passed-in ffi_closure in t0. Stores any arguments passed in registers onto the stack, then calls ffi_closure_mips_inner_O32, which then decodes them. Stack layout: 14 - Start of parameters, original sp 13 - ra save 12 - fp save 11 - $16 (s0) save 10 - cprestore 9 - return value high (v1) 8 - return value low (v0) 7 - f14 (le high, be low) 6 - f14 (le low, be high) 5 - f12 (le high, be low) 4 - f12 (le low, be high) 3 - Called function a3 save 2 - Called function a2 save 1 - Called function a1 save 0 - Called function a0 save our sp, fp point here */ #define SIZEOF_FRAME2 ( 14 * FFI_SIZEOF_ARG ) .text .align 2 .globl ffi_closure_O32 .ent ffi_closure_O32 ffi_closure_O32: $LFB1: # Prologue .frame $fp, SIZEOF_FRAME2, $31 .set noreorder .cpload $25 .set reorder SUBU $sp, SIZEOF_FRAME2 .cprestore SIZEOF_FRAME2 - 4*FFI_SIZEOF_ARG $LCFI4: REG_S $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Save s0 REG_S $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Save return address $LCFI6: move $fp, $sp $LCFI7: # Store all possible argument registers. If there are more than # four arguments, then they should be stored above where we put $7. REG_S $4, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG($fp) REG_S $5, SIZEOF_FRAME2 + 1*FFI_SIZEOF_ARG($fp) REG_S $6, SIZEOF_FRAME2 + 2*FFI_SIZEOF_ARG($fp) REG_S $7, SIZEOF_FRAME2 + 3*FFI_SIZEOF_ARG($fp) # Load ABI enum to $16 REG_L $16, 20($8) # cif pointer follows tramp. REG_L $16, 0($16) # abi is first member. li $13, 1 # FFI_O32 bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT # Store all possible float/double registers. s.d $f12, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG($fp) s.d $f14, SIZEOF_FRAME2 - 8*FFI_SIZEOF_ARG($fp) 1: # Call ffi_closure_mips_inner_O32 to do the work. la $25, ffi_closure_mips_inner_O32 move $4, $8 # Pointer to the ffi_closure addu $5, $fp, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG addu $6, $fp, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG addu $7, $fp, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG jalr $31, $25 # Load the return value into the appropriate register. move $8, $2 li $9, FFI_TYPE_VOID beq $8, $9, closure_done li $13, 1 # FFI_O32 bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT li $9, FFI_TYPE_FLOAT l.s $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) beq $8, $9, closure_done li $9, FFI_TYPE_DOUBLE l.d $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) beq $8, $9, closure_done 1: li $9, FFI_TYPE_SINT64 REG_L $3, SIZEOF_FRAME2 - 5*FFI_SIZEOF_ARG($fp) beq $8, $9, integer li $9, FFI_TYPE_UINT64 beq $8, $9, integer integer: REG_L $2, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) closure_done: # Epilogue move $sp, $fp REG_L $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Restore s0 REG_L $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer REG_L ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Restore return address ADDU $sp, SIZEOF_FRAME2 j ra $LFE1: .end ffi_closure_O32 /* DWARF-2 unwind info. */ .section .eh_frame,"a",@progbits $Lframe0: .4byte $LECIE0-$LSCIE0 # Length of Common Information Entry $LSCIE0: .4byte 0x0 # CIE Identifier Tag .byte 0x1 # CIE Version .ascii "zR\0" # CIE Augmentation .uleb128 0x1 # CIE Code Alignment Factor .sleb128 4 # CIE Data Alignment Factor .byte 0x1f # CIE RA Column .uleb128 0x1 # Augmentation size .byte 0x00 # FDE Encoding (absptr) .byte 0xc # DW_CFA_def_cfa .uleb128 0x1d .uleb128 0x0 .align 2 $LECIE0: $LSFDE0: .4byte $LEFDE0-$LASFDE0 # FDE Length $LASFDE0: .4byte $LASFDE0-$Lframe0 # FDE CIE offset .4byte $LFB0 # FDE initial location .4byte $LFE0-$LFB0 # FDE address range .uleb128 0x0 # Augmentation size .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI0-$LFB0 .byte 0xe # DW_CFA_def_cfa_offset .uleb128 0x18 .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI2-$LCFI0 .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x1e # $fp .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x1f # $ra .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI3-$LCFI2 .byte 0xc # DW_CFA_def_cfa .uleb128 0x1e .uleb128 0x18 .align 2 $LEFDE0: $LSFDE1: .4byte $LEFDE1-$LASFDE1 # FDE Length $LASFDE1: .4byte $LASFDE1-$Lframe0 # FDE CIE offset .4byte $LFB1 # FDE initial location .4byte $LFE1-$LFB1 # FDE address range .uleb128 0x0 # Augmentation size .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI4-$LFB1 .byte 0xe # DW_CFA_def_cfa_offset .uleb128 0x38 .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI6-$LCFI4 .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x10 # $16 .sleb128 -3 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x1e # $fp .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x1f # $ra .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) .byte 0x4 # DW_CFA_advance_loc4 .4byte $LCFI7-$LCFI6 .byte 0xc # DW_CFA_def_cfa .uleb128 0x1e .uleb128 0x38 .align 2 $LEFDE1: #endif --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1996 Red Hat, Inc. MIPS Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> #include <sys/cachectl.h> #if _MIPS_SIM == _ABIN32 #define FIX_ARGP \ FFI_ASSERT(argp <= &stack[bytes]); \ if (argp == &stack[bytes]) \ { \ argp = stack; \ ffi_stop_here(); \ } #else #define FIX_ARGP #endif /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ static void ffi_prep_args(char *stack, extended_cif *ecif, int bytes, int flags) { register int i; register void **p_argv; register char *argp; register ffi_type **p_arg; #if _MIPS_SIM == _ABIN32 /* If more than 8 double words are used, the remainder go on the stack. We reorder stuff on the stack here to support this easily. */ if (bytes > 8 * FFI_SIZEOF_ARG) argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)]; else argp = stack; #else argp = stack; #endif memset(stack, 0, bytes); #if _MIPS_SIM == _ABIN32 if ( ecif->cif->rstruct_flag != 0 ) #else if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) #endif { *(ffi_arg *) argp = (ffi_arg) ecif->rvalue; argp += sizeof(ffi_arg); FIX_ARGP; } p_argv = ecif->avalue; for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++) { size_t z; unsigned short a; /* Align if necessary */ a = (*p_arg)->alignment; if (a < FFI_SIZEOF_ARG) a = FFI_SIZEOF_ARG; if ((a - 1) & (unsigned) argp) { argp = (char *) ALIGN(argp, a); FIX_ARGP; } #if _MIPS_SIM == _ABIO32 #define OFFSET 0 #else #define OFFSET sizeof(int) #endif z = (*p_arg)->size; if (z < sizeof(ffi_arg)) { z = sizeof(ffi_arg); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); break; case FFI_TYPE_SINT32: *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); break; case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv); break; /* This can only happen with 64bit slots */ case FFI_TYPE_FLOAT: *(float *) argp = *(float *)(* p_argv); break; /* Handle small structures */ case FFI_TYPE_STRUCT: memcpy(argp, *p_argv, (*p_arg)->size); break; default: FFI_ASSERT(0); } } else { #if _MIPS_SIM == _ABIO32 memcpy(argp, *p_argv, z); #else { unsigned end = (unsigned) argp+z; unsigned cap = (unsigned) stack+bytes; /* Check if the data will fit within the register space. Handle it if it doesn't. */ if (end <= cap) memcpy(argp, *p_argv, z); else { unsigned portion = end - cap; memcpy(argp, *p_argv, portion); argp = stack; memcpy(argp, (void*)((unsigned)(*p_argv)+portion), z - portion); } } #endif } p_argv++; argp += z; FIX_ARGP; } return; } #if _MIPS_SIM == _ABIN32 /* The n32 spec says that if "a chunk consists solely of a double float field (but not a double, which is part of a union), it is passed in a floating point register. Any other chunk is passed in an integer register". This code traverses structure definitions and generates the appropriate flags. */ unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift) { unsigned flags = 0; unsigned index = 0; ffi_type *e; while (e = arg->elements[index]) { if (e->type == FFI_TYPE_DOUBLE) { flags += (FFI_TYPE_DOUBLE << *shift); *shift += FFI_FLAG_BITS; } else if (e->type == FFI_TYPE_STRUCT) flags += calc_n32_struct_flags(e, shift); else *shift += FFI_FLAG_BITS; index++; } return flags; } unsigned calc_n32_return_struct_flags(ffi_type *arg) { unsigned flags = 0; unsigned index = 0; unsigned small = FFI_TYPE_SMALLSTRUCT; ffi_type *e; /* Returning structures under n32 is a tricky thing. A struct with only one or two floating point fields is returned in $f0 (and $f2 if necessary). Any other struct results at most 128 bits are returned in $2 (the first 64 bits) and $3 (remainder, if necessary). Larger structs are handled normally. */ if (arg->size > 16) return 0; if (arg->size > 8) small = FFI_TYPE_SMALLSTRUCT2; e = arg->elements[0]; if (e->type == FFI_TYPE_DOUBLE) flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS; else if (e->type == FFI_TYPE_FLOAT) flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS; if (flags && (e = arg->elements[1])) { if (e->type == FFI_TYPE_DOUBLE) flags += FFI_TYPE_DOUBLE; else if (e->type == FFI_TYPE_FLOAT) flags += FFI_TYPE_FLOAT; else return small; if (flags && (arg->elements[2])) { /* There are three arguments and the first two are floats! This must be passed the old way. */ return small; } } else if (!flags) return small; return flags; } #endif /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { cif->flags = 0; #if _MIPS_SIM == _ABIO32 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT * does not have special handling for floating point args. */ if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32) { if (cif->nargs > 0) { switch ((cif->arg_types)[0]->type) { case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags += (cif->arg_types)[0]->type; break; default: break; } if (cif->nargs > 1) { /* Only handle the second argument if the first is a float or double. */ if (cif->flags) { switch ((cif->arg_types)[1]->type) { case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS; break; default: break; } } } } } /* Set the return type flag */ if (cif->abi == FFI_O32_SOFT_FLOAT) { switch (cif->rtype->type) { case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: case FFI_TYPE_DOUBLE: cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); break; case FFI_TYPE_FLOAT: default: cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); break; } } else { /* FFI_O32 */ switch (cif->rtype->type) { case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); break; default: cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); break; } } #endif #if _MIPS_SIM == _ABIN32 /* Set the flags necessary for N32 processing */ { unsigned shift = 0; unsigned count = (cif->nargs < 8) ? cif->nargs : 8; unsigned index = 0; unsigned struct_flags = 0; if (cif->rtype->type == FFI_TYPE_STRUCT) { struct_flags = calc_n32_return_struct_flags(cif->rtype); if (struct_flags == 0) { /* This means that the structure is being passed as a hidden argument */ shift = FFI_FLAG_BITS; count = (cif->nargs < 7) ? cif->nargs : 7; cif->rstruct_flag = !0; } else cif->rstruct_flag = 0; } else cif->rstruct_flag = 0; while (count-- > 0) { switch ((cif->arg_types)[index]->type) { case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags += ((cif->arg_types)[index]->type << shift); shift += FFI_FLAG_BITS; break; case FFI_TYPE_STRUCT: cif->flags += calc_n32_struct_flags((cif->arg_types)[index], &shift); break; default: shift += FFI_FLAG_BITS; } index++; } /* Set the return type flag */ switch (cif->rtype->type) { case FFI_TYPE_STRUCT: { if (struct_flags == 0) { /* The structure is returned through a hidden first argument. Do nothing, 'cause FFI_TYPE_VOID is 0 */ } else { /* The structure is returned via some tricky mechanism */ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8)); } break; } case FFI_TYPE_VOID: /* Do nothing, 'cause FFI_TYPE_VOID is 0 */ break; case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); break; default: cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); break; } } #endif return FFI_OK; } /* Low level routine for calling O32 functions */ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), extended_cif *, unsigned, unsigned, unsigned *, void (*)()); /* Low level routine for calling N32 functions */ extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), extended_cif *, unsigned, unsigned, unsigned *, void (*)()); void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; ecif.cif = cif; ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) ecif.rvalue = alloca(cif->rtype->size); else ecif.rvalue = rvalue; switch (cif->abi) { #if _MIPS_SIM == _ABIO32 case FFI_O32: case FFI_O32_SOFT_FLOAT: ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; #endif #if _MIPS_SIM == _ABIN32 case FFI_N32: ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; #endif default: FFI_ASSERT(0); break; } } #if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */ #if defined(FFI_MIPS_O32) extern void ffi_closure_O32(void); #endif /* FFI_MIPS_O32 */ ffi_status ffi_prep_closure (ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data) { unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned int fn; unsigned int ctx = (unsigned int) closure; #if defined(FFI_MIPS_O32) FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT); fn = (unsigned int) ffi_closure_O32; #else /* FFI_MIPS_N32 */ FFI_ASSERT(cif->abi == FFI_N32); FFI_ASSERT(!"not implemented"); #endif /* FFI_MIPS_O32 */ tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */ tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */ tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */ tramp[3] = 0x03200008; /* jr $25 */ tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */ closure->cif = cif; closure->fun = fun; closure->user_data = user_data; /* XXX this is available on Linux, but anything else? */ cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE); return FFI_OK; } /* * Decodes the arguments to a function, which will be stored on the * stack. AR is the pointer to the beginning of the integer arguments * (and, depending upon the arguments, some floating-point arguments * as well). FPR is a pointer to the area where floating point * registers have been saved, if any. * * RVALUE is the location where the function return value will be * stored. CLOSURE is the prepared closure to invoke. * * This function should only be called from assembly, which is in * turn called from a trampoline. * * Returns the function return type. * * Based on the similar routine for sparc. */ int ffi_closure_mips_inner_O32 (ffi_closure *closure, void *rvalue, unsigned long *ar, double *fpr) { ffi_cif *cif; void **avalue; ffi_type **arg_types; int i, avn, argn, seen_int; cif = closure->cif; avalue = alloca (cif->nargs * sizeof (void *)); seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); argn = 0; if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) { rvalue = (void *) ar[0]; argn = 1; } i = 0; avn = cif->nargs; arg_types = cif->arg_types; while (i < avn) { if (i < 2 && !seen_int && (arg_types[i]->type == FFI_TYPE_FLOAT || arg_types[i]->type == FFI_TYPE_DOUBLE)) { avalue[i] = ((char *) &fpr[i]); } else { if (arg_types[i]->alignment == 8 && (argn & 0x1)) argn++; avalue[i] = ((char *) &ar[argn]); seen_int = 1; } argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; i++; } /* Invoke the closure. */ (closure->fun) (cif, rvalue, avalue, closure->user_data); if (cif->abi == FFI_O32_SOFT_FLOAT) { switch (cif->rtype->type) { case FFI_TYPE_FLOAT: return FFI_TYPE_INT; case FFI_TYPE_DOUBLE: return FFI_TYPE_UINT64; default: return cif->rtype->type; } } else { return cif->rtype->type; } } #endif /* FFI_CLOSURES */ --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for MIPS. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H #ifndef LIBFFI_ASM #include <sgidefs.h> #endif #if !defined(_MIPS_SIM) -- something is very wrong -- #else # if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64)) # define FFI_MIPS_N32 # else # if _MIPS_SIM==_ABIO32 && defined(_ABIO32) # define FFI_MIPS_O32 # else -- this is an unsupported platform -- # endif # endif #endif #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ #define FFI_SIZEOF_ARG 4 #else /* N32 and N64 frames have 64bit integer args */ #define FFI_SIZEOF_ARG 8 #endif #define FFI_FLAG_BITS 2 /* SGI's strange assembler requires that we multiply by 4 rather than shift left by FFI_FLAG_BITS */ #define FFI_ARGS_D FFI_TYPE_DOUBLE #define FFI_ARGS_F FFI_TYPE_FLOAT #define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE #define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT #define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT #define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE /* Needed for N32 structure returns */ #define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8 #define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8 #if 0 /* The SGI assembler can't handle this.. */ #define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT /* (and so on) */ #else /* ...so we calculate these by hand! */ #define FFI_TYPE_STRUCT_D 61 #define FFI_TYPE_STRUCT_F 45 #define FFI_TYPE_STRUCT_DD 253 #define FFI_TYPE_STRUCT_FF 173 #define FFI_TYPE_STRUCT_FD 237 #define FFI_TYPE_STRUCT_DF 189 #define FFI_TYPE_STRUCT_SMALL 93 #define FFI_TYPE_STRUCT_SMALL2 109 #endif #ifdef LIBFFI_ASM #define v0 $2 #define v1 $3 #define a0 $4 #define a1 $5 #define a2 $6 #define a3 $7 #define a4 $8 #define a5 $9 #define a6 $10 #define a7 $11 #define t0 $8 #define t1 $9 #define t2 $10 #define t3 $11 #define t4 $12 #define t5 $13 #define t6 $14 #define t7 $15 #define t8 $24 #define t9 $25 #define ra $31 #ifdef FFI_MIPS_O32 #define REG_L lw #define REG_S sw #define SUBU subu #define ADDU addu #define SRL srl #define LI li #else /* !FFI_MIPS_O32 */ #define REG_L ld #define REG_S sd #define SUBU dsubu #define ADDU daddu #define SRL dsrl #define LI dli #endif /* !FFI_MIPS_O32 */ #else /* !LIBFFI_ASM */ #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ typedef unsigned int ffi_arg __attribute__((__mode__(__SI__))); typedef signed int ffi_sarg __attribute__((__mode__(__SI__))); #else /* N32 and N64 frames have 64bit integer args */ typedef unsigned int ffi_arg __attribute__((__mode__(__DI__))); typedef signed int ffi_sarg __attribute__((__mode__(__DI__))); #endif typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_O32, FFI_N32, FFI_N64, FFI_O32_SOFT_FLOAT, #ifdef FFI_MIPS_O32 #ifdef __mips_soft_float FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT, #else FFI_DEFAULT_ABI = FFI_O32, #endif #else FFI_DEFAULT_ABI = FFI_N32, #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag #endif /* !LIBFFI_ASM */ /* ---- Definitions for closures ----------------------------------------- */ #if defined(FFI_MIPS_O32) #define FFI_CLOSURES 1 #define FFI_TRAMPOLINE_SIZE 20 #else /* N32/N64 not implemented yet. */ #define FFI_CLOSURES 0 #endif /* FFI_MIPS_O32 */ #define FFI_NATIVE_RAW_API 0 #endif |
From: Thomas H. <th...@us...> - 2006-01-31 20:17:54
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/frv In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28311/src/frv Added Files: Tag: branch_1_0 eabi.S ffi.c ffitarget.h Log Message: Hm, somehow pcl-cvs managed to first add, then remove the files again ;-( --- NEW FILE: eabi.S --- /* ----------------------------------------------------------------------- eabi.S - Copyright (c) 2004 Anthony Green FR-V Assembly glue. $Id: eabi.S,v 1.1.2.3 2006/01/31 20:17:41 theller Exp $ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> .globl ffi_prep_args_EABI .text .p2align 4 .globl ffi_call_EABI .type ffi_call_EABI, @function # gr8 : ffi_prep_args # gr9 : &ecif # gr10: cif->bytes # gr11: fig->flags # gr12: ecif.rvalue # gr13: fn ffi_call_EABI: addi sp, #-80, sp sti fp, @(sp, #24) addi sp, #24, fp movsg lr, gr5 /* Make room for the new arguments. */ /* subi sp, fp, gr10 */ /* Store return address and incoming args on stack. */ sti gr5, @(fp, #8) sti gr8, @(fp, #-4) sti gr9, @(fp, #-8) sti gr10, @(fp, #-12) sti gr11, @(fp, #-16) sti gr12, @(fp, #-20) sti gr13, @(fp, #-24) sub sp, gr10, sp /* Call ffi_prep_args. */ ldi @(fp, #-4), gr4 addi sp, #0, gr8 ldi @(fp, #-8), gr9 #ifdef __FRV_FDPIC__ ldd @(gr4, gr0), gr14 calll @(gr14, gr0) #else calll @(gr4, gr0) #endif /* ffi_prep_args returns the new stack pointer. */ mov gr8, gr4 ldi @(sp, #0), gr8 ldi @(sp, #4), gr9 ldi @(sp, #8), gr10 ldi @(sp, #12), gr11 ldi @(sp, #16), gr12 ldi @(sp, #20), gr13 /* Always copy the return value pointer into the hidden parameter register. This is only strictly necessary when we're returning an aggregate type, but it doesn't hurt to do this all the time, and it saves a branch. */ ldi @(fp, #-20), gr3 /* Use the ffi_prep_args return value for the new sp. */ mov gr4, sp /* Call the target function. */ ldi @(fp, -24), gr4 #ifdef __FRV_FDPIC__ ldd @(gr4, gr0), gr14 calll @(gr14, gr0) #else calll @(gr4, gr0) #endif /* Store the result. */ ldi @(fp, #-16), gr10 /* fig->flags */ ldi @(fp, #-20), gr4 /* ecif.rvalue */ /* Is the return value stored in two registers? */ cmpi gr10, #8, icc0 bne icc0, 0, .L2 /* Yes, save them. */ sti gr8, @(gr4, #0) sti gr9, @(gr4, #4) bra .L3 .L2: /* Is the return value a structure? */ cmpi gr10, #-1, icc0 beq icc0, 0, .L3 /* No, save a 4 byte return value. */ sti gr8, @(gr4, #0) .L3: /* Restore the stack, and return. */ ldi @(fp, 8), gr5 ld @(fp, gr0), fp addi sp,#80,sp jmpl @(gr5,gr0) .size ffi_call_EABI, .-ffi_call_EABI --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 2004 Anthony Green FR-V Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ void *ffi_prep_args(char *stack, extended_cif *ecif) { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; register int count = 0; p_argv = ecif->avalue; argp = stack; for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); i--, p_arg++) { size_t z; z = (*p_arg)->size; if ((*p_arg)->type == FFI_TYPE_STRUCT) { z = sizeof(void*); *(void **) argp = *p_argv; } /* if ((*p_arg)->type == FFI_TYPE_FLOAT) { if (count > 24) { // This is going on the stack. Turn it into a double. *(double *) argp = (double) *(float*)(* p_argv); z = sizeof(double); } else *(void **) argp = *(void **)(* p_argv); } */ else if (z < sizeof(int)) { z = sizeof(int); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); break; default: FFI_ASSERT(0); } } else if (z == sizeof(int)) { *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); } else { memcpy(argp, *p_argv, z); } p_argv++; argp += z; count += z; } return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8))); } /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { if (cif->rtype->type == FFI_TYPE_STRUCT) cif->flags = -1; else cif->flags = cif->rtype->size; cif->bytes = ALIGN (cif->bytes, 8); return FFI_OK; } extern void ffi_call_EABI(void *(*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void (*fn)()); void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; ecif.cif = cif; ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } else ecif.rvalue = rvalue; switch (cif->abi) { case FFI_EABI: ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; default: FFI_ASSERT(0); break; } } void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, unsigned arg4, unsigned arg5, unsigned arg6) { /* This function is called by a trampoline. The trampoline stows a pointer to the ffi_closure object in gr7. We must save this pointer in a place that will persist while we do our work. */ register ffi_closure *creg __asm__ ("gr7"); ffi_closure *closure = creg; /* Arguments that don't fit in registers are found on the stack at a fixed offset above the current frame pointer. */ register char *frame_pointer __asm__ ("fp"); char *stack_args = frame_pointer + 16; /* Lay the register arguments down in a continuous chunk of memory. */ unsigned register_args[6] = { arg1, arg2, arg3, arg4, arg5, arg6 }; ffi_cif *cif = closure->cif; ffi_type **arg_types = cif->arg_types; void **avalue = alloca (cif->nargs * sizeof(void *)); char *ptr = (char *) register_args; int i; /* Find the address of each argument. */ for (i = 0; i < cif->nargs; i++) { switch (arg_types[i]->type) { case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: avalue[i] = ptr + 3; break; case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: avalue[i] = ptr + 2; break; case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_FLOAT: avalue[i] = ptr; break; case FFI_TYPE_STRUCT: avalue[i] = *(void**)ptr; break; default: /* This is an 8-byte value. */ avalue[i] = ptr; ptr += 4; break; } ptr += 4; /* If we've handled more arguments than fit in registers, start looking at the those passed on the stack. */ if (ptr == ((char *)register_args + (6*4))) ptr = stack_args; } /* Invoke the closure. */ if (cif->rtype->type == FFI_TYPE_STRUCT) { /* The caller allocates space for the return structure, and passes a pointer to this space in gr3. Use this value directly as the return value. */ register void *return_struct_ptr __asm__("gr3"); (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data); } else { /* Allocate space for the return value and call the function. */ long long rvalue; (closure->fun) (cif, &rvalue, avalue, closure->user_data); /* Functions return 4-byte or smaller results in gr8. 8-byte values also use gr9. We fill the both, even for small return values, just to avoid a branch. */ asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue)); asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1])); } } ffi_status ffi_prep_closure (ffi_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*, void*, void**, void*), void *user_data) { unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned long fn = (long) ffi_closure_eabi; unsigned long cls = (long) closure; #ifdef __FRV_FDPIC__ register void *got __asm__("gr15"); #endif int i; fn = (unsigned long) ffi_closure_eabi; #ifdef __FRV_FDPIC__ tramp[0] = &tramp[2]; tramp[1] = got; tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ tramp[4] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ tramp[5] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ tramp[6] = 0x9cc86000; /* ldi @(gr6, #0), gr14 */ tramp[7] = 0x8030e000; /* jmpl @(gr14, gr0) */ #else tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */ #endif closure->cif = cif; closure->fun = fun; closure->user_data = user_data; /* Cache flushing. */ for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) __asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i)); return FFI_OK; } --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2004 Red Hat, Inc. Target configuration macros for FR-V Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H /* ---- System specific configurations ----------------------------------- */ #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, #ifdef FRV FFI_EABI, FFI_DEFAULT_ABI = FFI_EABI, #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 #ifdef __FRV_FDPIC__ /* Trampolines are 8 4-byte instructions long. */ #define FFI_TRAMPOLINE_SIZE (8*4) #else /* Trampolines are 5 4-byte instructions long. */ #define FFI_TRAMPOLINE_SIZE (5*4) #endif #endif |
From: Thomas H. <th...@us...> - 2006-01-31 20:17:51
|
Update of /cvsroot/ctypes/ctypes/source/libffi/src/ia64 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28311/src/ia64 Added Files: Tag: branch_1_0 ffi.c ffitarget.h ia64_flags.h unix.S Log Message: Hm, somehow pcl-cvs managed to first add, then remove the files again ;-( --- NEW FILE: unix.S --- /* ----------------------------------------------------------------------- unix.S - Copyright (c) 1998 Red Hat, Inc. Copyright (c) 2000 Hewlett Packard Company IA64/unix Foreign Function Interface Primary author: Hans Boehm, HP Labs Loosely modeled on Cygnus code for other platforms. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> #include "ia64_flags.h" .pred.safe_across_calls p1-p5,p16-p63 .text /* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue, void (*fn)(), int flags); */ .align 16 .global ffi_call_unix .proc ffi_call_unix ffi_call_unix: .prologue /* Bit o trickiness. We actually share a stack frame with ffi_call. Rely on the fact that ffi_call uses a vframe and don't bother tracking one here at all. */ .fframe 0 .save ar.pfs, r36 // loc0 alloc loc0 = ar.pfs, 4, 3, 8, 0 .save rp, loc1 mov loc1 = b0 .body add r16 = 16, in0 mov loc2 = gp mov r8 = in1 ;; /* Load up all of the argument registers. */ ldf.fill f8 = [in0], 32 ldf.fill f9 = [r16], 32 ;; ldf.fill f10 = [in0], 32 ldf.fill f11 = [r16], 32 ;; ldf.fill f12 = [in0], 32 ldf.fill f13 = [r16], 32 ;; ldf.fill f14 = [in0], 32 ldf.fill f15 = [r16], 24 ;; ld8 out0 = [in0], 16 ld8 out1 = [r16], 16 ;; ld8 out2 = [in0], 16 ld8 out3 = [r16], 16 ;; ld8 out4 = [in0], 16 ld8 out5 = [r16], 16 ;; ld8 out6 = [in0] ld8 out7 = [r16] ;; /* Deallocate the register save area from the stack frame. */ mov sp = in0 /* Call the target function. */ ld8 r16 = [in2], 8 ;; ld8 gp = [in2] mov b6 = r16 br.call.sptk.many b0 = b6 ;; /* Dispatch to handle return value. */ mov gp = loc2 zxt1 r16 = in3 ;; mov ar.pfs = loc0 addl r18 = @ltoffx(.Lst_table), gp ;; ld8.mov r18 = [r18], .Lst_table mov b0 = loc1 ;; shladd r18 = r16, 3, r18 ;; ld8 r17 = [r18] shr in3 = in3, 8 ;; add r17 = r17, r18 ;; mov b6 = r17 br b6 ;; .Lst_void: br.ret.sptk.many b0 ;; .Lst_uint8: zxt1 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_sint8: sxt1 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_uint16: zxt2 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_sint16: sxt2 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_uint32: zxt4 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_sint32: sxt4 r8 = r8 ;; st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_int64: st8 [in1] = r8 br.ret.sptk.many b0 ;; .Lst_float: stfs [in1] = f8 br.ret.sptk.many b0 ;; .Lst_double: stfd [in1] = f8 br.ret.sptk.many b0 ;; .Lst_ldouble: stfe [in1] = f8 br.ret.sptk.many b0 ;; .Lst_small_struct: add sp = -16, sp cmp.lt p6, p0 = 8, in3 cmp.lt p7, p0 = 16, in3 cmp.lt p8, p0 = 24, in3 ;; add r16 = 8, sp add r17 = 16, sp add r18 = 24, sp ;; st8 [sp] = r8 (p6) st8 [r16] = r9 mov out0 = in1 (p7) st8 [r17] = r10 (p8) st8 [r18] = r11 mov out1 = sp mov out2 = in3 br.call.sptk.many b0 = memcpy# ;; mov ar.pfs = loc0 mov b0 = loc1 mov gp = loc2 br.ret.sptk.many b0 .Lst_hfa_float: add r16 = 4, in1 cmp.lt p6, p0 = 4, in3 ;; stfs [in1] = f8, 8 (p6) stfs [r16] = f9, 8 cmp.lt p7, p0 = 8, in3 cmp.lt p8, p0 = 12, in3 ;; (p7) stfs [in1] = f10, 8 (p8) stfs [r16] = f11, 8 cmp.lt p9, p0 = 16, in3 cmp.lt p10, p0 = 20, in3 ;; (p9) stfs [in1] = f12, 8 (p10) stfs [r16] = f13, 8 cmp.lt p6, p0 = 24, in3 cmp.lt p7, p0 = 28, in3 ;; (p6) stfs [in1] = f14 (p7) stfs [r16] = f15 br.ret.sptk.many b0 ;; .Lst_hfa_double: add r16 = 8, in1 cmp.lt p6, p0 = 8, in3 ;; stfd [in1] = f8, 16 (p6) stfd [r16] = f9, 16 cmp.lt p7, p0 = 16, in3 cmp.lt p8, p0 = 24, in3 ;; (p7) stfd [in1] = f10, 16 (p8) stfd [r16] = f11, 16 cmp.lt p9, p0 = 32, in3 cmp.lt p10, p0 = 40, in3 ;; (p9) stfd [in1] = f12, 16 (p10) stfd [r16] = f13, 16 cmp.lt p6, p0 = 48, in3 cmp.lt p7, p0 = 56, in3 ;; (p6) stfd [in1] = f14 (p7) stfd [r16] = f15 br.ret.sptk.many b0 ;; .Lst_hfa_ldouble: add r16 = 16, in1 cmp.lt p6, p0 = 16, in3 ;; stfe [in1] = f8, 32 (p6) stfe [r16] = f9, 32 cmp.lt p7, p0 = 32, in3 cmp.lt p8, p0 = 48, in3 ;; (p7) stfe [in1] = f10, 32 (p8) stfe [r16] = f11, 32 cmp.lt p9, p0 = 64, in3 cmp.lt p10, p0 = 80, in3 ;; (p9) stfe [in1] = f12, 32 (p10) stfe [r16] = f13, 32 cmp.lt p6, p0 = 96, in3 cmp.lt p7, p0 = 112, in3 ;; (p6) stfe [in1] = f14 (p7) stfe [r16] = f15 br.ret.sptk.many b0 ;; .endp ffi_call_unix .align 16 .global ffi_closure_unix .proc ffi_closure_unix #define FRAME_SIZE (8*16 + 8*8 + 8*16) ffi_closure_unix: .prologue .save ar.pfs, r40 // loc0 alloc loc0 = ar.pfs, 8, 4, 4, 0 .fframe FRAME_SIZE add r12 = -FRAME_SIZE, r12 .save rp, loc1 mov loc1 = b0 .save ar.unat, loc2 mov loc2 = ar.unat .body /* Retrieve closure pointer and real gp. */ mov out0 = gp add gp = 16, gp ;; ld8 gp = [gp] /* Spill all of the possible argument registers. */ add r16 = 16 + 8*16, sp add r17 = 16 + 8*16 + 16, sp ;; stf.spill [r16] = f8, 32 stf.spill [r17] = f9, 32 mov loc3 = gp ;; stf.spill [r16] = f10, 32 stf.spill [r17] = f11, 32 ;; stf.spill [r16] = f12, 32 stf.spill [r17] = f13, 32 ;; stf.spill [r16] = f14, 32 stf.spill [r17] = f15, 24 ;; .mem.offset 0, 0 st8.spill [r16] = in0, 16 .mem.offset 8, 0 st8.spill [r17] = in1, 16 add out1 = 16 + 8*16, sp ;; .mem.offset 0, 0 st8.spill [r16] = in2, 16 .mem.offset 8, 0 st8.spill [r17] = in3, 16 add out2 = 16, sp ;; .mem.offset 0, 0 st8.spill [r16] = in4, 16 .mem.offset 8, 0 st8.spill [r17] = in5, 16 mov out3 = r8 ;; .mem.offset 0, 0 st8.spill [r16] = in6 .mem.offset 8, 0 st8.spill [r17] = in7 /* Invoke ffi_closure_unix_inner for the hard work. */ br.call.sptk.many b0 = ffi_closure_unix_inner ;; /* Dispatch to handle return value. */ mov gp = loc3 zxt1 r16 = r8 ;; addl r18 = @ltoffx(.Lld_table), gp mov ar.pfs = loc0 ;; ld8.mov r18 = [r18], .Lld_table mov b0 = loc1 ;; shladd r18 = r16, 3, r18 mov ar.unat = loc2 ;; ld8 r17 = [r18] shr r8 = r8, 8 ;; add r17 = r17, r18 add r16 = 16, sp ;; mov b6 = r17 br b6 ;; .label_state 1 .Lld_void: .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_int8: .body .copy_state 1 ld1 r8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_int16: .body .copy_state 1 ld2 r8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_int32: .body .copy_state 1 ld4 r8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_int64: .body .copy_state 1 ld8 r8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_float: .body .copy_state 1 ldfs f8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_double: .body .copy_state 1 ldfd f8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_ldouble: .body .copy_state 1 ldfe f8 = [r16] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_small_struct: .body .copy_state 1 add r17 = 8, r16 cmp.lt p6, p0 = 8, r8 cmp.lt p7, p0 = 16, r8 cmp.lt p8, p0 = 24, r8 ;; ld8 r8 = [r16], 16 (p6) ld8 r9 = [r17], 16 ;; (p7) ld8 r10 = [r16] (p8) ld8 r11 = [r17] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_hfa_float: .body .copy_state 1 add r17 = 4, r16 cmp.lt p6, p0 = 4, r8 ;; ldfs f8 = [r16], 8 (p6) ldfs f9 = [r17], 8 cmp.lt p7, p0 = 8, r8 cmp.lt p8, p0 = 12, r8 ;; (p7) ldfs f10 = [r16], 8 (p8) ldfs f11 = [r17], 8 cmp.lt p9, p0 = 16, r8 cmp.lt p10, p0 = 20, r8 ;; (p9) ldfs f12 = [r16], 8 (p10) ldfs f13 = [r17], 8 cmp.lt p6, p0 = 24, r8 cmp.lt p7, p0 = 28, r8 ;; (p6) ldfs f14 = [r16] (p7) ldfs f15 = [r17] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_hfa_double: .body .copy_state 1 add r17 = 8, r16 cmp.lt p6, p0 = 8, r8 ;; ldfd f8 = [r16], 16 (p6) ldfd f9 = [r17], 16 cmp.lt p7, p0 = 16, r8 cmp.lt p8, p0 = 24, r8 ;; (p7) ldfd f10 = [r16], 16 (p8) ldfd f11 = [r17], 16 cmp.lt p9, p0 = 32, r8 cmp.lt p10, p0 = 40, r8 ;; (p9) ldfd f12 = [r16], 16 (p10) ldfd f13 = [r17], 16 cmp.lt p6, p0 = 48, r8 cmp.lt p7, p0 = 56, r8 ;; (p6) ldfd f14 = [r16] (p7) ldfd f15 = [r17] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .Lld_hfa_ldouble: .body .copy_state 1 add r17 = 16, r16 cmp.lt p6, p0 = 16, r8 ;; ldfe f8 = [r16], 32 (p6) ldfe f9 = [r17], 32 cmp.lt p7, p0 = 32, r8 cmp.lt p8, p0 = 48, r8 ;; (p7) ldfe f10 = [r16], 32 (p8) ldfe f11 = [r17], 32 cmp.lt p9, p0 = 64, r8 cmp.lt p10, p0 = 80, r8 ;; (p9) ldfe f12 = [r16], 32 (p10) ldfe f13 = [r17], 32 cmp.lt p6, p0 = 96, r8 cmp.lt p7, p0 = 112, r8 ;; (p6) ldfe f14 = [r16] (p7) ldfe f15 = [r17] .restore sp add sp = FRAME_SIZE, sp br.ret.sptk.many b0 ;; .endp ffi_closure_unix .section .rodata .align 8 .Lst_table: data8 @pcrel(.Lst_void) // FFI_TYPE_VOID data8 @pcrel(.Lst_sint32) // FFI_TYPE_INT data8 @pcrel(.Lst_float) // FFI_TYPE_FLOAT data8 @pcrel(.Lst_double) // FFI_TYPE_DOUBLE data8 @pcrel(.Lst_ldouble) // FFI_TYPE_LONGDOUBLE data8 @pcrel(.Lst_uint8) // FFI_TYPE_UINT8 data8 @pcrel(.Lst_sint8) // FFI_TYPE_SINT8 data8 @pcrel(.Lst_uint16) // FFI_TYPE_UINT16 data8 @pcrel(.Lst_sint16) // FFI_TYPE_SINT16 data8 @pcrel(.Lst_uint32) // FFI_TYPE_UINT32 data8 @pcrel(.Lst_sint32) // FFI_TYPE_SINT32 data8 @pcrel(.Lst_int64) // FFI_TYPE_UINT64 data8 @pcrel(.Lst_int64) // FFI_TYPE_SINT64 data8 @pcrel(.Lst_void) // FFI_TYPE_STRUCT data8 @pcrel(.Lst_int64) // FFI_TYPE_POINTER data8 @pcrel(.Lst_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lst_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT data8 @pcrel(.Lst_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE data8 @pcrel(.Lst_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE .Lld_table: data8 @pcrel(.Lld_void) // FFI_TYPE_VOID data8 @pcrel(.Lld_int32) // FFI_TYPE_INT data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE data8 @pcrel(.Lld_int8) // FFI_TYPE_UINT8 data8 @pcrel(.Lld_int8) // FFI_TYPE_SINT8 data8 @pcrel(.Lld_int16) // FFI_TYPE_UINT16 data8 @pcrel(.Lld_int16) // FFI_TYPE_SINT16 data8 @pcrel(.Lld_int32) // FFI_TYPE_UINT32 data8 @pcrel(.Lld_int32) // FFI_TYPE_SINT32 data8 @pcrel(.Lld_int64) // FFI_TYPE_UINT64 data8 @pcrel(.Lld_int64) // FFI_TYPE_SINT64 data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT data8 @pcrel(.Lld_int64) // FFI_TYPE_POINTER data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE data8 @pcrel(.Lld_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1998 Red Hat, Inc. Copyright (c) 2000 Hewlett Packard Company IA64 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> #include <stdbool.h> #include <float.h> #include "ia64_flags.h" /* A 64-bit pointer value. In LP64 mode, this is effectively a plain pointer. In ILP32 mode, it's a pointer that's been extended to 64 bits by "addp4". */ typedef void *PTR64 __attribute__((mode(DI))); /* Memory image of fp register contents. This is the implementation specific format used by ldf.fill/stf.spill. All we care about is that it wants a 16 byte aligned slot. */ typedef struct { UINT64 x[2] __attribute__((aligned(16))); } fpreg; /* The stack layout given to ffi_call_unix and ffi_closure_unix_inner. */ struct ia64_args { fpreg fp_regs[8]; /* Contents of 8 fp arg registers. */ UINT64 gp_regs[8]; /* Contents of 8 gp arg registers. */ UINT64 other_args[]; /* Arguments passed on stack, variable size. */ }; /* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes. */ static inline void * endian_adjust (void *addr, size_t len) { #ifdef __BIG_ENDIAN__ return addr + (8 - len); #else return addr; #endif } /* Store VALUE to ADDR in the current cpu implementation's fp spill format. */ static inline void stf_spill(fpreg *addr, __float80 value) { asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value)); } /* Load a value from ADDR, which is in the current cpu implementation's fp spill format. */ static inline __float80 ldf_fill(fpreg *addr) { __float80 ret; asm ("ldf.fill %0 = %1%P1" : "=f"(ret) : "m"(*addr)); return ret; } /* Return the size of the C type associated with with TYPE. Which will be one of the FFI_IA64_TYPE_HFA_* values. */ static size_t hfa_type_size (int type) { switch (type) { case FFI_IA64_TYPE_HFA_FLOAT: return sizeof(float); case FFI_IA64_TYPE_HFA_DOUBLE: return sizeof(double); case FFI_IA64_TYPE_HFA_LDOUBLE: return sizeof(__float80); default: abort (); } } /* Load from ADDR a value indicated by TYPE. Which will be one of the FFI_IA64_TYPE_HFA_* values. */ static __float80 hfa_type_load (int type, void *addr) { switch (type) { case FFI_IA64_TYPE_HFA_FLOAT: return *(float *) addr; case FFI_IA64_TYPE_HFA_DOUBLE: return *(double *) addr; case FFI_IA64_TYPE_HFA_LDOUBLE: return *(__float80 *) addr; default: abort (); } } /* Load VALUE into ADDR as indicated by TYPE. Which will be one of the FFI_IA64_TYPE_HFA_* values. */ static void hfa_type_store (int type, void *addr, __float80 value) { switch (type) { case FFI_IA64_TYPE_HFA_FLOAT: *(float *) addr = value; break; case FFI_IA64_TYPE_HFA_DOUBLE: *(double *) addr = value; break; case FFI_IA64_TYPE_HFA_LDOUBLE: *(__float80 *) addr = value; break; default: abort (); } } /* Is TYPE a struct containing floats, doubles, or extended doubles, all of the same fp type? If so, return the element type. Return FFI_TYPE_VOID if not. */ static int hfa_element_type (ffi_type *type, int nested) { int element = FFI_TYPE_VOID; switch (type->type) { case FFI_TYPE_FLOAT: /* We want to return VOID for raw floating-point types, but the synthetic HFA type if we're nested within an aggregate. */ if (nested) element = FFI_IA64_TYPE_HFA_FLOAT; break; case FFI_TYPE_DOUBLE: /* Similarly. */ if (nested) element = FFI_IA64_TYPE_HFA_DOUBLE; break; case FFI_TYPE_LONGDOUBLE: /* Similarly, except that that HFA is true for double extended, but not quad precision. Both have sizeof == 16, so tell the difference based on the precision. */ if (LDBL_MANT_DIG == 64 && nested) element = FFI_IA64_TYPE_HFA_LDOUBLE; break; case FFI_TYPE_STRUCT: { ffi_type **ptr = &type->elements[0]; for (ptr = &type->elements[0]; *ptr ; ptr++) { int sub_element = hfa_element_type (*ptr, 1); if (sub_element == FFI_TYPE_VOID) return FFI_TYPE_VOID; if (element == FFI_TYPE_VOID) element = sub_element; else if (element != sub_element) return FFI_TYPE_VOID; } } break; default: return FFI_TYPE_VOID; } return element; } /* Perform machine dependent cif processing. */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { int flags; /* Adjust cif->bytes to include space for the bits of the ia64_args frame that preceeds the integer register portion. The estimate that the generic bits did for the argument space required is good enough for the integer component. */ cif->bytes += offsetof(struct ia64_args, gp_regs[0]); if (cif->bytes < sizeof(struct ia64_args)) cif->bytes = sizeof(struct ia64_args); /* Set the return type flag. */ flags = cif->rtype->type; switch (cif->rtype->type) { case FFI_TYPE_LONGDOUBLE: /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision, and encode quad precision as a two-word integer structure. */ if (LDBL_MANT_DIG != 64) flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8); break; case FFI_TYPE_STRUCT: { size_t size = cif->rtype->size; int hfa_type = hfa_element_type (cif->rtype, 0); if (hfa_type != FFI_TYPE_VOID) { size_t nelts = size / hfa_type_size (hfa_type); if (nelts <= 8) flags = hfa_type | (size << 8); } else { if (size <= 32) flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8); } } break; default: break; } cif->flags = flags; return FFI_OK; } extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(), UINT64); void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { struct ia64_args *stack; long i, avn, gpcount, fpcount; ffi_type **p_arg; FFI_ASSERT (cif->abi == FFI_UNIX); /* If we have no spot for a return value, make one. */ if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID) rvalue = alloca (cif->rtype->size); /* Allocate the stack frame. */ stack = alloca (cif->bytes); gpcount = fpcount = 0; avn = cif->nargs; for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) { switch ((*p_arg)->type) { case FFI_TYPE_SINT8: stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i]; break; case FFI_TYPE_UINT8: stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i]; break; case FFI_TYPE_SINT16: stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i]; break; case FFI_TYPE_UINT16: stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i]; break; case FFI_TYPE_SINT32: stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i]; break; case FFI_TYPE_UINT32: stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i]; break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i]; break; case FFI_TYPE_POINTER: stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i]; break; case FFI_TYPE_FLOAT: if (gpcount < 8 && fpcount < 8) stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]); stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i]; break; case FFI_TYPE_DOUBLE: if (gpcount < 8 && fpcount < 8) stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]); stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i]; break; case FFI_TYPE_LONGDOUBLE: if (gpcount & 1) gpcount++; if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]); memcpy (&stack->gp_regs[gpcount], avalue[i], 16); gpcount += 2; break; case FFI_TYPE_STRUCT: { size_t size = (*p_arg)->size; size_t align = (*p_arg)->alignment; int hfa_type = hfa_element_type (*p_arg, 0); FFI_ASSERT (align <= 16); if (align == 16 && (gpcount & 1)) gpcount++; if (hfa_type != FFI_TYPE_VOID) { size_t hfa_size = hfa_type_size (hfa_type); size_t offset = 0; size_t gp_offset = gpcount * 8; while (fpcount < 8 && offset < size && gp_offset < 8 * 8) { stf_spill (&stack->fp_regs[fpcount], hfa_type_load (hfa_type, avalue[i] + offset)); offset += hfa_size; gp_offset += hfa_size; fpcount += 1; } } memcpy (&stack->gp_regs[gpcount], avalue[i], size); gpcount += (size + 7) / 8; } break; default: abort (); } } ffi_call_unix (stack, rvalue, fn, cif->flags); } /* Closures represent a pair consisting of a function pointer, and some user data. A closure is invoked by reinterpreting the closure as a function pointer, and branching to it. Thus we can make an interpreted function callable as a C function: We turn the interpreter itself, together with a pointer specifying the interpreted procedure, into a closure. For IA64, function pointer are already pairs consisting of a code pointer, and a gp pointer. The latter is needed to access global variables. Here we set up such a pair as the first two words of the closure (in the "trampoline" area), but we replace the gp pointer with a pointer to the closure itself. We also add the real gp pointer to the closure. This allows the function entry code to both retrieve the user data, and to restire the correct gp pointer. */ extern void ffi_closure_unix (); ffi_status ffi_prep_closure (ffi_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data) { /* The layout of a function descriptor. A C function pointer really points to one of these. */ struct ia64_fd { UINT64 code_pointer; UINT64 gp; }; struct ffi_ia64_trampoline_struct { UINT64 code_pointer; /* Pointer to ffi_closure_unix. */ UINT64 fake_gp; /* Pointer to closure, installed as gp. */ UINT64 real_gp; /* Real gp value. */ }; struct ffi_ia64_trampoline_struct *tramp; struct ia64_fd *fd; FFI_ASSERT (cif->abi == FFI_UNIX); tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp; fd = (struct ia64_fd *)(void *)ffi_closure_unix; tramp->code_pointer = fd->code_pointer; tramp->real_gp = fd->gp; tramp->fake_gp = (UINT64)(PTR64)closure; closure->cif = cif; closure->user_data = user_data; closure->fun = fun; return FFI_OK; } UINT64 ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, void *rvalue, void *r8) { ffi_cif *cif; void **avalue; ffi_type **p_arg; long i, avn, gpcount, fpcount; cif = closure->cif; avn = cif->nargs; avalue = alloca (avn * sizeof (void *)); /* If the structure return value is passed in memory get that location from r8 so as to pass the value directly back to the caller. */ if (cif->flags == FFI_TYPE_STRUCT) rvalue = r8; gpcount = fpcount = 0; for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) { switch ((*p_arg)->type) { case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1); break; case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2); break; case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4); break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: avalue[i] = &stack->gp_regs[gpcount++]; break; case FFI_TYPE_POINTER: avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*)); break; case FFI_TYPE_FLOAT: if (gpcount < 8 && fpcount < 8) { void *addr = &stack->fp_regs[fpcount++]; avalue[i] = addr; *(float *)addr = ldf_fill (addr); } else avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4); gpcount++; break; case FFI_TYPE_DOUBLE: if (gpcount < 8 && fpcount < 8) { void *addr = &stack->fp_regs[fpcount++]; avalue[i] = addr; *(double *)addr = ldf_fill (addr); } else avalue[i] = &stack->gp_regs[gpcount]; gpcount++; break; case FFI_TYPE_LONGDOUBLE: if (gpcount & 1) gpcount++; if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) { void *addr = &stack->fp_regs[fpcount++]; avalue[i] = addr; *(__float80 *)addr = ldf_fill (addr); } else avalue[i] = &stack->gp_regs[gpcount]; gpcount += 2; break; case FFI_TYPE_STRUCT: { size_t size = (*p_arg)->size; size_t align = (*p_arg)->alignment; int hfa_type = hfa_element_type (*p_arg, 0); FFI_ASSERT (align <= 16); if (align == 16 && (gpcount & 1)) gpcount++; if (hfa_type != FFI_TYPE_VOID) { size_t hfa_size = hfa_type_size (hfa_type); size_t offset = 0; size_t gp_offset = gpcount * 8; void *addr = alloca (size); avalue[i] = addr; while (fpcount < 8 && offset < size && gp_offset < 8 * 8) { hfa_type_store (hfa_type, addr + offset, ldf_fill (&stack->fp_regs[fpcount])); offset += hfa_size; gp_offset += hfa_size; fpcount += 1; } if (offset < size) memcpy (addr + offset, (char *)stack->gp_regs + gp_offset, size - offset); } else avalue[i] = &stack->gp_regs[gpcount]; gpcount += (size + 7) / 8; } break; default: abort (); } } closure->fun (cif, rvalue, avalue, closure->user_data); return cif->flags; } --- NEW FILE: ia64_flags.h --- /* ----------------------------------------------------------------------- ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company IA64/unix Foreign Function Interface Original author: Hans Boehm, HP Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ /* "Type" codes used between assembly and C. When used as a part of a cfi->flags value, the low byte will be these extra type codes, and bits 8-31 will be the actual size of the type. */ /* Small structures containing N words in integer registers. */ #define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1) /* Homogeneous Floating Point Aggregates (HFAs) which are returned in FP registers. */ #define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2) #define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3) #define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4) --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for IA-64. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_UNIX, /* Linux and all Unix variants use the same conventions */ FFI_DEFAULT_ABI = FFI_UNIX, FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */ /* can be interpreted as a C function */ /* descriptor: */ #endif |