Merge remote-tracking branch 'origin/master' into no_std
This commit is contained in:
@@ -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]
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
==================
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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::
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
45
cranelift/filetests/isa/intel/legalize-mulhi.cton
Normal file
45
cranelift/filetests/isa/intel/legalize-mulhi.cton
Normal 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
|
||||
}
|
||||
@@ -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: }
|
||||
|
||||
@@ -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
|
||||
|
||||
60
cranelift/filetests/preopt/div_by_const_indirect.cton
Normal file
60
cranelift/filetests/preopt/div_by_const_indirect.cton
Normal 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
|
||||
}
|
||||
267
cranelift/filetests/preopt/div_by_const_non_power_of_2.cton
Normal file
267
cranelift/filetests/preopt/div_by_const_non_power_of_2.cton
Normal 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
|
||||
}
|
||||
293
cranelift/filetests/preopt/div_by_const_power_of_2.cton
Normal file
293
cranelift/filetests/preopt/div_by_const_power_of_2.cton
Normal 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
|
||||
}
|
||||
286
cranelift/filetests/preopt/rem_by_const_non_power_of_2.cton
Normal file
286
cranelift/filetests/preopt/rem_by_const_non_power_of_2.cton
Normal 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
|
||||
}
|
||||
292
cranelift/filetests/preopt/rem_by_const_power_of_2.cton
Normal file
292
cranelift/filetests/preopt/rem_by_const_power_of_2.cton
Normal 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
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
50
cranelift/src/filetest/preopt.rs
Normal file
50
cranelift/src/filetest/preopt.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
77
cranelift/wasmtests/unreachable_code.wat
Normal file
77
cranelift/wasmtests/unreachable_code.wat
Normal 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))
|
||||
)
|
||||
Reference in New Issue
Block a user