Load, store, local variables.
This commit is contained in:
@@ -19,7 +19,7 @@ from sphinx.directives import ObjectDescription
|
|||||||
from sphinx.domains import Domain, ObjType
|
from sphinx.domains import Domain, ObjType
|
||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.util.docfields import Field, TypedField
|
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
|
|
||||||
class CtonObject(ObjectDescription):
|
class CtonObject(ObjectDescription):
|
||||||
@@ -120,6 +120,7 @@ class CtonInst(CtonObject):
|
|||||||
TypedField('result', label=l_('Results'),
|
TypedField('result', label=l_('Results'),
|
||||||
names=('out', 'result'),
|
names=('out', 'result'),
|
||||||
typerolename='type', typenames=('type',)),
|
typerolename='type', typenames=('type',)),
|
||||||
|
GroupedField('flag', names=('flag',), label=l_('Flags')),
|
||||||
Field('resulttype', label=l_('Result type'), has_arg=False,
|
Field('resulttype', label=l_('Result type'), has_arg=False,
|
||||||
names=('rtype',)),
|
names=('rtype',)),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class CretonneLexer(RegexLexer):
|
|||||||
# Reserved words.
|
# Reserved words.
|
||||||
(keywords('function', 'entry'), Keyword),
|
(keywords('function', 'entry'), Keyword),
|
||||||
# Known attributes.
|
# Known attributes.
|
||||||
(keywords('align', 'uext', 'sext', 'inreg'), Name.Attribute),
|
(keywords('align', 'aligntrap', 'uext', 'sext', 'inreg'), Name.Attribute),
|
||||||
# Well known value types.
|
# Well known value types.
|
||||||
(r'\b(bool|i\d+|f32|f64)(x\d+)?\b', Keyword.Type),
|
(r'\b(bool|i\d+|f32|f64)(x\d+)?\b', Keyword.Type),
|
||||||
# v<nn> = value
|
# v<nn> = value
|
||||||
@@ -38,7 +38,7 @@ class CretonneLexer(RegexLexer):
|
|||||||
(r'(ebb)\d+', Name.Label),
|
(r'(ebb)\d+', Name.Label),
|
||||||
# Match instruction names in context.
|
# Match instruction names in context.
|
||||||
(r'(=)( *)([a-z]\w*)', bygroups(Operator, Whitespace, Name.Function)),
|
(r'(=)( *)([a-z]\w*)', bygroups(Operator, Whitespace, Name.Function)),
|
||||||
(r'^( +)([a-z]\w*\b)(?! *[,=])', bygroups(Whitespace, Name.Function)),
|
(r'^( *)([a-z]\w*\b)(?! *[,=])', bygroups(Whitespace, Name.Function)),
|
||||||
# Other names: results and arguments
|
# Other names: results and arguments
|
||||||
(r'[a-z]\w*', Name),
|
(r'[a-z]\w*', Name),
|
||||||
(r'->|=|:', Operator),
|
(r'->|=|:', Operator),
|
||||||
|
|||||||
124
docs/langref.rst
124
docs/langref.rst
@@ -390,6 +390,130 @@ Indirect function calls use a signature declared in the preample.
|
|||||||
:inst:`br_table`.
|
:inst:`br_table`.
|
||||||
|
|
||||||
|
|
||||||
|
Memory
|
||||||
|
======
|
||||||
|
|
||||||
|
Cretonne provides fully general :inst:`load` and :inst:`store` instructions for
|
||||||
|
accessing memory. However, it can be very complicated to verify the safety of
|
||||||
|
general loads and stores when compiling code for a sandboxed environment, so
|
||||||
|
Cretonne also provides more restricted memory operations that are always safe.
|
||||||
|
|
||||||
|
.. inst:: a = load p, Offset, Flags...
|
||||||
|
|
||||||
|
Load from memory at ``p + Offset``.
|
||||||
|
|
||||||
|
This is a polymorphic instruction that can load any value type which has a
|
||||||
|
memory representation (i.e., everything except :type:`bool` and boolean
|
||||||
|
vectors).
|
||||||
|
|
||||||
|
:arg iPtr p: Base address.
|
||||||
|
:arg Offset: Immediate signed offset.
|
||||||
|
:flag align(N): Expected alignment of ``p + Offset``. Power of two.
|
||||||
|
:flag aligntrap: Always trap if the memory access is misaligned.
|
||||||
|
:result T a: Loaded value.
|
||||||
|
|
||||||
|
.. inst:: store x, p, Offset, Flags...
|
||||||
|
|
||||||
|
Store ``x`` to memory at ``p + Offset``.
|
||||||
|
|
||||||
|
This is a polymorphic instruction that can store any value type with a
|
||||||
|
memory representation.
|
||||||
|
|
||||||
|
:arg T x: Value to store.
|
||||||
|
:arg iPtr p: Base address.
|
||||||
|
:arg Offset: Immediate signed offset.
|
||||||
|
:flag align(N): Expected alignment of ``p + Offset``. Power of two.
|
||||||
|
:flag aligntrap: Always trap if the memory access is misaligned.
|
||||||
|
|
||||||
|
Loads and stores are *misaligned* if the resultant address is not a multiple of
|
||||||
|
the expected alignment. Depending on the target architecture, misaligned memory
|
||||||
|
accesses may trap, or they may work. Sometimes, operating systems catch
|
||||||
|
alignment traps and emulate the misaligned memory access.
|
||||||
|
|
||||||
|
On target architectures like x86 that don't check alignment, Cretonne expands
|
||||||
|
the aligntrap flag into a conditional trap instruction::
|
||||||
|
|
||||||
|
v5 = load.i32 v1, 4, align(4), aligntrap
|
||||||
|
; Becomes:
|
||||||
|
v10 = and_imm v1, 3
|
||||||
|
trapnz v10
|
||||||
|
v5 = load.i32 v1, 4
|
||||||
|
|
||||||
|
|
||||||
|
Local variables
|
||||||
|
---------------
|
||||||
|
|
||||||
|
One set of restricted memory operations access the current function's stack
|
||||||
|
frame. The stack frame is divided into fixed-size stack slots that are
|
||||||
|
allocated in the :term:`function preample`. Stack slots are not typed, they
|
||||||
|
simply represent a contiguous sequence of bytes in the stack frame.
|
||||||
|
|
||||||
|
.. inst:: SS = stack_slot Bytes, Flags...
|
||||||
|
|
||||||
|
Allocate a stack slot in the preample.
|
||||||
|
|
||||||
|
If no alignment is specified, Cretonne will pick an appropriate alignment
|
||||||
|
for the stack slot based on its size and access patterns.
|
||||||
|
|
||||||
|
:arg Bytes: Stack slot size on bytes.
|
||||||
|
:flag align(N): Request at least N bytes alignment.
|
||||||
|
:result SS: Stack slot index.
|
||||||
|
|
||||||
|
.. inst:: a = stack_load SS, Offset
|
||||||
|
|
||||||
|
Load a value from a stack slot at the constant offset.
|
||||||
|
|
||||||
|
This is a polymorphic instruction that can load any value type which has a
|
||||||
|
memory representation.
|
||||||
|
|
||||||
|
The offset is an immediate constant, not an SSA value. The memory access
|
||||||
|
cannot go out of bounds, i.e. ``sizeof(a) + Offset <= sizeof(SS)``.
|
||||||
|
|
||||||
|
:arg SS: Stack slot declared with :inst:`stack_slot`.
|
||||||
|
:arg Offset: Immediate non-negative offset.
|
||||||
|
:result T a: Value loaded.
|
||||||
|
|
||||||
|
.. inst:: stack_store x, SS, Offset
|
||||||
|
|
||||||
|
Store a value to a stack slot at a constant offset.
|
||||||
|
|
||||||
|
This is a polymorphic instruction that can store any value type with a
|
||||||
|
memory representation.
|
||||||
|
|
||||||
|
The offset is an immediate constant, not an SSA value. The memory access
|
||||||
|
cannot go out of bounds, i.e. ``sizeof(a) + Offset <= sizeof(SS)``.
|
||||||
|
|
||||||
|
:arg T x: Value to be stored.
|
||||||
|
:arg SS: Stack slot declared with :inst:`stack_slot`.
|
||||||
|
:arg Offset: Immediate non-negative offset.
|
||||||
|
|
||||||
|
The dedicated stack access instructions are easy ofr the compiler to reason
|
||||||
|
about because stack slots and offsets are fixed at compile time. For example,
|
||||||
|
the alignment of these stack memory accesses can be inferred from the offsets
|
||||||
|
and stack slot alignments.
|
||||||
|
|
||||||
|
It can be necessary to escape from the safety of the restricted instructions by
|
||||||
|
taking the address of a stack slot.
|
||||||
|
|
||||||
|
.. inst:: a = stack_addr SS, Offset
|
||||||
|
|
||||||
|
Get the address of a stack slot.
|
||||||
|
|
||||||
|
Compute the absolute address of a byte in a stack slot. The offset must
|
||||||
|
refer to a byte inside the stack slot: ``0 <= Offset < sizeof(SS)``.
|
||||||
|
|
||||||
|
:arg SS: Stack slot declared with :inst:`stack_slot`.
|
||||||
|
:arg Offset: Immediate non-negative offset.
|
||||||
|
:result iPtr a: Address.
|
||||||
|
|
||||||
|
The :inst:`stack_addr` instruction can be used to macro-expand the stack access
|
||||||
|
instructions before instruction selection::
|
||||||
|
|
||||||
|
v1 = stack_load.f64 ss3, 16
|
||||||
|
; Expands to:
|
||||||
|
v9 = stack_addr ss3, 16
|
||||||
|
v1 = load.f64 v9
|
||||||
|
|
||||||
|
|
||||||
Operations
|
Operations
|
||||||
==========
|
==========
|
||||||
|
|||||||
Reference in New Issue
Block a user