To keep cross-compiling straightforward, Cretonne shouldn't have any
behavior that depends on the host. This renames the "Native" calling
convention to "SystemV", which has a defined meaning for each target,
so that it's clear that the calling convention doesn't change
depending on what host Cretonne is running on.
* Add a pre-opt optimization to change constants into immediates.
This converts 'iadd' + 'iconst' into 'iadd_imm', and so on.
* Optimize away redundant `bint` instructions.
Cretonne has a concept of "Testable" values, which can be either boolean
or integer. When the an instruction needing a "Testable" value receives
the result of a `bint`, converting boolean to integer, eliminate the
`bint`, as it's redundant.
* Postopt: Optimize using CPU flags.
This introduces a post-legalization optimization pass which converts
compare+branch sequences to use flags values on CPUs which support it.
* Define a form of x86's `urm` that doesn't clobber FLAGS.
movzbl/movsbl/etc. don't clobber FLAGS; define a form of the `urm`
recipe that represents this.
* Implement a DCE pass.
This pass deletes instructions with no side effects and no results that
are used.
* Clarify ambiguity about "32-bit" and "64-bit" in comments.
* Add x86 encodings for icmp_imm.
* Add a testcase for postopt CPU flags optimization.
This covers the basic functionality of transforming compare+branch
sequences to use CPU flags.
* Pattern-match irsub_imm in preopt.
While the specifics of these terms are debatable, "IR" generally
isn't incorrect in this context, and is the more widely recognized
term at this time.
See also the discussion in #267.
Fixes#267.
Mark loads from globals generated by cton_wasm or by legalization as
`aligned` and `notrap`, since memory for these globals should be
allocated by the runtime environment for that purpose. This reduces
the number of potentially trapping instructions, which can reduce
the amount of metadata required by embedding environments.
This allows us to run the tests via a library call rather than just
as a command execution. And, it's a step toward a broader goal, which
is to keep the code in the top-level src directory minimal, with
important functionality exposed as crates.
Refactor the filetests harness so that it can be run as part of
`cargo test`. And begin reorganizing the test harness code in preparation
for moving it out of the src directory.
- Test subcommand files are now named `test_*.rs`.
- cton-util subcommand files now just export their `run` and nothing else.
- src/filetest/mod.rs now also just exports `run` and nothing else.
- Tests are now run in release mode (with debug assertions enabled).
The term "local variables" predated the SSA builder in the front-end
crate, which also provides a way to implement source-language local
variables. The name "explicit stack slot" makes it clear what this
construct is.
This is the floating point equivalent of trapif: Trap when a given
condition is in the floating-point flags.
Define Intel encodings comparable to the trapif encodings.
This instruction loads a stack limit from a global variable and compares
it to the stack pointer, trapping if the stack has grown beyond the
limit.
Also add a expand_flags transform group containing legalization patterns
for ISAs with CPU flags.
Fixes#234.
Changes:
* Adds a new generic instruction, SELECTIF, that does value selection (a la
conditional move) similarly to existing SELECT, except that it is
controlled by condition code input and flags-register inputs.
* Adds a new Intel x86_64 variant, 'baseline', that supports SSE2 and
nothing else.
* Adds new Intel x86_64 instructions BSR and BSF.
* Implements generic CLZ, CTZ and POPCOUNT on x86_64 'baseline' targets
using the new BSR, BSF and SELECTIF instructions.
* Implements SELECTIF on x86_64 targets using conditional-moves.
* new test filetests/isa/intel/baseline_clz_ctz_popcount.cton
(for legalization)
* new test filetests/isa/intel/baseline_clz_ctz_popcount_encoding.cton
(for encoding)
* Allow lib/cretonne/meta/gen_legalizer.py to generate non-snake-caseified
Rust without rustc complaining.
Fixes#238.
Add a "cfg_postorder:" printout to the "test domtree" file tests and use
that to check the computed CFG post-order instead of doing it manually
with Rust code.
`stack_addr` and unrestricted loads and stores *can* be used with entirely
defined behavior. The sense in which they're not "safe" is only that it's
possible to misuse them. This subtlety wasn't captured in the definition
of "safe" here, so for now, just remove the definition so that it doesn't
cause confusion.
* Clarify undefined behavior and notrap.
Remove the "No undefined behavior" paragraph from the README. The other
paragraphs, specifically "Portable semantics" and
"Fast sandbox verification", describe Cretonne's goals in this area.
Define *addressable* and *accessible* memory, so that trapping remains a fully defined part of the semantics, and we have a clear boundary around undefined behavior, and use these terms to describe related constructs.
Add EBB parameter and EBB argument to the langref glossary to clarify
the distinction between formal EBB parameter values and arguments passed
to branches.
- Replace "ebb_arg" with "ebb_param" in function names that deal with
EBB parameters.
- Rename the ValueDef variants to Result and Param.
- A bunch of other small langref fixes.
No functional changes intended.
Add integer and floating comparison instructions that return CPU flags:
ifcmp, ifcmp_imm, and ffcmp.
Add conditional branch instructions that check CPU flags: brif, brff
Add instructions that check a condition in the CPU flags and return a
b1: trueif, trueff.
These two value types represent the state of CPU flags after an integer
comparison and a floating point comparison respectively.
Instructions using these types TBD.
The value types are now classified into three groups:
1. Lane types are scalar types that can also be used to form vectors.
2. Vector types 2-256 copies of a lane type.
3. Special types. This is where the CPU flag types will go.
The special types can't be used to form vectors.
Change the numbering scheme for value types to make room for the special
types and add `is_lane()` and `is_special()` classification methods.
The VOID type still has number 0, but it can no longer appear as a
vector lane. It classifies as special now.
The word "scalar" is a bit vague and tends to mean "non-vector". Since
we are about to add new CPU flag value types that can't appear as vector
lanes, make the distinction clear: LaneType represents value types that
can appear as a vector lane.
Also replace the Type::is_scalar() method with an is_vector() method.
These are parallels to the existing regmove instruction, but the divert
the value to and from a stack slot.
Like regmove diversions, this is a temporary diversion that must be
local to the EBB.
The expansion of a heap_addr instruction depends on the type of heap and
its configuration, so this is handled by custom code.
Add a couple examples of heap access code to the language reference
manual.
Add preamble syntax for declaring static and dynamic heaps, and update
the langref section on heaps. Add IR support for heap references.
Remove the heap_load and heap_store as discussed in #144. We will use
heap_addr along with native load and store instructions in their place.
Add the heap_addr instruction and document its bounds checking
semantics.
The code to compute the address of a global variable depends on the kind
of variable, so custom legalization is required.
- Add a legalizer::globalvar module which exposes an
expand_global_addr() function. This module is likely to grow as we add
more types of global variables.
- Add a ArgumentPurpose::VMContext enumerator. This is used to represent
special 'vmctx' arguments that are used as base pointers for vmctx
globals.
See #144 for discussion.
- Add a new GlobalVar entity type both in Python and Rust.
- Define a UnaryGlobalVar instruction format containing a GlobalVar
reference.
- Add a globalvar.rs module defining the GlobalVarData with support for
'vmctx' and 'deref' global variable kinds.
Langref:
Add a section about global variables and the global_addr
instruction.
Parser:
Add support for the UnaryGlobalVar instruction format as well as
global variable declarations in the preamble.