Commit 04042076 authored by Andreas Krämer's avatar Andreas Krämer
Browse files

Merge branch 'master' into charmmfixes

parents d59f19e4 2ff59259
......@@ -4,8 +4,11 @@
.. _the-openmm-application-layer-introduction:
The OpenMM Application Layer: Introduction
##########################################
The OpenMM Application Layer: Getting Started
#############################################
Introduction
************
The first thing to understand about the OpenMM application layer is that it is
not exactly an application in the traditional sense: there is no program called
......@@ -32,23 +35,9 @@ the results.
.. _installing-openmm:
Installing OpenMM
#################
Follow these instructions to install OpenMM. There also is an online
troubleshooting guide that describes common problems and how to fix them
(http://wiki.simtk.org/openmm/FAQApp).
There are two ways to install OpenMM: using the Conda package manager (http://conda.pydata.org),
or with standalone installers. (A third option is to compile it from source, which is
discussed in Chapter :ref:`compiling-openmm-from-source-code`.) Using Conda is
the easier method, and is recommended for most users. It is described first,
and then the following sections describe how to use the standalone installers
for various platforms.
Installing with Conda
*********************
*****************
OpenMM is installed using the Conda package manager (http://conda.pydata.org).
Conda is included as part of the Anaconda Python distribution, which you can
download from http://docs.continuum.io/anaconda/install. This is a Python
distribution specifically designed for scientific applications, with many of the
......@@ -58,12 +47,16 @@ which includes only Python itself, plus the Conda package manager. That offers
a much smaller initial download, with the ability to then install only the
packages you want.
1. Begin by installing the most recent 64 bit, Python 3.x version of either
(A third option is to compile OpenMM from source. This provides more flexibility,
but it is much more work, and there is rarely a need for anyone but advanced users
to compile from source. Detailed instruction are in Chapter :ref:`compiling-openmm-from-source-code`.)
\1. Begin by installing the most recent 64 bit, Python 3.x version of either
Anaconda or Miniconda.
2. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL.
\2. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL.
* If you have an Nvidia GPU, download CUDA 8.0 from
* If you have an Nvidia GPU, download CUDA from
https://developer.nvidia.com/cuda-downloads. Be sure to install both the
drivers and toolkit. OpenCL is included with the CUDA drivers.
* If you have an AMD GPU and are using Linux or Windows, download the latest
......@@ -74,144 +67,22 @@ Anaconda or Miniconda.
3. Open a command line terminal and type the following command
::
conda install -c omnia openmm
4. Verify your installation by typing the following command:
::
python -m simtk.testInstallation
This command confirms that OpenMM is installed, checks whether GPU acceleration
is available (via the OpenCL and/or CUDA platforms), and verifies that all
platforms produce consistent results.
.. _installing-on-mac-os-x:
Installing on Mac OS X
**********************
OpenMM works on Mac OS X 10.7 or later. OpenCL is supported on OS X 10.10.3 or
later.
1. Download the pre-compiled binary of OpenMM for Mac OS X from
https://simtk.org/project/xml/downloads.xml?group_id=161, then double click
the .zip file to expand it.
2. If you have not already done so, install Apples Xcode developer tools from
the App Store. They are required to use OpenMM. (With Xcode 4.3 and later, you
must then launch Xcode, open the Preferences window, go to the Downloads tab,
and tell it to install the command line tools. With Xcode 4.2 and earlier, the
command line tools are automatically installed when you install Xcode.)
3. (Optional) If you have an Nvidia GPU and want to use the CUDA platform,
download CUDA 8.0 from https://developer.nvidia.com/cuda-downloads. Be sure to
install both the drivers and toolkit.
4. (Optional) If you plan to use the CPU platform, it is recommended that you
install FFTW, available from http://www.fftw.org. When configuring it, be sure
to specify single precision and multiple threads (the |--|\ :code:`enable-float`
and |--|\ :code:`enable-threads` options). OpenMM will still work without FFTW,
but the performance of particle mesh Ewald (PME) will be much worse.
5. Launch the Terminal application. Change to the OpenMM directory by typing
::
cd <openmm_directory>
where :code:`<openmm_directory>` is the path to the OpenMM folder. Then run
the install script by typing
::
sudo ./install.sh
It will prompt you for an install location and the path to the python
executable. Unless you are certain you know what you are doing, accept the
defaults for both options.
conda install -c omnia -c conda-forge openmm
6. (Optional) To use the CUDA platform on an Nvidia GPU, you must add the CUDA
libraries to your library path so your computer knows where to find them. You
can do this by typing
This installs a version of OpenMM that is compiled to work with CUDA 9.2.
Alternatively you can request a version that is compiled for a specific CUDA
version with the command
::
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib
conda install -c omnia/label/cuda92 -c conda-forge openmm
This will affect only the particular Terminal window you type it into. If you
want to run OpenMM in another Terminal window, you must type the above command
in the new window.
7. Verify your installation by typing the following command:
::
python -m simtk.testInstallation
This command confirms that OpenMM is installed, checks whether GPU acceleration
is available (via the OpenCL and/or CUDA platforms), and verifies that all
platforms produce consistent results.
Important Note: Some Mac laptops have two GPUs, only one of which is capable of
running OpenMM. If you have a laptop, open the System Preferences and go to
the Energy Saver panel. There will be a checkbox labeled Automatic graphics
switching, which should be disabled. Otherwise, trying to run OpenMM may
produce an error. You will only see this option if your laptop has two GPUs
.. _installing-on-linux:
Installing on Linux
*******************
1. Download the pre-compiled binary of OpenMM for Linux from
https://simtk.org/project/xml/downloads.xml?group_id=161, then double click the
.zip file to expand it.
2. Make sure you have Python 2.7 or higher (earlier versions will not work) and
a C++ compiler (typically :program:`gcc` or :program:`clang`) installed on your computer. You can
check what version of Python is installed by typing :code:`python` |--|\ :code:`version`
into a console window.
3. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL.
* If you have an Nvidia GPU, download CUDA 8.0 from
https://developer.nvidia.com/cuda-downloads. Be sure to install both the
drivers and toolkit. OpenCL is included with the CUDA drivers.
* If you have an AMD GPU, download the latest version of the Catalyst driver
from http://support.amd.com.
where :code:`cuda92` should be replaced with the particular CUDA version
installed on your computer. Supported values are :code:`cuda75`, :code:`cuda80`,
:code:`cuda90`, :code:`cuda91`, :code:`cuda92`, and :code:`cuda100`. Because
different CUDA releases are not binary compatible with each other, OpenMM can
only work with the particular CUDA version it was compiled with.
4. (Optional) If you plan to use the CPU platform, it is recommended that you
install FFTW. It is probably available through your systems package manager
such as :program:`yum` or :program:`apt-get`\ . Alternatively, you can download
it from http://www.fftw.org. When configuring it, be sure to specify single
precision and multiple threads (the |--|\ :code:`enable-float` and
|--|\ :code:`enable-threads` options). OpenMM will still work without FFTW, but the
performance of particle mesh Ewald (PME) will be much worse.
5. In a console window, change to the OpenMM directory by typing
::
cd <openmm_directory>
where :code:`<openmm_directory>` is the path to the OpenMM folder. Then run
the install script by typing
::
sudo ./install.sh
It will prompt you for an install location and the path to the python
executable. Unless you are certain you know what you are doing, accept the
defaults for both options.
6. (Optional) To use the CUDA platform on an Nvidia GPU, you must add the CUDA
libraries to your library path so your computer knows where to find them. You
can do this by typing
::
export LD_LIBRARY_PATH=/usr/local/cuda/lib
This will affect only the particular console window you type it into. If you
want to run OpenMM in another console window, you must type the above command in
the new window.
7. Verify your installation by typing the following command:
4. Verify your installation by typing the following command:
::
python -m simtk.testInstallation
......@@ -220,88 +91,6 @@ This command confirms that OpenMM is installed, checks whether GPU acceleration
is available (via the OpenCL and/or CUDA platforms), and verifies that all
platforms produce consistent results.
.. _installing-on-windows:
Installing on Windows
*********************
1. Download the pre-compiled binary of OpenMM for Windows from
https://simtk.org/project/xml/downloads.xml?group_id=161, then double click the
.zip file to expand it. Move the files to :file:`C:\\Program Files\\OpenMM`.
2. Make sure you have the 64-bit version of Python 3.3 or 3.4 (other versions will not
work) installed on your computer. To do this, launch the Python program (either
the command line version or the GUI version). The first line in the Python
window will indicate the version you have, as well as whether you have a 32-bit
or 64-bit version.
3. Double click the Python API Installer to install the Python components. (On
some versions of Windows, a Program Compatibility Assistant window may appear
with the warning, This program might not have installed correctly. This is
just Microsoft trying to scare you. Click This program installed correctly
and ignore it.)
4. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL.
* If you have an Nvidia GPU, download CUDA 8.0 from
https://developer.nvidia.com/cuda-downloads. Be sure to install both the
drivers and toolkit. OpenCL is included with the CUDA drivers.
* If you have an AMD GPU, download the latest version of the Catalyst driver
from http://support.amd.com.
5. (Optional) If you plan to use the CPU platform, it is recommended that you
install FFTW. Precompiled binaries are available from http://www.fftw.org.
OpenMM will still work without FFTW, but the performance of particle mesh Ewald
(PME) will be much worse.
6. Before running OpenMM, you must add the OpenMM and FFTW libraries to your
PATH environment variable. You may also need to add the Python executable to
your PATH.
* To find out if the Python executable is already in your PATH, open a command
prompt window by clicking on :menuselection:`Start --> Programs --> Accessories --> Command Prompt`.
(On Windows 7, select :menuselection:`Start --> All Programs --> Accessories --> Command Prompt`).
Type
::
python
If you get an error message, such as "‘python’ is not recognized as an
internal or external command, operable program or batch file," then you need
to add Python to your PATH. To do so, locate it by typing
::
dir C:\py*
The files are typically located in a directory like :file:`C:\\Python33`. Remember this
location. You will need to enter it, along with the location of the OpenMM
libraries, later in this process.
* Click on :menuselection:`Start --> Control Panel --> System` (On Windows 7, select :menuselection:`Start -->
Control Panel --> System and Security --> System`)
* Click on the :menuselection:`Advanced` tab or the :menuselection:`Advanced system settings` link
* Click :menuselection:`Environment Variables`
* Under :menuselection:`System variables`, select the line for :menuselection:`Path` and click :menuselection:`Edit`
* Add :file:`C:\\Program Files\\OpenMM\\lib` and :file:`C:\\Program Files\\OpenMM\\lib\\plugins`
to the Variable value. If you also need to add Python or FFTW to your
PATH, enter their directory locations here. Directory locations need to be
separated by semi-colons (;).
If you installed OpenMM somewhere other than the default location, you must also
set :envvar:`OPENMM_PLUGIN_DIR` to point to the plugins directory. If this variable is
not set, it will assume plugins are in the default location (:file:`C:\\Program
Files\\OpenMM\\lib\\plugins`).
7. Verify your installation by typing the following command:
::
python -m simtk.testInstallation
This command confirms that OpenMM is installed, checks whether GPU acceleration
is available (via the OpenCL and/or CUDA platforms), and verifies that all
platforms produce consistent results.
.. _running-simulations:
......@@ -314,7 +103,7 @@ A First Example
***************
Lets begin with our first example of an OpenMM script. It loads a PDB file
called :file:`input.pdb` that defines a biomolecular system, parameterizes it using the Amber99SB force field and TIP3P water
called :file:`input.pdb` that defines a biomolecular system, parameterizes it using the Amber14 force field and TIP3P-FB water
model, energy minimizes it, simulates it for 10,000 steps with a Langevin
integrator, and saves a snapshot frame to a PDB file called :file:`output.pdb` every 1000 time
steps.
......@@ -328,7 +117,7 @@ steps.
from sys import stdout
pdb = PDBFile('input.pdb')
forcefield = ForceField('amber99sb.xml', 'tip3p.xml')
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME,
nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
......@@ -390,14 +179,14 @@ Make sure you include the single quotes around the file name. OpenMM also can l
files in the newer PDBx/mmCIF format: just change :class:`PDBFile` to :class:`PDBxFile`.
::
forcefield = ForceField('amber99sb.xml', 'tip3p.xml')
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
This line specifies the force field to use for the simulation. Force fields are
defined by XML files. OpenMM includes XML files defining lots of standard force fields (see Section :ref:`force-fields`).
If you find you need to extend the repertoire of force fields available,
you can find more information on how to create these XML files in Chapter :ref:`creating-force-fields`.
In this case we load two of those files: :file:`amber99sb.xml`, which contains the
Amber99SB force field, and :file:`tip3p.xml`, which contains the TIP3P water model. The
In this case we load two of those files: :file:`amber14-all.xml`, which contains the
Amber14 force field, and :file:`amber14/tip3pfb.xml`, which contains the TIP3P-FB water model. The
:class:`ForceField` object is assigned to a variable called :code:`forcefield`\ .
::
......@@ -681,31 +470,37 @@ Note that both the CHARMM and XPLOR versions of the :file:`psf` file format are
.. _the-script-builder-application:
The Script Builder Application
******************************
One option for writing your own scripts is to start with one of the examples
given above (the one in Section :ref:`a-first-example` if you are starting from a PDB file, section
:ref:`using_amber_files` if you are starting from AMBER :file:`prmtop` and :file:`inpcrd` files, section
:ref:`using_gromacs_files` if you are starting from Gromacs :file:`gro` and :file:`top` files, or section
:ref:`using-charmm-files` if you are starting from CHARMM files), then customize it
to suit your needs. Another option is to use the `OpenMM Script Builder`_ application.
The OpenMM-Setup Application
****************************
One way to create your own scripts is to start with one of the examples given
above and customize it to suit your needs, but there's an even easier option.
OpenMM-Setup is a graphical application that walks you through the whole process
of loading your input files and setting options. It then generates a complete
script, and can even run it for you.
.. figure:: ../images/ScriptBuilder.png
.. figure:: ../images/OpenMMSetup.png
:align: center
:width: 100%
:autonumber:`Figure,script builder`: The Script Builder application
:autonumber:`Figure,openmm setup`: The OpenMM-Setup application
To install OpenMM-Setup, open a command line terminal and type the following command
::
conda install -c omnia openmm-setup
This is a web application available at https://builder.openmm.org. It provides
a graphical interface with simple choices for all the most common simulation
options, then automatically generates a script based on them. As you change the
settings, the script is instantly updated to reflect them. Once everything is
set the way you want, click the :menuselection:`Save Script` button to save it to disk, or
simply copy and paste it into a text editor.
You can then launch it by typing the command
::
openmm-setup
.. _`OpenMM Script Builder`: https://builder.openmm.org
It will automatically open a window in your web browser displaying the user interface.
OpenMM-Setup is far more than just a script generator. It can fix problems in
your input files, add missing atoms, build membranes and water boxes, and much
more. It is a very easy way to quickly do all necessary preparation and setup.
We highly recommend it to all users of OpenMM, from novices to experts.
.. _simulation-parameters:
......@@ -760,57 +555,187 @@ the main force field, and possibly a second file to define the water model
(either implicit or explicit). For example:
::
forcefield = ForceField('amber99sb.xml', 'tip3p.xml')
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
In some cases, one XML file may load several others. For example, :file:`amber14-all.xml`
is really just a shortcut for loading several different files that together make up
the AMBER14 force field. If you need finer grained control over which parameters
are loaded, you can instead specify the component files individually.
Be aware that some force fields and water models include "extra particles", such
as lone pairs or Drude particles. Examples include the CHARMM polarizable force
field and all of the 4 and 5 site water models. To use these force fields, you
must first add the extra particles to the :class:`Topology`. See section
:ref:`adding-or-removing-extra-particles` for details.
The force fields described below are the ones that are bundled with OpenMM.
Additional force fields are available online at https://github.com/choderalab/openmm-forcefields.
Amber14
-------
For the main force field, OpenMM provides the following options:
The Amber14\ :cite:`Maier2015` force field is made up of various files that define
parameters for proteins, DNA, RNA, lipids, water, and ions.
.. tabularcolumns:: |l|L|
=================================== ============================================
File Parameters
=================================== ============================================
:file:`amber14/protein.ff14SB.xml` Protein (recommended)
:file:`amber14/protein.ff15ipq.xml` Protein (alternative)
:file:`amber14/DNA.OL15.xml` DNA (recommended)
:file:`amber14/DNA.bsc1.xml` DNA (alternative)
:file:`amber14/RNA.OL3.xml` RNA
:file:`amber14/lipid17.xml` Lipid
:file:`amber14/tip3p.xml` TIP3P water model\ :cite:`Jorgensen1983` and ions
:file:`amber14/tip3pfb.xml` TIP3P-FB water model\ :cite:`Wang2014` and ions
:file:`amber14/tip4pew.xml` TIP4P-Ew water model\ :cite:`Horn2004` and ions
:file:`amber14/tip4pfb.xml` TIP4P-FB water model\ :cite:`Wang2014` and ions
:file:`amber14/spce.xml` SPC/E water model\ :cite:`Berendsen1987` and ions
=================================== ============================================
As a convenience, the file :file:`amber14-all.xml` can be used as a shortcut to include
:file:`amber14/protein.ff14SB.xml`, :file:`amber14/DNA.OL15.xml`, :file:`amber14/RNA.OL3.xml`,
and :file:`amber14/lipid17.xml`. In most cases, you can simply include that file,
plus one of the water models, such as :file:`amber14/tip3pfb.xml` for the TIP3P-FB
water model and ions\ :cite:`Wang2014`:
::
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
.. tip:: The solvent model XML files included under the :file:`amber14/` directory
include both water *and* ions compatible with that water model, so if you
mistakenly specify :file:`tip3p.xml` instead of :file:`amber14/tip3p.xml`,
you run the risk of having :class:`ForceField` throw an exception since
:file:`tip3p.xml` will be missing parameters for ions in your system.
The converted parameter sets come from the `AmberTools 17 release <http://ambermd.org/AmberTools17-get.html>`_
and were converted using the `openmm-forcefields <https://github.com/choderalab/openmm-forcefields>`_ package and `ParmEd <https://github.com/parmed/parmed>`_.
CHARMM36
--------
The CHARMM36\ :cite:`Best2012` force field provides parameters for proteins, DNA,
RNA, lipids, carbohydrates, water, ions, and various small molecules (see `here <http://mackerell.umaryland.edu/charmm_ff.shtml#refs>`_
for full references).
.. tabularcolumns:: |l|L|
================================= ============================================
File Parameters
================================= ============================================
:file:`charmm36.xml` Protein, DNA, RNA, lipids, carbohydrates, and small molecules
:file:`charmm36/water.xml` Default CHARMM water model (a modified version of TIP3P\ :cite:`Jorgensen1983`) and ions
:file:`charmm36/spce.xml` SPC/E water model\ :cite:`Berendsen1987` and ions
:file:`charmm36/tip3p-pme-b.xml` TIP3P-PME-B water model\ :cite:`Price2004` and ions
:file:`charmm36/tip3p-pme-f.xml` TIP3P-PME-F water model\ :cite:`Price2004` and ions
:file:`charmm36/tip4pew.xml` TIP4P-Ew water model\ :cite:`Horn2004` and ions
:file:`charmm36/tip4p2005.xml` TIP4P-2005 water model\ :cite:`Abascal2005` and ions
:file:`charmm36/tip5p.xml` TIP5P water model\ :cite:`Mahoney2000` and ions
:file:`charmm36/tip5pew.xml` TIP5P-Ew water model\ :cite:`Rick2004` and ions
================================= ============================================
The file :file:`charmm36.xml` bundles everything but the water and ions into a single
file. In most cases, you can simply include that file, plus one of the water models,
such as :file:`charmm36/water.xml`, which specifies the default CHARMM water model
(a modified version of TIP3P\ :cite:`Jorgensen1983`) and ions:
::
forcefield = ForceField('charmm36.xml', 'charmm36/water.xml')
.. warning:: Drude polarizable sites and lone pairs are not yet supported
by `ParmEd <https://github.com/parmed/parmed>`_ and the CHARMM36 forcefields
that depend on these features are not included in this port.
To use the CHARMM 2013 polarizable force field\ :cite:`Lopes2013`,
include the single file :file:`charmm_polar_2013.xml`.
.. tip:: The solvent model XML files included under the :file:`charmm36/` directory
include both water *and* ions compatible with that water model, so if you
mistakenly specify :file:`tip3p.xml` instead of :file:`charmm36/water.xml`,
you run the risk of having :class:`ForceField` raise an exception due to
missing parameters for ions in your system.
.. tip:: CHARMM makes extensive use of patches, which are automatically combined with
residue templates to create an expanded library of patched residue templates
by :class:`ForceField`. That means that patched residues, such as ``ACE`` and
``NME`` patched termini, must occur as a single residue in order for :class:`ForceField`
to correctly match the residue template and apply parameters. Since these
patched residues are not standard PDB residues, :class:`Modeller` does not know
how to add hydrogens to these nonstandard residues, and your input topologies
must already contain appropriate hydrogens. This can often cause problems when
trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_
that do not generate PDB files that comply with the `PDB standard <http://www.wwpdb.org/documentation/file-format>`_.
If you're using files from `CHARMM-GUI <http://charmm-gui.org/>`_, it's easiest to load
the PSF file directly, as discussed in Section :ref:`using-charmm-files`.
.. tip:: Trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_
that do not generate PDB files that comply with the `PDB standard <http://www.wwpdb.org/documentation/file-format>`_
and omit ``CONECT`` records specifying bonds between residues (such as cysteines)
or include ``CONECT`` records specifying non-chemical ``H-H`` bonds in waters
can cause issues with the detection and parameter assignment for disulfide bonds.
Make sure the files you read in comply with the appropriate standards regarding
additional bonds and nonstandard residue definitions. If you're using files from
`CHARMM-GUI <http://charmm-gui.org/>`_, it's easiest to load
the PSF file directly, as discussed in Section :ref:`using-charmm-files`.
The converted parameter sets come from the `CHARMM36 July 2017 update <http://mackerell.umaryland.edu/charmm_ff.shtml>`_
and were converted using the `openmm-forcefields <https://github.com/choderalab/openmm-forcefields>`_ package and `parmed <https://github.com/parmed/parmed>`_.
AMOEBA
------
The AMOEBA polarizable force field provides parameters for proteins, water, and ions.
.. tabularcolumns:: |l|L|
============================= ================================================================================
File Force Field
File Parameters
============================= ================================================================================
:code:`amber96.xml` Amber96\ :cite:`Kollman1997`
:code:`amber99sb.xml` Amber99\ :cite:`Wang2000` with modified backbone torsions\ :cite:`Hornak2006`
:code:`amber99sbildn.xml` Amber99SB plus improved side chain torsions\ :cite:`Lindorff-Larsen2010`
:code:`amber99sbnmr.xml` Amber99SB with modifications to fit NMR data\ :cite:`Li2010`
:code:`amber03.xml` Amber03\ :cite:`Duan2003`
:code:`amber10.xml` Amber10 (documented in the AmberTools_ manual as `ff10`)
:code:`amberfb15.xml` AMBER-FB15\ :cite:`Wang2017`. Intramolecular parameters optimized with
ForceBalance using high-level ab initio data.
:code:`amoeba2009.xml` AMOEBA 2009\ :cite:`Ren2002`. This force field is deprecated. It is
:file:`amoeba2013.xml` AMOEBA 2013\ :cite:`Shi2013`
:file:`amoeba2013_gk.xml` Generalized Kirkwood solvation model\ :cite:`Schnieders2007` for use with AMOEBA 2013 force field
:file:`amoeba2009.xml` AMOEBA 2009\ :cite:`Ren2002`. This force field is deprecated. It is
recommended to use AMOEBA 2013 instead.
:code:`amoeba2013.xml` AMOEBA 2013\ :cite:`Shi2013`
:code:`charmm_polar_2013.xml` CHARMM 2013 polarizable force field\ :cite:`Lopes2013`
:file:`amoeba2009_gk.xml` Generalized Kirkwood solvation model for use with AMOEBA 2009 force field
============================= ================================================================================
For explicit solvent simulations, just include the single file :file:`amoeba2013.xml`.
AMOEBA also supports implicit solvent using a Generalized Kirkwood model. To enable
it, also include :file:`amoeba2013_gk.xml`.
The AMBER files do not include parameters for water molecules. This allows you
to separately select which water model you want to use. For simulations that
include explicit water molecules, you should also specify one of the following
files:
The older AMOEBA 2009 force field is provided only for backward compatibility, and is not
recommended for most simulations.
.. tabularcolumns:: |l|L|
CHARMM Polarizable Force Field
------------------------------
=================== ============================================
File Water Model
=================== ============================================
:code:`tip3p.xml` TIP3P water model\ :cite:`Jorgensen1983`
:code:`tip3pfb.xml` TIP3P-FB water model\ :cite:`Wang2014`
:code:`tip4pew.xml` TIP4P-Ew water model\ :cite:`Horn2004`
:code:`tip4pfb.xml` TIP4P-FB water model\ :cite:`Wang2014`
:code:`tip5p.xml` TIP5P water model\ :cite:`Mahoney2000`
:code:`spce.xml` SPC/E water model\ :cite:`Berendsen1987`
:code:`swm4ndp.xml` SWM4-NDP water model\ :cite:`Lamoureux2006`
=================== ============================================
To use the CHARMM 2013 polarizable force field\ :cite:`Lopes2013`, include the
single file :file:`charmm_polar_2013.xml`. It includes parameters for proteins,
water, and ions. When using this force field, remember to add extra particles to
the :class:`Topology` as described in section :ref:`adding-or-removing-extra-particles`.
Older Amber Force Fields
------------------------
For the polarizable force fields (AMOEBA and CHARMM), only one explicit water model
is currently available and the water parameters are included in the same file as
the macromolecule parameters. Also, the polarizable force fields only include
parameters for amino acids and ions, not for nucleic acids.
OpenMM includes several older Amber force fields as well. For most simulations
Amber14 is preferred over any of these, but they are still useful for reproducing
older results.
If you want to include an implicit solvation model, you can also specify one of
the following files:
.. tabularcolumns:: |l|L|
============================= ================================================================================
File Force Field
============================= ================================================================================
:code:`amber96.xml` Amber96\ :cite:`Kollman1997`
:code:`amber99sb.xml` Amber99\ :cite:`Wang2000` with modified backbone torsions\ :cite:`Hornak2006`
:code:`amber99sbildn.xml` Amber99SB plus improved side chain torsions\ :cite:`Lindorff-Larsen2010`
:code:`amber99sbnmr.xml` Amber99SB with modifications to fit NMR data\ :cite:`Li2010`
:code:`amber03.xml` Amber03\ :cite:`Duan2003`
:code:`amber10.xml` Amber10 (documented in the AmberTools_ manual as `ff10`)
============================= ================================================================================
Several of these force fields support implicit solvent. To enable it, also
include the corresponding OBC file.
.. tabularcolumns:: |l|L|
......@@ -818,37 +743,37 @@ the following files:
File Implicit Solvation Model
========================= =================================================================================================
:code:`amber96_obc.xml` GBSA-OBC solvation model\ :cite:`Onufriev2004` for use with Amber96 force field
:code:`amber99_obc.xml` GBSA-OBC solvation model for use with Amber99 force fields
:code:`amber99_obc.xml` GBSA-OBC solvation model for use with Amber99 force field and its variants
:code:`amber03_obc.xml` GBSA-OBC solvation model for use with Amber03 force field
:code:`amber10_obc.xml` GBSA-OBC solvation model for use with Amber10 force field
:code:`amoeba2009_gk.xml` Generalized Kirkwood solvation model\ :cite:`Schnieders2007` for use with AMOEBA 2009 force field
:code:`amoeba2013_gk.xml` Generalized Kirkwood solvation model for use with AMOEBA 2013 force field
========================= =================================================================================================
For example, to use the GBSA-OBC solvation model with the Amber99SB force field,
you would type:
::
forcefield = ForceField('amber99sb.xml', 'amber99_obc.xml')
Note that the GBSA-OBC parameters in these files are those used in TINKER.\ :cite:`Tinker`
They are designed for use with Amber force fields, but they are different from
the parameters found in the AMBER application.
If you are running a vacuum simulation, you do not need to specify a water
model. The following line specifies the Amber10 force field and no water model.
If you try to use it with a PDB file that contains explicit water, it will
produce an error since no water parameters are defined:
::
Water Models
------------
forcefield = ForceField('amber10.xml')
The following files define popular water models. They can be used with force fields
that do not provide their own water models. When using Amber14 or CHARMM36, use
the water files included with those force fields instead, since they also include
ion parameters.
.. tabularcolumns:: |l|L|
=================== ============================================
File Water Model
=================== ============================================
:code:`tip3p.xml` TIP3P water model\ :cite:`Jorgensen1983`
:code:`tip3pfb.xml` TIP3P-FB water model\ :cite:`Wang2014`
:code:`tip4pew.xml` TIP4P-Ew water model\ :cite:`Horn2004`
:code:`tip4pfb.xml` TIP4P-FB water model\ :cite:`Wang2014`
:code:`tip5p.xml` TIP5P water model\ :cite:`Mahoney2000`
:code:`spce.xml` SPC/E water model\ :cite:`Berendsen1987`
:code:`swm4ndp.xml` SWM4-NDP water model\ :cite:`Lamoureux2006`
=================== ============================================
Be aware that some force fields and water models include "extra particles", such
as lone pairs or Drude particles. Examples include the CHARMM polarizable force
field and all of the 4 and 5 site water models. To use these force fields, you
must first add the extra particles to the :class:`Topology`. See section
:ref:`adding-or-removing-extra-particles` for details.
AMBER Implicit Solvent
======================
......@@ -940,6 +865,16 @@ The error tolerance is roughly equal to the fractional error in the forces due
to truncating the Ewald summation. If you do not specify it, a default value of
0.0005 is used.
Another optional parameter when using a cutoff is :code:`switchDistance`. This
causes Lennard-Jones interactions to smoothly go to zero over some finite range,
rather than being sharply truncated at the cutoff distance. This can improve
energy conservation. To use it, specify a distance at which the interactions
should start being reduced. For example:
::
system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer,
switchDistance=0.9*nanometer)
Nonbonded Forces for AMOEBA
---------------------------
......@@ -1166,16 +1101,6 @@ algorithm\ :cite:`Tuckerman1992`. This allows some forces in the system to be e
frequently than others. For details on how to use it, consult the API
documentation.
aMD Integrator
--------------
There are three different integrator types that implement variations of the
aMD\ :cite:`Hamelberg2007` accelerated sampling algorithm: :class:`AMDIntegrator`,
:class:`AMDForceGroupIntegrator`, and :class:`DualAMDIntegrator`. They
perform integration on a modified potential energy surface to allow much faster
sampling of conformations. For details on how to use them, consult the API
documentation.
Compound Integrator
-------------------
......@@ -1436,6 +1361,55 @@ a checkpoint file every 5,000 steps, for example:
Note that the checkpoint reporter will overwrite the last checkpoint file.
Enhanced Sampling Methods
=========================
In many situations, the goal of a simulation is to sample the range of configurations
accessible to a system. It does not matter whether the simulation represents a
single, physically realistic trajectory, only whether it produces a correct distribution
of states. In this case, a variety of methods can be used to sample configuration
space much more quickly and efficiently than a single physical trajectory would.
These are known as enhanced sampling methods. OpenMM offers several that you
can choose from. They are briefly described here. Consult the API documentation
for more detailed descriptions and example code.
Simulated Tempering
-------------------
Simulated tempering\ :cite:`Marinari1992` involves making frequent changes to the
temperature of a simulation. At high temperatures, it can quickly cross energy barriers
and explore a wide range of configurations. At lower temperatures, it more thoroughly
explores each local region of configuration space. This is a powerful method to
speed up sampling when you do not know in advance what motions you want to sample.
Simply specify the range of temperatures to simulate and the algorithm handles
everything for you mostly automatically.
Metadynamics
------------
Metadynamics\ :cite:`Barducci2008` is used when you do know in advance what
motions you want to sample. You specify one or more collective variables, and the
algorithm adds a biasing potential to make the simulation explore a wide range of
values for those variables. It does this by periodically adding "bumps" to the biasing
potential at the current values of the collective variables. This encourages the simulation
to move away from regions it has already explored and sample a wide range of values.
At the end of the simulation, the biasing potential can be used to calculate the
free energy of the system as a function of the collective variables.
Accelerated Molecular Dynamics (aMD)
------------------------------------
aMD\ :cite:`Hamelberg2007` is another method that can be used when you do not know in
advance what motions you want to accelerate. It alters the potential energy surface
by adding a "boost" potential whenever the potential energy is below a threshold.
This makes local minima shallower and allows more frequent transitions between them.
The boost can be applied to the total potential energy, to just a subset of interactions
(typically the dihedral torsions), or both. There are separate integrator classes
for each of these options: :class:`AMDIntegrator`, :class:`AMDForceGroupIntegrator`,
and :class:`DualAMDIntegrator`.
.. _model-building-and-editing:
Model Building and Editing
......@@ -1582,6 +1556,29 @@ Allowed values for :code:`positiveIon` are ``'Cs+'``, ``'K+'``, ``'Li+'``, ``'Na
some force fields do not include parameters for all of these ion types, so you
need to use types that are supported by your chosen force field.
Adding a Membrane
*****************
If you want to simulate a membrane protein, you may need to create a membrane as
well. You can do this by calling :meth:`addMembrane`. Call it *instead* of
:meth:`addSolvent`, not in addition to it. This one method adds the membrane,
solvent, and ions all at once, making sure the lipid head groups are properly
solvated. For example, this creates a POPC membrane, ensuring at least 1 nm of
padding on all sides:
::
modeller.addMembrane(forcefield, lipidType='POPC', minimumPadding=1*nanometer)
The membrane is added in the XY plane, and the existing protein is assumed to already be oriented
and positioned correctly. When possible, it is recommended to start with a model
from the `Orientations of Proteins in Membranes`_ (OPM) database. Otherwise, it
is up to you to select the protein position yourself.
Because this method also adds solvent, it takes many of the same arguments as
:meth:`addSolvent`. See the API documentation for details.
.. _`Orientations of Proteins in Membranes`: http://opm.phar.umich.edu
.. _adding-or-removing-extra-particles:
Adding or Removing Extra Particles
......@@ -1794,7 +1791,7 @@ Here is the definition of the :class:`ForceReporter` class:
def describeNextReport(self, simulation):
steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, False, False, True, False)
return (steps, False, False, True, False, None)
def report(self, simulation, state):
forces = state.getForces().value_in_unit(kilojoules/mole/nanometer)
......@@ -1814,7 +1811,7 @@ We then have two methods that every reporter must implement:
:meth:`describeNextReport()` and :meth:`report()`. A Simulation object
periodically calls :meth:`describeNextReport()` on each of its reporters to
find out when that reporter will next generate a report, and what information
will be needed to generate it. The return value should be a five element tuple,
will be needed to generate it. The return value should be a six element tuple,
whose elements are as follows:
* The number of time steps until the next report. We calculate this as
......@@ -1825,6 +1822,9 @@ whose elements are as follows:
* Whether the next report will need particle velocities.
* Whether the next report will need forces.
* Whether the next report will need energies.
* Whether the positions should be wrapped to the periodic box. If None, it will
automatically decide whether to wrap positions based on whether the System uses
periodic boundary conditions.
When the time comes for the next scheduled report, the :class:`Simulation` calls
......@@ -2956,12 +2956,6 @@ relative either to the directory containing the parent XML file (the one with
the :code:`<Include>` tag) or the OpenMM data directory (the one containing
built in force fields).
The included file is fully processed before any other tags in the parent file
are processed, and its definitions are added to the force field. This means the
parent file can refer to atom types defined in the included file, but not the
other way around. If there are multiple :code:`<Include>` tags, they are processed
in the order they appear in the file.
Using Multiple Files
********************
......
......@@ -42,7 +42,7 @@ master_doc = 'index'
# General information about the project.
project = u'OpenMM Users Guide'
copyright = u'2008-2014, Stanford University'
copyright = u'2008-2017, Stanford University'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
......
......@@ -10,7 +10,7 @@ OpenMM Users Manual and Theory Guide
.. toctree::
:numbered:
:maxdepth: 3
:maxdepth: 4
introduction
application
......
......@@ -27,7 +27,7 @@ Online Resources
****************
You can find more documentation and other material at our website
http://simtk.org/home/openmm. Among other things there is a discussion forum,
http://openmm.org. Among other things there is a discussion forum,
a wiki, and videos of lectures on using OpenMM.
......@@ -36,11 +36,10 @@ Referencing OpenMM
Any work that uses OpenMM should cite the following publication:
P. Eastman, M. S. Friedrichs, J. D. Chodera, R. J. Radmer, C. M. Bruns, J. P.
Ku, K. A. Beauchamp, T. J. Lane, L.-P. Wang, D. Shukla, T. Tye, M. Houston, T.
Stich, C. Klein, M. R. Shirts, and V. S. Pande. "OpenMM 4: A Reusable,
Extensible, Hardware Independent Library for High Performance Molecular
Simulation." J. Chem. Theor. Comput. 9(1): 461-469. (2013).
P. Eastman, J. Swails, J. D. Chodera, R. T. McGibbon, Y. Zhao, K. A. Beauchamp,
L.-P. Wang, A. C. Simmonett, M. P. Harrigan, C. D. Stern, R. P. Wiewiora,
B. R. Brooks, and V. S. Pande. "OpenMM 7: Rapid development of high performance
algorithms for molecular dynamics." PLOS Comp. Biol. 13(7): e1005659. (2017)
We depend on academic research grants to fund the OpenMM development efforts;
citations of our publication will help demonstrate the value of OpenMM.
......@@ -51,7 +50,6 @@ Acknowledgments
OpenMM software and all related activities, such as this manual, are funded by
the Simbios National Center for Biomedical Computing through the National
Institutes of Health Roadmap for Medical Research, Grant U54 GM072970.
Information on the National Centers can be found at
http://nihroadmap.nih.gov/bioinformatics.
Institutes of Health Roadmap for Medical Research, Grant U54 GM072970, and by
National Institutes of Health grant R01-GM062868.
......@@ -455,6 +455,7 @@ CMake.
* Python 2.7 or later (http://www.python.org)
* SWIG (http://www.swig.org)
* Doxygen (http://www.doxygen.org)
* Cython (https://cython.org)
* For compiling the CPU platform, you need:
......@@ -2555,69 +2556,6 @@ Python API
**********
Installing the Python API
=========================
There are currently two types of packages for installing the Python API. One
contains wrapper source code for Unix-type machines (including Linux and Mac
operating systems). You will need a C++ compiler to install it using this type
of package. The other type of installation package is a binary package which
contains compiled wrapper code for Windows machines (no compilers are needed to
install binary packages).
Installing on Windows
---------------------
OpenMM on Windows only works with Python 3.5, so make sure that version is
installed before you try installing. For Python installation packages and
instructions, go to http://python.org. We suggest that you install Python using
the default options.
Double click on the Python API Installer icon, located in the top level
directory for the OpenMM installation (by default, this is C:\Program
Files\OpenMM). This will install the OpenMM package into the Python
installation area. If you have more than one Python installation, you will be
asked which Python to use—make sure to select Python 3.5.
Installing on Linux and Mac
---------------------------
Make sure you have Python 2.7 or later installed. For Python installation
packages and instructions, go to http://python.org. If you do not have the
correct Python version, install a valid version using the default options. Most
versions of Linux and Mac OS X have a suitable Python preinstalled. You can
check by typing “\ :code:`python` |--|\ :code:`version`\ ” in a terminal window.
You must have a C++ compiler to install the OpenMM Python API. If you are using
a Mac, install Apple's Xcode development tools
(http://developer.apple.com/TOOLS/Xcode) to get the needed compiler. On other
Unix-type systems, install gcc or clang. We recommend clang, since it produces
faster code than gcc.
The install.sh script installs the Python API automatically as part of the
installation process, so you probably already have it installed. If for some
reason you need to install it manually, you can do that with the
:code:`setup.py` script included with OpenMM. Before executing this script,
you must set two environment variables: :code:`OPENMM_INCLUDE_PATH` must
point to the directory containing OpenMM header files, and
:code:`OPENMM_LIB_PATH` must point to the directory containing OpenMM library
files. Assuming OpenMM is installed in the default location
(\ :code:`/usr/local/openmm`\ ), you would type the following commands.
Note that if you are using the system Python (as opposed to a locally installed
version), you may need to use the :code:`sudo` command when running
:code:`python setup.py install`\ .
::
export OPENMM_INCLUDE_PATH=/usr/local/openmm/include
export OPENMM_LIB_PATH=/usr/local/openmm/lib
python setup.py build
python setup.py install
If you are compiling OpenMM from source, you can also install by building the
PythonInstall target:
:code:`make PythonInstall` OR :code:`sudo make PythonInstall`
Mapping from the C++ API to the Python API
==========================================
......
Portions copyright (c) 2008-2016 Stanford University and the Authors
Portions copyright (c) 2008-2017 Stanford University and the Authors
Contributors: Kyle Beauchamp, Christopher Bruns, John Chodera, Peter Eastman, Mark
Friedrichs, Joy P. Ku, Tom Markland, Vijay Pande, Randy Radmer, Michael Sherman,
......
@article{Abascal2005
author = {Abascal, J.L.F. and Vega, C.},
title = {A general purpose model for the condensed phases of water: TIP4P/2005},
journal = {Journal of Chemical Physics},
volume = {123},
pages = {234505},
year = {2005},
type = {Journal Article}
}
@article{Andersen1980
author = {Andersen, Hans C.},
title = {Molecular dynamics simulations at constant pressure and/or temperature},
......@@ -19,6 +29,18 @@
type = {Journal Article}
}
@article{Barducci2008,
title = {Well-Tempered Metadynamics: A Smoothly Converging and Tunable Free-Energy Method},
author = {Barducci, Alessandro and Bussi, Giovanni and Parrinello, Michele},
journal = {Physical Review Letters},
volume = {100},
issue = {2},
pages = {020603},
year = {2008},
publisher = {American Physical Society},
doi = {10.1103/PhysRevLett.100.020603},
}
@article{Berendsen1987
author = {Berendsen, H. J. C. and Grigera, J. R. and Straatsma, T. P.},
title = {The missing term in effective pair potentials},
......@@ -29,6 +51,17 @@
type = {Journal Article}
}
@article{Best2012,
author = {Best, Robert B. and Zhu, Xiao and Shim, Jihyun and Lopes, Pedro E. M. and Mittal, Jeetain and Feig, Michael and MacKerell, Alexander D.},
title = {Optimization of the Additive CHARMM All-Atom Protein Force Field Targeting Improved Sampling of the Backbone $\phi$, $\psi$, and Side-Chain $\chi$1 and $\chi$2 Dihedral Angles},
journal = {Journal of Chemical Theory and Computation},
volume = {8},
number = {9},
pages = {3257-3273},
year = {2012},
type = {Journal Article}
}
@article{Ceriotti2010
author = {Ceriotti, M. and Parrinello, M. and Markland, Thomas E. and Manolopoulos, David E.},
title = {Efficient stochastic thermostatting of path integral molecular dynamics},
......@@ -258,6 +291,29 @@
type = {Journal Article}
}
@article{Maier2015
author = {Maier, James A. and Martinez, Carmenza and Kasavajhala, Koushik and Wickstrom, Lauren and Hauser, Kevin E. and Simmerling, Carlos},
title = {ff14SB: Improving the Accuracy of Protein Side Chain and Backbone Parameters from ff99SB},
journal = {Journal of Chemical Theory and Computation},
volume = {11},
number = {8},
pages = {3696-3713},
year = {2015},
type = {Journal Article}
}
@article{Marinari1992,
doi = {10.1209/0295-5075/19/6/002},
year = 1992,
publisher = {{IOP} Publishing},
volume = {19},
number = {6},
pages = {451--458},
author = {E Marinari and G Parisi},
title = {Simulated Tempering: A New Monte Carlo Scheme},
journal = {Europhysics Letters ({EPL})},
}
@article{Markland2008
author = {Markland, Thomas E. and Manolopoulos, David E.},
title = {An efficient ring polymer contraction scheme for imaginary time path integral simulations},
......@@ -318,6 +374,16 @@
type = {Personal Communication}
}
@article{Price2004
author = {Price, D.J. and Brooks, C.L. III},
title = {A modified TIP3P water potential for simulation with Ewald summation},
journal = {Journal of Chemical Physics},
volume = {121},
pages = {10096-10103},
year = {2004},
type = {Journal Article}
}
@article{Ren2002
author = {Ren, P. and Ponder, Jay W.},
title = {A Consistent Treatment of Inter- and Intramolecular Polarization in Molecular Mechanics Calculations},
......@@ -338,6 +404,16 @@
type = {Journal Article}
}
@article{Rick2004
author = {Rick, S.W.},
title = {A reoptimization of the five-site water potential (TIP5P) for use with Ewald sums},
journal = {Journal of Chemical Physics},
volume = {120},
pages = {6085-6093},
year = {2004},
type = {Journal Article}
}
@article{Schaefer1998
author = {Schaefer, Michael and Bartels, Christian and Karplus, Martin},
title = {Solution conformations and thermodynamics of structured peptides: molecular dynamics simulation with an implicit solvation model},
......
......@@ -762,6 +762,26 @@ where :math:`m_i` and :math:`\mathbf{v}_i` are the mass and velocity of particle
\ *i*\ . It then subtracts :math:`\mathbf{v}_\text{CM}` from the velocity of every
particle.
RMSDForce
*********
RMSDForce computes the root-mean-squared deviation (RMSD) between the current
particle positions :math:`\mathbf{x}_i` and a set of reference positions
:math:`\mathbf{x}_i^\text{ref}`:
.. math::
\text{RMSD} = \sqrt{\frac{\sum_{i} \| \mathbf{x}_i - \mathbf{x}_i^\text{ref} \|^2}{N}}
Before computing this, the reference positions are first translated and rotated
so as to minimize the RMSD. The computed value is therefore :math:`argmin(\text{RMSD})`,
where the :math:`argmin` is taken over all possible translations and rotations.
This force is normally used with a CustomCVForce (see Section :ref:`customcvforce`).
One rarely wants a force whose energy exactly equals the RMSD, but there are many
situations where it is useful to have a restraining or biasing force that depends
on the RMSD in some way.
Custom Forces
#############
......@@ -831,7 +851,7 @@ by the user. That is, the interaction energy of each angle is given by
where :math:`f(\theta)` is a user defined mathematical expression. The angle
:math:`\theta` is guaranteed to be in the range [-π, π]. Like PeriodicTorsionForce, it
:math:`\theta` is guaranteed to be in the range :math:`[-\pi, +\pi]`\ . Like PeriodicTorsionForce, it
is defined to be zero when the first and last particles are on the same side of
the bond formed by the middle two particles (the *cis* configuration).
......@@ -953,7 +973,7 @@ of four particles. That is, the interaction energy of each bond is given by
where *f*\ (\ *...*\ ) is a user defined mathematical expression. It may
depend on an arbitrary set of positions {\ :math:`x_i`\ }, distances {\ :math:`r_i`\ },
angles {\ :math:`\theta_i`\ }, and dihedral angles {\ :math:`\phi_i`\ }
guaranteed to be in the range [-π, π].
guaranteed to be in the range :math:`[-\pi, +\pi]`\ .
Each distance, angle, or dihedral is defined by specifying a sequence of
particles chosen from among the particles that make up the bond. A distance
......@@ -1158,6 +1178,8 @@ specified in three ways:
* Per-donor parameters are defined by specifying a value for each donor group.
* Per-acceptor parameters are defined by specifying a value for each acceptor group.
.. _customcvforce:
CustomCVForce
*************
......@@ -1187,7 +1209,7 @@ The following operators are supported: + (add), - (subtract), * (multiply), /
(divide), and ^ (power). Parentheses “(“ and “)” may be used for grouping.
The following standard functions are supported: sqrt, exp, log, sin, cos, sec,
csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs,
csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs,
floor, ceil, step, delta, select. step(x) = 0 if x < 0, 1 otherwise.
delta(x) = 1 if x is 0, 0 otherwise. select(x,y,z) = z if x = 0, y otherwise.
Some custom forces allow additional functions to be defined from tabulated values.
......@@ -1212,6 +1234,32 @@ is exactly equivalent to
The definition of an intermediate value may itself involve other intermediate
values. All uses of a value must appear *before* that value’s definition.
Setting Parameters
******************
Most custom forces have two types of parameters you can define. The simplest type
are global parameters, which represent a single number. The value is stored in
the :class:`Context`, and can be changed at any time by calling :meth:`setParameter`
on it. Global parameters are designed to be very inexpensive to change. Even if
you set a new value for a global parameter on every time step, the overhead will
usually be quite small. There can be exceptions to this rule, however. For
example, if a :class:`CustomNonbondedForce` uses a long range correction, changing
a global parameter may require the correction coefficient to be recalculated,
which is expensive.
The other type of parameter is ones that record many values, one for each element
of the force, such as per-particle or per-bond parameters. These values are stored
directly in the force object itself, and hence are part of the system definition.
When a :class:`Context` is created, the values are copied over to it, and thereafter
the two are disconnected. Modifying the force will have no effect on any
:class:`Context` that already exists.
Some forces do provide a way to modify these parameters via an :meth:`updateParametersInContext`
method. These methods tend to be somewhat expensive, so it is best not to call
them too often. On the other hand, they are still much less expensive than calling
:meth:`reinitialize` on the :class:`Context`, which is the other way of updating
the system definition for a running simulation.
Parameter Derivatives
*********************
......
......@@ -93,7 +93,7 @@ FOREACH(EX_ROOT ${F_EXAMPLES})
INSTALL(FILES ${EX_ROOT}.f90 DESTINATION examples)
ENDFOREACH(EX_ROOT ${F_EXAMPLES})
INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py benchmark.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top 5dfr_minimized.pdb 5dfr_solv-cube_equil.pdb
INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py benchmark.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top 5dfr_minimized.pdb 5dfr_solv-cube_equil.pdb apoa1.pdb
DESTINATION examples)
INSTALL(FILES VisualStudio/HelloArgon.vcproj
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -14,13 +14,14 @@ def timeIntegration(context, steps, initialSteps):
context.getIntegrator().step(steps)
context.getState(getEnergy=True)
end = datetime.now()
elapsed = end -start
elapsed = end-start
return elapsed.seconds + elapsed.microseconds*1e-6
def runOneTest(testName, options):
"""Perform a single benchmarking simulation."""
explicit = (testName in ('rf', 'pme', 'amoebapme'))
amoeba = (testName in ('amoebagk', 'amoebapme'))
apoa1 = testName.startswith('apoa1')
hydrogenMass = None
print()
if amoeba:
......@@ -54,7 +55,20 @@ def runOneTest(testName, options):
dt = 0.002*unit.picoseconds
integ = mm.MTSIntegrator(dt, [(0,2), (1,1)])
else:
if explicit:
if apoa1:
ff = app.ForceField('amber14/protein.ff14SB.xml', 'amber14/lipid17.xml', 'amber14/tip3p.xml')
pdb = app.PDBFile('apoa1.pdb')
if testName == 'apoa1pme':
method = app.PME
cutoff = options.cutoff
elif testName == 'apoa1ljpme':
method = app.LJPME
cutoff = options.cutoff
else:
method = app.CutoffPeriodic
cutoff = 1*unit.nanometers
friction = 1*(1/unit.picoseconds)
elif explicit:
ff = app.ForceField('amber99sb.xml', 'tip3p.xml')
pdb = app.PDBFile('5dfr_solv-cube_equil.pdb')
if testName == 'pme':
......@@ -116,7 +130,7 @@ def runOneTest(testName, options):
parser = OptionParser()
platformNames = [mm.Platform.getPlatform(i).getName() for i in range(mm.Platform.getNumPlatforms())]
parser.add_option('--platform', dest='platform', choices=platformNames, help='name of the platform to benchmark')
parser.add_option('--test', dest='test', choices=('gbsa', 'rf', 'pme', 'amoebagk', 'amoebapme'), help='the test to perform: gbsa, rf, pme, amoebagk, or amoebapme [default: all]')
parser.add_option('--test', dest='test', choices=('gbsa', 'rf', 'pme', 'apoa1rf', 'apoa1pme', 'apoa1ljpme', 'amoebagk', 'amoebapme'), help='the test to perform: gbsa, rf, pme, apoa1rf, apoa1pme, apoa1ljpme, amoebagk, or amoebapme [default: all]')
parser.add_option('--pme-cutoff', default='0.9', dest='cutoff', type='float', help='direct space cutoff for PME in nm [default: 0.9]')
parser.add_option('--seconds', default='60', dest='seconds', type='float', help='target simulation length in seconds [default: 60]')
parser.add_option('--polarization', default='mutual', dest='polarization', choices=('direct', 'extrapolated', 'mutual'), help='the polarization method for AMOEBA: direct, extrapolated, or mutual [default: mutual]')
......@@ -138,7 +152,7 @@ if options.platform in ('CUDA', 'OpenCL'):
# Run the simulations.
if options.test is None:
for test in ('gbsa', 'rf', 'pme', 'amoebagk', 'amoebapme'):
for test in ('gbsa', 'rf', 'pme', 'apoa1rf', 'apoa1pme', 'apoa1ljpme', 'amoebagk', 'amoebapme'):
try:
runOneTest(test, options)
except Exception as ex:
......
......@@ -4,7 +4,7 @@ from simtk.unit import *
from sys import stdout
pdb = PDBFile('input.pdb')
forcefield = ForceField('amber99sb.xml', 'tip3p.xml')
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(pdb.topology, system, integrator)
......
AsmJit - Complete x86/x64 JIT and Remote Assembler for C++
Copyright (c) 2008-2014, Petr Kobalicek <kobalicek.petr@gmail.com>
Copyright (c) 2008-2017, Petr Kobalicek
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
......
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_ARM_H
#define _ASMJIT_ARM_H
// [Dependencies]
#include "./base.h"
#include "./arm/armassembler.h"
#include "./arm/armbuilder.h"
#include "./arm/armcompiler.h"
#include "./arm/arminst.h"
#include "./arm/armoperand.h"
// [Guard]
#endif // _ASMJIT_ARM_H
......@@ -12,368 +12,36 @@
// [asmjit_mainpage]
// ============================================================================
//! @mainpage
//! \mainpage
//!
//! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++.
//!
//! AsmJit is a complete JIT and remote assembler for C++ language. It can
//! generate native code for x86 and x64 architectures having support for
//! a full instruction set, from legacy MMX to the newest AVX2. It has a
//! type-safe API that allows C++ compiler to do a semantic checks at
//! compile-time even before the assembled code is generated or run.
//!
//! AsmJit is not a virtual machine (VM). It doesn't have functionality to
//! implement VM out of the box; however, it can be be used as a JIT backend
//! for your own VM. The usage of AsmJit is not limited at all; it's suitable
//! for multimedia, VM backends or remote code generation.
//!
//! @section AsmJit_Concepts Code Generation Concepts
//!
//! AsmJit has two completely different code generation concepts. The difference
//! is in how the code is generated. The first concept, also referred as the low
//! level concept, is called 'Assembler' and it's the same as writing RAW
//! assembly by using physical registers directly. In this case AsmJit does only
//! instruction encoding, verification and relocation.
//!
//! The second concept, also referred as the high level concept, is called
//! 'Compiler'. Compiler lets you use virtually unlimited number of registers
//! (called variables) significantly simplifying the code generation process.
//! Compiler allocates these virtual registers to physical registers after the
//! code generation is done. This requires some extra effort - Compiler has to
//! generate information for each node (instruction, function declaration,
//! function call) in the code, perform a variable liveness analysis and
//! translate the code having variables into code having only registers.
//!
//! In addition, Compiler understands functions and function calling conventions.
//! It has been designed in a way that the code generated is always a function
//! having prototype like in a programming language. By having a function
//! prototype the Compiler is able to insert prolog and epilog to a function
//! being generated and it is able to call a function inside a generated one.
//!
//! There is no conclusion on which concept is better. Assembler brings full
//! control on how the code is generated, while Compiler makes the generation
//! more portable.
//!
//! @section AsmJit_Main_CodeGeneration Code Generation
//!
//! - \ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler.
//! - \ref asmjit_compiler "Compiler" - High level code generation.
//! - \ref asmjit_cpuinfo "Cpu Information" - Get information about host processor.
//! - \ref asmjit_logging "Logging" - Logging and error handling.
//! - \ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management.
//!
//! @section AsmJit_Main_HomePage AsmJit Homepage
//!
//! - https://github.com/kobalicek/asmjit
// ============================================================================
// [asmjit_base]
// ============================================================================
//! \defgroup asmjit_base AsmJit
//!
//! \brief AsmJit.
// ============================================================================
// [asmjit_base_general]
// ============================================================================
//! \defgroup asmjit_base_general AsmJit General API
//! \ingroup asmjit_base
//!
//! \brief AsmJit general API.
//!
//! Contains all `asmjit` classes and helper functions that are architecture
//! independent or abstract. Abstract classes are implemented by the backend,
//! for example `Assembler` is implemented by `X86Assembler`.
//!
//! - See `Assembler` for low level code generation documentation.
//! - See `Compiler` for high level code generation documentation.
//! - See `Operand` for operand's overview.
//!
//! Logging and Error Handling
//! --------------------------
//!
//! AsmJit contains robust interface that can be used to log the generated code
//! and to handle possible errors. Base logging interface is defined in `Logger`
//! class that is abstract and can be overridden. AsmJit contains two loggers
//! that can be used out of the box - `FileLogger` that logs into a pure C
//! `FILE*` stream and `StringLogger` that just concatenates all log messages
//! by using a `StringBuilder` class.
//!
//! The following snippet shows how to setup a logger that logs to `stderr`:
//!
//! ~~~
//! // `FileLogger` instance.
//! FileLogger logger(stderr);
//!
//! // `Compiler` or any other `CodeGen` interface.
//! host::Compiler c;
//!
//! // use `setLogger` to replace the `CodeGen` logger.
//! c.setLogger(&logger);
//! ~~~
//!
//! \sa \ref Logger, \ref FileLogger, \ref StringLogger.
//! Introduction provided by the project page at https://github.com/asmjit/asmjit.
// ============================================================================
// [asmjit_base_compiler]
// ============================================================================
//! \defgroup asmjit_base_compiler AsmJit Compiler
//! \ingroup asmjit_base
//!
//! \brief AsmJit code-tree used by Compiler.
//! \defgroup asmjit_base AsmJit Base API (architecture independent)
//!
//! AsmJit intermediate code-tree is a double-linked list that is made of nodes
//! that represent assembler instructions, directives, labels and high-level
//! constructs compiler is using to represent functions and function calls. The
//! node list can only be used together with \ref Compiler.
//!
//! TODO
// ============================================================================
// [asmjit_base_util]
// ============================================================================
//! \brief Backend Neutral API.
//! \defgroup asmjit_base_util AsmJit Utilities
//! \ingroup asmjit_base
//!
//! \brief AsmJit utility classes.
//!
//! AsmJit contains numerous utility classes that are needed by the library
//! itself. The most useful ones have been made public and are now exported.
//! \defgroup asmjit_x86 AsmJit X86/X64 API
//!
//! POD Containers
//! --------------
//!
//! POD containers are used by AsmJit to manage its own data structures. The
//! following classes can be used by AsmJit consumers:
//!
//! - \ref PodVector - Simple growing array-like container for POD data.
//! - \ref StringBuilder - Simple string builder that can append string
//! and integers.
//!
//! Zone Memory Allocator
//! ---------------------
//!
//! Zone memory allocator is an incremental memory allocator that can be used
//! to allocate data of short life-time. It has much better performance
//! characteristics than all other allocators, because the only thing it can do
//! is to increment a pointer and return its previous address. See \ref Zone
//! for more details.
//!
//! CPU Ticks
//! ---------
//!
//! CPU Ticks is a simple helper that can be used to do basic benchmarks. See
//! \ref CpuTicks class for more details.
//!
//! Integer Utilities
//! -----------------
//!
//! Integer utilities are all implemented by a static class \ref IntUtil.
//! There are utilities for bit manipulation and bit counting, utilities to get
//! an integer minimum / maximum and various other helpers required to perform
//! alignment checks and binary casting from float to integer and vica versa.
//!
//! Vector Utilities
//! ----------------
//!
//! SIMD code generation often requires to embed constants after each function
//! or a block of functions generated. AsmJit contains classes `Vec64`,
//! `Vec128` and `Vec256` that can be used to prepare data useful when
//! generating SIMD code.
//!
//! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm`
//! which can be used to embed 64-bit, 128-bit and 256-bit data structures into
//! machine code (both assembler and compiler are supported).
//!
//! \note Compiler contains a constant pool, which should be used instead of
//! embedding constants manually after the function body.
// ============================================================================
// [asmjit_x86]
// ============================================================================
//! \defgroup asmjit_x86 X86/X64
//!
//! \brief X86/X64 module
// ============================================================================
// [asmjit_x86_general]
// ============================================================================
//! \defgroup asmjit_x86_general X86/X64 General API
//! \ingroup asmjit_x86
//!
//! \brief X86/X64 general API.
//!
//! X86/X64 Registers
//! -----------------
//!
//! There are static objects that represents X86 and X64 registers. They can
//! be used directly (like `eax`, `mm`, `xmm`, ...) or created through
//! these functions:
//!
//! - `asmjit::gpb_lo()` - Get Gpb-lo register.
//! - `asmjit::gpb_hi()` - Get Gpb-hi register.
//! - `asmjit::gpw()` - Get Gpw register.
//! - `asmjit::gpd()` - Get Gpd register.
//! - `asmjit::gpq()` - Get Gpq Gp register.
//! - `asmjit::gpz()` - Get Gpd/Gpq register.
//! - `asmjit::fp()` - Get Fp register.
//! - `asmjit::mm()` - Get Mm register.
//! - `asmjit::xmm()` - Get Xmm register.
//! - `asmjit::ymm()` - Get Ymm register.
//!
//! X86/X64 Addressing
//! ------------------
//!
//! X86 and x64 architectures contains several addressing modes and most ones
//! are possible with AsmJit library. Memory represents are represented by
//! `BaseMem` class. These functions are used to make operands that represents
//! memory addresses:
//!
//! - `asmjit::ptr()` - Address size not specified.
//! - `asmjit::byte_ptr()` - 1 byte.
//! - `asmjit::word_ptr()` - 2 bytes (Gpw size).
//! - `asmjit::dword_ptr()` - 4 bytes (Gpd size).
//! - `asmjit::qword_ptr()` - 8 bytes (Gpq/Mm size).
//! - `asmjit::tword_ptr()` - 10 bytes (FPU).
//! - `asmjit::oword_ptr()` - 16 bytes (Xmm size).
//! - `asmjit::yword_ptr()` - 32 bytes (Ymm size).
//! - `asmjit::zword_ptr()` - 64 bytes (Zmm size).
//!
//! Most useful function to make pointer should be `asmjit::ptr()`. It creates
//! pointer to the target with unspecified size. Unspecified size works in all
//! intrinsics where are used registers (this means that size is specified by
//! register operand or by instruction itself). For example `asmjit::ptr()`
//! can't be used with `Assembler::inc()` instruction. In this case size must
//! be specified and it's also reason to make difference between pointer sizes.
//!
//! Supported are simple address forms `[base + displacement]` and complex
//! address forms `[base + index * scale + displacement]`.
//!
//! X86/X64 Immediates
//! ------------------
//!
//! Immediate values are constants thats passed directly after instruction
//! opcode. To create such value use `imm()` or `imm_u()` methods to create
//! signed or unsigned immediate value.
//!
//! X86/X64 CPU Information
//! -----------------------
//!
//! The CPUID instruction can be used to get an exhaustive information about
//! the host X86/X64 processor. AsmJit contains utilities that can get the most
//! important information related to the features supported by the CPU and the
//! host operating system, in addition to host processor name and number of
//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality
//! specific to X86 and X64.
//!
//! By default AsmJit queries the CPU information after the library is loaded
//! and the queried information is reused by all instances of `JitRuntime`.
//! The global instance of `X86CpuInfo` can't be changed, because it will affect
//! the code generation of all `Runtime`s. If there is a need to have a
//! specific CPU information which contains modified features or processor
//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting
//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into
//! an existing `X86CpuInfo` instance - it may become handly if only one property
//! has to be turned on/off.
//!
//! If the high-level interface `X86CpuInfo` offers is not enough there is also
//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction
//! with a given parameters and to consume the output.
//!
//! Cpu detection is important when generating a JIT code that may or may not
//! use certain CPU features. For example there used to be a SSE/SSE2 detection
//! in the past and today there is often AVX/AVX2 detection.
//!
//! The example below shows how to detect SSE2:
//!
//! ~~~
//! using namespace asmjit;
//!
//! // Get `X86CpuInfo` global instance.
//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost();
//!
//! if (cpuInfo->hasFeature(kX86CpuFeatureSSE2)) {
//! // Processor has SSE2.
//! }
//! else if (cpuInfo->hasFeature(kX86CpuFeatureMMX)) {
//! // Processor doesn't have SSE2, but has MMX.
//! }
//! else {
//! // Processor is archaic; it's a wonder AsmJit works here!
//! }
//! ~~~
//!
//! The next example shows how to call `CPUID` directly:
//!
//! ~~~
//! using namespace asmjit;
//!
//! // Call cpuid, first two arguments are passed in Eax/Ecx.
//! X86CpuId out;
//! X86CpuUtil::callCpuId(0, 0, &out);
//!
//! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor.
//! char cpuVendor[13];
//! ::memcpy(cpuVendor, &out.ebx, 4);
//! ::memcpy(cpuVendor + 4, &out.edx, 4);
//! ::memcpy(cpuVendor + 8, &out.ecx, 4);
//! vendor[12] = '\0';
//!
//! // Print a CPU vendor retrieved from CPUID.
//! ::printf("%s", cpuVendor);
//! ~~~
// ============================================================================
// [asmjit_x86_compiler]
// ============================================================================
//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree
//! \ingroup asmjit_x86
//!
//! \brief X86/X64 code-tree and helpers.
// ============================================================================
// [asmjit_x86_inst]
// ============================================================================
//! \defgroup asmjit_x86_inst X86/X64 Instructions
//! \ingroup asmjit_x86
//!
//! \brief X86/X64 low-level instruction definitions.
// ============================================================================
// [asmjit_x86_util]
// ============================================================================
//! \defgroup asmjit_x86_util X86/X64 Utilities
//! \ingroup asmjit_x86
//!
//! \brief X86/X64 utility classes.
// ============================================================================
// [asmjit_contrib]
// ============================================================================
//! \brief X86/X64 Backend API.
//! \defgroup asmjit_contrib Contributions
//! \defgroup asmjit_arm AsmJit ARM32/ARM64 API
//!
//! \brief Contributions.
//! \brief ARM32/ARM64 Backend API.
// [Dependencies - Base]
#include "base.h"
// [Dependencies]
#include "./base.h"
// [Dependencies - X86/X64]
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
#include "x86.h"
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
// [X86/X64]
#if defined(ASMJIT_BUILD_X86)
#include "./x86.h"
#endif // ASMJIT_BUILD_X86
// [Dependencies - Host]
#include "host.h"
// [ARM32/ARM64]
#if defined(ASMJIT_BUILD_ARM)
#include "./arm.h"
#endif // ASMJIT_BUILD_ARM
// [Guard]
#endif // _ASMJIT_ASMJIT_H
......@@ -4,56 +4,74 @@
// [License]
// Zlib - See LICENSE.md file in the package.
// [Dependencies - AsmJit]
// [Dependencies]
#if !defined(_ASMJIT_BUILD_H)
#include "build.h"
# include "./build.h"
#endif // !_ASMJIT_BUILD_H
// [Guard]
#if !defined(ASMJIT_API_SCOPE)
# define ASMJIT_API_SCOPE
#else
# error "AsmJit - Api-Scope is already active, previous scope not closed by apiend.h?"
# error "[asmjit] api-scope is already active, previous scope not closed by asmjit_apiend.h?"
#endif // ASMJIT_API_SCOPE
// ============================================================================
// [Override]
// [C++ Support]
// ============================================================================
#if !defined(ASMJIT_CC_HAS_OVERRIDE) && !defined(override)
// [NoExcept]
#if !ASMJIT_CC_HAS_NOEXCEPT && !defined(noexcept)
# define noexcept ASMJIT_NOEXCEPT
# define ASMJIT_UNDEF_NOEXCEPT
#endif // !ASMJIT_CC_HAS_NOEXCEPT && !noexcept
// [NullPtr]
#if !ASMJIT_CC_HAS_NULLPTR && !defined(nullptr)
# define nullptr NULL
# define ASMJIT_UNDEF_NULLPTR
#endif // !ASMJIT_CC_HAS_NULLPTR && !nullptr
// [Override]
#if !ASMJIT_CC_HAS_OVERRIDE && !defined(override)
# define override
# define ASMJIT_UNDEF_OVERRIDE
#endif // !ASMJIT_CC_HAS_OVERRIDE && !override
// ============================================================================
// [NoExcept]
// [Compiler Support]
// ============================================================================
#if !defined(ASMJIT_CC_HAS_NOEXCEPT) && !defined(noexcept)
# define noexcept ASMJIT_NOEXCEPT
# define ASMJIT_UNDEF_NOEXCEPT
#endif // !ASMJIT_CC_HAS_NOEXCEPT && !noexcept
// [Clang]
#if ASMJIT_CC_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wc++11-extensions"
# pragma clang diagnostic ignored "-Wconstant-logical-operand"
# pragma clang diagnostic ignored "-Wunnamed-type-template-args"
#endif // ASMJIT_CC_CLANG
// ============================================================================
// [MSC]
// ============================================================================
// [GCC]
#if ASMJIT_CC_GCC
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wbool-operation"
# if ASMJIT_CC_GCC_GE(8, 0, 0)
# pragma GCC diagnostic ignored "-Wclass-memaccess"
# endif
#endif // ASMJIT_CC_GCC
#if defined(_MSC_VER)
// Disable some warnings we know about
// [MSC]
#if ASMJIT_CC_MSC
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4201) // nameless struct/union
# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible
// loss of data
# pragma warning(disable: 4251) // struct needs to have dll-interface to be used
// by clients of struct ...
# pragma warning(disable: 4275) // non dll-interface struct ... used as base for
// dll-interface struct
# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible loss of data
# pragma warning(disable: 4251) // struct needs to have dll-interface to be used by clients of struct ...
# pragma warning(disable: 4275) // non dll-interface struct ... used as base for dll-interface struct
# pragma warning(disable: 4355) // this used in base member initializer list
# pragma warning(disable: 4480) // specifying underlying type for enum
# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
// Rename symbols.
# pragma warning(disable: 4838) // comversion from 'int' to ...
# if _MSC_VER < 1900
# if !defined(vsnprintf)
# define ASMJIT_UNDEF_VSNPRINTF
# define vsnprintf _vsnprintf
......@@ -62,23 +80,43 @@
# define ASMJIT_UNDEF_SNPRINTF
# define snprintf _snprintf
# endif // !snprintf
#endif // _MSC_VER
# endif
#endif // ASMJIT_CC_MSC
// ============================================================================
// [CLang]
// [Custom Macros]
// ============================================================================
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunnamed-type-template-args"
#endif // __clang__
// ============================================================================
// [GCC]
// ============================================================================
// [ASMJIT_NON...]
#if ASMJIT_CC_HAS_DELETE_FUNCTION
#define ASMJIT_NONCONSTRUCTIBLE(...) \
private: \
__VA_ARGS__() = delete; \
__VA_ARGS__(const __VA_ARGS__& other) = delete; \
__VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \
public:
#define ASMJIT_NONCOPYABLE(...) \
private: \
__VA_ARGS__(const __VA_ARGS__& other) = delete; \
__VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \
public:
#else
#define ASMJIT_NONCONSTRUCTIBLE(...) \
private: \
inline __VA_ARGS__(); \
inline __VA_ARGS__(const __VA_ARGS__& other); \
inline __VA_ARGS__& operator=(const __VA_ARGS__& other); \
public:
#define ASMJIT_NONCOPYABLE(...) \
private: \
inline __VA_ARGS__(const __VA_ARGS__& other); \
inline __VA_ARGS__& operator=(const __VA_ARGS__& other); \
public:
#endif // ASMJIT_CC_HAS_DELETE_FUNCTION
#if defined(__GNUC__) && !defined(__clang__)
# if __GNUC__ >= 4 && !defined(__MINGW32__)
# pragma GCC visibility push(hidden)
# endif // GCC 4+
#endif // __GNUC__
// [ASMJIT_ENUM]
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define ASMJIT_ENUM(NAME) enum NAME : uint32_t
#else
# define ASMJIT_ENUM(NAME) enum NAME
#endif
......@@ -8,60 +8,67 @@
#if defined(ASMJIT_API_SCOPE)
# undef ASMJIT_API_SCOPE
#else
# error "AsmJit - Api-Scope not active, forgot to include apibegin.h?"
# error "[asmjit] api-scope not active, forgot to include asmjit_apibegin.h?"
#endif // ASMJIT_API_SCOPE
// ============================================================================
// [Override]
// [C++ Support]
// ============================================================================
// [NoExcept]
#if defined(ASMJIT_UNDEF_NOEXCEPT)
# undef noexcept
# undef ASMJIT_UNDEF_NOEXCEPT
#endif // ASMJIT_UNDEF_NOEXCEPT
// [NullPtr]
#if defined(ASMJIT_UNDEF_NULLPTR)
# undef nullptr
# undef ASMJIT_UNDEF_NULLPTR
#endif // ASMJIT_UNDEF_NULLPTR
// [Override]
#if defined(ASMJIT_UNDEF_OVERRIDE)
# undef override
# undef ASMJIT_UNDEF_OVERRIDE
#endif // ASMJIT_UNDEF_OVERRIDE
// ============================================================================
// [NoExcept]
// [Compiler Support]
// ============================================================================
#if defined(ASMJIT_UNDEF_NOEXCEPT)
# undef noexcept
# undef ASMJIT_UNDEF_NOEXCEPT
#endif // ASMJIT_UNDEF_NOEXCEPT
// [Clang]
#if ASMJIT_CC_CLANG
# pragma clang diagnostic pop
#endif // ASMJIT_CC_CLANG
// ============================================================================
// [MSC]
// ============================================================================
// [GCC]
#if ASMJIT_CC_GCC
# pragma GCC diagnostic pop
#endif // ASMJIT_CC_GCC
#if defined(_MSC_VER)
// [MSC]
#if ASMJIT_CC_MSC
# pragma warning(pop)
# if _MSC_VER < 1900
# if defined(ASMJIT_UNDEF_VSNPRINTF)
# undef vsnprintf
# undef ASMJIT_UNDEF_VSNPRINTF
# endif // ASMJIT_UNDEF_VSNPRINTF
# if defined(ASMJIT_UNDEF_SNPRINTF)
# undef snprintf
# undef ASMJIT_UNDEF_SNPRINTF
# endif // ASMJIT_UNDEF_SNPRINTF
#endif // _MSC_VER
# endif
#endif // ASMJIT_CC_MSC
// ============================================================================
// [CLang]
// [Custom Macros]
// ============================================================================
#if defined(__clang__)
# pragma clang diagnostic pop
#endif // __clang__
// ============================================================================
// [GCC]
// ============================================================================
// [ASMJIT_NON...]
#undef ASMJIT_NONCONSTRUCTIBLE
#undef ASMJIT_NONCOPYABLE
#if defined(__GNUC__) && !defined(__clang__)
# if __GNUC__ >= 4 && !defined(__MINGW32__)
# pragma GCC visibility pop
# endif // GCC 4+
#endif // __GNUC__
// [ASMJIT_ENUM]
#undef ASMJIT_ENUM
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_BUILD_H
#define _ASMJIT_BUILD_H
// ============================================================================
// [asmjit::Build - Configuration]
// ============================================================================
// AsmJit is by default compiled only for a host processor for the purpose of
// JIT code generation. Both Assembler and CodeCompiler emitters are compiled
// by default. Preprocessor macros can be used to change the default behavior.
// External Config File
// --------------------
//
// Define in case your configuration is generated in an external file to be
// included.
#if defined(ASMJIT_CONFIG_FILE)
# include ASMJIT_CONFIG_FILE
#endif // ASMJIT_CONFIG_FILE
// AsmJit Static Builds and Embedding
// ----------------------------------
//
// These definitions can be used to enable static library build. Embed is used
// when AsmJit's source code is embedded directly in another project, implies
// static build as well.
//
// #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC).
// #define ASMJIT_STATIC // Define to enable static-library build.
// AsmJit Build Modes
// ------------------
//
// These definitions control the build mode and tracing support. The build mode
// should be auto-detected at compile time, but it's possible to override it in
// case that the auto-detection fails.
//
// Tracing is a feature that is never compiled by default and it's only used to
// debug AsmJit itself.
//
// #define ASMJIT_DEBUG // Define to enable debug-mode.
// #define ASMJIT_RELEASE // Define to enable release-mode.
// AsmJit Build Backends
// ---------------------
//
// These definitions control which backends to compile. If none of these is
// defined AsmJit will use host architecture by default (for JIT code generation).
//
// #define ASMJIT_BUILD_X86 // Define to enable X86 and X64 code-generation.
// #define ASMJIT_BUILD_ARM // Define to enable ARM32 and ARM64 code-generation.
// #define ASMJIT_BUILD_HOST // Define to enable host instruction set.
// AsmJit Build Features
// ---------------------
//
// Flags can be defined to disable standard features. These are handy especially
// when building AsmJit statically and some features are not needed or unwanted
// (like CodeCompiler).
//
// AsmJit features are enabled by default.
// #define ASMJIT_DISABLE_COMPILER // Disable CodeCompiler (completely).
// #define ASMJIT_DISABLE_LOGGING // Disable logging and formatting (completely).
// #define ASMJIT_DISABLE_TEXT // Disable everything that contains text
// // representation (instructions, errors, ...).
// #define ASMJIT_DISABLE_VALIDATION // Disable Validation (completely).
// Prevent compile-time errors caused by misconfiguration.
#if defined(ASMJIT_DISABLE_TEXT) && !defined(ASMJIT_DISABLE_LOGGING)
# error "[asmjit] ASMJIT_DISABLE_TEXT requires ASMJIT_DISABLE_LOGGING to be defined."
#endif // ASMJIT_DISABLE_TEXT && !ASMJIT_DISABLE_LOGGING
// Detect ASMJIT_DEBUG and ASMJIT_RELEASE if not forced from outside.
#if !defined(ASMJIT_DEBUG) && !defined(ASMJIT_RELEASE)
# if !defined(NDEBUG)
# define ASMJIT_DEBUG
# else
# define ASMJIT_RELEASE
# endif
#endif
// ASMJIT_EMBED implies ASMJIT_STATIC.
#if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC)
# define ASMJIT_STATIC
#endif
// ============================================================================
// [asmjit::Build - VERSION]
// ============================================================================
// [@VERSION{@]
#define ASMJIT_VERSION_MAJOR 1
#define ASMJIT_VERSION_MINOR 0
#define ASMJIT_VERSION_PATCH 0
#define ASMJIT_VERSION_STRING "1.0.0"
// [@VERSION}@]
// ============================================================================
// [asmjit::Build - WIN32]
// ============================================================================
// [@WIN32_CRT_NO_DEPRECATE{@]
#if defined(_MSC_VER) && defined(ASMJIT_EXPORTS)
# if !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
# endif
# if !defined(_CRT_SECURE_NO_WARNINGS)
# define _CRT_SECURE_NO_WARNINGS
# endif
#endif
// [@WIN32_CRT_NO_DEPRECATE}@]
// [@WIN32_LEAN_AND_MEAN{@]
#if (defined(_WIN32) || defined(_WINDOWS)) && !defined(_WINDOWS_)
# if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# define ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
# endif
# if !defined(NOMINMAX)
# define NOMINMAX
# define ASMJIT_UNDEF_NOMINMAX
# endif
# include <windows.h>
# if defined(ASMJIT_UNDEF_NOMINMAX)
# undef NOMINMAX
# undef ASMJIT_UNDEF_NOMINMAX
# endif
# if defined(ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN)
# undef WIN32_LEAN_AND_MEAN
# undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
# endif
#endif
// [@WIN32_LEAN_AND_MEAN}@]
// ============================================================================
// [asmjit::Build - OS]
// ============================================================================
// [@OS{@]
#if defined(_WIN32) || defined(_WINDOWS)
#define ASMJIT_OS_WINDOWS (1)
#else
#define ASMJIT_OS_WINDOWS (0)
#endif
#if defined(__APPLE__)
# include <TargetConditionals.h>
# define ASMJIT_OS_MAC (TARGET_OS_MAC)
# define ASMJIT_OS_IOS (TARGET_OS_IPHONE)
#else
# define ASMJIT_OS_MAC (0)
# define ASMJIT_OS_IOS (0)
#endif
#if defined(__ANDROID__)
# define ASMJIT_OS_ANDROID (1)
#else
# define ASMJIT_OS_ANDROID (0)
#endif
#if defined(__linux__) || defined(__ANDROID__)
# define ASMJIT_OS_LINUX (1)
#else
# define ASMJIT_OS_LINUX (0)
#endif
#if defined(__DragonFly__)
# define ASMJIT_OS_DRAGONFLYBSD (1)
#else
# define ASMJIT_OS_DRAGONFLYBSD (0)
#endif
#if defined(__FreeBSD__)
# define ASMJIT_OS_FREEBSD (1)
#else
# define ASMJIT_OS_FREEBSD (0)
#endif
#if defined(__NetBSD__)
# define ASMJIT_OS_NETBSD (1)
#else
# define ASMJIT_OS_NETBSD (0)
#endif
#if defined(__OpenBSD__)
# define ASMJIT_OS_OPENBSD (1)
#else
# define ASMJIT_OS_OPENBSD (0)
#endif
#if defined(__QNXNTO__)
# define ASMJIT_OS_QNX (1)
#else
# define ASMJIT_OS_QNX (0)
#endif
#if defined(__sun)
# define ASMJIT_OS_SOLARIS (1)
#else
# define ASMJIT_OS_SOLARIS (0)
#endif
#if defined(__CYGWIN__)
# define ASMJIT_OS_CYGWIN (1)
#else
# define ASMJIT_OS_CYGWIN (0)
#endif
#define ASMJIT_OS_BSD ( \
ASMJIT_OS_FREEBSD || \
ASMJIT_OS_DRAGONFLYBSD || \
ASMJIT_OS_NETBSD || \
ASMJIT_OS_OPENBSD || \
ASMJIT_OS_MAC)
#define ASMJIT_OS_POSIX (!ASMJIT_OS_WINDOWS)
// [@OS}@]
// ============================================================================
// [asmjit::Build - ARCH]
// ============================================================================
// [@ARCH{@]
// \def ASMJIT_ARCH_ARM32
// True if the target architecture is a 32-bit ARM.
//
// \def ASMJIT_ARCH_ARM64
// True if the target architecture is a 64-bit ARM.
//
// \def ASMJIT_ARCH_X86
// True if the target architecture is a 32-bit X86/IA32
//
// \def ASMJIT_ARCH_X64
// True if the target architecture is a 64-bit X64/AMD64
//
// \def ASMJIT_ARCH_LE
// True if the target architecture is little endian.
//
// \def ASMJIT_ARCH_BE
// True if the target architecture is big endian.
//
// \def ASMJIT_ARCH_64BIT
// True if the target architecture is 64-bit.
#if (defined(_M_X64 ) || defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(__amd64 ) || defined(__amd64__ ))
# define ASMJIT_ARCH_X64 1
#else
# define ASMJIT_ARCH_X64 0
#endif
#if (defined(_M_IX86 ) || defined(__X86__ ) || defined(__i386 ) || \
defined(__IA32__) || defined(__I86__ ) || defined(__i386__) || \
defined(__i486__) || defined(__i586__) || defined(__i686__))
# define ASMJIT_ARCH_X86 (!ASMJIT_ARCH_X64)
#else
# define ASMJIT_ARCH_X86 0
#endif
#if defined(__aarch64__)
# define ASMJIT_ARCH_ARM64 1
#else
# define ASMJIT_ARCH_ARM64 0
#endif
#if (defined(_M_ARM ) || defined(__arm ) || defined(__thumb__ ) || \
defined(_M_ARMT ) || defined(__arm__ ) || defined(__thumb2__))
# define ASMJIT_ARCH_ARM32 (!ASMJIT_ARCH_ARM64)
#else
# define ASMJIT_ARCH_ARM32 0
#endif
#define ASMJIT_ARCH_LE ( \
ASMJIT_ARCH_X86 || \
ASMJIT_ARCH_X64 || \
ASMJIT_ARCH_ARM32 || \
ASMJIT_ARCH_ARM64 )
#define ASMJIT_ARCH_BE (!(ASMJIT_ARCH_LE))
#define ASMJIT_ARCH_64BIT (ASMJIT_ARCH_X64 || ASMJIT_ARCH_ARM64)
// [@ARCH}@]
// [@ARCH_UNALIGNED_RW{@]
// \def ASMJIT_ARCH_UNALIGNED_16
// True if the target architecture allows unaligned 16-bit reads and writes.
//
// \def ASMJIT_ARCH_UNALIGNED_32
// True if the target architecture allows unaligned 32-bit reads and writes.
//
// \def ASMJIT_ARCH_UNALIGNED_64
// True if the target architecture allows unaligned 64-bit reads and writes.
#define ASMJIT_ARCH_UNALIGNED_16 (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64)
#define ASMJIT_ARCH_UNALIGNED_32 (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64)
#define ASMJIT_ARCH_UNALIGNED_64 (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64)
// [@ARCH_UNALIGNED_RW}@]
// ============================================================================
// [asmjit::Build - CC]
// ============================================================================
// [@CC{@]
// \def ASMJIT_CC_CLANG
// Non-zero if the detected C++ compiler is CLANG (contains normalized CLANG version).
//
// \def ASMJIT_CC_CODEGEAR
// Non-zero if the detected C++ compiler is CODEGEAR or BORLAND (version not normalized).
//
// \def ASMJIT_CC_INTEL
// Non-zero if the detected C++ compiler is INTEL (version not normalized).
//
// \def ASMJIT_CC_GCC
// Non-zero if the detected C++ compiler is GCC (contains normalized GCC version).
//
// \def ASMJIT_CC_MSC
// Non-zero if the detected C++ compiler is MSC (contains normalized MSC version).
//
// \def ASMJIT_CC_MINGW
// Non-zero if the detected C++ compiler is MINGW32 (set to 32) or MINGW64 (set to 64).
#define ASMJIT_CC_CLANG 0
#define ASMJIT_CC_CODEGEAR 0
#define ASMJIT_CC_GCC 0
#define ASMJIT_CC_INTEL 0
#define ASMJIT_CC_MSC 0
// Intel masquerades as GCC, so check for it first.
#if defined(__INTEL_COMPILER)
# undef ASMJIT_CC_INTEL
# define ASMJIT_CC_INTEL __INTEL_COMPILER
#elif defined(__CODEGEARC__)
# undef ASMJIT_CC_CODEGEAR
# define ASMJIT_CC_CODEGEAR (__CODEGEARC__)
#elif defined(__BORLANDC__)
# undef ASMJIT_CC_CODEGEAR
# define ASMJIT_CC_CODEGEAR (__BORLANDC__)
#elif defined(__clang__) && defined(__clang_minor__)
# undef ASMJIT_CC_CLANG
# define ASMJIT_CC_CLANG (__clang_major__ * 10000000 + __clang_minor__ * 100000 + __clang_patchlevel__)
#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# undef ASMJIT_CC_GCC
# define ASMJIT_CC_GCC (__GNUC__ * 10000000 + __GNUC_MINOR__ * 100000 + __GNUC_PATCHLEVEL__)
#elif defined(_MSC_VER) && defined(_MSC_FULL_VER)
# undef ASMJIT_CC_MSC
# if _MSC_VER == _MSC_FULL_VER / 10000
# define ASMJIT_CC_MSC (_MSC_VER * 100000 + (_MSC_FULL_VER % 10000))
# else
# define ASMJIT_CC_MSC (_MSC_VER * 100000 + (_MSC_FULL_VER % 100000))
# endif
#else
# error "[asmjit] Unable to detect the C/C++ compiler."
#endif
#if ASMJIT_CC_INTEL && (defined(__GNUC__) || defined(__clang__))
# define ASMJIT_CC_INTEL_COMPAT_MODE 1
# else
# define ASMJIT_CC_INTEL_COMPAT_MODE 0
#endif
#define ASMJIT_CC_CODEGEAR_EQ(x, y) (ASMJIT_CC_CODEGEAR == (((x) << 8) + (y)))
#define ASMJIT_CC_CODEGEAR_GE(x, y) (ASMJIT_CC_CODEGEAR >= (((x) << 8) + (y)))
#define ASMJIT_CC_CLANG_EQ(x, y, z) (ASMJIT_CC_CLANG == ((x) * 10000000 + (y) * 100000 + (z)))
#define ASMJIT_CC_CLANG_GE(x, y, z) (ASMJIT_CC_CLANG >= ((x) * 10000000 + (y) * 100000 + (z)))
#define ASMJIT_CC_GCC_EQ(x, y, z) (ASMJIT_CC_GCC == ((x) * 10000000 + (y) * 100000 + (z)))
#define ASMJIT_CC_GCC_GE(x, y, z) (ASMJIT_CC_GCC >= ((x) * 10000000 + (y) * 100000 + (z)))
#define ASMJIT_CC_INTEL_EQ(x, y) (ASMJIT_CC_INTEL == (((x) * 100) + (y)))
#define ASMJIT_CC_INTEL_GE(x, y) (ASMJIT_CC_INTEL >= (((x) * 100) + (y)))
#define ASMJIT_CC_MSC_EQ(x, y, z) (ASMJIT_CC_MSC == ((x) * 10000000 + (y) * 100000 + (z)))
#define ASMJIT_CC_MSC_GE(x, y, z) (ASMJIT_CC_MSC >= ((x) * 10000000 + (y) * 100000 + (z)))
#if defined(__MINGW64__)
# define ASMJIT_CC_MINGW 64
#elif defined(__MINGW32__)
# define ASMJIT_CC_MINGW 32
#else
# define ASMJIT_CC_MINGW 0
#endif
#if defined(__cplusplus)
# if __cplusplus >= 201103L
# define ASMJIT_CC_CXX_VERSION __cplusplus
# elif defined(__GXX_EXPERIMENTAL_CXX0X__) || ASMJIT_CC_MSC_GE(18, 0, 0) || ASMJIT_CC_INTEL_GE(14, 0)
# define ASMJIT_CC_CXX_VERSION 201103L
# else
# define ASMJIT_CC_CXX_VERSION 199711L
# endif
#endif
#if !defined(ASMJIT_CC_CXX_VERSION)
# define ASMJIT_CC_CXX_VERSION 0
#endif
// [@CC}@]
// [@CC_FEATURES{@]
#if ASMJIT_CC_CLANG
# define ASMJIT_CC_HAS_ATTRIBUTE (1)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALIGNED (__has_attribute(__aligned__))
# define ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(__always_inline__))
# define ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE (__has_attribute(__noinline__))
# define ASMJIT_CC_HAS_ATTRIBUTE_NORETURN (__has_attribute(__noreturn__))
# define ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE (__has_attribute(__optimize__))
# define ASMJIT_CC_HAS_BUILTIN_ASSUME (__has_builtin(__builtin_assume))
# define ASMJIT_CC_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned))
# define ASMJIT_CC_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
# define ASMJIT_CC_HAS_BUILTIN_UNREACHABLE (__has_builtin(__builtin_unreachable))
# define ASMJIT_CC_HAS_ALIGNAS (__has_extension(__cxx_alignas__))
# define ASMJIT_CC_HAS_ALIGNOF (__has_extension(__cxx_alignof__))
# define ASMJIT_CC_HAS_CONSTEXPR (__has_extension(__cxx_constexpr__))
# define ASMJIT_CC_HAS_DECLTYPE (__has_extension(__cxx_decltype__))
# define ASMJIT_CC_HAS_DEFAULT_FUNCTION (__has_extension(__cxx_defaulted_functions__))
# define ASMJIT_CC_HAS_DELETE_FUNCTION (__has_extension(__cxx_deleted_functions__))
# define ASMJIT_CC_HAS_FINAL (__has_extension(__cxx_override_control__))
# define ASMJIT_CC_HAS_INITIALIZER_LIST (__has_extension(__cxx_generalized_initializers__))
# define ASMJIT_CC_HAS_LAMBDA (__has_extension(__cxx_lambdas__))
# define ASMJIT_CC_HAS_NATIVE_CHAR (1)
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (1)
# define ASMJIT_CC_HAS_NATIVE_CHAR16_T (__has_extension(__cxx_unicode_literals__))
# define ASMJIT_CC_HAS_NATIVE_CHAR32_T (__has_extension(__cxx_unicode_literals__))
# define ASMJIT_CC_HAS_NOEXCEPT (__has_extension(__cxx_noexcept__))
# define ASMJIT_CC_HAS_NULLPTR (__has_extension(__cxx_nullptr__))
# define ASMJIT_CC_HAS_OVERRIDE (__has_extension(__cxx_override_control__))
# define ASMJIT_CC_HAS_RVALUE (__has_extension(__cxx_rvalue_references__))
# define ASMJIT_CC_HAS_STATIC_ASSERT (__has_extension(__cxx_static_assert__))
# define ASMJIT_CC_HAS_VARIADIC_TEMPLATES (__has_extension(__cxx_variadic_templates__))
#endif
#if ASMJIT_CC_CODEGEAR
# define ASMJIT_CC_HAS_DECLSPEC_ALIGN (ASMJIT_CC_CODEGEAR >= 0x0610)
# define ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE (0)
# define ASMJIT_CC_HAS_DECLSPEC_NOINLINE (0)
# define ASMJIT_CC_HAS_DECLSPEC_NORETURN (ASMJIT_CC_CODEGEAR >= 0x0610)
# define ASMJIT_CC_HAS_ALIGNAS (0)
# define ASMJIT_CC_HAS_ALIGNOF (0)
# define ASMJIT_CC_HAS_CONSTEXPR (0)
# define ASMJIT_CC_HAS_DECLTYPE (ASMJIT_CC_CODEGEAR >= 0x0610)
# define ASMJIT_CC_HAS_DEFAULT_FUNCTION (0)
# define ASMJIT_CC_HAS_DELETE_FUNCTION (0)
# define ASMJIT_CC_HAS_FINAL (0)
# define ASMJIT_CC_HAS_INITIALIZER_LIST (0)
# define ASMJIT_CC_HAS_LAMBDA (0)
# define ASMJIT_CC_HAS_NATIVE_CHAR (1)
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (1)
# define ASMJIT_CC_HAS_NATIVE_CHAR16_T (0)
# define ASMJIT_CC_HAS_NATIVE_CHAR32_T (0)
# define ASMJIT_CC_HAS_NOEXCEPT (0)
# define ASMJIT_CC_HAS_NULLPTR (0)
# define ASMJIT_CC_HAS_OVERRIDE (0)
# define ASMJIT_CC_HAS_RVALUE (ASMJIT_CC_CODEGEAR >= 0x0610)
# define ASMJIT_CC_HAS_STATIC_ASSERT (ASMJIT_CC_CODEGEAR >= 0x0610)
# define ASMJIT_CC_HAS_VARIADIC_TEMPLATES (0)
#endif
#if ASMJIT_CC_GCC
# define ASMJIT_CC_HAS_ATTRIBUTE (1)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALIGNED (ASMJIT_CC_GCC_GE(2, 7, 0))
# define ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE (ASMJIT_CC_GCC_GE(4, 4, 0) && !ASMJIT_CC_MINGW)
# define ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE (ASMJIT_CC_GCC_GE(3, 4, 0) && !ASMJIT_CC_MINGW)
# define ASMJIT_CC_HAS_ATTRIBUTE_NORETURN (ASMJIT_CC_GCC_GE(2, 5, 0))
# define ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE (ASMJIT_CC_GCC_GE(4, 4, 0))
# define ASMJIT_CC_HAS_BUILTIN_ASSUME (0)
# define ASMJIT_CC_HAS_BUILTIN_ASSUME_ALIGNED (ASMJIT_CC_GCC_GE(4, 7, 0))
# define ASMJIT_CC_HAS_BUILTIN_EXPECT (1)
# define ASMJIT_CC_HAS_BUILTIN_UNREACHABLE (ASMJIT_CC_GCC_GE(4, 5, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_ALIGNAS (ASMJIT_CC_GCC_GE(4, 8, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_ALIGNOF (ASMJIT_CC_GCC_GE(4, 8, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_CONSTEXPR (ASMJIT_CC_GCC_GE(4, 6, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_DECLTYPE (ASMJIT_CC_GCC_GE(4, 3, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_DEFAULT_FUNCTION (ASMJIT_CC_GCC_GE(4, 4, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_DELETE_FUNCTION (ASMJIT_CC_GCC_GE(4, 4, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_FINAL (ASMJIT_CC_GCC_GE(4, 7, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_INITIALIZER_LIST (ASMJIT_CC_GCC_GE(4, 4, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_LAMBDA (ASMJIT_CC_GCC_GE(4, 5, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_NATIVE_CHAR (1)
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (1)
# define ASMJIT_CC_HAS_NATIVE_CHAR16_T (ASMJIT_CC_GCC_GE(4, 5, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_NATIVE_CHAR32_T (ASMJIT_CC_GCC_GE(4, 5, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_NOEXCEPT (ASMJIT_CC_GCC_GE(4, 6, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_NULLPTR (ASMJIT_CC_GCC_GE(4, 6, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_OVERRIDE (ASMJIT_CC_GCC_GE(4, 7, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_RVALUE (ASMJIT_CC_GCC_GE(4, 3, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_STATIC_ASSERT (ASMJIT_CC_GCC_GE(4, 3, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
# define ASMJIT_CC_HAS_VARIADIC_TEMPLATES (ASMJIT_CC_GCC_GE(4, 3, 0) && ASMJIT_CC_CXX_VERSION >= 201103L)
#endif
#if ASMJIT_CC_INTEL
# define ASMJIT_CC_HAS_ATTRIBUTE (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALIGNED (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_ATTRIBUTE_NORETURN (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_BUILTIN_EXPECT (ASMJIT_CC_INTEL_COMPAT_MODE)
# define ASMJIT_CC_HAS_DECLSPEC_ALIGN (ASMJIT_CC_INTEL_COMPAT_MODE == 0)
# define ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE (ASMJIT_CC_INTEL_COMPAT_MODE == 0)
# define ASMJIT_CC_HAS_DECLSPEC_NOINLINE (ASMJIT_CC_INTEL_COMPAT_MODE == 0)
# define ASMJIT_CC_HAS_DECLSPEC_NORETURN (ASMJIT_CC_INTEL_COMPAT_MODE == 0)
# define ASMJIT_CC_HAS_ASSUME (1)
# define ASMJIT_CC_HAS_ASSUME_ALIGNED (1)
# define ASMJIT_CC_HAS_ALIGNAS (ASMJIT_CC_INTEL >= 1500)
# define ASMJIT_CC_HAS_ALIGNOF (ASMJIT_CC_INTEL >= 1500)
# define ASMJIT_CC_HAS_CONSTEXPR (ASMJIT_CC_INTEL >= 1400)
# define ASMJIT_CC_HAS_DECLTYPE (ASMJIT_CC_INTEL >= 1200)
# define ASMJIT_CC_HAS_DEFAULT_FUNCTION (ASMJIT_CC_INTEL >= 1200)
# define ASMJIT_CC_HAS_DELETE_FUNCTION (ASMJIT_CC_INTEL >= 1200)
# define ASMJIT_CC_HAS_FINAL (ASMJIT_CC_INTEL >= 1400)
# define ASMJIT_CC_HAS_INITIALIZER_LIST (ASMJIT_CC_INTEL >= 1400)
# define ASMJIT_CC_HAS_LAMBDA (ASMJIT_CC_INTEL >= 1200)
# define ASMJIT_CC_HAS_NATIVE_CHAR (1)
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (1)
# define ASMJIT_CC_HAS_NATIVE_CHAR16_T (ASMJIT_CC_INTEL >= 1400 || (ASMJIT_CC_INTEL_COMPAT_MODE > 0 && ASMJIT_CC_INTEL >= 1206))
# define ASMJIT_CC_HAS_NATIVE_CHAR32_T (ASMJIT_CC_INTEL >= 1400 || (ASMJIT_CC_INTEL_COMPAT_MODE > 0 && ASMJIT_CC_INTEL >= 1206))
# define ASMJIT_CC_HAS_NOEXCEPT (ASMJIT_CC_INTEL >= 1400)
# define ASMJIT_CC_HAS_NULLPTR (ASMJIT_CC_INTEL >= 1206)
# define ASMJIT_CC_HAS_OVERRIDE (ASMJIT_CC_INTEL >= 1400)
# define ASMJIT_CC_HAS_RVALUE (ASMJIT_CC_INTEL >= 1110)
# define ASMJIT_CC_HAS_STATIC_ASSERT (ASMJIT_CC_INTEL >= 1110)
# define ASMJIT_CC_HAS_VARIADIC_TEMPLATES (ASMJIT_CC_INTEL >= 1206)
#endif
#if ASMJIT_CC_MSC
# define ASMJIT_CC_HAS_DECLSPEC_ALIGN (1)
# define ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE (1)
# define ASMJIT_CC_HAS_DECLSPEC_NOINLINE (1)
# define ASMJIT_CC_HAS_DECLSPEC_NORETURN (1)
# define ASMJIT_CC_HAS_ASSUME (1)
# define ASMJIT_CC_HAS_ASSUME_ALIGNED (0)
# define ASMJIT_CC_HAS_ALIGNAS (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_ALIGNOF (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_CONSTEXPR (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_DECLTYPE (ASMJIT_CC_MSC_GE(16, 0, 0))
# define ASMJIT_CC_HAS_DEFAULT_FUNCTION (ASMJIT_CC_MSC_GE(18, 0, 0))
# define ASMJIT_CC_HAS_DELETE_FUNCTION (ASMJIT_CC_MSC_GE(18, 0, 0))
# define ASMJIT_CC_HAS_FINAL (ASMJIT_CC_MSC_GE(14, 0, 0))
# define ASMJIT_CC_HAS_INITIALIZER_LIST (ASMJIT_CC_MSC_GE(18, 0, 0))
# define ASMJIT_CC_HAS_LAMBDA (ASMJIT_CC_MSC_GE(16, 0, 0))
# define ASMJIT_CC_HAS_NATIVE_CHAR (1)
# if defined(_NATIVE_WCHAR_T_DEFINED)
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (1)
# else
# define ASMJIT_CC_HAS_NATIVE_WCHAR_T (0)
# endif
# define ASMJIT_CC_HAS_NATIVE_CHAR16_T (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_NATIVE_CHAR32_T (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_NOEXCEPT (ASMJIT_CC_MSC_GE(19, 0, 0))
# define ASMJIT_CC_HAS_NULLPTR (ASMJIT_CC_MSC_GE(16, 0, 0))
# define ASMJIT_CC_HAS_OVERRIDE (ASMJIT_CC_MSC_GE(14, 0, 0))
# define ASMJIT_CC_HAS_RVALUE (ASMJIT_CC_MSC_GE(16, 0, 0))
# define ASMJIT_CC_HAS_STATIC_ASSERT (ASMJIT_CC_MSC_GE(16, 0, 0))
# define ASMJIT_CC_HAS_VARIADIC_TEMPLATES (ASMJIT_CC_MSC_GE(18, 0, 0))
#endif
// Fixup some vendor specific keywords.
#if !defined(ASMJIT_CC_HAS_ASSUME)
# define ASMJIT_CC_HAS_ASSUME (0)
#endif
#if !defined(ASMJIT_CC_HAS_ASSUME_ALIGNED)
# define ASMJIT_CC_HAS_ASSUME_ALIGNED (0)
#endif
// Fixup compilers that don't support '__attribute__'.
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE)
# define ASMJIT_CC_HAS_ATTRIBUTE (0)
#endif
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE_ALIGNED)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALIGNED (0)
#endif
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE)
# define ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE (0)
#endif
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE)
# define ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE (0)
#endif
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE_NORETURN)
# define ASMJIT_CC_HAS_ATTRIBUTE_NORETURN (0)
#endif
#if !defined(ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE)
# define ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE (0)
#endif
// Fixup compilers that don't support '__builtin?'.
#if !defined(ASMJIT_CC_HAS_BUILTIN_ASSUME)
# define ASMJIT_CC_HAS_BUILTIN_ASSUME (0)
#endif
#if !defined(ASMJIT_CC_HAS_BUILTIN_ASSUME_ALIGNED)
# define ASMJIT_CC_HAS_BUILTIN_ASSUME_ALIGNED (0)
#endif
#if !defined(ASMJIT_CC_HAS_BUILTIN_EXPECT)
# define ASMJIT_CC_HAS_BUILTIN_EXPECT (0)
#endif
#if !defined(ASMJIT_CC_HAS_BUILTIN_UNREACHABLE)
# define ASMJIT_CC_HAS_BUILTIN_UNREACHABLE (0)
#endif
// Fixup compilers that don't support 'declspec'.
#if !defined(ASMJIT_CC_HAS_DECLSPEC_ALIGN)
# define ASMJIT_CC_HAS_DECLSPEC_ALIGN (0)
#endif
#if !defined(ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE)
# define ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE (0)
#endif
#if !defined(ASMJIT_CC_HAS_DECLSPEC_NOINLINE)
# define ASMJIT_CC_HAS_DECLSPEC_NOINLINE (0)
#endif
#if !defined(ASMJIT_CC_HAS_DECLSPEC_NORETURN)
# define ASMJIT_CC_HAS_DECLSPEC_NORETURN (0)
#endif
// [@CC_FEATURES}@]
// [@CC_API{@]
// \def ASMJIT_API
// The decorated function is asmjit API and should be exported.
#if !defined(ASMJIT_API)
# if defined(ASMJIT_STATIC)
# define ASMJIT_API
# elif ASMJIT_OS_WINDOWS
# if (ASMJIT_CC_GCC || ASMJIT_CC_CLANG) && !ASMJIT_CC_MINGW
# if defined(ASMJIT_EXPORTS)
# define ASMJIT_API __attribute__((__dllexport__))
# else
# define ASMJIT_API __attribute__((__dllimport__))
# endif
# else
# if defined(ASMJIT_EXPORTS)
# define ASMJIT_API __declspec(dllexport)
# else
# define ASMJIT_API __declspec(dllimport)
# endif
# endif
# else
# if ASMJIT_CC_CLANG || ASMJIT_CC_GCC_GE(4, 0, 0) || ASMJIT_CC_INTEL
# define ASMJIT_API __attribute__((__visibility__("default")))
# endif
# endif
#endif
// [@CC_API}@]
// [@CC_VARAPI{@]
// \def ASMJIT_VARAPI
// The decorated variable is part of asmjit API and is exported.
#if !defined(ASMJIT_VARAPI)
# define ASMJIT_VARAPI extern ASMJIT_API
#endif
// [@CC_VARAPI}@]
// [@CC_VIRTAPI{@]
// \def ASMJIT_VIRTAPI
// The decorated class has a virtual table and is part of asmjit API.
//
// This is basically a workaround. When using MSVC and marking class as DLL
// export everything gets exported, which is unwanted in most projects. MSVC
// automatically exports typeinfo and vtable if at least one symbol of the
// class is exported. However, GCC has some strange behavior that even if
// one or more symbol is exported it doesn't export typeinfo unless the
// class itself is decorated with "visibility(default)" (i.e. asmjit_API).
#if (ASMJIT_CC_GCC || ASMJIT_CC_CLANG) && !ASMJIT_OS_WINDOWS
# define ASMJIT_VIRTAPI ASMJIT_API
#else
# define ASMJIT_VIRTAPI
#endif
// [@CC_VIRTAPI}@]
// [@CC_INLINE{@]
// \def ASMJIT_INLINE
// Always inline the decorated function.
#if ASMJIT_CC_HAS_ATTRIBUTE_ALWAYS_INLINE
# define ASMJIT_INLINE inline __attribute__((__always_inline__))
#elif ASMJIT_CC_HAS_DECLSPEC_FORCEINLINE
# define ASMJIT_INLINE __forceinline
#else
# define ASMJIT_INLINE inline
#endif
// [@CC_INLINE}@]
// [@CC_NOINLINE{@]
// \def ASMJIT_NOINLINE
// Never inline the decorated function.
#if ASMJIT_CC_HAS_ATTRIBUTE_NOINLINE
# define ASMJIT_NOINLINE __attribute__((__noinline__))
#elif ASMJIT_CC_HAS_DECLSPEC_NOINLINE
# define ASMJIT_NOINLINE __declspec(noinline)
#else
# define ASMJIT_NOINLINE
#endif
// [@CC_NOINLINE}@]
// [@CC_NORETURN{@]
// \def ASMJIT_NORETURN
// The decorated function never returns (exit, assertion failure, etc...).
#if ASMJIT_CC_HAS_ATTRIBUTE_NORETURN
# define ASMJIT_NORETURN __attribute__((__noreturn__))
#elif ASMJIT_CC_HAS_DECLSPEC_NORETURN
# define ASMJIT_NORETURN __declspec(noreturn)
#else
# define ASMJIT_NORETURN
#endif
// [@CC_NORETURN}@]
// [@CC_CDECL{@]
// \def ASMJIT_CDECL
// Standard C function calling convention decorator (__cdecl).
#if ASMJIT_ARCH_X86
# if ASMJIT_CC_HAS_ATTRIBUTE
# define ASMJIT_CDECL __attribute__((__cdecl__))
# else
# define ASMJIT_CDECL __cdecl
# endif
#else
# define ASMJIT_CDECL
#endif
// [@CC_CDECL}@]
// [@CC_STDCALL{@]
// \def ASMJIT_STDCALL
// StdCall function calling convention decorator (__stdcall).
#if ASMJIT_ARCH_X86
# if ASMJIT_CC_HAS_ATTRIBUTE
# define ASMJIT_STDCALL __attribute__((__stdcall__))
# else
# define ASMJIT_STDCALL __stdcall
# endif
#else
# define ASMJIT_STDCALL
#endif
// [@CC_STDCALL}@]
// [@CC_FASTCALL{@]
// \def ASMJIT_FASTCALL
// FastCall function calling convention decorator (__fastcall).
#if ASMJIT_ARCH_X86
# if ASMJIT_CC_HAS_ATTRIBUTE
# define ASMJIT_FASTCALL __attribute__((__fastcall__))
# else
# define ASMJIT_FASTCALL __fastcall
# endif
#else
# define ASMJIT_FASTCALL
#endif
// [@CC_FASTCALL}@]
// [@CC_REGPARM{@]
// \def ASMJIT_REGPARM(n)
// A custom calling convention which passes n arguments in registers.
#if ASMJIT_ARCH_X86 && ASMJIT_CC_HAS_ATTRIBUTE
# define ASMJIT_REGPARM(n) __attribute__((__regparm__(n)))
#else
# define ASMJIT_REGPARM(n)
#endif
// [@CC_REGPARM}@]
// [@CC_NOEXCEPT{@]
// \def ASMJIT_NOEXCEPT
// The decorated function never throws an exception (noexcept).
#if ASMJIT_CC_HAS_NOEXCEPT
# define ASMJIT_NOEXCEPT noexcept
#else
# define ASMJIT_NOEXCEPT
#endif
// [@CC_NOEXCEPT}@]
// [@CC_NOP{@]
// \def ASMJIT_NOP
// No operation.
#if !defined(ASMJIT_NOP)
# define ASMJIT_NOP ((void)0)
#endif
// [@CC_NOP}@]
// [@CC_ASSUME{@]
// \def ASMJIT_ASSUME(exp)
// Assume that the expression exp is always true.
#if ASMJIT_CC_HAS_ASSUME
# define ASMJIT_ASSUME(exp) __assume(exp)
#elif ASMJIT_CC_HAS_BUILTIN_ASSUME
# define ASMJIT_ASSUME(exp) __builtin_assume(exp)
#elif ASMJIT_CC_HAS_BUILTIN_UNREACHABLE
# define ASMJIT_ASSUME(exp) do { if (!(exp)) __builtin_unreachable(); } while (0)
#else
# define ASMJIT_ASSUME(exp) ((void)0)
#endif
// [@CC_ASSUME}@]
// [@CC_ASSUME_ALIGNED{@]
// \def ASMJIT_ASSUME_ALIGNED(p, alignment)
// Assume that the pointer 'p' is aligned to at least 'alignment' bytes.
#if ASMJIT_CC_HAS_ASSUME_ALIGNED
# define ASMJIT_ASSUME_ALIGNED(p, alignment) __assume_aligned(p, alignment)
#elif ASMJIT_CC_HAS_BUILTIN_ASSUME_ALIGNED
# define ASMJIT_ASSUME_ALIGNED(p, alignment) p = __builtin_assume_aligned(p, alignment)
#else
# define ASMJIT_ASSUME_ALIGNED(p, alignment) ((void)0)
#endif
// [@CC_ASSUME_ALIGNED}@]
// [@CC_EXPECT{@]
// \def ASMJIT_LIKELY(exp)
// Expression exp is likely to be true.
//
// \def ASMJIT_UNLIKELY(exp)
// Expression exp is likely to be false.
#if ASMJIT_CC_HAS_BUILTIN_EXPECT
# define ASMJIT_LIKELY(exp) __builtin_expect(!!(exp), 1)
# define ASMJIT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
#else
# define ASMJIT_LIKELY(exp) (exp)
# define ASMJIT_UNLIKELY(exp) (exp)
#endif
// [@CC_EXPECT}@]
// [@CC_FALLTHROUGH{@]
// \def ASMJIT_FALLTHROUGH
// The code falls through annotation (switch / case).
#if ASMJIT_CC_CLANG && __cplusplus >= 201103L
# define ASMJIT_FALLTHROUGH [[clang::fallthrough]]
#else
# define ASMJIT_FALLTHROUGH (void)0
#endif
// [@CC_FALLTHROUGH}@]
// [@CC_UNUSED{@]
// \def ASMJIT_UNUSED(x)
// Mark a variable x as unused.
#define ASMJIT_UNUSED(x) (void)(x)
// [@CC_UNUSED}@]
// [@CC_OFFSET_OF{@]
// \def ASMJIT_OFFSET_OF(x, y).
// Get the offset of a member y of a struct x at compile-time.
#define ASMJIT_OFFSET_OF(x, y) ((int)(intptr_t)((const char*)&((const x*)0x1)->y) - 1)
// [@CC_OFFSET_OF}@]
// [@CC_ARRAY_SIZE{@]
// \def ASMJIT_ARRAY_SIZE(x)
// Get the array size of x at compile-time.
#define ASMJIT_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
// [@CC_ARRAY_SIZE}@]
// ============================================================================
// [asmjit::Build - STDTYPES]
// ============================================================================
// [@STDTYPES{@]
#if defined(__MINGW32__) || defined(__MINGW64__)
# include <sys/types.h>
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1600)
# include <limits.h>
# if !defined(ASMJIT_SUPPRESS_STD_TYPES)
# if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
# else
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
# endif
# endif
#else
# include <stdint.h>
# include <limits.h>
#endif
// [@STDTYPES}@]
// ============================================================================
// [asmjit::Build - Dependencies]
// ============================================================================
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <new>
#if ASMJIT_OS_POSIX
# include <pthread.h>
#endif // ASMJIT_OS_POSIX
// ============================================================================
// [asmjit::Build - Additional]
// ============================================================================
// Build host architecture if no architecture is selected.
#if !defined(ASMJIT_BUILD_HOST) && \
!defined(ASMJIT_BUILD_X86) && \
!defined(ASMJIT_BUILD_ARM)
# define ASMJIT_BUILD_HOST
#endif
// Detect host architecture if building only for host.
#if defined(ASMJIT_BUILD_HOST)
# if (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && !defined(ASMJIT_BUILD_X86)
# define ASMJIT_BUILD_X86
# endif // ASMJIT_ARCH_X86
#endif // ASMJIT_BUILD_HOST
#if ASMJIT_CC_MSC
# define ASMJIT_UINT64_C(x) x##ui64
#else
# define ASMJIT_UINT64_C(x) x##ull
#endif
#if ASMJIT_ARCH_LE
# define ASMJIT_PACK32_4x8(A, B, C, D) ((A) + ((B) << 8) + ((C) << 16) + ((D) << 24))
#else
# define ASMJIT_PACK32_4x8(A, B, C, D) ((D) + ((C) << 8) + ((B) << 16) + ((A) << 24))
#endif
// Internal macros that are only used when building AsmJit itself.
#if defined(ASMJIT_EXPORTS)
# if !defined(ASMJIT_DEBUG) && ASMJIT_CC_HAS_ATTRIBUTE_OPTIMIZE
# define ASMJIT_FAVOR_SIZE __attribute__((__optimize__("Os")))
# else
# define ASMJIT_FAVOR_SIZE
# endif
#endif // ASMJIT_EXPORTS
// ============================================================================
// [asmjit::Build - Test]
// ============================================================================
// Include a unit testing package if this is a `asmjit_test` build.
#if defined(ASMJIT_TEST)
# include "../../test/broken.h"
#endif // ASMJIT_TEST
// [Guard]
#endif // _ASMJIT_BUILD_H
......@@ -8,27 +8,27 @@
#ifndef _ASMJIT_BASE_H
#define _ASMJIT_BASE_H
// [Dependencies - AsmJit]
#include "build.h"
#include "base/assembler.h"
#include "base/codegen.h"
#include "base/compiler.h"
#include "base/constpool.h"
#include "base/containers.h"
#include "base/cpuinfo.h"
#include "base/cputicks.h"
#include "base/error.h"
#include "base/globals.h"
#include "base/intutil.h"
#include "base/lock.h"
#include "base/logger.h"
#include "base/operand.h"
#include "base/runtime.h"
#include "base/string.h"
#include "base/vectypes.h"
#include "base/vmem.h"
#include "base/zone.h"
// [Dependencies]
#include "./base/arch.h"
#include "./base/assembler.h"
#include "./base/codebuilder.h"
#include "./base/codecompiler.h"
#include "./base/codeemitter.h"
#include "./base/codeholder.h"
#include "./base/constpool.h"
#include "./base/cpuinfo.h"
#include "./base/func.h"
#include "./base/globals.h"
#include "./base/inst.h"
#include "./base/logging.h"
#include "./base/operand.h"
#include "./base/osutils.h"
#include "./base/runtime.h"
#include "./base/simdtypes.h"
#include "./base/string.h"
#include "./base/utils.h"
#include "./base/vmem.h"
#include "./base/zone.h"
// [Guard]
#endif // _ASMJIT_BASE_H
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
// [Dependencies]
#include "../base/arch.h"
#if defined(ASMJIT_BUILD_X86)
#include "../x86/x86operand.h"
#endif // ASMJIT_BUILD_X86
// [Api-Begin]
#include "../asmjit_apibegin.h"
namespace asmjit {
// ============================================================================
// [asmjit::ArchInfo]
// ============================================================================
static const uint32_t archInfoTable[] = {
// <-------------+---------------------+-----------------------+-------+
// | Type | SubType | GPInfo|
// <-------------+---------------------+-----------------------+-------+
ASMJIT_PACK32_4x8(ArchInfo::kTypeNone , ArchInfo::kSubTypeNone, 0, 0),
ASMJIT_PACK32_4x8(ArchInfo::kTypeX86 , ArchInfo::kSubTypeNone, 4, 8),
ASMJIT_PACK32_4x8(ArchInfo::kTypeX64 , ArchInfo::kSubTypeNone, 8, 16),
ASMJIT_PACK32_4x8(ArchInfo::kTypeX32 , ArchInfo::kSubTypeNone, 8, 16),
ASMJIT_PACK32_4x8(ArchInfo::kTypeA32 , ArchInfo::kSubTypeNone, 4, 16),
ASMJIT_PACK32_4x8(ArchInfo::kTypeA64 , ArchInfo::kSubTypeNone, 8, 32)
};
ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
// Make sure the `archInfoTable` array is correctly indexed.
_signature = archInfoTable[index];
ASMJIT_ASSERT(_type == index);
// Even if the architecture is not known we setup its type and sub-type,
// however, such architecture is not really useful.
_type = type;
_subType = subType;
}
// ============================================================================
// [asmjit::ArchUtils]
// ============================================================================
ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
uint32_t typeId = typeIdInOut;
// Zero the signature so it's clear in case that typeId is not invalid.
regInfo._signature = 0;
#if defined(ASMJIT_BUILD_X86)
if (ArchInfo::isX86Family(archType)) {
// Passed RegType instead of TypeId?
if (typeId <= Reg::kRegMax)
typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
return DebugUtils::errored(kErrorInvalidTypeId);
// First normalize architecture dependent types.
if (TypeId::isAbstract(typeId)) {
if (typeId == TypeId::kIntPtr)
typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kI32 : TypeId::kI64;
else
typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kU32 : TypeId::kU64;
}
// Type size helps to construct all kinds of registers. If the size is zero
// then the TypeId is invalid.
uint32_t size = TypeId::sizeOf(typeId);
if (ASMJIT_UNLIKELY(!size))
return DebugUtils::errored(kErrorInvalidTypeId);
if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
return DebugUtils::errored(kErrorInvalidUseOfF80);
uint32_t regType = 0;
switch (typeId) {
case TypeId::kI8:
case TypeId::kU8:
regType = X86Reg::kRegGpbLo;
break;
case TypeId::kI16:
case TypeId::kU16:
regType = X86Reg::kRegGpw;
break;
case TypeId::kI32:
case TypeId::kU32:
regType = X86Reg::kRegGpd;
break;
case TypeId::kI64:
case TypeId::kU64:
if (archType == ArchInfo::kTypeX86)
return DebugUtils::errored(kErrorInvalidUseOfGpq);
regType = X86Reg::kRegGpq;
break;
// F32 and F64 are always promoted to use vector registers.
case TypeId::kF32:
typeId = TypeId::kF32x1;
regType = X86Reg::kRegXmm;
break;
case TypeId::kF64:
typeId = TypeId::kF64x1;
regType = X86Reg::kRegXmm;
break;
// Mask registers {k}.
case TypeId::kMask8:
case TypeId::kMask16:
case TypeId::kMask32:
case TypeId::kMask64:
regType = X86Reg::kRegK;
break;
// MMX registers.
case TypeId::kMmx32:
case TypeId::kMmx64:
regType = X86Reg::kRegMm;
break;
// XMM|YMM|ZMM registers.
default:
if (size <= 16)
regType = X86Reg::kRegXmm;
else if (size == 32)
regType = X86Reg::kRegYmm;
else
regType = X86Reg::kRegZmm;
break;
}
typeIdInOut = typeId;
regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
return kErrorOk;
}
#endif // ASMJIT_BUILD_X86
return DebugUtils::errored(kErrorInvalidArch);
}
} // asmjit namespace
// [Api-End]
#include "../asmjit_apiend.h"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment