Home | History | Annotate | Download | only in design
      1 # MacroAssembler and Assembler Code Generation Behaviours
      2 
      3 This design document describes the way that the Assembler and MacroAssembler
      4 generate code. This has wide implications, including buffer management,
      5 instruction-precise generation and related control over code generation.
      6 
      7 **NOTE**: This document describes design decisions, but the code does not
      8 implement or match everything that is described in this document.
      9 TODO: Work on the code to achieve what is expressed in this document, and update
     10 the documentation.
     11 
     12 ## Basic Use-Cases
     13 
     14 ### Simple Code Generation
     15 
     16 For normal code generation, the MacroAssembler should be used. We recommend this
     17 even if the caller doesn't require the macro behaviour, because it acts as a
     18 (partial) fail-safe in case calling code accidentally passes out-of-range
     19 immediates and suchlike. The MacroAssembler is also able to check and emit
     20 literal pools.
     21 
     22 Note that the MacroAssembler is allowed to emit an arbitrary amount of code in
     23 order to achieve the requested effect. (Note that "arbitrary" includes no code,
     24 for macros with no effect other than to advance the PC.) In practical terms, a
     25 macro can effectively generate a huge amount of code if it needs to emit a
     26 literal pool (for example).
     27 
     28 ### Precise Code Generation
     29 
     30 Sometimes, the caller needs to generate a very precise code sequence. The
     31 typical use-case is where code needs to be patched. In these cases, the
     32 MacroAssembler must not be used, but the Assembler can be called directly. Since
     33 the caller most likely has a MacroAssembler object, we provide
     34 ExactAssemblyScope to restrict any MacroAssembler methods from being used for
     35 its duration, and allow access to the Assembler.
     36 
     37 ### Fuzzy Cases: Approximate Size Limits
     38 
     39 Sometimes the caller wants the convenience and fail-safe features of the
     40 MacroAssembler, and isn't worried about the precise code sequence used, but
     41 needs to ensure that the total code size does not exceed the range of a branch
     42 (or similar PC-relative instruction). Veneers simplify many cases like this, but
     43 not all (and not necessarily optimally). For example, VIXL32's Switch-Case
     44 macros probably do not have sufficient range to cope with a literal pool in
     45 the middle.
     46 
     47 For these cases, we'd like to ensure that the MacroAssembler doesn't emit _too
     48 much_ code. This is very fuzzy, and in practice means avoiding pools, but
     49 allowing standard macros. The catch is that the caller must specify the upper
     50 limit on the size of the generated code.
     51 
     52 A corner-case that is relevant for VIXL32 (but mostly irrelevant for VIXL64) is
     53 that the protected region could easily be larger than the range of some
     54 load-literal instructions, so we should not actually _block_ the pool. For
     55 example, `vldr` has a range of about 1KB, but `tbh` can easily exceed this
     56 range. If one of the Cases generates an FP literal-load, the MacroAssembler
     57 needs to put the pool in the middle of the Switch-Case sequence.
     58 
     59 This case is currently accomodated by MacroAssembler::EnsureEmitFor.
     60 
     61 ## Proposal
     62 
     63 These behaviours are similar to (or the same as) existing cases to avoid
     64 breaking backwards compatibility. Several potentially-unsafe scopes have been
     65 deprecated, and a few have been given more flexibility.
     66 
     67 Each scope utility will behave in the same way for VIXL64 as for VIXL32, even if
     68 the implementations differ.
     69 
     70 ### `CodeBufferCheckScope(Assembler* assm, size_t size, ...)`
     71 
     72 - Allow code emission from the specified `Assembler`.
     73 - Optionally reserve space in the `CodeBuffer` (if it is managed by VIXL).
     74 - Optionally, on destruction, check the size of the generated code.
     75   (The size can be either exact or a maximum size.)
     76 
     77 This scope exists so that callers can use an Assembler by itself, without even
     78 instantiating a MacroAssembler.
     79 
     80 ### `CodeBufferCheckScope(MacroAssembler* masm, ...)`
     81 
     82 - DEPRECATED
     83 
     84 Otherwise, this is the same as `CodeBufferCheckScope(Assembler*)`.
     85 
     86 It is unfortunate that this scope allows the Assembler and MacroAssembler to be
     87 mixed freely; this can cause numerous problems. For example, the Assembler
     88 doesn't know about the pools, so use of the Assembler can push the pools out of
     89 range. This was acceptable in VIXL64, where the pool range is very large, but
     90 not in VIXL32.
     91 
     92 We should retain the existing functionality for a while, but mark the
     93 `MacroAssembler*` form as DEPRECATED. A suitable replacement is
     94 EmissionCheckScope, which allows the Assembler and MacroAssembler to be mixed,
     95 but also blocks pools and therefore avoids the problems that
     96 `CodeBufferCheckScope` has.
     97 
     98 ### `EmissionCheckScope(MacroAssembler* masm, size_t size, AssertPolicy ...)`
     99 
    100 - Do the same as `CodeBufferCheckSCope`, but:
    101   - If managed by VIXL, always reserve space in the `CodeBuffer`.
    102   - Always check the (exact or maximum) size of the generated code on
    103     destruction.
    104 - Emit pools if the specified size would push them out of range.
    105 - Block pools emission for the duration of the scope.
    106 
    107 This scope allows the `Assembler` and `MacroAssembler` to be freely and safely
    108 mixed for its duration.
    109 
    110 The MacroAssembler uses this to implement its own macros.
    111 
    112 ### `ExactAssemblyScope(MacroAssembler* masm, ...)`
    113 
    114 - Do the same as `EmissionCheckScope`.
    115 - Block access to the MacroAssemblerInterface (using run-time assertions).
    116 
    117 This scope allows safely generating exact assembly code. Compared to
    118 `CodeBufferCheckScope`, it disables the `MacroAssembler`, and guarantees that
    119 no pools will be emitted during code generation.
    120 
    121 This replaces VIXL64's InstructionAccurateScope.
    122 
    123 ### `BlockPoolsScope` (and variants)
    124 
    125 - DEPRECATED
    126 - Block the pools for the duration.
    127 
    128 These scopes really shouldn't be used outside VIXL itself. Since uses inside
    129 VIXL are minimal, we should mark it as DEPRECATED and replace our own uses with
    130 EmissionCheckScope or manual `MacroAssembler::BlockPools()` calls.
    131 
    132 Note that this scope made sense in VIXL64, where pool ranges are large and we
    133 have a large contingency region built into the pool checks. In VIXL32, where the
    134 ranges are tight, we can't generally afford to block the constant pools at
    135 arbitrary points, even for short sequences of instructions.
    136 
    137 ### `InstructionAccurateScope`
    138 
    139 - DEPRECATED
    140 - Replaced by ExactAssemblyScope.
    141 
    142 When generating T32, we need something like InstructionAccurateScope to check
    143 the code _size_, rather than the instruction count, since the instruction size
    144 is much more likely to vary in a way that matters. However, it's not safe to
    145 just change `InstructionAccurateScope`'s behaviour because the constructor
    146 prototype would be unchanged, so there would be no compile-time warning for
    147 users.
    148 
    149 ### `MacroAssembler::EnsureEmitFor`
    150 
    151 - Private to the MacroAssembler (but available, in a DEPRECATED form, to
    152   VIXL64 users).
    153 - Ensure that there is space in the CodeBuffer so that `size` bytes can be
    154   emitted contiguously.
    155 
    156 Pools are emitted if `size` bytes would push them out of range, but they are not
    157 actually blocked; pools can still be emitted during the specified range if they
    158 are used during the range.
    159 
    160     __ EnsureEmitFor(4096);   // Might dump pools.
    161     __ Add(...);
    162     __ Add(...);              // These macros will not dump pools. They might
    163     __ Add(...);              // emit multiple instructions.
    164     __ Add(...);
    165     __ Vldr(d0, 12345.0);     // Adds an entry to the literal pool (range ~1KB).
    166     __ Add(...);
    167     ...
    168     __ Add(...);
    169     __ Add(...);              // The pool containing 12345.0 will be dumped
    170     __ Add(...);              // before the end of the EnsureEmitFor range.
    171     __ Add(...);
    172 
    173 This is a one-shot call, not a scope utility, so there is no size checking
    174 available. For that reason, it is risky, but still useful in certain cases.
    175 There are also tricky corner-cases to consider. Most notably, if literals are
    176 added to the pool during the `EnsureEmitFor` range, a pool might still be
    177 generated in that range. This can be avoided by including the size of new
    178 literals in the size check, but because this is not a scope utility and has not
    179 destruction checks, we cannot assert that the usage was safe.
    180 
    181 Also note that this does not acquire the CodeBuffer, so it is not possible to
    182 use the Assembler after using this utility alone.
    183 
    184 ## Usage Examples
    185 
    186 ### Basic Usage
    187 
    188     void fn(MacroAssembler* masm) {
    189       // - Uses delegates if necessary.
    190       // - Arbitrary length (including 0, potentially).
    191       // - Can automatically reserve space in the code buffer.
    192       // - Can automatically dump pools.
    193       masm->Add(...);
    194     }
    195 
    196     void fn(MacroAssembler* masm) {
    197       // - No delegates allowed.
    198       //   - If a delegate is called, it should crash even in release mode.
    199       //     (This helps to avoid security bugs derived from data-dependent code
    200       //     generation.)
    201       // - Always generates exactly one instruction.
    202       // - No automatic buffer growth, but does check that there is space. (In
    203       //   VIXL64, this is done by the CodeBuffer.)
    204       // - In VIXL64, this requires that the code buffer has been "acquired".
    205       //   Any of the EmissionCheckScopes can do this, as can ExactAssemblyScope
    206       //   and CodeBufferCheckScope.
    207       SingleEmissionCheckScope(masm);
    208       masm->add(...);
    209     }
    210 
    211     void fn(Assembler* assm) {
    212       // Identical to the MacroAssembler::add example, except that we must use
    213       // CodeBufferCheckScope to acquire the buffer.
    214       CodeBufferCheckScope(assm, ...);
    215       assm->add(...);
    216     }
    217 
    218 ### Macros: Simple Code Generation
    219 
    220     void MacroAssembler::Add(...) {
    221       // A macro no larger than
    222       // `MacroEmissionCheckScope::kTypicalMacroInstructionMaxSize`.
    223       MacroEmissionCheckScope scope(...);
    224       ...
    225     }
    226 
    227     void MacroAssembler::Printf(...) {
    228       // A macro larger than
    229       // `MacroEmissionCheckScope::kTypicalMacroInstructionMaxSize`.
    230       // We start no scope, but rely only on upper-case macros which create
    231       // their own MacroEmissionCheckScopes. Pools can be emitted during
    232       // this large macro.
    233       Add(...)
    234       Ldr(...)
    235       ...
    236     }
    237 
    238 ### Patchable Regions: Precise Code Generation
    239 
    240     void fn(MacroAssembler* masm) {
    241       __ Add(...);
    242       __ Add(...);
    243       __ Add(...);
    244       {
    245         // We want this sequence of instructions to be patched later, so we need
    246         // to use instruction-accurate code generation with a predictable size.
    247         // It is forbidden to use macros during this scope.
    248         ExactAssemblyScope(masm, 4 * kInstructionSize);
    249         __ bind(&patch_location);
    250         __ add(...);
    251         __ add(...);
    252         __ add(...);
    253         __ add(...);
    254       }
    255       __ Add(...);
    256       __ Add(...);
    257       __ Add(...);
    258     }
    259