Commit Graph

55 Commits

Author SHA1 Message Date
Dan Gohman
685cde98a4 Mark loads from globals aligned and notrap.
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.
2018-03-26 21:21:54 -07:00
Dan Gohman
c59e9180de Tidy up whitespace. 2018-03-05 06:55:27 -08:00
Julian Seward
7054f25abb Adds support to transform integer div and rem by constants into cheaper equivalents.
Adds support for transforming integer division and remainder by constants
into sequences that do not involve division instructions.

* div/rem by constant powers of two are turned into right shifts, plus some
  fixups for the signed cases.

* div/rem by constant non-powers of two are turned into double length
  multiplies by a magic constant, plus some fixups involving shifts,
  addition and subtraction, that depends on the constant, the word size and
  the signedness involved.

* The following cases are transformed: div and rem, signed or unsigned, 32
  or 64 bit.  The only un-transformed cases are: unsigned div and rem by
  zero, signed div and rem by zero or -1.

* This is all incorporated within a new transformation pass, "preopt", in
  lib/cretonne/src/preopt.rs.

* In preopt.rs, fn do_preopt() is the main driver.  It is designed to be
  extensible to transformations of other kinds of instructions.  Currently
  it merely uses a helper to identify div/rem transformation candidates and
  another helper to perform the transformation.

* In preopt.rs, fn get_div_info() pattern matches to find candidates, both
  cases where the second arg is an immediate, and cases where the second
  arg is an identifier bound to an immediate at its definition point.

* In preopt.rs, fn do_divrem_transformation() does the heavy lifting of the
  transformation proper.  It in turn uses magic{S,U}{32,64} to calculate the
  magic numbers required for the transformations.

* There are many test cases for the transformation proper:
    filetests/preopt/div_by_const_non_power_of_2.cton
    filetests/preopt/div_by_const_power_of_2.cton
    filetests/preopt/rem_by_const_non_power_of_2.cton
    filetests/preopt/rem_by_const_power_of_2.cton
    filetests/preopt/div_by_const_indirect.cton
  preopt.rs also contains a set of tests for magic number generation.

* The main (non-power-of-2) transformation requires instructions that return
  the high word of a double-length multiply.  For this, instructions umulhi
  and smulhi have been added to the core instruction set.  These will map
  directly to single instructions on most non-intel targets.

* intel does not have an instruction exactly like that.  For intel,
  instructions x86_umulx and x86_smulx have been added.  These map to real
  instructions and return both result words.  The intel legaliser will
  rewrite {s,u}mulhi into x86_{s,u}mulx uses that throw away the lower half
  word.  Tests:
    filetests/isa/intel/legalize-mulhi.cton (new file)
    filetests/isa/intel/binary64.cton (added x86_{s,u}mulx encoding tests)
2018-02-28 11:41:36 -08:00
Jakob Stoklund Olesen
b9b1d0fcd5 Add a trapff instruction.
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.
2018-02-20 14:35:41 -08:00
Jakob Stoklund Olesen
3ccc3f4f9b Add a stack_check instruction.
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.
2018-02-13 10:48:06 -08:00
Jakob Stoklund Olesen
73c4c356c9 Add an ifcmp_sp instruction.
This will be used to implement the stack_check macro.
2018-02-09 13:59:49 -08:00
Jakob Stoklund Olesen
11c721934c Add a trapif instruction.
This is a conditional trap controlled by integer CPU flags.
Compare to brif.
2018-02-08 14:40:46 -08:00
Julian Seward
6f8a54b6a5 Adds support for legalizing CLZ, CTZ and POPCOUNT on baseline x86_64 targets.
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.
2018-02-06 09:43:00 -08:00
Tyler McMullen
ced39f5186 Fix up adjust_sp_imm instruction.
* Use imm64 rather than offset32
* Add predicate to enforce signed 32-bit limit to imm
* Remove AdjustSpImm format
* Add encoding tests for adjust_sp_imm
* Adjust use of adjust_sp_imm in Intel prologue_epilogue to match
2017-12-05 11:49:12 -08:00
Tyler McMullen
3b1b33e0ac Add docs and tests for copy_special instruction. Fixes encoding issue that tests revealed. 2017-12-05 11:49:12 -08:00
Tyler McMullen
ffab87318e Add adjust_sp_imm instruction. Note: This enables using rsp and rbp as normal registers. Which is... wrong. 2017-12-05 11:49:12 -08:00
Tyler McMullen
cdf70ccb77 Add copy_special instruction. 2017-12-05 11:49:12 -08:00
Dan Gohman
9c54c3fff0 Introduce globalsym_addr.
This is an instruction used in legalization of GlobalVarData::Sym global
variables.
2017-10-30 13:26:56 -07:00
Dan Gohman
fc0671a0cf Avoid dangling references to block params when sealing an unreachable block. 2017-10-25 10:04:18 -07:00
Dan Gohman
7c9b9e3d27 Mark spill and fill as can_store and can_load.
This allows GVN to avoid hoisting them. These will be to coarse for
things that want more precise dependence information, however we can
work that out when we build such things.
2017-10-19 13:11:33 -07:00
Dan Gohman
3ccee371a7 Remove the todo for smod.
It's not present in either WebAssembly or Rust, for example. We can
still add smod in the future if future use cases need it.
2017-10-19 12:59:10 -07:00
Dan Gohman
55bc368bf8 Remove minnum/maxnum. 2017-10-18 15:44:17 -07:00
Jakob Stoklund Olesen
1f98fc491c Add instructions using CPU flags.
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.
2017-10-12 19:12:28 -07:00
Jakob Stoklund Olesen
dda3efcbdd Add regspill and regfill instructions.
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.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
e8723be33f Add trap codes to the Cretonne IL.
The trap and trapz/trapnz instructions now take a trap code immediate
operand which indicates the reason for trapping.
2017-09-20 15:50:02 -07:00
Jakob Stoklund Olesen
d92686d1cd Add a func_addr instruction.
Get the callable address of a function. Use for long distance calls and
for creating arguments to call_indirect in general.
2017-09-19 15:54:02 -07:00
Jakob Stoklund Olesen
3b71a27632 Add heaps to the Cretonne IL.
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.
2017-08-23 14:15:59 -07:00
Jakob Stoklund Olesen
bf4ae3bb2e Add global variables to Cretonne IL.
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.
2017-08-17 14:41:27 -07:00
Jakob Stoklund Olesen
7e402a6104 Document memory operation flags.
Also move the extending loads and truncating stores into the bulkier
"Operations" section to improve the flow of the "Memory" section in the
language reference.
2017-08-17 10:42:43 -07:00
Denis Merigoux
07e1f682d0 Added Intel x86-64 encodings for 64bit loads and store instructions (#127)
* Added Intel x86-64 encodings for 64bit loads and store instructions

* Using GPR registers instead of ABCD for istore8 with REX prefix
Fixed testing of 64bit intel encoding

* Emit REX and REX-less encodings for optional REX prefix
Value renumbering in binary64.cton
2017-07-31 14:52:39 -07:00
Dimo
d5ca31a6fd bextend/breduce need constraints 2017-07-28 10:47:08 -07:00
Jakob Stoklund Olesen
a42eaa77b4 Add bitwise ops that invert the second operand.
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.
2017-07-20 11:20:06 -07:00
Dan Gohman
5a4aa11274 Add a bconst instruction. (#116)
* Add a bconst instruction.
2017-07-13 10:12:25 -07:00
Jakob Stoklund Olesen
435a15b88d Add Intel encodings for popcnt.
Change the result type for the bit-counting instructions from a fixed i8
to the iB type variable which is the type of the input. This matches the
convention in WebAssembly, and at least Intel's instructions will set a
full register's worth of count result, even if it is always < 64.

Duplicate the Intel 'ur' encoding recipe into 'umr' and 'urm' variants
corresponding to the RM and MR encoding variants. The difference is
which register is encoded as 'reg' and which is 'r/m' in the ModR/M
byte. A 'mov' register copy uses the MR variant, a unary popcnt uses the
RM variant.
2017-07-12 14:17:16 -07:00
Jakob Stoklund Olesen
d56d4d171e Tag the regmove instruction with other_side_effects.
This instruction moves a value between registers. This counts as a side
effect that is not tracked by the SSA data flow graph.
2017-07-12 10:43:42 -07:00
d1m0
7c438f866c Add fix for #114 (#115)
* Reduce code duplication in TypeConstraint subclasses; Add ConstrainWiderOrEqual to ti and to ireduce,{s,u}extend and f{promote,demote}; Fix bug in emitting constraint edges in TypeEnv.dot(); Modify runtime constraint checks to reject match when they encounter overflow

* Rename Constrain types to something shorter; Move lane_bits/lane_counts in subclasses of ValueType; Add wider_or_eq function in rust and python;
2017-07-12 08:51:55 -07:00
Dan Gohman
4a5d48fe11 Documentation fixes (#103)
* 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.
2017-06-22 12:01:32 -07:00
Dan Gohman
c826aefa0a Start a very simple GVN pass (#79)
* Skeleton simple_gvn pass.
* Basic testing infrastructure for simple-gvn.
* Add can_load and can_store flags to instructions.
* Move the replace_values function into the DataFlowGraph.
* Make InstructionData derive from Hash, PartialEq, and Eq.
* Make EntityList's hash and eq functions panic.
* Change Ieee32 and Ieee64 to store u32 and u64, respectively.
2017-05-18 18:18:57 -07:00
Dan Gohman
976b22d816 Make srem have the sign of the dividend.
This is how remainder is defined in C (as of C99), C++ (as of C++11), Rust,
and WebAssembly, for example.
2017-05-09 12:28:15 -07:00
Jakob Stoklund Olesen
950838c489 Add a regmove instruction.
This will be used to locally change the register locations of values in
order to satisfy instruction constraints.
2017-05-02 11:32:12 -07:00
Jakob Stoklund Olesen
0cb36c9031 Remove the return_reg instruction.
RISC architectures that take a return address in a register can use a
special-purpose `link` return value to do so.
2017-04-19 16:08:16 -07:00
Jakob Stoklund Olesen
b4ac520332 Extending loads and truncating stores 2017-04-11 10:30:03 -07:00
Jakob Stoklund Olesen
aad6ebebb5 Add load and store instructions.
Define a MemFlags class, currently holding a notrap and aligned flag.
2017-04-11 09:54:55 -07:00
Jakob Stoklund Olesen
b474485c0d Add heap_load, heap_store, and heap_addr instructions.
These are used when lowering WebAssembly sandbox code.
2017-04-10 15:04:33 -07:00
Jakob Stoklund Olesen
222ae8af22 Define stack_load, stack_store, and stack_addr instructions. 2017-04-10 13:56:57 -07:00
Jakob Stoklund Olesen
fa4f151b9b Add a fallthrough instruction.
Change jumps to fallthroughs in the branch relaxation pass before
computing the EBB offsets.
2017-04-06 14:22:32 -07:00
Jakob Stoklund Olesen
1b6a6f4e48 Add the br_icmp instruction.
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.
2017-04-03 15:04:42 -07:00
Jakob Stoklund Olesen
e23d12bbc7 Add an icmp_imm instruction.
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.
2017-04-03 09:49:44 -07:00
Jakob Stoklund Olesen
7a0092754d Allow vector types for isplit and iconcat.
These two instructions make sense for vector types by simply performing
the same operation on each lane, like most other vector operations.

Problem found by @angusholder's verifier.
2017-03-29 15:18:39 -07:00
Jakob Stoklund Olesen
272df6489c Iteratively split EBB arguments.
When the legalizer splits a value into halves, it would previously stop
if the value was an EBB argument. With this change, we also split EBB
arguments and iteratively split arguments on branches to the EBB.

The iterative splitting stops when we hit the entry block arguments or
an instruction that isn't one of the concatenation instructions.
2017-03-22 13:12:19 -07:00
Jakob Stoklund Olesen
2a321f42fb Strip the _lohi suffix from the isplit instructions.
For symmetry with the vector splitting instructions, we now have:

    isplit iconcat
    vsplit vconcat

No functional change.
2017-03-21 13:22:50 -07:00
Angus Holder
11a0daa7fd Define boolean conversion instructions. 2017-03-11 10:25:55 -08:00
Jakob Stoklund Olesen
9fbfd0d2a6 Remove the vconst instruction and the UnaryImmVector 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.
2017-03-10 11:57:49 -08:00
Jakob Stoklund Olesen
c50e5f3f66 Separate immediate and value operands in the instruction format.
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'.
2017-03-10 11:20:39 -08:00
Jakob Stoklund Olesen
ecc46e56e1 Add is_call and is_return instruction attributes. 2017-03-08 14:48:50 -08:00