| Age | Commit message (Collapse) | Author |
|
|
|
|
|
Bitvectors that aren't fixed size, but can still be shown to fit
within 64-bits, now have a specialised representation. Still need to
introduce more optimized functions, as right now we mostly have to
convert them into large bitvectors to pass them into most
functions. Nevertheless, this doubles the performance of the TLBLookup
function in ARMv8.
|
|
- Propagate types more accurately to improve optimization on ANF
representation.
- Add a generic optimization pass to remove redundant variables that
simply alias other variables.
- Modify Sail interactive mode, so it can compile a specification with
the :compile command, view generated intermediate representation via
the :ir <function> command, and step-through the IR with :exec <exp>
(although this is very incomplete)
- Introduce a third bitvector representation, between fast
fixed-precision bitvectors, and variable length large
bitvectors. The bitvector types are now from most efficient to least
* CT_fbits for fixed precision, 64-bit or less bitvectors
* CT_sbits for 64-bit or less, variable length bitvectors
* CT_lbits for arbitrary variable length bitvectors
- Support for generating C code using CT_sbits is currently
incomplete, it just exists in the intermediate representation right
now.
- Include ctyp in AV_C_fragment, so we don't have to recompute it
|
|
|
|
because >100 field records slow everything down
|
|
|
|
|
|
71020c2f460e6031776df17cf8f2f71df5bb9730 introduced assert error messages containing " revealing unescaped string literals in generated lem and prompting review of other backends.
|
|
|
|
|
|
Also fix some C optimisations
|
|
|
|
Also fix a test with an insufficient constraint
|
|
Fixes CHERI Lem build
|
|
This was _really_ slow - about 50secs for ARM. If this changes causes
breakages we should fix them in some other way.
Also using Reporting.err_unreachable in ANF translation, and fix slice
optimization when creating slices larger than 64-bits in C translation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This brings Sail closer to MiniSail, and means that
type my_range 'n 'm = {'o, 'n <= 'o <= 'm. int('o)}
will work on the left hand side of a function type in the same way as
a regular built-in range type. This means that in principle neither
range nor int need be built-in types, as both can be implemented in
terms of int('n) (atom internally). It also means we can easily
identify type variables that need to be made into implict arguments,
with the criterion for that being simply any type variable that
doesn't appear in a base type on the LHS of the function, or only
appears on the RHS.
|
|
|
|
|
|
|
|
details (TODO make this optional).
|
|
|
|
|
|
usere more flexibility about formatting generated latex.
|
|
Also add a special case for shift-left when we are shifting 8 by a two
bit opcode, or 32 by a one bit opcode.
|
|
This fixes another case we often have to patch manually in translated ASL
code where a function returns a (result, Constraint)-pair.
Also (slightly) improve the error message for when we fail to infer a
l-expression, as we are going to hit this case more often now.
|
|
Previously the following would fail:
```
default Order dec
$include <prelude.sail>
register V : vector(1, dec, vector(32, dec, bit))
val zeros : forall 'n, 'n >= 0. unit -> vector('n, dec, bit)
function main() : unit -> unit = {
V[0] = zeros()
}
```
Since the type-checker wouldn't see that zeros() must have type
`vector(32, dec, bit)` from the type of `V[0]`. It now tries both to
infer the expression, and use that to check the assignment, and if
that fails we infer the lexp to check the assignment. This pattern
occurs a lot in ASL, and we often had to patch zeros() to zeros(32) or
similar there.
|
|
|
|
Also ensure no collisions for function clause constructor categories
|
|
|
|
|
|
The main changes so far are:
* Allow markdown formatting in doc comments. We parse the markdown
using Omd, which is a OCaml library for parsing markdown. The nice
thing about this library is it's pure OCaml and has no dependencies
other the the stdlib. Incidentally it was also developed at OCaml
labs. Using markdown keeps our doc-comments from becoming latex
specfic, and having an actual parser is _much_ nicer than trying to
hackily process latex in doc-comments using OCamls somewhat sub-par
regex support.
* More sane conversion latex identifiers the main approach is to
convert Sail identifiers to lowerCamelCase, replacing numbers with
words, and then add a 'category' code based on the type of
identifier, so for a function we'd have fnlowerCamelCase and for
type synonym typelowerCamelCase etc. Because this transformation is
non-injective we keep track of identifiers we've generated so we end
up with identifierA, identifierB, identifierC when there are
collisions.
* Because we parse markdown in doc comments doc comments can use Sail
identifiers directly in hyperlinks, without having to care about how
they are name-mangled down into TeX compatible things.
* Allow directives to be passed through the compiler to
backends. There are various $latex directives that modify the latex
output. Most usefully there's a
$latex newcommand name markdown
directive that uses the markdown parser to generate latex
commands. An example of why this is useful is bellow. We can also use
$latex noref id
To suppress automatically inserting links to an identifier
* Refactor the latex generator to make the overall generation process
cleaner
* Work around the fact that some operating systems consider
case-sensitive file names to be a good thing
* Fix a bug where latex generation wouldn't occur unless the directory
specified by -o didn't exist
This isn't quite all the requested features for good CHERI
documentation, but new features should be much easier to add now.
|
|
|
|
|
|
|
|
|
|
* Previously we allowed the following bizarre syntax for a forall
quantifier on a function:
val foo(arg1: int('n), arg2: typ2) -> forall 'n, 'n >= 0. unit
this commit changes this to the more sane:
val foo forall 'n, 'n >= 2. (arg1: int('n), arg2: typ2) -> unit
Having talked about it today, we could consider adding the syntax
val foo where 'n >= 2. (arg1: int('n), arg2: typ2) -> unit
which would avoid the forall (by implicitly quantifying variables in
the constraint), and be slightly more friendly especially for
documentation purposes. Only RISC-V used this syntax, so all uses of
it there have been switched to the new style.
* Second, there is a new (somewhat experimental) syntax for
existentials, that is hopefully more readable and closer to
minisail:
val foo(x: int, y: int) -> int('m) with 'm >= 2
"type('n) with constraint" is equivalent to minisail: {'n: type | constraint}
the type variables in typ are implicitly quantified, so this is equivalent to
{'n, constraint. typ('n)}
In order to make this syntax non-ambiguous we have to use == in
constraints rather than =, but this is a good thing anyway because
the previous situation where = was type level equality and == term
level equality was confusing. Now all the type type-level and
term-level operators can be consistent. However, to avoid breaking
anything = is still allowed in non-with constraints, and produces a
deprecated warning when parsed.
|
|
* Previously we allowed the following bizarre syntax for a forall
quantifier on a function:
val foo(arg1: int('n), arg2: typ2) -> forall 'n, 'n >= 0. unit
this commit changes this to the more sane:
val foo forall 'n, 'n >= 2. (arg1: int('n), arg2: typ2) -> unit
Having talked about it today, we could consider adding the syntax
val foo where 'n >= 2. (arg1: int('n), arg2: typ2) -> unit
which would avoid the forall (by implicitly quantifying variables in
the constraint), and be slightly more friendly especially for
documentation purposes. Only RISC-V used this syntax, so all uses of
it there have been switched to the new style.
* Second, there is a new (somewhat experimental) syntax for
existentials, that is hopefully more readable and closer to
minisail:
val foo(x: int, y: int) -> int('m) with 'm >= 2
"type('n) with constraint" is equivalent to minisail: {'n: type | constraint}
the type variables in typ are implicitly quantified, so this is equivalent to
{'n, constraint. typ('n)}
In order to make this syntax non-ambiguous we have to use == in
constraints rather than =, but this is a good thing anyway because
the previous situation where = was type level equality and == term
level equality was confusing. Now all the type type-level and
term-level operators can be consistent. However, to avoid breaking
anything = is still allowed in non-with constraints, and produces a
deprecated warning when parsed.
|
|
|
|
This should fix the issue in cheri128
Also introduce a feature to more easily debug the C backend:
sail -dfunction Name
will pretty-print the ANF and IR representation of just the Name
function. I want to make this work for the type-checker as well, but
it's a bit hard to get that to not fire during re-writing passes right
now.
|
|
This goes partway to resolving issue #23, as it now generates C code,
but it seems like there is still an issue with the generated C.
|
|
|
|
We need to ensure that we expand type-synonyms when calculating which
types a register depends on during topological sorting in order to
place the undefined_type function in the correct place, even when type
is indirected through a function.
|
|
When topologically sorting the top-level definitions, we add the
undefined_X functions for any type X to a registers dependencies if it
uses the type X, this ensures that any such functions are generated
before the register declaration. In theory this is only needed for
OCaml, but adding these edges in the definition graph shouldn't cause
any issues.
|