Now that we have a value list of the arguments, we can get rid of:
- The first_arg and last_arg members in EbbData,
- The next member in the ValueData::Arg variant.
Rather than returning the head of a linked list of EBB arguments, just
return the whole value list of all the arguments.
Delete the next_ebb_arg() method which was only used for traversing that
list.
This is the first step of the value list refactoring which will replace
linked lists of values with value lists.
- Keep a ValueList in the EbbData struct containing all the EBB
arguments.
- Change dfg.ebb_args() to return a slice instead of an iterator.
This leaves us in a temporary hybrid state where we maintain both a
linked list and a ValueList vector of the EBB arguments.
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 affects the comparison instructions which now read "icmp ult a, b".
This mimics LLVM's style and makes it simpler to add instruction flags
in the future, such as "load v1" -> "load aligned v1".
These enumerated operands and flags feel like opcode modifiers rather
than value operands, so displaying them differently makes sense.
Value and numeric operands are still comma separated.
Compute exact EBB header offsets and check that branches are in range.
Not implemented yet: Relax branches that are not in range.
Invoke the relax_branches() pass from the 'test binemit' file tests so
they can verify the proper encoding of branch instructions too.
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.
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.
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.
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.
The meaning of format.typevar_operand changes recently to be relative to
value operands only instead of all operands. The Sphinx cton domain
wasn't updated.
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.
When defining an instruction encoding, allow part of the instruction
predicate to be provided as operands on the instruction opcode:
icmp.i32(intcc.ult, x, y)
This generates an instruction predicate that checks
IntCompare.cond == IntCC::UnsignedLessThan
Compute an instruction predicate from any constant values given as
arguments for the immediate operands in an instruction pattern.
Allows for patterns like icmp.i32(intcc.ugt, x, y) or iadd_imm.i32(x, 1)
Trap these predicates in the legalizer code generator since we can't
actually handle them yet.
Consolidate the imm_members and imm_kinds into this list so the
FormatField is the single definition of these properties.
This makes it easier to access the precomputed FormatFields
parametrically, avoiding going through getattr().
This is better for type checking too.
The meta language patterns sometimes need to refer to specific values of
enumerated immediate operands. The dot syntax provides a namespaced,
typed way of doing that: icmp(intcc.ult, a, x).
Add an ast.Enumerator class for representing this kind of AST leaf node.
Add value definitions for the intcc and floatcc immediate operand kinds.
Run the verify_contexti() function after invoking the legalize() and
regalloc() context functions. This will help catch bad code produced by
these passes.
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.