A CallConv enum on every function signature makes it possible to
generate calls to functions with different calling conventions within
the same ISA / within a single function.
The calling conventions also serve as a way of customizing Cretonne's
behavior when embedded inside a VM. As an example, the SpiderWASM
calling convention is used to compile WebAssembly functions that run
inside the SpiderMonkey virtual machine.
All function signatures must have a calling convention at the end, so
this changes the textual IL syntax.
Before:
sig1 = signature(i32, f64) -> f64
After
sig1 = (i32, f64) -> f64 native
sig2 = (i32) spiderwasm
When printing functions, the signature goes after the return types:
function %r1() -> i32, f32 spiderwasm {
ebb1:
...
}
In the parser, this calling convention is optional and defaults to
"native". This is mostly to avoid updating all the existing test cases
under filetests/. When printing a function, the calling convention is
always included, including for "native" functions.
ARM has all of these as scalar integer instructions. Intel has band_not
in SSE and as a scalar in BMI1.
Add the trivial legalization patterns that use a bnot instruction.
Add instructions representing Intel's division instructions which use a
numerator that is twice as wide as the denominator and produce both the
quotient and remainder.
Add encodings for the x86_[su]divmodx instructions.
* Clarify that extended basic blocks are abbreviated as EBB.
* Fix typo.
* Fix a typo.
* Fix typos.
* Use the same phrase to indicate scalar-only as other places in the doc.
* Mention that `band_imm` and friends are scalar-only.
And mention that they're equivalent to their respective
non-immediate-form counterparts.
Add a StackSlotKind enumeration to help keep track of the different
kinds of stack slots supported:
- Incoming and outgoing function arguments on the stack.
- Spill slots and locals.
Change the text format syntax for declaring a stack slot to use a kind
keyword rather than just 'stack_slot'.
* Function names should start with %
* Create FunctionName from string
* Implement displaying of FunctionName as %nnnn with fallback to #xxxx
* Run rustfmt and fix FunctionName::with_string in parser
* Implement FunctionName::new as a generic function
* Binary function names should start with #
* Implement NameRepr for function name
* Fix examples in docs to reflect that function names start with %
* Rebase and fix filecheck tests
Enumerate a set of special purposes for function arguments that general
purpose code needs to know about. Some of these argument purposes will
only appear in the signature of the current function, representing
things the prologue and epilogues need to know about like the link
register and callee-saved registers.
Get rid of the 'inreg' argument flag. Arguments can be pre-assigned to a
specific register instead.
Any *.cton files in the docs directory are now included when running the
test-all.sh script. This is to ensure that the examples are in fact
correct IL.
Always print NaN and Inf floats with a sign. Print the positive ones as
+NaN and +Inf to make them easier to parse.
This instruction behaves like icmp fused with brnz, and it can be used
to represent fused compare+branch instruction on Intel when optimizing
for macro-op fusion.
RISC-V provides compare-and-branch instructions directly, and it is
needed there too.
Compare a scalar integer to an immediate constant. Both Intel and RISC-V
ISAs have this operation.
This requires the addition of a new IntCompareImm instruction format.
No instruction sets actually have single instructions for materializing
vector constants. You always need to use a constant pool.
Cretonne doesn't have constant pools yet, but it will in the future, and
that is how vector constants should be represented.
Instruction formats are now identified by a signature that doesn't
include the ordering of value operands relative to immediate operands.
This means that the BinaryRev instruction format becomes redundant, so
delete it. The isub_imm instruction was the only one using that format.
Rename it to irsub_imm to make it clear what it does now that it is
printed as 'irsub_imm v2, 45'.
Add support for two new type variable functions: half_vector() and
double_vector().
Use these two instructions to break down unsupported SIMD types and
build them up again.
Specify the location of arguments as well as the size of stack argument
array needed. The ABI annotations are optional, just like the value
locations.
Remove the Eq implementation for Signature which was only used by a
single parser test.
The copy/spill/fill instructions will be used by the register allocator
for splitting live ranges. The copy instruction is also useful when
rewriting values:
If a primary value is rewritten as a secondary result, a copy
instruction can be used instead:
a = foo x
=>
t, vx1 = call ...
a = copy vx1
Since a primary value must be the first value of an instruction, this
doesn't work:
a = foo x
=>
t, a = call ...
These refer to external functions and function signatures declared in
the preamble. Since we're already using the type names 'Signature' and
'Function', these entity references don't folow the usual EntityData /
Entity naming convention.
The isplit_lohi instruction breaks an integer into two halves. This will
typically be used to get the two halves of an `i64` value on 32-bit
CPUs.
The iconcat_lohi is the reverse operation. It reconstructs the `i64`
from the low and high bits.
This was supposed to make verification fast, but WebAssembly is no longer in
this form since it's blocks can produce values.
Also, computing a flow graph and dominator tree is really fast anyway.
It is possible to return multiple values from a function, so ReturnData contains
a VariableArgs instance.
We don't want return instructions to appear as 'return (v1)', so tweak the
printing of VariableArgs so the parantheses are added externally.
Naming is interesting here. Since 'truncate' refers to removing the least
significant digits, use 'ireduce' instead. The 'extend' use is fairly
established. Don't abbreviate, avoid unfortunate modern vernacular.
This instruction uses two type variables: input and output. Make sure that our
parser can handle it. The output type variable annotation is mandatory.
Add a ValueTypeSet::example() method which is used to provide better diagnostics
for a missing type variable.
Add new intcc and floatcc operand types for the immediate condition codes on
these instructions.
Add new IntCompare and FloatCompare instruction formats.
Add a generic match_enum() parser function that can match any identifier-like
enumerated operand kind that implements FromStr.
Define the icmp and fcmp instructions in case.py. Include documentation for the
condition codes with these two instructions.