Merge remote-tracking branch 'origin/master' into no_std

This commit is contained in:
Dan Gohman
2018-03-12 12:55:57 -07:00
138 changed files with 3795 additions and 1168 deletions

View File

@@ -1,7 +1,7 @@
[package]
name = "cretonne-tools"
authors = ["The Cretonne Project Developers"]
version = "0.1.0"
version = "0.3.4"
description = "Binaries for testing the Cretonne library"
license = "Apache-2.0"
documentation = "https://cretonne.readthedocs.io/"
@@ -13,18 +13,18 @@ name = "cton-util"
path = "src/cton-util.rs"
[dependencies]
cretonne = { path = "lib/cretonne", version = "0.1.0" }
cretonne-reader = { path = "lib/reader", version = "0.1.0" }
cretonne-frontend = { path = "lib/frontend", version = "0.1.0" }
cretonne-wasm = { path = "lib/wasm", version = "0.1.0" }
cretonne-native = { path = "lib/native", version = "0.1.0" }
cretonne = { path = "lib/cretonne", version = "0.3.4" }
cretonne-reader = { path = "lib/reader", version = "0.3.4" }
cretonne-frontend = { path = "lib/frontend", version = "0.3.4" }
cretonne-wasm = { path = "lib/wasm", version = "0.3.4" }
cretonne-native = { path = "lib/native", version = "0.3.4" }
filecheck = { path = "lib/filecheck" }
docopt = "0.8.0"
serde = "1.0.8"
serde_derive = "1.0.8"
num_cpus = "1.5.1"
tempdir="0.3.5"
term = "0.4.6"
term = "0.5"
[workspace]

View File

@@ -1,196 +1,24 @@
# Makefile for Sphinx documentation
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXABUILD = sphinx-autobuild
PAPER =
SPHINXPROJ = cretonne
SOURCEDIR = .
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
# Put it first so that "make" without argument is like "make help".
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
autohtml: html
$(SPHINXABUILD) -z ../lib/cretonne/meta --ignore '.*' -b html -E $(ALLSPHINXOPTS) $(BUILDDIR)/html
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: help Makefile
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/cretonne.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/cretonne.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/cretonne"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/cretonne"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@@ -2,9 +2,9 @@
Cretonne compared to LLVM
*************************
`LLVM <http://llvm.org>`_ is a collection of compiler components implemented as
`LLVM <https://llvm.org>`_ is a collection of compiler components implemented as
a set of C++ libraries. It can be used to build both JIT compilers and static
compilers like `Clang <http://clang.llvm.org>`_, and it is deservedly very
compilers like `Clang <https://clang.llvm.org>`_, and it is deservedly very
popular. `Chris Lattner's chapter about LLVM
<http://www.aosabook.org/en/llvm.html>`_ in the `Architecture of Open Source
Applications <http://aosabook.org/en/index.html>`_ book gives an excellent
@@ -40,7 +40,7 @@ Intermediate representations
LLVM uses multiple intermediate representations as it translates a program to
binary machine code:
`LLVM IR <http://llvm.org/docs/LangRef.html>`_
`LLVM IR <https://llvm.org/docs/LangRef.html>`_
This is the primary intermediate language which has textual, binary, and
in-memory representations. It serves two main purposes:
@@ -49,7 +49,7 @@ binary machine code:
- Intermediate representation for common mid-level optimizations. A large
library of code analysis and transformation passes operate on LLVM IR.
`SelectionDAG <http://llvm.org/docs/CodeGenerator.html#instruction-selection-section>`_
`SelectionDAG <https://llvm.org/docs/CodeGenerator.html#instruction-selection-section>`_
A graph-based representation of the code in a single basic block is used by
the instruction selector. It has both ISA-agnostic and ISA-specific
opcodes. These main passes are run on the SelectionDAG representation:
@@ -65,7 +65,7 @@ binary machine code:
The SelectionDAG representation automatically eliminates common
subexpressions and dead code.
`MachineInstr <http://llvm.org/docs/CodeGenerator.html#machine-code-representation>`_
`MachineInstr <https://llvm.org/docs/CodeGenerator.html#machine-code-representation>`_
A linear representation of ISA-specific instructions that initially is in
SSA form, but it can also represent non-SSA form during and after register
allocation. Many low-level optimizations run on MI code. The most important
@@ -74,7 +74,7 @@ binary machine code:
- Scheduling.
- Register allocation.
`MC <http://llvm.org/docs/CodeGenerator.html#the-mc-layer>`_
`MC <https://llvm.org/docs/CodeGenerator.html#the-mc-layer>`_
MC serves as the output abstraction layer and is the basis for LLVM's
integrated assembler. It is used for:
@@ -126,7 +126,7 @@ condition is false. The Cretonne representation is closer to how machine code
works; LLVM's representation is more abstract.
LLVM uses `phi instructions
<http://llvm.org/docs/LangRef.html#phi-instruction>`_ in its SSA
<https://llvm.org/docs/LangRef.html#phi-instruction>`_ in its SSA
representation. Cretonne passes arguments to EBBs instead. The two
representations are equivalent, but the EBB arguments are better suited to
handle EBBs that may contain multiple branches to the same destination block

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# cretonne documentation build configuration file, created by
# sphinx-quickstart on Fri Jan 8 10:11:19 2016.
# sphinx-quickstart on Fri Mar 2 12:49:24 2018.
#
# This file is execfile()d with the current directory set to its
# containing dir.
@@ -12,14 +12,13 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
from __future__ import absolute_import
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
from __future__ import absolute_import
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
# Also add the meta directory to sys.path so autodoc can find the Cretonne meta
@@ -28,6 +27,10 @@ sys.path.insert(0, os.path.abspath('../lib/cretonne/meta'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
@@ -47,6 +50,7 @@ templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
@@ -55,7 +59,7 @@ master_doc = 'index'
# General information about the project.
project = u'cretonne'
copyright = u'2016, Cretonne Developers'
copyright = u'2018, Cretonne Developers'
author = u'Cretonne Developers'
# The version info for the project you're documenting, acts as replacement for
@@ -76,7 +80,8 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
@@ -89,22 +94,54 @@ todo_include_todos = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#
# html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'cretonnedoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'cretonne.tex', u'cretonne Documentation',
author, 'manual'),
(master_doc, 'cretonne.tex', u'cretonne Documentation',
author, 'manual'),
]
@@ -124,9 +161,9 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'cretonne', u'cretonne Documentation',
author, 'cretonne', 'One line description of project.',
'Miscellaneous'),
(master_doc, 'cretonne', u'cretonne Documentation',
author, 'cretonne', 'One line description of project.',
'Miscellaneous'),
]

View File

@@ -1,7 +1,7 @@
test verifier
function %average(i32, i32) -> f32 native {
ss1 = local 8 ; Stack slot for ``sum``.
ss1 = explicit_slot 8 ; Stack slot for ``sum``.
ebb1(v1: i32, v2: i32):
v3 = f64const 0x0.0

View File

@@ -12,6 +12,28 @@ Contents:
regalloc
compare-llvm
Rust Crate Documentation
========================
`cretonne <https://docs.rs/cretonne/>`_
This is the core code generator crate. It takes Cretonne IR as input
and emits encoded machine instructions, along with symbolic relocations,
as output.
`cretonne-wasm <https://docs.rs/cretonne-wasm/>`_
This crate translates WebAssembly code into Cretonne IR.
`cretonne-frontend <https://docs.rs/cretonne-frontend/>`_
This crate provides utilities for translating code into Cretonne IR.
`cretonne-native <https://docs.rs/cretonne-native/>`_
This crate performs auto-detection of the host, allowing Cretonne to
generate code optimized for the machine it's running on.
`cretonne-reader <https://docs.rs/cretonne-reader/>`_
This crate translates from Cretonne IR's text format into Cretonne IR
in in-memory data structures.
Indices and tables
==================

View File

@@ -37,7 +37,7 @@ The first line of a function definition provides the function *name* and
the :term:`function signature` which declares the parameter and return types.
Then follows the :term:`function preamble` which declares a number of entities
that can be referenced inside the function. In the example above, the preamble
declares a single local variable, ``ss1``.
declares a single explicit stack slot, ``ss1``.
After the preamble follows the :term:`function body` which consists of
:term:`extended basic block`\s (EBBs), the first of which is the
@@ -440,7 +440,7 @@ Cretonne provides fully general :inst:`load` and :inst:`store` instructions for
accessing memory, as well as :ref:`extending loads and truncating stores
<extload-truncstore>`.
If the memory at the given addresss is not :term:`addressable`, the behavior of
If the memory at the given address is not :term:`addressable`, the behavior of
these instructions is undefined. If it is addressable but not
:term:`accessible`, they :term:`trap`.
@@ -471,8 +471,8 @@ the expected alignment. By default, misaligned loads and stores are allowed,
but when the ``aligned`` flag is set, a misaligned memory access is allowed to
:term:`trap`.
Local variables
---------------
Explicit Stack Slots
--------------------
One set of restricted memory operations access the current function's stack
frame. The stack frame is divided into fixed-size stack slots that are
@@ -480,9 +480,9 @@ allocated in the :term:`function preamble`. Stack slots are not typed, they
simply represent a contiguous sequence of :term:`accessible` bytes in the stack
frame.
.. inst:: SS = local Bytes, Flags...
.. inst:: SS = explicit_slot Bytes, Flags...
Allocate a stack slot for a local variable in the preamble.
Allocate a stack slot in the preamble.
If no alignment is specified, Cretonne will pick an appropriate alignment
for the stack slot based on its size and access patterns.
@@ -559,7 +559,7 @@ runtime data structures.
The address of GV can be computed by first loading a pointer from BaseGV
and adding Offset to it.
It is assumed the BaseGV resides in readable memory with the apropriate
It is assumed the BaseGV resides in readable memory with the appropriate
alignment for storing a pointer.
Chains of ``deref`` global variables are possible, but cycles are not
@@ -782,7 +782,7 @@ Integer operations
For example, see
`llvm.sadd.with.overflow.*` and `llvm.ssub.with.overflow.*` in
`LLVM <http://llvm.org/docs/LangRef.html#arithmetic-with-overflow-intrinsics>`_.
`LLVM <https://llvm.org/docs/LangRef.html#arithmetic-with-overflow-intrinsics>`_.
.. autoinst:: imul
.. autoinst:: imul_imm
@@ -1135,7 +1135,7 @@ Glossary
A list of declarations of entities that are used by the function body.
Some of the entities that can be declared in the preamble are:
- Local variables.
- Stack slots.
- Functions that are called directly.
- Function signatures for indirect function calls.
- Function flags and attributes that are not part of the signature.
@@ -1160,7 +1160,19 @@ Glossary
stack slot
A fixed size memory allocation in the current function's activation
frame. Also called a local variable.
frame. These include :term:`explicit stack slot`\s and
:term:`spill stack slot`\s.
explicit stack slot
A fixed size memory allocation in the current function's activation
frame. These differ from :term:`spill stack slot`\s in that they can
be created by frontends and they may have their addresses taken.
spill stack slot
A fixed size memory allocation in the current function's activation
frame. These differ from :term:`explicit stack slot`\s in that they are
only created during register allocation, and they may not have their
address taken.
terminator instruction
A control flow instruction that unconditionally directs the flow of

View File

@@ -1,62 +1,19 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
set SPHINXPROJ=cretonne
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
@@ -65,199 +22,15 @@ if errorlevel 9009 (
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
echo.https://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\cretonne.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\cretonne.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

View File

@@ -119,7 +119,7 @@ All types of tests allow shared Cretonne settings to be modified:
option : flag | setting "=" value
The shared settings available for all target ISAs are defined in
:file:`lib/cretonne/meta/cretonne/settings.py`.
:file:`lib/cretonne/meta/base/settings.py`.
The ``set`` lines apply settings cumulatively::

View File

@@ -552,3 +552,35 @@ ebb1:
return
}
; Tests for i32/i8 conversion instructions.
function %I32_I8() {
ebb0:
[-,%rcx] v1 = iconst.i32 1
[-,%rcx] v11 = ireduce.i8 v1 ; bin:
; asm: movsbl %cl, %esi
[-,%rsi] v20 = sextend.i32 v11 ; bin: 0f be f1
; asm: movzbl %cl, %esi
[-,%rsi] v30 = uextend.i32 v11 ; bin: 0f b6 f1
trap user0 ; bin: 0f 0b
}
; Tests for i32/i16 conversion instructions.
function %I32_I16() {
ebb0:
[-,%rcx] v1 = iconst.i32 1
[-,%rcx] v11 = ireduce.i16 v1 ; bin:
; asm: movswl %cx, %esi
[-,%rsi] v20 = sextend.i32 v11 ; bin: 0f bf f1
; asm: movzwl %cx, %esi
[-,%rsi] v30 = uextend.i32 v11 ; bin: 0f b7 f1
trap user0 ; bin: 0f 0b
}

View File

@@ -20,6 +20,7 @@ ebb0:
[-,%rsi] v1 = iconst.i32 2
[-,%rax] v2 = iconst.i64 11
[-,%r14] v3 = iconst.i64 12
[-,%r13] v4 = iconst.i64 13
; asm: cvtsi2ssl %r11d, %xmm5
[-,%xmm5] v10 = fcvt_from_sint.f32 v0 ; bin: f3 41 0f 2a eb
@@ -173,6 +174,10 @@ ebb0:
[-] store.f32 v100, v3 ; bin: 66 41 0f 7e 2e
; asm: movd %xmm10, (%rax)
[-] store.f32 v101, v2 ; bin: 66 44 0f 7e 10
; asm: movd %xmm5, (%r13)
[-] store.f32 v100, v4 ; bin: 66 41 0f 7e 6d 00
; asm: movd %xmm10, (%r13)
[-] store.f32 v101, v4 ; bin: 66 45 0f 7e 55 00
; asm: movd %xmm5, 50(%r14)
[-] store.f32 v100, v3+50 ; bin: 66 41 0f 7e 6e 32
; asm: movd %xmm10, -50(%rax)
@@ -250,6 +255,7 @@ ebb0:
[-,%rsi] v1 = iconst.i32 2
[-,%rax] v2 = iconst.i64 11
[-,%r14] v3 = iconst.i64 12
[-,%r13] v4 = iconst.i64 13
; asm: cvtsi2sdl %r11d, %xmm5
[-,%xmm5] v10 = fcvt_from_sint.f64 v0 ; bin: f2 41 0f 2a eb
@@ -403,6 +409,10 @@ ebb0:
[-] store.f64 v100, v3 ; bin: 66 41 0f d6 2e
; asm: movq %xmm10, (%rax)
[-] store.f64 v101, v2 ; bin: 66 44 0f d6 10
; asm: movq %xmm5, (%r13)
[-] store.f64 v100, v4 ; bin: 66 41 0f d6 6d 00
; asm: movq %xmm10, (%r13)
[-] store.f64 v101, v4 ; bin: 66 45 0f d6 55 00
; asm: movq %xmm5, 50(%r14)
[-] store.f64 v100, v3+50 ; bin: 66 41 0f d6 6e 32
; asm: movq %xmm10, -50(%rax)

View File

@@ -336,6 +336,28 @@ ebb0:
; asm: divq %r10
[-,%rax,%rdx] v202, v203 = x86_udivmodx v190, v191, v3 ; bin: 49 f7 f2
; double-length multiply instructions, 64 bit
[-,%rax] v1001 = iconst.i64 1
[-,%r15] v1002 = iconst.i64 2
; asm: mulq %r15
[-,%rax,%rdx] v1003, v1004 = x86_umulx v1001, v1002 ; bin: 49 f7 e7
; asm: imulq %r15
[-,%rax,%rdx] v1005, v1006 = x86_smulx v1001, v1002 ; bin: 49 f7 ef
; double-length multiply instructions, 32 bit
[-,%rax] v1011 = iconst.i32 1
[-,%r15] v1012 = iconst.i32 2
[-,%rcx] v1017 = iconst.i32 3
; asm: mull %r15d
[-,%rax,%rdx] v1013, v1014 = x86_umulx v1011, v1012 ; bin: 41 f7 e7
; asm: imull %r15d
[-,%rax,%rdx] v1015, v1016 = x86_smulx v1011, v1012 ; bin: 41 f7 ef
; asm: mull %ecx
[-,%rax,%rdx] v1018, v1019 = x86_umulx v1011, v1017 ; bin: f7 e1
; asm: imull %ecx
[-,%rax,%rdx] v1020, v1021 = x86_smulx v1011, v1017 ; bin: f7 e9
; Bit-counting instructions.
; asm: popcntq %rsi, %rcx
@@ -1062,6 +1084,118 @@ ebb2:
jump ebb1 ; bin: eb fd
}
; Tests for i32/i8 conversion instructions.
function %I32_I8() {
ebb0:
[-,%rcx] v1 = iconst.i32 1
[-,%rsi] v2 = iconst.i32 2
[-,%r10] v3 = iconst.i32 3
[-,%rcx] v11 = ireduce.i8 v1 ; bin:
[-,%rsi] v12 = ireduce.i8 v2 ; bin:
[-,%r10] v13 = ireduce.i8 v3 ; bin:
; asm: movsbl %cl, %esi
[-,%rsi] v20 = sextend.i32 v11 ; bin: 0f be f1
; asm: movsbl %sil, %r10d
[-,%r10] v21 = sextend.i32 v12 ; bin: 44 0f be d6
; asm: movsbl %r10b, %ecx
[-,%rcx] v22 = sextend.i32 v13 ; bin: 41 0f be ca
; asm: movzbl %cl, %esi
[-,%rsi] v30 = uextend.i32 v11 ; bin: 0f b6 f1
; asm: movzbl %sil, %r10d
[-,%r10] v31 = uextend.i32 v12 ; bin: 44 0f b6 d6
; asm: movzbl %r10b, %ecx
[-,%rcx] v32 = uextend.i32 v13 ; bin: 41 0f b6 ca
trap user0 ; bin: 0f 0b
}
; Tests for i32/i16 conversion instructions.
function %I32_I16() {
ebb0:
[-,%rcx] v1 = iconst.i32 1
[-,%rsi] v2 = iconst.i32 2
[-,%r10] v3 = iconst.i32 3
[-,%rcx] v11 = ireduce.i16 v1 ; bin:
[-,%rsi] v12 = ireduce.i16 v2 ; bin:
[-,%r10] v13 = ireduce.i16 v3 ; bin:
; asm: movswl %cx, %esi
[-,%rsi] v20 = sextend.i32 v11 ; bin: 0f bf f1
; asm: movswl %si, %r10d
[-,%r10] v21 = sextend.i32 v12 ; bin: 44 0f bf d6
; asm: movswl %r10w, %ecx
[-,%rcx] v22 = sextend.i32 v13 ; bin: 41 0f bf ca
; asm: movzwl %cx, %esi
[-,%rsi] v30 = uextend.i32 v11 ; bin: 0f b7 f1
; asm: movzwl %si, %r10d
[-,%r10] v31 = uextend.i32 v12 ; bin: 44 0f b7 d6
; asm: movzwl %r10w, %ecx
[-,%rcx] v32 = uextend.i32 v13 ; bin: 41 0f b7 ca
trap user0 ; bin: 0f 0b
}
; Tests for i64/i8 conversion instructions.
function %I64_I8() {
ebb0:
[-,%rcx] v1 = iconst.i64 1
[-,%rsi] v2 = iconst.i64 2
[-,%r10] v3 = iconst.i64 3
[-,%rcx] v11 = ireduce.i8 v1 ; bin:
[-,%rsi] v12 = ireduce.i8 v2 ; bin:
[-,%r10] v13 = ireduce.i8 v3 ; bin:
; asm: movsbq %cl, %rsi
[-,%rsi] v20 = sextend.i64 v11 ; bin: 48 0f be f1
; asm: movsbq %sil, %r10
[-,%r10] v21 = sextend.i64 v12 ; bin: 4c 0f be d6
; asm: movsbq %r10b, %rcx
[-,%rcx] v22 = sextend.i64 v13 ; bin: 49 0f be ca
; asm: movzbl %cl, %esi
[-,%rsi] v30 = uextend.i64 v11 ; bin: 0f b6 f1
; asm: movzbl %sil, %r10d
[-,%r10] v31 = uextend.i64 v12 ; bin: 44 0f b6 d6
; asm: movzbl %r10b, %ecx
[-,%rcx] v32 = uextend.i64 v13 ; bin: 41 0f b6 ca
trap user0 ; bin: 0f 0b
}
; Tests for i64/i16 conversion instructions.
function %I64_I16() {
ebb0:
[-,%rcx] v1 = iconst.i64 1
[-,%rsi] v2 = iconst.i64 2
[-,%r10] v3 = iconst.i64 3
[-,%rcx] v11 = ireduce.i16 v1 ; bin:
[-,%rsi] v12 = ireduce.i16 v2 ; bin:
[-,%r10] v13 = ireduce.i16 v3 ; bin:
; asm: movswq %cx, %rsi
[-,%rsi] v20 = sextend.i64 v11 ; bin: 48 0f bf f1
; asm: movswq %si, %r10
[-,%r10] v21 = sextend.i64 v12 ; bin: 4c 0f bf d6
; asm: movswq %r10w, %rcx
[-,%rcx] v22 = sextend.i64 v13 ; bin: 49 0f bf ca
; asm: movzwl %cx, %esi
[-,%rsi] v30 = uextend.i64 v11 ; bin: 0f b7 f1
; asm: movzwl %si, %r10d
[-,%r10] v31 = uextend.i64 v12 ; bin: 44 0f b7 d6
; asm: movzwl %r10w, %ecx
[-,%rcx] v32 = uextend.i64 v13 ; bin: 41 0f b7 ca
trap user0 ; bin: 0f 0b
}
; Tests for i64/i32 conversion instructions.
function %I64_I32() {
ebb0:

View File

@@ -0,0 +1,45 @@
test compile
set is_64bit
isa intel baseline
; umulhi/smulhi on 64 bit operands
function %i64_umulhi(i64, i64) -> i64 {
ebb0(v10: i64, v11: i64):
v12 = umulhi v10, v11
; check: %rdi -> %rax
; check: x86_umulx
; check: %rdx -> %rax
return v12
}
function %i64_smulhi(i64, i64) -> i64 {
ebb0(v20: i64, v21: i64):
v22 = smulhi v20, v21
; check: %rdi -> %rax
; check: x86_smulx
; check: %rdx -> %rax
return v22
}
; umulhi/smulhi on 32 bit operands
function %i32_umulhi(i32, i32) -> i32 {
ebb0(v30: i32, v31: i32):
v32 = umulhi v30, v31
; check: %rdi -> %rax
; check: x86_umulx
; check: %rdx -> %rax
return v32
}
function %i32_smulhi(i32, i32) -> i32 {
ebb0(v40: i32, v41: i32):
v42 = smulhi v40, v41
; check: %rdi -> %rax
; check: x86_smulx
; check: %rdx -> %rax
return v42
}

View File

@@ -4,13 +4,13 @@ set is_compressed
isa intel haswell
function %foo() {
ss0 = local 168
ss0 = explicit_slot 168
ebb0:
return
}
; check: function %foo(i64 fp [%rbp], i64 csr [%rbx], i64 csr [%r12], i64 csr [%r13], i64 csr [%r14], i64 csr [%r15]) -> i64 fp [%rbp], i64 csr [%rbx], i64 csr [%r12], i64 csr [%r13], i64 csr [%r14], i64 csr [%r15] native {
; nextln: ss0 = local 168, offset -224
; nextln: ss0 = explicit_slot 168, offset -224
; nextln: ss1 = incoming_arg 56, offset -56
; check: ebb0(v0: i64 [%rbp], v1: i64 [%rbx], v2: i64 [%r12], v3: i64 [%r13], v4: i64 [%r14], v5: i64 [%r15]):
; nextln: x86_push v0
@@ -29,4 +29,4 @@ ebb0:
; nextln: v7 = x86_pop.i64
; nextln: v6 = x86_pop.i64
; nextln: return v6, v7, v8, v9, v10, v11
; nextln: }
; nextln: }

View File

@@ -124,7 +124,7 @@ ebb0(v90: i32, v91: f32):
; Stack slot references
function %stack() {
ss10 = spill_slot 8
ss2 = local 4
ss2 = explicit_slot 4
ss3 = incoming_arg 4, offset 8
ss4 = outgoing_arg 4
ss5 = emergency_slot 4
@@ -136,7 +136,7 @@ ebb0:
stack_store v2, ss2
}
; sameln: function %stack() native {
; check: ss2 = local 4
; check: ss2 = explicit_slot 4
; check: ss3 = incoming_arg 4, offset 8
; check: ss4 = outgoing_arg 4
; check: ss5 = emergency_slot 4

View File

@@ -0,0 +1,60 @@
test preopt
isa intel baseline
; Cases where the denominator is created by an iconst
function %indir_udiv32(i32) -> i32 {
ebb0(v0: i32):
v1 = iconst.i32 7
v2 = udiv v0, v1
; check: iconst.i32 7
; check: iconst.i32 0x2492_4925
; check: umulhi v0, v3
; check: isub v0, v4
; check: ushr_imm v5, 1
; check: iadd v6, v4
; check: ushr_imm v7, 2
; check: copy v8
return v2
}
function %indir_sdiv32(i32) -> i32 {
ebb0(v0: i32):
v1 = iconst.i32 -17
v2 = sdiv v0, v1
; check: iconst.i32 -17
; check: iconst.i32 0xffff_ffff_8787_8787
; check: smulhi v0, v3
; check: sshr_imm v4, 3
; check: ushr_imm v5, 31
; check: iadd v5, v6
; check: copy v7
return v2
}
function %indir_udiv64(i64) -> i64 {
ebb0(v0: i64):
v1 = iconst.i64 1337
v2 = udiv v0, v1
; check: iconst.i64 1337
; check: iconst.i64 0xc411_9d95_2866_a139
; check: umulhi v0, v3
; check: ushr_imm v4, 10
; check: copy v5
return v2
}
function %indir_sdiv64(i64) -> i64 {
ebb0(v0: i64):
v1 = iconst.i64 -90210
v2 = sdiv v0, v1
; check: iconst.i64 0xffff_ffff_fffe_9f9e
; check: iconst.i64 0xd181_4ee8_939c_b8bb
; check: smulhi v0, v3
; check: sshr_imm v4, 14
; check: ushr_imm v5, 63
; check: iadd v5, v6
; check: copy v7
return v2
}

View File

@@ -0,0 +1,267 @@
test preopt
isa intel baseline
; -------- U32 --------
; complex case (mul, sub, shift, add, shift)
function %t_udiv32_p7(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 7
; check: iconst.i32 0x2492_4925
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 2
; check: copy v7
return v1
}
; simple case (mul, shift)
function %t_udiv32_p125(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 125
; check: iconst.i32 0x1062_4dd3
; check: umulhi v0, v2
; check: ushr_imm v3, 3
; check: copy v4
return v1
}
; simple case w/ shift by zero (mul)
function %t_udiv32_p641(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 641
; check: iconst.i32 0x0066_3d81
; check: umulhi v0, v2
; check: copy v3
return v1
}
; -------- S32 --------
; simple case w/ shift by zero (mul, add-sign-bit)
function %t_sdiv32_n6(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -6
; check: iconst.i32 0xffff_ffff_d555_5555
; check: smulhi v0, v2
; check: ushr_imm v3, 31
; check: iadd v3, v4
; check: copy v5
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_sdiv32_n5(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -5
; check: iconst.i32 0xffff_ffff_9999_9999
; check: smulhi v0, v2
; check: sshr_imm v3, 1
; check: ushr_imm v4, 31
; check: iadd v4, v5
; check: copy v6
return v1
}
; case d < 0 && M > 0 (mul, sub, shift, add-sign-bit)
function %t_sdiv32_n3(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -3
; check: iconst.i32 0x5555_5555
; check: smulhi v0, v2
; check: isub v3, v0
; check: sshr_imm v4, 1
; check: ushr_imm v5, 31
; check: iadd v5, v6
; check: copy v7
return v1
}
; simple case w/ shift by zero (mul, add-sign-bit)
function %t_sdiv32_p6(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 6
; check: iconst.i32 0x2aaa_aaab
; check: smulhi v0, v2
; check: ushr_imm v3, 31
; check: iadd v3, v4
; check: copy v5
return v1
}
; case d > 0 && M < 0 (mull, add, shift, add-sign-bit)
function %t_sdiv32_p7(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 7
; check: iconst.i32 0xffff_ffff_9249_2493
; check: smulhi v0, v2
; check: iadd v3, v0
; check: sshr_imm v4, 2
; check: ushr_imm v5, 31
; check: iadd v5, v6
; check: copy v7
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_sdiv32_p625(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 625
; check: iconst.i32 0x68db_8bad
; check: smulhi v0, v2
; check: sshr_imm v3, 8
; check: ushr_imm v4, 31
; check: iadd v4, v5
; check: copy v6
return v1
}
; -------- U64 --------
; complex case (mul, sub, shift, add, shift)
function %t_udiv64_p7(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 7
; check: iconst.i64 0x2492_4924_9249_2493
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 2
; check: copy v7
return v1
}
; simple case (mul, shift)
function %t_udiv64_p9(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 9
; check: iconst.i64 0xe38e_38e3_8e38_e38f
; check: umulhi v0, v2
; check: ushr_imm v3, 3
; check: copy v4
return v1
}
; complex case (mul, sub, shift, add, shift)
function %t_udiv64_p125(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 125
; check: iconst.i64 0x0624_dd2f_1a9f_be77
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 6
; check: copy v7
return v1
}
; simple case w/ shift by zero (mul)
function %t_udiv64_p274177(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 274177
; check: iconst.i64 0x3d30_f19c_d101
; check: umulhi v0, v2
; check: copy v3
return v1
}
; -------- S64 --------
; simple case (mul, shift, add-sign-bit)
function %t_sdiv64_n625(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -625
; check: iconst.i64 0xcb92_3a29_c779_a6b5
; check: smulhi v0, v2
; check: sshr_imm v3, 7
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: copy v6
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_sdiv64_n6(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -6
; check: iconst.i64 0xd555_5555_5555_5555
; check: smulhi v0, v2
; check: ushr_imm v3, 63
; check: iadd v3, v4
; check: copy v5
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_sdiv64_n5(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -5
; check: iconst.i64 0x9999_9999_9999_9999
; check: smulhi v0, v2
; check: sshr_imm v3, 1
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: copy v6
return v1
}
; case d < 0 && M > 0 (mul, sub, shift, add-sign-bit)
function %t_sdiv64_n3(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -3
; check: iconst.i64 0x5555_5555_5555_5555
; check: smulhi v0, v2
; check: isub v3, v0
; check: sshr_imm v4, 1
; check: ushr_imm v5, 63
; check: iadd v5, v6
; check: copy v7
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_sdiv64_p6(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 6
; check: iconst.i64 0x2aaa_aaaa_aaaa_aaab
; check: smulhi v0, v2
; check: ushr_imm v3, 63
; check: iadd v3, v4
; check: copy v5
return v1
}
; case d > 0 && M < 0 (mul, add, shift, add-sign-bit)
function %t_sdiv64_p15(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 15
; check: iconst.i64 0x8888_8888_8888_8889
; check: smulhi v0, v2
; check: iadd v3, v0
; check: sshr_imm v4, 3
; check: ushr_imm v5, 63
; check: iadd v5, v6
; check: copy v7
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_sdiv64_p625(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 625
; check: iconst.i64 0x346d_c5d6_3886_594b
; check: smulhi v0, v2
; check: sshr_imm v3, 7
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: copy v6
return v1
}

View File

@@ -0,0 +1,293 @@
test preopt
isa intel baseline
; -------- U32 --------
; ignored
function %t_udiv32_p0(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 0
; check: udiv_imm v0, 0
return v1
}
; converted to a copy
function %t_udiv32_p1(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 1
; check: copy v0
return v1
}
; shift
function %t_udiv32_p2(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 2
; check: ushr_imm v0, 1
return v1
}
; shift
function %t_udiv32_p2p31(i32) -> i32 {
ebb0(v0: i32):
v1 = udiv_imm v0, 0x8000_0000
; check: ushr_imm v0, 31
return v1
}
; -------- U64 --------
; ignored
function %t_udiv64_p0(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 0
; check: udiv_imm v0, 0
return v1
}
; converted to a copy
function %t_udiv64_p1(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 1
; check: copy v0
return v1
}
; shift
function %t_udiv64_p2(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 2
; check: ushr_imm v0, 1
return v1
}
; shift
function %t_udiv64_p2p63(i64) -> i64 {
ebb0(v0: i64):
v1 = udiv_imm v0, 0x8000_0000_0000_0000
; check: ushr_imm v0, 63
return v1
}
; -------- S32 --------
; ignored
function %t_sdiv32_p0(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 0
; check: sdiv_imm v0, 0
return v1
}
; converted to a copy
function %t_sdiv32_p1(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 1
; check: copy v0
return v1
}
; ignored
function %t_sdiv32_n1(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -1
; check: sdiv_imm v0, -1
return v1
}
; shift
function %t_sdiv32_p2(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 2
; check: ushr_imm v0, 31
; check: iadd v0, v2
; check: sshr_imm v3, 1
; check: copy v4
return v1
}
; shift
function %t_sdiv32_n2(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -2
; check: ushr_imm v0, 31
; check: iadd v0, v2
; check: sshr_imm v3, 1
; check: irsub_imm v4, 0
return v1
}
; shift
function %t_sdiv32_p4(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 4
; check: v2 = sshr_imm v0, 1
; check: ushr_imm v2, 30
; check: iadd v0, v3
; check: sshr_imm v4, 2
; check: copy v5
return v1
}
; shift
function %t_sdiv32_n4(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 30
; check: iadd v0, v3
; check: sshr_imm v4, 2
; check: irsub_imm v5, 0
return v1
}
; shift
function %t_sdiv32_p2p30(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, 0x4000_0000
; check: sshr_imm v0, 29
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: sshr_imm v4, 30
; check: copy v5
return v1
}
; shift
function %t_sdiv32_n2p30(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -0x4000_0000
; check: sshr_imm v0, 29
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: sshr_imm v4, 30
; check: irsub_imm v5, 0
return v1
}
; there's no positive version of this, since -(-0x8000_0000) isn't
; representable.
function %t_sdiv32_n2p31(i32) -> i32 {
ebb0(v0: i32):
v1 = sdiv_imm v0, -0x8000_0000
; check: sshr_imm v0, 30
; check: ushr_imm v2, 1
; check: iadd v0, v3
; check: sshr_imm v4, 31
; check: irsub_imm v5, 0
return v1
}
; -------- S64 --------
; ignored
function %t_sdiv64_p0(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 0
; check: sdiv_imm v0, 0
return v1
}
; converted to a copy
function %t_sdiv64_p1(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 1
; check: copy v0
return v1
}
; ignored
function %t_sdiv64_n1(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -1
; check: sdiv_imm v0, -1
return v1
}
; shift
function %t_sdiv64_p2(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 2
; check: ushr_imm v0, 63
; check: iadd v0, v2
; check: sshr_imm v3, 1
; check: copy v4
return v1
}
; shift
function %t_sdiv64_n2(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -2
; check: ushr_imm v0, 63
; check: iadd v0, v2
; check: sshr_imm v3, 1
; check: irsub_imm v4, 0
return v1
}
; shift
function %t_sdiv64_p4(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 62
; check: iadd v0, v3
; check: sshr_imm v4, 2
; check: copy v5
return v1
}
; shift
function %t_sdiv64_n4(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 62
; check: iadd v0, v3
; check: sshr_imm v4, 2
; check: irsub_imm v5, 0
return v1
}
; shift
function %t_sdiv64_p2p62(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, 0x4000_0000_0000_0000
; check: sshr_imm v0, 61
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: sshr_imm v4, 62
; check: copy v5
return v1
}
; shift
function %t_sdiv64_n2p62(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -0x4000_0000_0000_0000
; check: sshr_imm v0, 61
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: sshr_imm v4, 62
; check: irsub_imm v5, 0
return v1
}
; there's no positive version of this, since -(-0x8000_0000_0000_0000) isn't
; representable.
function %t_sdiv64_n2p63(i64) -> i64 {
ebb0(v0: i64):
v1 = sdiv_imm v0, -0x8000_0000_0000_0000
; check: sshr_imm v0, 62
; check: ushr_imm v2, 1
; check: iadd v0, v3
; check: sshr_imm v4, 63
; check: irsub_imm v5, 0
return v1
}

View File

@@ -0,0 +1,286 @@
test preopt
isa intel baseline
; -------- U32 --------
; complex case (mul, sub, shift, add, shift)
function %t_urem32_p7(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 7
; check: iconst.i32 0x2492_4925
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 2
; check: imul_imm v7, 7
; check: isub v0, v8
return v1
}
; simple case (mul, shift)
function %t_urem32_p125(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 125
; check: iconst.i32 0x1062_4dd3
; check: umulhi v0, v2
; check: ushr_imm v3, 3
; check: imul_imm v4, 125
; check: isub v0, v5
return v1
}
; simple case w/ shift by zero (mul)
function %t_urem32_p641(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 641
; check: iconst.i32 0x0066_3d81
; check: umulhi v0, v2
; check: imul_imm v3, 641
; check: isub v0, v4
return v1
}
; -------- S32 --------
; simple case w/ shift by zero (mul, add-sign-bit)
function %t_srem32_n6(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -6
; check: iconst.i32 0xffff_ffff_d555_5555
; check: smulhi v0, v2
; check: ushr_imm v3, 31
; check: iadd v3, v4
; check: imul_imm v5, -6
; check: isub v0, v6
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_srem32_n5(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -5
; check: iconst.i32 0xffff_ffff_9999_9999
; check: smulhi v0, v2
; check: sshr_imm v3, 1
; check: ushr_imm v4, 31
; check: iadd v4, v5
; check: imul_imm v6, -5
; check: isub v0, v7
return v1
}
; case d < 0 && M > 0 (mul, sub, shift, add-sign-bit)
function %t_srem32_n3(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -3
; check: iconst.i32 0x5555_5555
; check: smulhi v0, v2
; check: isub v3, v0
; check: sshr_imm v4, 1
; check: ushr_imm v5, 31
; check: iadd v5, v6
; check: imul_imm v7, -3
; check: isub v0, v8
return v1
}
; simple case w/ shift by zero (mul, add-sign-bit)
function %t_srem32_p6(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 6
; check: iconst.i32 0x2aaa_aaab
; check: smulhi v0, v2
; check: ushr_imm v3, 31
; check: iadd v3, v4
; check: imul_imm v5, 6
; check: isub v0, v6
return v1
}
; case d > 0 && M < 0 (mull, add, shift, add-sign-bit)
function %t_srem32_p7(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 7
; check: iconst.i32 0xffff_ffff_9249_2493
; check: smulhi v0, v2
; check: iadd v3, v0
; check: sshr_imm v4, 2
; check: ushr_imm v5, 31
; check: iadd v5, v6
; check: imul_imm v7, 7
; check: isub v0, v8
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_srem32_p625(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 625
; check: iconst.i32 0x68db_8bad
; check: smulhi v0, v2
; check: sshr_imm v3, 8
; check: ushr_imm v4, 31
; check: iadd v4, v5
; check: imul_imm v6, 625
; check: isub v0, v7
return v1
}
; -------- U64 --------
; complex case (mul, sub, shift, add, shift)
function %t_urem64_p7(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 7
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 2
; check: imul_imm v7, 7
; check: isub v0, v8
return v1
}
; simple case (mul, shift)
function %t_urem64_p9(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 9
; check: iconst.i64 0xe38e_38e3_8e38_e38f
; check: umulhi v0, v2
; check: ushr_imm v3, 3
; check: imul_imm v4, 9
; check: isub v0, v5
return v1
}
; complex case (mul, sub, shift, add, shift)
function %t_urem64_p125(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 125
; check: iconst.i64 0x0624_dd2f_1a9f_be77
; check: umulhi v0, v2
; check: isub v0, v3
; check: ushr_imm v4, 1
; check: iadd v5, v3
; check: ushr_imm v6, 6
; check: imul_imm v7, 125
; check: isub v0, v8
return v1
}
; simple case w/ shift by zero (mul)
function %t_urem64_p274177(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 274177
; check: iconst.i64 0x3d30_f19c_d101
; check: umulhi v0, v2
; check: imul_imm v3, 0x0004_2f01
; check: isub v0, v4
return v1
}
; -------- S64 --------
; simple case (mul, shift, add-sign-bit)
function %t_srem64_n625(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -625
; check: iconst.i64 0xcb92_3a29_c779_a6b5
; check: smulhi v0, v2
; check: sshr_imm v3, 7
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: imul_imm v6, -625
; check: isub v0, v7
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_srem64_n6(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -6
; check: iconst.i64 0xd555_5555_5555_5555
; check: smulhi v0, v2
; check: ushr_imm v3, 63
; check: iadd v3, v4
; check: imul_imm v5, -6
; check: isub v0, v6
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_srem64_n5(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -5
; check: iconst.i64 0x9999_9999_9999_9999
; check: smulhi v0, v2
; check: sshr_imm v3, 1
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: imul_imm v6, -5
; check: isub v0, v7
return v1
}
; case d < 0 && M > 0 (mul, sub, shift, add-sign-bit)
function %t_srem64_n3(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -3
; check: iconst.i64 0x5555_5555_5555_5555
; check: smulhi v0, v2
; check: isub v3, v0
; check: sshr_imm v4, 1
; check: ushr_imm v5, 63
; check: iadd v5, v6
; check: imul_imm v7, -3
; check: isub v0, v8
return v1
}
; simple case w/ zero shift (mul, add-sign-bit)
function %t_srem64_p6(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 6
; check: iconst.i64 0x2aaa_aaaa_aaaa_aaab
; check: smulhi v0, v2
; check: ushr_imm v3, 63
; check: iadd v3, v4
; check: imul_imm v5, 6
; check: isub v0, v6
return v1
}
; case d > 0 && M < 0 (mul, add, shift, add-sign-bit)
function %t_srem64_p15(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 15
; check: iconst.i64 0x8888_8888_8888_8889
; check: smulhi v0, v2
; check: iadd v3, v0
; check: sshr_imm v4, 3
; check: ushr_imm v5, 63
; check: iadd v5, v6
; check: imul_imm v7, 15
; check: isub v0, v8
return v1
}
; simple case (mul, shift, add-sign-bit)
function %t_srem64_p625(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 625
; check: iconst.i64 0x346d_c5d6_3886_594b
; check: smulhi v0, v2
; check: sshr_imm v3, 7
; check: ushr_imm v4, 63
; check: iadd v4, v5
; check: imul_imm v6, 625
; check: isub v0, v7
return v1
}

View File

@@ -0,0 +1,292 @@
test preopt
isa intel baseline
; -------- U32 --------
; ignored
function %t_urem32_p0(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 0
; check: urem_imm v0, 0
return v1
}
; converted to constant zero
function %t_urem32_p1(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 1
; check: iconst.i32 0
return v1
}
; shift
function %t_urem32_p2(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 2
; check: band_imm v0, 1
return v1
}
; shift
function %t_urem32_p2p31(i32) -> i32 {
ebb0(v0: i32):
v1 = urem_imm v0, 0x8000_0000
; check: band_imm v0, 0x7fff_ffff
return v1
}
; -------- U64 --------
; ignored
function %t_urem64_p0(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 0
; check: urem_imm v0, 0
return v1
}
; converted to constant zero
function %t_urem64_p1(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 1
; check: iconst.i64 0
return v1
}
; shift
function %t_urem64_p2(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 2
; check: band_imm v0, 1
return v1
}
; shift
function %t_urem64_p2p63(i64) -> i64 {
ebb0(v0: i64):
v1 = urem_imm v0, 0x8000_0000_0000_0000
; check: band_imm v0, 0x7fff_ffff_ffff_ffff
return v1
}
; -------- S32 --------
; ignored
function %t_srem32_n1(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -1
; check: srem_imm v0, -1
return v1
}
; ignored
function %t_srem32_p0(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 0
; check: srem_imm v0, 0
return v1
}
; converted to constant zero
function %t_srem32_p1(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 1
; check: iconst.i32 0
return v1
}
; shift
function %t_srem32_p2(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 2
; check: ushr_imm v0, 31
; check: iadd v0, v2
; check: band_imm v3, -2
; check: isub v0, v4
return v1
}
; shift
function %t_srem32_n2(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -2
; check: ushr_imm v0, 31
; check: iadd v0, v2
; check: band_imm v3, -2
; check: isub v0, v4
return v1
}
; shift
function %t_srem32_p4(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 30
; check: iadd v0, v3
; check: band_imm v4, -4
; check: isub v0, v5
return v1
}
; shift
function %t_srem32_n4(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 30
; check: iadd v0, v3
; check: band_imm v4, -4
; check: isub v0, v5
return v1
}
; shift
function %t_srem32_p2p30(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, 0x4000_0000
; check: sshr_imm v0, 29
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: band_imm v4, 0xffff_ffff_c000_0000
; check: isub v0, v5
return v1
}
; shift
function %t_srem32_n2p30(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -0x4000_0000
; check: sshr_imm v0, 29
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: band_imm v4, 0xffff_ffff_c000_0000
; check: isub v0, v5
return v1
}
; there's no positive version of this, since -(-0x8000_0000) isn't
; representable.
function %t_srem32_n2p31(i32) -> i32 {
ebb0(v0: i32):
v1 = srem_imm v0, -0x8000_0000
; check: sshr_imm v0, 30
; check: ushr_imm v2, 1
; check: iadd v0, v3
; check: band_imm v4, 0xffff_ffff_8000_0000
; check: isub v0, v5
return v1
}
; -------- S64 --------
; ignored
function %t_srem64_n1(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -1
; check: srem_imm v0, -1
return v1
}
; ignored
function %t_srem64_p0(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 0
; check: srem_imm v0, 0
return v1
}
; converted to constant zero
function %t_srem64_p1(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 1
; check: iconst.i64 0
return v1
}
; shift
function %t_srem64_p2(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 2
; check: ushr_imm v0, 63
; check: iadd v0, v2
; check: band_imm v3, -2
; check: isub v0, v4
return v1
}
; shift
function %t_srem64_n2(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -2
; check: ushr_imm v0, 63
; check: iadd v0, v2
; check: band_imm v3, -2
; check: isub v0, v4
return v1
}
; shift
function %t_srem64_p4(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 62
; check: iadd v0, v3
; check: band_imm v4, -4
; check: isub v0, v5
return v1
}
; shift
function %t_srem64_n4(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -4
; check: sshr_imm v0, 1
; check: ushr_imm v2, 62
; check: iadd v0, v3
; check: band_imm v4, -4
; check: isub v0, v5
return v1
}
; shift
function %t_srem64_p2p62(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, 0x4000_0000_0000_0000
; check: sshr_imm v0, 61
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: band_imm v4, 0xc000_0000_0000_0000
; check: isub v0, v5
return v1
}
; shift
function %t_srem64_n2p62(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -0x4000_0000_0000_0000
; check: sshr_imm v0, 61
; check: ushr_imm v2, 2
; check: iadd v0, v3
; check: band_imm v4, 0xc000_0000_0000_0000
; check: isub v0, v5
return v1
}
; there's no positive version of this, since -(-0x8000_0000_0000_0000) isn't
; representable.
function %t_srem64_n2p63(i64) -> i64 {
ebb0(v0: i64):
v1 = srem_imm v0, -0x8000_0000_0000_0000
; check: sshr_imm v0, 62
; check: ushr_imm v2, 1
; check: iadd v0, v3
; check: band_imm v4, 0x8000_0000_0000_0000
; check: isub v0, v5
return v1
}

View File

@@ -1,10 +1,8 @@
#!/bin/bash
set -euo pipefail
# Format all sources using rustfmt.
# Exit immediately on errors.
set -e
cd $(dirname "$0")
# Make sure we can find rustfmt.

View File

@@ -1,11 +1,11 @@
#!/bin/bash
set -e
set -euo pipefail
cd $(dirname "$0")
topdir=$(pwd)
topdir="$(pwd)"
# All the cretonne-* crates have the same version number
# The filecheck crate version is managed independently.
version="0.1.0"
version="0.3.4"
# Update all of the Cargo.toml files.
#
@@ -16,9 +16,9 @@ for crate in . lib/*; do
continue
fi
# Update the version number of this crate to $version.
sed -i "" -e "s/^version = .*/version = \"$version\"/" $crate/Cargo.toml
sed -i.bk -e "s/^version = .*/version = \"$version\"/" "$crate/Cargo.toml"
# Update the required version number of any cretonne* dependencies.
sed -i "" -e "/^cretonne/s/version = \"[^\"]*\"/version = \"$version\"/" $crate/Cargo.toml
sed -i.bk -e "/^cretonne/s/version = \"[^\"]*\"/version = \"$version\"/" "$crate/Cargo.toml"
done
# Update our local Cargo.lock (not checked in).
@@ -29,6 +29,10 @@ cargo update
#
# Note that libraries need to be published in topological order.
echo git commit -a -m "\"Bump version to $version"\"
echo git push
for crate in filecheck cretonne frontend native reader wasm; do
echo cargo publish --manifest-path lib/$crate/Cargo.toml
echo cargo publish --manifest-path "lib/$crate/Cargo.toml"
done
echo
echo Then, go to https://github.com/Cretonne/cretonne/releases/ and define a new release.

View File

@@ -13,7 +13,7 @@ use filetest::subtest::{self, SubTest, Context, Result as STResult};
pub fn run(files: Vec<String>) -> CommandResult {
for (i, f) in files.into_iter().enumerate() {
if i != 0 {
println!("");
println!();
}
cat_one(f)?
}
@@ -30,7 +30,7 @@ fn cat_one(filename: String) -> CommandResult {
for (idx, func) in items.into_iter().enumerate() {
if idx != 0 {
println!("");
println!();
}
print!("{}", func);
}

View File

@@ -6,9 +6,45 @@ use cton_reader::parse_test;
use std::path::PathBuf;
use cretonne::Context;
use cretonne::settings::FlagsOrIsa;
use cretonne::{binemit, ir};
use std::path::Path;
use utils::{pretty_error, read_to_string, parse_sets_and_isa};
struct PrintRelocs {
flag_print: bool,
}
impl binemit::RelocSink for PrintRelocs {
fn reloc_ebb(
&mut self,
where_: binemit::CodeOffset,
r: binemit::Reloc,
offset: binemit::CodeOffset,
) {
if self.flag_print {
println!("reloc_ebb: {} {} at {}", r, offset, where_);
}
}
fn reloc_external(
&mut self,
where_: binemit::CodeOffset,
r: binemit::Reloc,
name: &ir::ExternalName,
addend: binemit::Addend,
) {
if self.flag_print {
println!("reloc_ebb: {} {} {} at {}", r, name, addend, where_);
}
}
fn reloc_jt(&mut self, where_: binemit::CodeOffset, r: binemit::Reloc, jt: ir::JumpTable) {
if self.flag_print {
println!("reloc_ebb: {} {} at {}", r, jt, where_);
}
}
}
pub fn run(
files: Vec<String>,
flag_print: bool,
@@ -37,7 +73,7 @@ fn handle_module(
let test_file = parse_test(&buffer).map_err(|e| format!("{}: {}", name, e))?;
// If we have an isa from the command-line, use that. Otherwise if the
// file contins a unique isa, use that.
// file contains a unique isa, use that.
let isa = if let Some(isa) = fisa.isa {
isa
} else if let Some(isa) = test_file.isa_spec.unique_isa() {
@@ -49,12 +85,32 @@ fn handle_module(
for (func, _) in test_file.functions {
let mut context = Context::new();
context.func = func;
context.compile(isa).map_err(|err| {
let size = context.compile(isa).map_err(|err| {
pretty_error(&context.func, Some(isa), err)
})?;
if flag_print {
println!("{}", context.func.display(isa));
}
// Encode the result as machine code.
let mut mem = Vec::new();
let mut relocs = PrintRelocs { flag_print };
mem.resize(size as usize, 0);
context.emit_to_memory(mem.as_mut_ptr(), &mut relocs, &*isa);
if flag_print {
print!(".byte ");
let mut first = true;
for byte in &mem {
if first {
first = false;
} else {
print!(", ");
}
print!("{}", byte);
}
println!();
}
}
Ok(())

View File

@@ -126,7 +126,7 @@ impl SubTest for TestBinEmit {
// Fix the stack frame layout so we can test spill/fill encodings.
let min_offset = func.stack_slots
.keys()
.map(|ss| func.stack_slots[ss].offset)
.map(|ss| func.stack_slots[ss].offset.unwrap())
.min();
func.stack_slots.frame_size = min_offset.map(|off| (-off) as u32);
@@ -271,13 +271,12 @@ impl SubTest for TestBinEmit {
"No encodings found for: {}",
func.dfg.display_inst(inst, isa)
));
} else {
return Err(format!(
}
return Err(format!(
"No matching encodings for {} in {}",
func.dfg.display_inst(inst, isa),
DisplayList(&encodings),
));
}
}
let have = sink.text.trim();
if have != want {

View File

@@ -119,7 +119,7 @@ fn worker_thread(
loop {
// Lock the mutex only long enough to extract a request.
let Request(jobid, path) = match requests.lock().unwrap().recv() {
Err(..) => break, // TX end shuit down. exit thread.
Err(..) => break, // TX end shut down. exit thread.
Ok(req) => req,
};

View File

@@ -19,6 +19,7 @@ mod concurrent;
mod domtree;
mod legalizer;
mod licm;
mod preopt;
mod regalloc;
mod runner;
mod runone;
@@ -64,6 +65,7 @@ fn new_subtest(parsed: &TestCommand) -> subtest::Result<Box<subtest::SubTest>> {
"domtree" => domtree::subtest(parsed),
"legalizer" => legalizer::subtest(parsed),
"licm" => licm::subtest(parsed),
"preopt" => preopt::subtest(parsed),
"print-cfg" => print_cfg::subtest(parsed),
"regalloc" => regalloc::subtest(parsed),
"simple-gvn" => simple_gvn::subtest(parsed),

View File

@@ -0,0 +1,50 @@
//! Test command for testing the preopt pass.
//!
//! The resulting function is sent to `filecheck`.
use cretonne::ir::Function;
use cretonne;
use cton_reader::TestCommand;
use filetest::subtest::{SubTest, Context, Result, run_filecheck};
use std::borrow::Cow;
use std::fmt::Write;
use utils::pretty_error;
struct TestPreopt;
pub fn subtest(parsed: &TestCommand) -> Result<Box<SubTest>> {
assert_eq!(parsed.command, "preopt");
if !parsed.options.is_empty() {
Err(format!("No options allowed on {}", parsed))
} else {
Ok(Box::new(TestPreopt))
}
}
impl SubTest for TestPreopt {
fn name(&self) -> Cow<str> {
Cow::from("preopt")
}
fn is_mutating(&self) -> bool {
true
}
fn run(&self, func: Cow<Function>, context: &Context) -> Result<()> {
// Create a compilation context, and drop in the function.
let mut comp_ctx = cretonne::Context::new();
comp_ctx.func = func.into_owned();
let isa = context.isa.expect("preopt needs an ISA");
comp_ctx.flowgraph();
comp_ctx.preopt(isa).map_err(|e| {
pretty_error(&comp_ctx.func, context.isa, Into::into(e))
})?;
let mut text = String::new();
write!(&mut text, "{}", &comp_ctx.func).map_err(
|e| e.to_string(),
)?;
run_filecheck(&text, context)
}
}

View File

@@ -221,7 +221,7 @@ impl TestRunner {
}
self.tests[jobid].state = State::Done(result);
// Rports jobs in order.
// Reports jobs in order.
while self.report_job() {
self.reported_tests += 1;
}

View File

@@ -17,7 +17,7 @@ use utils::read_to_string;
pub fn run(files: Vec<String>) -> CommandResult {
for (i, f) in files.into_iter().enumerate() {
if i != 0 {
println!("");
println!();
}
print_cfg(f)?
}
@@ -100,7 +100,7 @@ fn print_cfg(filename: String) -> CommandResult {
for (idx, func) in items.into_iter().enumerate() {
if idx != 0 {
println!("");
println!();
}
print!("{}", CFGPrinter::new(&func));
}

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# This is the top-level test script:
#
@@ -10,8 +11,9 @@
#
# All tests run by this script should be passing at all times.
# Exit immediately on errors.
set -e
# Disable generation of .pyc files because they cause trouble for vendoring
# scripts, and this is a build step that isn't run very often anyway.
export PYTHONDONTWRITEBYTECODE=1
# Repository top-level directory.
cd $(dirname "$0")

View File

@@ -0,0 +1,77 @@
(module
(type (;0;) (func (param i32 i64 f64) (result f64)))
(type (;1;) (func))
(type (;2;) (func (result f32)))
(type (;3;) (func (result f64)))
(type (;4;) (func (param f64 f64) (result f64)))
(type (;5;) (func (result i32)))
(func (result i32)
block (result i32)
unreachable
end
block
end
i32.clz
)
(func (result i32)
loop (result i32)
unreachable
end
block
end
i32.clz
)
(func (;0;) (type 5) (result i32)
nop
block (result i32) ;; label = @1
block ;; label = @2
block ;; label = @3
nop
block ;; label = @4
i32.const 1
if ;; label = @5
nop
block ;; label = @6
nop
nop
loop (result i32) ;; label = @7
nop
block (result i32) ;; label = @8
nop
nop
block (result i32) ;; label = @9
nop
unreachable
end
end
end
block (result i32) ;; label = @7
block ;; label = @8
nop
end
i32.const 0
end
br_if 5 (;@1;)
drop
end
else
nop
end
nop
end
end
end
unreachable
end)
(func
block (result i32)
block (result i32)
i32.const 1
br 1
end
end
drop
)
(table (;0;) 16 anyfunc)
(elem (i32.const 0))
)