Commit Graph

81 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
a4a8c83aab Start adding Intel 64-bit encodings.
Add a TailRecipe.rex() method which creates an encoding recipe with a
REX prefix.

Define I64 encodings with REX.W for i64 operations and with/without REX
for i32 ops. Only test the with-REX encodings for now. We don't yet have
an instruction shrinking pass that can select the non-REX encodings.
2017-07-11 11:05:27 -07:00
Jakob Stoklund Olesen
fb227cb389 Move Intel recipe_* bodies into intel/recipes.py.
Use a PUT_OP macro in the TailRecipe Python class to replace the code
snippet that emits the prefixes + opcode part of the instruction encoding.

Prepare for the addition of REX prefixes by giving the PUT_OP functions
a third argument representing the REX prefix. For the non-REX encodings,
verify that no REX bits wold be needed.
2017-07-11 11:05:27 -07:00
Jakob Stoklund Olesen
528e6ff3f5 Generate instruction unwrapping code for binemit recipes.
Generate code to:

- Unwrap the instruction and generate an error if the instruction format
  doesn't match the recipe.
- Look up the value locations of register and stack arguments.

The recipe_* functions in the ISA binemit modules now take these
unwrapped items as arguments.

Also add an optional `emit` argument to the EncRecipe constructor which
makes it possible to provide inline Rust code snippets for code
emission. This requires a lot less boilerplate than recipe_* functions.
2017-07-07 15:10:17 -07:00
Jakob Stoklund Olesen
9662f102e5 Intel 32-bit encodings for copy.i32. 2017-07-05 15:48:06 -07:00
Jakob Stoklund Olesen
811c1059fc Add Intel call/return encodings. 2017-06-30 12:21:36 -07:00
Jakob Stoklund Olesen
c592d3174f Add Intel iconst.i32 encoding. 2017-06-30 11:41:06 -07:00
Jakob Stoklund Olesen
7bc2e82b16 Implement the basics of the x86-64 ABI.
This is just a rough sketch to get us started. There are bound to be
some issues.

This also legalizes signatures for x86-32, but probably not correctly.
It's basically implementing the x86-64 ABI for 32-bit.
2017-06-30 10:41:26 -07:00
Jakob Stoklund Olesen
05cf44a156 Add an offset to StackSlotData.
The offset is relative to the stack pointer in the calling function, so
it excludes the return address pushed by the call instruction itself on
Intel ISAs.

Change the ArgumentLoc::Stack offset to an i32, so it matches the stack
slot offsets.
2017-06-28 14:38:13 -07:00
Jakob Stoklund Olesen
e15c332471 Encode iconst.i32 for RISC-V.
For large constants with the low 12 bits clear, we already have the
"lui" encoding. Add "addi %x0" encodings for signed 12-bit constants.
2017-06-22 12:13:37 -07:00
Jakob Stoklund Olesen
b6cff6a98a Move EntityRef and entity_impl! into a new module.
The EntityRef trait is used by more than just the EntityMap now, so it
should live in its own module.

Also move the entity_impl! macro into the new module so it can be used
for defining new entity references anywhere.
2017-06-20 10:16:27 -07:00
Dan Gohman
0c7316ae28 Lint fixes (#99)
* Replace a single-character string literal with a character literal.

* Use is_some() instead of comparing with Some(_).

* Add code-quotes around type names in comments.

* Use !...is_empty() instead of len() != 0.

* Tidy up redundant returns.

* Remove redundant .clone() calls.

* Remove unnecessary explicit lifetime parameters.

* Tidy up unnecessary '&'s.

* Add parens to make operator precedence explicit.

* Use debug_assert_eq instead of debug_assert with ==.

* Replace a &Vec argument with a &[...].

* Replace `a = a op b` with `a op= b`.

* Avoid unnecessary closures.

* Avoid .iter() and .iter_mut() for iterating over containers.

* Remove unneeded qualification.
2017-06-19 16:24:10 -07:00
Aleksey Kuznetsov
3693735874 Implement an iterator over encodings (#96)
* Implement an iterator over encodings

* Implement TargetIsa::legal_encodings

* Exclude non-boolean settings of isa flags bytes

* Address flake8 long line error
2017-06-19 08:52:19 -07:00
Jakob Stoklund Olesen
4503306f0e Add RISC-V encodings for call_indirect. 2017-06-14 16:14:16 -07:00
Jakob Stoklund Olesen
3e1e2b6e5e Add RISC-V encodings for copy instructions. 2017-06-14 15:36:25 -07:00
Jakob Stoklund Olesen
5336bbd4cc Add RISC-V encodings for spill and fill.
Add a Stack() class for specifying operand constraints for values on the
stack.

Add encoding recipes for RISC-V spill and fill instructions. Don't
implement the encoding recipe functions yet since we don't have the
stack slot layout yet.
2017-06-13 13:39:52 -07:00
Jakob Stoklund Olesen
6787a4ea5c Add a RegClassMask typedef and a MAX_TOPRCS constant.
Avoid spreading u32 as a bitmask of register classes throughout the
code.

Enforce the limit of 32 register classes total. This could easily be
raised if needed.

The MAX_TOPRCS constant is the highest possible number of top-level
register classes in an ISA. The RegClassData.toprc field is always
smaller than this limit.
2017-05-15 16:22:22 -07:00
Jakob Stoklund Olesen
71bb7483b7 Compute top-level register classes for each register bank.
A top-level register class is one that has no sub-classes. It is
possible to have multiple top-level register classes in the same
register bank. For example, ARM's FPR bank has both D and Q top-level
register classes.

Number register classes such that all top-level register classes appear
as a contiguous sequence starting from 0. This will be used by the
register allocator when counting used registers per top-level register
class.
2017-05-15 15:19:49 -07:00
Jakob Stoklund Olesen
621f3a2f50 Add a register bank index to RegClassData.
This makes it possible to find the register bank that contains a
register class.
2017-05-15 15:17:58 -07:00
Benjamin Bouvier
29dc723e25 Update rustfmt to 0.8.4; (#81) 2017-05-15 15:10:47 -07:00
Jakob Stoklund Olesen
bd8230411a Encodings for load/store instructions.
We don't support the full set of Intel addressing modes yet. So far we
have:

- Register indirect, no displacement.
- Register indirect, 8-bit signed displacement.
- Register indirect, 32-bit signed displacement.

The SIB addressing modes will need new Cretonne instruction formats to
represent.
2017-05-12 16:49:39 -07:00
Jakob Stoklund Olesen
f4929825ca Add subtract and logical instruction encodings to Intel-32.
Also add versions with 8-bit and 32-bit immediate operands.
2017-05-12 15:37:12 -07:00
Jakob Stoklund Olesen
31b7330b8d Return the first applicable encoding from general_encoding().
We'll arrange encoding lists such that the first suitable encoding is
the best choice for the legalizer. This is the most intuitive way of
generating the encodings.

After register allocation, we may choose a different encoding, but that
will require looking at the whole list.
2017-05-12 15:31:08 -07:00
Jakob Stoklund Olesen
6fd95c1158 Implement reloc_names() for all targets.
This gets rid of the last TargetIsa method with a default
implementation.
2017-05-11 17:58:11 -07:00
Jakob Stoklund Olesen
9be262e878 Implement a move resolver for the register constraint solver.
After finding a register solution, it need to be executed as a sequence
of regmove instructions. This often requires a topological ordering of
the moves so they don't conflict.

When the solution contains cycles, try to grab an available scratch
register to implement the copies. Panic if that fails (later, we'll
implement emergency spilling in this case).

Make sure we handle odd aliasing in the arm32 floating point register
bank. Not everything is a simple cycle in that case, so make sure we
don't assume so.
2017-05-11 11:54:02 -07:00
Jakob Stoklund Olesen
6b4c28d554 Use a constraint solver for register coloring.
Most of the time, register coloring is almost trivial: just pick
available registers for the values defined by the current instruction.
However, some instructions have register operand constraints, and it may
be necessary to move live registers around to satisfy the constraints.
Sometimes the instruction's own operands can interfere with each other
in a way that you can't just pick a register assignment for each output
in order.

This is complicated enough that it is worthwhile to represent as a
constraint satisfaction problem in a separate solver module. The
representation is chosen to be very fast in the common case where the
constraints are trivial to solve.

The current implementation is still incomplete, but as functional as the
code it's replacing. Missing features:

- Handle tied operand constraints.
- Handle ABI constraints on calls and return instructions.
- Execute a constraint solution by emitting regmove instructions.
- Handling register diversions before leaving the EBB.
2017-05-09 14:48:45 -07:00
Jakob Stoklund Olesen
a0085434af Add encodings for Intel dynamic shift instructions.
These instructions have a fixed register constraint; the shift amount is
passed in CL.

Add meta language syntax so a fixed register can be specified as
"GPR.rcx".
2017-05-09 13:11:50 -07:00
Jakob Stoklund Olesen
041fda63ac Add the very basics of Intel 32-bit instruction encodings.
Tabulate the Intel opcode representations and implement an OP() function
which computes the encoding bits.

Implement the single-byte opcode with a reg-reg ModR/M byte.
2017-05-08 16:57:38 -07:00
Jakob Stoklund Olesen
39e69ff565 Add constraint summaries to RecipeConstraints.
Most instructions don't have any fixed register constraints. Add boolean
summaries that can be used to check if it is worthwhile to scan the
constraint lists when looking for a fixed register constraint.

Also add a tied_ops summary bool which indicates that the instruction
has tied operand constraints.
2017-05-08 16:41:24 -07:00
Jakob Stoklund Olesen
0f41cbdee2 Add support for tied operand constraints.
The register constraint for an output operand can be specified as an
integer indicating the input operand number to tie. The tied operands
must use the same register.

Generate operand constraints using ConstraintKind::Tied(n) for both the
tied operands. The n index refers to the opposite array. The input
operand refers to the outs array and vice versa.
2017-05-08 16:31:47 -07:00
Jakob Stoklund Olesen
f8a3a01f96 Add a few register utilities. 2017-05-08 13:39:26 -07:00
Jakob Stoklund Olesen
aaa70a677d Add a regs_overlap function to the isa module.
Test it with the arm32 register banks which have the most interesting
properties. Most other registers have a single register unit.
2017-05-08 13:36:27 -07:00
Jakob Stoklund Olesen
ee5f035e31 Upgrade to Rust 1.17.
- Remove some uses of 'static in const and static globals that are no
  longer needed.
- Use the new struct initialization shorthand.
2017-04-27 12:46:44 -07:00
Jakob Stoklund Olesen
6197bfff72 Add a TargetIsa::allocatable_registers() method.
This gives the target ISA a chance to reserve registers like the stack
pointer or hard-wired 0 registers like %x0 on RISC-V.
2017-04-26 13:54:40 -07:00
Jakob Stoklund Olesen
a4acc26d5a Add an enable_e setting for the RV32E instruction set.
This limited RISC-V version only has registers %x0 - %x15.

Make sure the ABI lowering code doesn't use the banned registers for
arguments.
2017-04-26 13:50:52 -07:00
Jakob Stoklund Olesen
2f81fbdb77 Add an Affinity::display() method.
Make it possible to display affinities given a RegInfo reference.
2017-04-26 11:16:38 -07:00
Jakob Stoklund Olesen
e67f5e210f Add a TargetIsa::regclass_for_abi_type() function.
The legalize_signature() function will return ArgumentLoc::Reg arguments
that contain a register unit. However, the register also needs to be
able to associate a register class with the argument values to fully
track the used registers.

When values are defined by instructions, the register class is part for
the operand constraints for the instruction. For values defined on ABI
boundaries like function arguments and return values from a call, the
register class is provided by the new regclass_for_abi_type() function.

Provide implementations of this function in abi modules of all the
targets, even those that don't have a legalize_signature()
implementation yet.

Since we're adding abi modules to all targets, move the
legalize_signature() stubs in there and make the function mandatory in
TargetIsa. All targets will eventually need this function.
2017-04-26 10:29:18 -07:00
Eric Anholt
042418b367 Update a comment for the move of display_enc(). 2017-04-23 17:21:32 -07:00
Jakob Stoklund Olesen
d66a9d196e Implement binary emission of RISC-V return instructions.
The return address is now always supplied in %x1, so the return address
predictor will recognize the jalr as a return and not some indirect
branch.
2017-04-19 16:26:04 -07:00
Jakob Stoklund Olesen
e44a5a4391 Append link and sret arguments in legalize_signature.
These special-purpose arguments and return values are only relevant for
the function being compiled, so add a `current` flag to
legalize_signature().

- Add the necessary argument values to the entry block to represent
  the special-purpose arguments.
- Propagate the link and sret arguments to return instructions if the
  legalized signature asks for it.
2017-04-19 15:55:12 -07:00
Jakob Stoklund Olesen
18b567f88e Flatten the Value reference representation.
All values are now references into the value table, so drop the
distinction between direct and table values. Direct values don't exist
any more.

Also remove the parser support for the 'vxNN' syntax. Only 'vNN' values
can be parsed now.
2017-04-12 14:45:22 -07:00
Jakob Stoklund Olesen
b165d9a313 Remove the first_type() methods from InstructionData.
Also remove the type field from all the variants. The type of the first
result value can be recovered from the value table now.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
28ff7b7925 Move the ctrl_typevar function into dfg.
Soon, InstructionData won't have sufficient information to compute this.

Give TargetIsa::encode() an explicit ctrl_typevar argument. This
function does not require the instruction to be inserted in the DFG
tables.
2017-04-12 14:32:13 -07:00
Jakob Stoklund Olesen
4ee519e620 Add RISC-V call instruction encodings.
Calls are jal with a fixed %x1 link register.
2017-04-11 10:40:38 -07:00
Jakob Stoklund Olesen
896ac935b9 Add jump encodings to RISC-V.
Fix a bug in gen_encoding.py when dealing with non-polymorphic
instructions where the type variable is None in Python, VOID in Rust.
2017-04-06 15:17:57 -07:00
Jakob Stoklund Olesen
856a67ca3a Use EBB offsets for encoding RISC-V branches.
Stop emitting EBB relocations. Use the offsets computed by
relax_branches() to encode the correct displacements immediately.
2017-04-06 12:55:57 -07:00
Jakob Stoklund Olesen
598c81c12e Add encoding size information to EncInfo.
Two new pieces of information are available for all encoding recipes:

- The size in bytes of an encoded instruction, and
- The range of a branch encoded with the recipe, if any.

In the meta language, EncRecipe takes two new constructor arguments. The
size is required for all encodings and branch_range is required for all
recipes used to encode branches.
2017-04-05 11:46:19 -07:00
Jakob Stoklund Olesen
f47c62ba8c Move encoding-related information into an EncInfo struct.
The tables returned by recipe_names() and recipe_constraints() are now
collected into an EncInfo struct that is available from
TargetIsa::encoding_info(). This is equivalent to the register bank
tables available fro TargetIsa::register_info().

This cleans of the TargetIsa interface and makes it easier to add
encoding-related information.
2017-04-05 10:07:19 -07:00
Jakob Stoklund Olesen
1984c96f7c rustfmt 0.8.1 2017-04-05 09:00:11 -07:00
Jakob Stoklund Olesen
e641c97670 Add RISC-V encodings for brz and brnz.
These branches compare a register to zero. RISC-V implements this with
the %x0 hard-coded zero register.
2017-04-03 15:20:57 -07:00
Jakob Stoklund Olesen
479ff156c1 Add conditional branch encodings for RISC-V.
Not all br_icmp opcodes are present in the ISA. The missing ones can be
reached by commuting operands.

Don't attempt to encode EBB offsets yet. For now just emit an EBB
relocation for the branch instruction.
2017-04-03 15:16:25 -07:00