1 /* Instruction rewrite functionality header.
2 
3    Copyright (C) 2017, 2018 Luca Saiu
4    Updated in 2019 by Luca Saiu
5    Written by Luca Saiu
6 
7    This file is part of Jitter.
8 
9    Jitter is free software: you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13 
14    Jitter is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with Jitter.  If not, see <http://www.gnu.org/licenses/>. */
21 
22 
23 #ifndef JITTER_REWRITE_H_
24 #define JITTER_REWRITE_H_
25 
26 #include <jitter/jitter.h>
27 #include <jitter/jitter-instruction.h>
28 #include <jitter/jitter-mutable-routine.h>
29 
30 
31 /* Rewriter API.
32  * ************************************************************************** */
33 
34 /* Instruction rewriting entails replacing a sequence of one or more
35    unspecialized instructions with another sequence of zero or more equivalent
36    unspecified instructions; each instruction in the replacement will be
37    specializable, while the original instruction might not be.
38 
39    There are two distinct use cases for rewriting:
40      (a) peephole optimization;
41      (b) reducing the number of specialized instructions in order to make the
42          generated C code smaller, possibly enabling the user of more fast
43          registers.
44    Case (b) is important, but is not exploited yet.
45 
46    About case (b):
47    The rewriting mechanism can reduce the number of specialized instructions by
48    removing redundant ways of describing the same operation.  Let us assume for
49    example a meta-instruction add (?r, ?r, !r); then the two unspecialized
50    instructions
51      add %r0, %r1, %r2
52    and
53      add %r1, %r0, %r2
54    have the same semantics because of commutativity, and we can systematically
55    rewrite one of them into the other (for example the one having input register
56    indices in non-decreasing order), arbitrarily chosen as the normal form.
57    This cuts the specialized instructions in half, allowing the user to compile
58    a Jittery system using less resources, or to keep using the same resources
59    but affording a higher number of fast registers.
60 
61    Other rewritings yield slightly suboptimal code, but reduce the specialized
62    instruction set even more dramatically.  The add instruction above has O(n^3)
63    specializations, but by requring the second and third arguments to be equal
64    we can cut specialized instructions to O(n^2).  Assuming a register copying
65    meta-instruction mov (?r, !r) such a rewriting would require replacing, for
66    example,
67      add %r0, %r1, %r2
68    with the two-instruction sequence
69      mov %r1, %r2
70      add %r0, %r2, %r2
71    . Other add instructions already having the same register as their second
72    and third arguments would not be rewritten.
73 
74    Rewriting happens after each instruction is completed, by a call to
75    jitter_mutable_routine_append_instruction_name or one of the jitter_mutable_routine_append_*_parameter
76    functions.  Rewriting can never happen "across" a label: an original
77    unspecialized instruction before rewriting is replaced with a sequence, and
78    both the original and the rewritten sequence lie completely before or
79    completely after each label: it is not possible, by construction, to have
80    part of the replacement before and part of the replacement after a label.
81 
82    As an exception the implicit label added after a callee instruction is not
83    restricted by the limitation above, at least for the purposes of case (a): it
84    is possible, and in fact useful, to rewrite a sequence containing a call
85    instruction into a more efficient sequence.  As always the user has the
86    responsibility of ensuring that her rewritten code is semantically equivalent
87    to the original, but calls seem to present no particular problem. */
88 
89 
90 
91 
92 /* This API is not for the user.
93  * ************************************************************************** */
94 
95 /* The functions and macros delcared here are used internally by the rewriter or
96    by generated code, and not intended for the user.  The user specifies rewrite
97    rules as part of the Jitter VM speciefication, using Jitter syntax. */
98 
99 
100 
101 
102 /* Rewriter entry point.
103  * ************************************************************************** */
104 
105 /* The rewriter entry point is the machine-generated vmprefix_rewrite , called
106    at instruction closing thru the rewrite function pointer within struct
107    jitter_vm.
108 
109    See the comment for vmprefix_rewrite in the template header. */
110 
111 
112 
113 
114 /* Rewriter internal functions.
115  * ************************************************************************** */
116 
117 /* These functions are used internally for the implementation of
118    vmprefix_rewrite. */
119 
120 /* Return a pointer to the last instruction in the given program; the returned
121    pointer refers the only instance of the instruction, and is not a copy.  Fail
122    fatally if no instructions exist or if the last one is not complete, or if the
123    program is not unspecialized. */
124 struct jitter_instruction*
125 jitter_last_instruction (struct jitter_mutable_routine *p);
126 
127 /* Return a pointer pointing within an array of pointers to instructions,
128    how_many elements from the last one.  The pointed memory may be invalidated
129    by any instruction modification, so this is only meant for *reading* the last
130    few instructions in order to check whether a rewrite rule applies.
131    The intended way of using this is for checking whether a rule applying
132    to N instruction can fire: it will be called with how_many = N, and
133    the result will be an array of N pointers to the last instructions. */
134 /* Fail fatally if no instructions exist or if the last one is not complete, or
135    if the program is not unspecialized.  [FIXME: possibly change this] */
136 struct jitter_instruction**
137 jitter_last_instructions (struct jitter_mutable_routine *p, size_t how_many);
138 
139 /* Pop the last instruction off the pointed program, which must be complete, and
140    return a pointer to it; fail fatally if the instruction is not complete or
141    does not exist, or if the program is unspecialized.  This removes the pointer
142    to the instruction from the dynamic buffer in the program, but does not
143    deallocate the instruction: in fact the result of this function is the
144    pointer to the still-valid instruction, allocated according to the
145    conventions in jitter-instruction.h .  It is the caller's responsibility to
146    release memory after usage, normally by a call to jitter_destroy_instruction
147    .  The intended use case for this is fisrt checking whether a replacement
148    should occour, and then if so calling jitter_pop_instruction once; the result
149    pointer will be used to determine which instructions to append as a
150    replacement, by the usual jitter_mutable_routine_append_instruction_name /
151    jitter_mutable_routine_append_*_parameter functions, which may in their turn trigger rewrites
152    -- or by jitter_mutable_routine_append_instruction, which also triggers rewrites.
153 
154    Notice that rewrites are applied eagerly, as soon as each appended
155    instruction is complete and until no more rewrites are possible.  For this
156    reason simply removing instructions from the end of a program never triggers
157    new rewrites, and therefore the caller of this function can assume that after
158    the function returns every program instruction before the last one which was
159    removed remain unchanged.
160 
161    It is the user's responsiblity to ensure that her rewrite rules don't loop
162    forever. */
163 struct jitter_instruction*
164 jitter_pop_instruction (struct jitter_mutable_routine *p);
165 
166 /* Pop the last how_many instructions from the given program, and destroy them.
167    Undefined behavior if the program has less than how_many rewritable
168    instructions.  The last instruction must be complete.
169 
170    Notice, again, that destroying the last how_many instructions of a program
171    can never trigger a rewrite: see the jitter_pop_instruction comment for a
172    justification. */
173 void
174 jitter_destroy_last_instructions (struct jitter_mutable_routine *p,
175                                   size_t how_many);
176 
177 
178 
179 
180 /* Fixed code for vmprefix_rewrite.
181  * ************************************************************************** */
182 
183 /* Expand to C declarations and statements to be emitted at the beginning of
184    vmprefix_rewrite .  This macro is used in the machine-generated definition of
185    vmprefix_rewrite .  It may expand to a sequence of statements and
186    declarations of variables to be visible to the entire function, so it is not
187    do..while(false)-protected. */
188 #define JITTTER_REWRITE_FUNCTION_PROLOG_                                      \
189   /* How many instructions are rewritable in the current program.  This */    \
190   /* value will be used a lot in the function, and it's better to cache */    \
191   /* it in an automatic const variable rather than re-loading it from */      \
192   /* memory every time, in a context where GCC might not be able to infer */  \
193   /* that the value is, in fact, constant. */                                 \
194   const int jitter_rewritable_instruction_no =                                \
195     jitter_mutable_routine_p->rewritable_instruction_no;                      \
196   /* A pointer to the first instruction which is potentially a candidate */   \
197   /* for rewriting, with any rule.  Making this a constant pointer to */      \
198   /* constant data should help GCC to share condition computations across */  \
199   /* rules; this is correct, as rule conditions don't in fact change */       \
200   /* instructions -- Only if a rule matches some memory changes are made, */  \
201   /* and in that case we exit this function after the rule section ends. */   \
202   const struct jitter_instruction * const * const                             \
203      jitter_all_rewritable_instructions __attribute__ ((unused))              \
204        = ((const struct jitter_instruction * const * const)                   \
205           jitter_last_instructions (jitter_mutable_routine_p,                 \
206                                     jitter_rewritable_instruction_no))
207 
208 
209 
210 
211 
212 /* Rewriting macros for rule compilation: introduction.
213  * ************************************************************************** */
214 
215 /* The macros in the following sections provide a facility for executing rewrite
216    rules at runtime (not at generation time) from machine-generated C, expressed
217    in a structured, abstract way.  The expanded C code is meant to be fast in
218    the more common case, which is to say when rules do *not* fire.
219 
220    Each rewrite rule is translated into a C conditional with a complex condition
221    made of clauses all in logical and, having side effects on local variables,
222    which eventually evaluates to true if the rule fires.  In that case some head
223    instruction arguments are cloned heap-to-heap into templates, head
224    instruction destroyed, and new instructions appended in their place, using
225    the cloned placeholder to instantiate the rule template; after the new
226    instructions are appended the cloned templates are destroyed, and the
227    rewriting function returns.  When a rule does not match, instead, evaluation
228    falls thru to the conditional for the next rule.
229 
230    The rewriting process is inherently recursive: appending an instruction, be
231    it from the user C code or from another rewrite, may in its turn trigger a
232    rewrite.  This recursion is indirect and spans compilation units, which can
233    make it difficult for the C compiler to optimize away; however recursive
234    calls are at least in tail position when there are no templates to destroy.
235 
236    Notice that macro-level rule "sections" don't match the statement nesting of
237    C-level blocks: in particular the rule conditional body is opened by
238    JITTER_RULE_END_CONDITIONS and closed by
239    JITTER_RULE_END_PLACEHOLDER_DESTRUCTION .  Macro-level sections are nested in
240    a rigid, fixed way, to keep the generated code legible.  Their C
241    implementation is focused on exploiting C's statement evaluation in an
242    appropriate way (in particular, there are complex side-effects within an if
243    conditional) and that C variables have the intended scope.
244    Some sections may be empty, but their opening and closing is mandatory for
245    every rule, in the required order.
246 
247    An example of the rewrite rule changing
248        pop $a; push $a
249    into
250        copy-to-r $a
251    translated into C:
252 
253    JITTER_RULE_BEGIN(2)
254      JITTER_RULE_BEGIN_PLACEHOLDER_DECLARATIONS
255        JITTER_RULE_DECLARE_PLACEHOLDER_(a);
256      JITTER_RULE_END_PLACEHOLDER_DECLARATIONS
257      JITTER_RULE_BEGIN_CONDITIONS
258        JITTER_RULE_CONDITION_MATCH_OPCODE(0, pop)
259        JITTER_RULE_CONDITION_MATCH_OPCODE(1, push)
260        JITTER_RULE_CONDITION_MATCH_PLACEHOLDER(0, 0, a)
261        JITTER_RULE_CONDITION_MATCH_PLACEHOLDER(1, 0, a)
262      JITTER_RULE_END_CONDITIONS
263      JITTER_RULE_BEGIN_PLACEHOLDER_CLONING
264        JITTER_RULE_CLONE_PLACEHOLDER_(a);
265      JITTER_RULE_END_PLACEHOLDER_CLONING
266      JITTER_RULE_BEGIN_BODY
267        JITTER_RULE_APPEND_INSTRUCTION_(copy_mto_mr);
268        JITTER_RULE_APPEND_PLACEHOLDER_(a);
269      JITTER_RULE_END_BODY
270      JITTER_RULE_BEGIN_PLACEHOLDER_DESTRUCTION
271        JITTER_RULE_DESTROY_PLACEHOLDER_(a);
272      JITTER_RULE_END_PLACEHOLDER_DESTRUCTION
273    JITTER_RULE_END  */
274 
275 
276 
277 
278 /* Rewriting macros for rule compilation: sections.
279  * ************************************************************************** */
280 
281 /* Open a rule section, for a rule whose head matches the given number of VM
282    instructions.  This must be followed by a call to
283    JITTER_RULE_BEGIN_PLACEHOLDER_DECLARATIONS . */
284 #define JITTER_RULE_BEGIN(_jitter_head_instruction_no)                         \
285   { /* Begin the rule block.  */                                               \
286     /* Set the head size as a variable, so that we don't have to pass */       \
287     /* _jitter_head_instruction_no to multiple macros. */                      \
288     const int jitter_head_instruction_no = (_jitter_head_instruction_no);      \
289     /* A pointer to the first instruction which is potentially a */            \
290     /* candidate for rewriting, with the current rule.  This might not */      \
291     /* even point to a valid instruction: we have to check how many */         \
292     /* rewritable instructions there are before using it. */                   \
293     const struct jitter_instruction * const * const                            \
294        jitter_candidate_instructions __attribute__ ((unused))                  \
295          = (jitter_all_rewritable_instructions                                 \
296             + jitter_rewritable_instruction_no - jitter_head_instruction_no);  \
297     /* This will contain placeholder variable declarations, and then */        \
298     /* the rule conditional. */
299 
300 /* Close a rule section. */
301 #define JITTER_RULE_END          \
302   } /* Close the rule block. */
303 
304 /* Open the placeholder declaration section.  This must come right after the
305    JITTER_RULE_BEGIN call. */
306 #define JITTER_RULE_BEGIN_PLACEHOLDER_DECLARATIONS                            \
307   /* Nothing, not even a "{": we need the coming variable declarations to */  \
308   /* be visible in the following code, up until placeholder destruction. */
309 
310 /* Close the placeholder declaration section. */
311 #define JITTER_RULE_END_PLACEHOLDER_DECLARATIONS  \
312   /* Nothing, not even a "}".  See above. */
313 
314 /* Begin the rule condition section.  This must come right after placeholder
315    declarations.  The condition sections may contain any number of conditions,
316    which must *all* evaluate to true for the rule to fire. */
317 #define JITTER_RULE_BEGIN_CONDITIONS                        \
318   if (   (jitter_rewritable_instruction_no                  \
319             >= (jitter_head_instruction_no))                \
320       /* Here will come the other conditions, all in && */
321       /* with one another. */
322 
323 /* Close the rule condition section. */
324 #define JITTER_RULE_END_CONDITIONS                                          \
325      ) /* Close the if condition */                                         \
326     { /* Begin the rule conditional body, executed when the rule fires. */  \
327       /* The rule conditional body is distinct from the rule body! */
328 
329 /* Open the block holding placeholder cloning calls.  This block must occur
330    after rule conditions and before the rule body. */
331 #define JITTER_RULE_BEGIN_PLACEHOLDER_CLONING  \
332   { /* Open the placeholder cloning block. */
333 
334 /* Close the block holding placeholder cloning calls. */
335 #define JITTER_RULE_END_PLACEHOLDER_CLONING     \
336   } /* Close the placeholder cloning block. */
337 
338 /* Open the block holding placeholder destructions calls.  This block must occur
339    after the rule body. */
340 #define JITTER_RULE_BEGIN_PLACEHOLDER_DESTRUCTION      \
341     { /* Open the placeholder destruction block... */
342 
343 /* Close the block holding placeholder destructions calls. */
344 #define JITTER_RULE_END_PLACEHOLDER_DESTRUCTION                  \
345     } /* ...Close the placeholder destruction block. */          \
346     /* One rewrite rule fired, and if we have appended new */    \
347     /* instructions they have been rewritten as well.  Done. */  \
348     return; /*goto jitter_rewrite_again_label;*/                 \
349   } /* Close the rule conditional body. */
350 
351 /* Open the rule body section.  This must come after placeholder cloning. */
352 #define JITTER_RULE_BEGIN_BODY                                               \
353   { /* Open the rule body block, which occurs within the rule */             \
354     /* conditional body. */                                                  \
355     /* Destroy the instructions matching the rule head.  We have already */  \
356     /* copied the arguments we need for rewriting. */                        \
357     jitter_destroy_last_instructions (jitter_mutable_routine_p,              \
358                                       jitter_head_instruction_no);           \
359     /* From here on it's incorrect to use head instructions or non-cloned */ \
360     /* placeholders. */
361 
362 /* Close the rule body section. */
363 #define JITTER_RULE_END_BODY                                             \
364   } /* Close the rule body block, but not the rule conditional body. */  \
365     /* That will be closed later, after placeholders are destroyed. */
366 
367 
368 
369 
370 /* Rewriting macros for rule compilation: placeholders.
371  * ************************************************************************** */
372 
373 /* The name of a placeholder variable as a C identifier. */
374 #define JITTER_PLACEHOLDER_NAME(_jitter_suffix)                \
375   JITTER_CONCATENATE_TWO(jitter_placeholder_, _jitter_suffix)
376 
377 /* Expand to a pointer variable declaration for the given placeholder, also
378    initializing the pointer to NULL so that it matches any instruction argument.
379    It is sensible to declare the variable to point to const data: this will
380    allow GCC to share checks on arguments across different rule conditions;
381    arguments are in fact not modified, until one rule matches -- and then
382    the other rules become irrelevent.  Not do..while(false)-protected. */
383 #define JITTER_RULE_DECLARE_PLACEHOLDER_(_jitter_placeholder_name)  \
384   const struct jitter_parameter *                                   \
385      JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name)              \
386        = NULL
387 
388 /* Replace the pointer variable for the given placeholder, which must be
389    non-NULL, with a pointer to a freshly cloned argument.  This way the
390    placeholder will be usable from the rule body to fill the rule template,
391    after the matching head instructions are destroyed.  Not
392    do..while(false)-protected. */
393 #define JITTER_RULE_CLONE_PLACEHOLDER_(_jitter_placeholder_name)  \
394   JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name)               \
395     = jitter_clone_instruction_parameter                          \
396          (JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name))
397 
398 /* Destroy the instruction parameter pointed by the local placeholder variable
399    for the named placeholder.  The pointer must be non-NULL.  Not
400    do..while(false)-protected. */
401 #define JITTER_RULE_DESTROY_PLACEHOLDER_(_jitter_placeholder_name)  \
402   jitter_destroy_instruction_parameter                              \
403      ((struct jitter_parameter *)                                   \
404       JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name));
405 
406 
407 
408 
409 /* Rewriting macros for rule compilation: instruction/argument access.
410  * ************************************************************************** */
411 
412 /* Expand to a struct jitter_instruction * r-value evaluating to the
413    _jitter_instruction_idx-th (0-based) candidate instruction.
414    This is useful for referring to the first, second, and so on, instrction
415    among the ones matching the head of a rule. */
416 #define JITTER_RULE_INSTRUCTION(_jitter_instruction_idx)     \
417   (jitter_candidate_instructions [_jitter_instruction_idx])
418 
419 /* Expand to a struct jitter_parameter * r-value evaluating to the
420    _jitter_argument_idx-th (0-based) argument of the
421    _jitter_instruction_idx-th (0-based) candidate instruction.
422    This is useful for referring to a given argument of a given instruction
423    among the ones matching the head of a rule. */
424 #define JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,  \
425                                          _jitter_argument_idx)     \
426   (JITTER_RULE_INSTRUCTION(_jitter_instruction_idx)                \
427      ->parameters [_jitter_argument_idx])
428 
429 /* Expand to an r-value of type enum jitter_parameter_type evaluating to the
430    actual type of the given argument. */
431 #define JITTER_RULE_ARGUMENT_TYPE(_jitter_instruction_idx,    \
432                                   _jitter_argument_idx)       \
433   (JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,  \
434                                     _jitter_argument_idx)     \
435       ->type)
436 
437 
438 
439 
440 /* Rewriting macros for rule compilation: macros for argument field extraction.
441  * ************************************************************************** */
442 
443 /* Given an r-value evaluating to a pointer to a (possibly const) struct
444    jitter_parameter , expand to an r-value which evaluates to its content as
445    literal.  The argument type is not checked. */
446 #define JITTER_RULE_LITERAL_FIELD(_jitter_argument_expression)  \
447   ((_jitter_argument_expression)->literal)
448 
449 /* Given an r-value evaluating to a pointer to a (possibly const) struct
450    jitter_parameter , expand to an r-value which evaluates to its register-index
451    content.  The argument type is not checked. */
452 #define JITTER_RULE_REGISTER_INDEX_FIELD(_jitter_argument_expression)  \
453   ((_jitter_argument_expression)->register_index)
454 
455 
456 
457 
458 /* Rewriting macros for rule compilation: macros for condition evaluation.
459  * ************************************************************************** */
460 
461 /* Expand to a boolean r-value, evaluating to true iff the given actual
462    argument is a register. */
463 #define JITTER_RULE_ARGUMENT_IS_A_REGISTER(_jitter_instruction_idx,  \
464                                            _jitter_argument_idx)     \
465   (JITTER_RULE_ARGUMENT_TYPE(_jitter_instruction_idx,                \
466                               _jitter_argument_idx)                  \
467    == jitter_parameter_type_register_id)
468 
469 /* Expand to a boolean r-value, evaluating to true iff the given actual
470    argument is a literal. */
471 #define JITTER_RULE_ARGUMENT_IS_A_LITERAL(_jitter_instruction_idx,  \
472                                           _jitter_argument_idx)     \
473   (JITTER_RULE_ARGUMENT_TYPE(_jitter_instruction_idx,               \
474                              _jitter_argument_idx)                  \
475    == jitter_parameter_type_literal)
476 
477 /* Expand to a boolean r-value, evaluating to true iff the given actual
478    argument is a label -- there is no distinction here between fast
479    and slow labels. */
480 #define JITTER_RULE_ARGUMENT_IS_A_LABEL(_jitter_instruction_idx,  \
481                                         _jitter_argument_idx)     \
482   (JITTER_RULE_ARGUMENT_TYPE(_jitter_instruction_idx,             \
483                              _jitter_argument_idx)                \
484    == jitter_parameter_type_label)
485 
486 
487 
488 
489 /* Rewriting macros for rule compilation: conditions.
490  * ************************************************************************** */
491 
492 /* Expand to a condition, to be &&'ed to the previous conditions in the rule
493    conditional.  A condition expression may have side effects, and its result
494    must be non-zero if evaluation of the following conditions is to continue;
495    when a condition expression evaluates to zero the following conditions are
496    not evaluated, and the current rule does not fire.
497    A condition must not have side effects visible out of the current rule
498    block, since any following condition may fail.  Setting placeholders is
499    allowed because placeholder variables are just pointers local to the block,
500    and don't refer to newly allocated memory during the condition evaluation.
501    Only if the condition eventually evaluates to a non-zero value
502    placeholders are cloned, and head instructions are destroyed: at that point
503    the rule is known to fire, and its effects will be visible. */
504 #define JITTER_RULE_CONDITION(_jitter_condition_expression)  \
505       && (_jitter_condition_expression)
506 
507 /* Expand to a condition on the opcode of the _jitter_instruction_idx-th
508    instruction (0-based, from the first head candidate).  Conditions like these
509    should always be the first ones in a rule conditional: after they have all
510    matched we can safely access instruction arguments knowing that the arities
511    will be what we are expecting from their respective instructions.
512    The opcode is given with the same conventions as the second argument of
513    VMPREFIX_APPEND_INSTRUCTION . */
514 #define JITTER_RULE_CONDITION_MATCH_OPCODE(_jitter_instruction_idx,        \
515                                            _jitter_mangled_opcode_suffix)  \
516   JITTER_RULE_CONDITION(                                                   \
517      (JITTER_RULE_INSTRUCTION(_jitter_instruction_idx)                     \
518          ->meta_instruction->id)                                           \
519       == JITTER_CONCATENATE_THREE(JITTER_VM_PREFIX_LOWER_CASE,             \
520                                   _meta_instruction_id_,                   \
521                                   _jitter_mangled_opcode_suffix))
522 
523 /* Match the _jitter_argument_idx-th (0-based) argument of the
524    _jitter_instruction_idx-th (0-based) instruction with the given
525    placeholder.
526    - if the placeholder is NULL, set it to the argument pointer and evaluate to
527      true;
528    - if the placeholder is already set, check if it's equal to the given
529      parameter (this will occur in non-linear patterns): if so evaluate to true,
530      otherwise evaluate to false.
531      In either case the parameter is not cloned: the placeholder at this
532      point may only hold a pointer to an *existing* heap-allocated datum. */
533 #define JITTER_RULE_CONDITION_MATCH_PLACEHOLDER(_jitter_instruction_idx,   \
534                                                 _jitter_argument_idx,      \
535                                                 _jitter_placeholder_name)  \
536   JITTER_RULE_CONDITION(                                                   \
537      ((JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name) == NULL)          \
538       ? ((JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name)                \
539             = JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,    \
540                                                _jitter_argument_idx))      \
541          /* Without ", true" GCC would complain about ? : having a */      \
542          /* pointer and and integer on different branches. */              \
543          , true)                                                           \
544       : jitter_instruction_parameters_equal                                \
545            (JITTER_PLACEHOLDER_NAME(_jitter_placeholder_name),             \
546             JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,      \
547                                              _jitter_argument_idx))))
548 
549 /* Expand to a rule condition like above, evaluating to true iff the mentioned
550    instruction argument is a literal with the given value.  Do not check the
551    register class, as each instruction register argument can have only one, and
552    that has been already checked statically.  No side effects. */
553 #define JITTER_RULE_CONDITION_MATCH_REGISTER_ARGUMENT(_jitter_instruction_idx, \
554                                                       _jitter_argument_idx,    \
555                                                       _jitter_register_index)  \
556   JITTER_RULE_CONDITION(                                                       \
557         JITTER_RULE_ARGUMENT_IS_A_REGISTER(_jitter_instruction_idx,            \
558                                            _jitter_argument_idx)               \
559      && (JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,             \
560                                           _jitter_argument_idx)                \
561            ->register_index                                                    \
562          == (_jitter_argument_value)))
563 
564 /* Expand to a rule condition like above, evaluating to true iff the mentioned
565    instruction argument is a register with the given index.  No side effects. */
566 #define JITTER_RULE_CONDITION_MATCH_LITERAL_ARGUMENT(_jitter_instruction_idx, \
567                                                      _jitter_argument_idx,    \
568                                                      _jitter_argument_value)  \
569   JITTER_RULE_CONDITION(                                                      \
570         JITTER_RULE_ARGUMENT_IS_A_LITERAL(_jitter_instruction_idx,            \
571                                           _jitter_argument_idx)               \
572      && (JITTER_RULE_LITERAL_FIELD(                                           \
573             JITTER_RULE_INSTRUCTION_ARGUMENT(_jitter_instruction_idx,         \
574                                              _jitter_argument_idx))           \
575                .fixnum                                                        \
576          == (_jitter_argument_value)))
577 
578 /* Expand to the predicate JITTER_RULE_ARGUMENT_IS_A_REGISTER within a
579    condition.  Like in the case of JITTER_RULE_ARGUMENT_IS_A_REGISTER there is
580    no need to supply a register class; see its comment. */
581 #define JITTER_RULE_CONDITION_ARGUMENT_IS_A_REGISTER(_jitter_instruction_idx,  \
582                                                      _jitter_argument_idx)     \
583   JITTER_RULE_CONDITION(                                                       \
584      JITTER_RULE_ARGUMENT_IS_A_REGISTER(_jitter_instruction_idx,               \
585                                         _jitter_argument_idx))
586 
587 /* Expand to the predicate JITTER_RULE_ARGUMENT_IS_A_LITERAL within a
588    condition. */
589 #define JITTER_RULE_CONDITION_ARGUMENT_IS_A_LITERAL(_jitter_instruction_idx,  \
590                                                     _jitter_argument_idx)     \
591   JITTER_RULE_CONDITION(                                                      \
592      JITTER_RULE_ARGUMENT_IS_A_LITERAL(_jitter_instruction_idx,               \
593                                        _jitter_argument_idx))
594 
595 /* Expand to the predicate JITTER_RULE_ARGUMENT_IS_A_LABEL within a
596    condition.  There is no distinction between fast and slow labels. */
597 #define JITTER_RULE_CONDITION_ARGUMENT_IS_A_LABEL(_jitter_instruction_idx,  \
598                                                   _jitter_argument_idx)     \
599   JITTER_RULE_CONDITION(                                                    \
600      JITTER_RULE_ARGUMENT_IS_A_LABEL(_jitter_instruction_idx,               \
601                                      _jitter_argument_idx))
602 
603 
604 
605 
606 /* Rewriting macros for rule compilation: template expressions.
607  * ************************************************************************** */
608 
609 /* Template expressions expand to C r-values, having access to constants and
610    placeholders but not to the original instructions, which except for the case
611    of the rule guard have already been destroyed.
612    The expansion has no side effects except in the case of errors, which should
613    never happen if typechecking has passed.
614    The C type of the expansion depends on the context, and is checked
615    statically. */
616 
617 /* Expand to a template expression evaluating to the boolean constants true and
618    false. */
619 #define JITTER_RULE_EXPRESSION_TRUE  \
620   true
621 #define JITTER_RULE_EXPRESSION_FALSE  \
622   false
623 
624 /* Expand to a template expression evaluating to an integer expression
625    containing the given constant. */
626 #define JITTER_RULE_EXPRESSION_INTEGER(_jitter_literal1)  \
627   (_jitter_literal1)
628 
629 /* Expand to a template expression evaluating to a boolean expression combining
630    the given operands with the appropriate connective. */
631 #define JITTER_RULE_EXPRESSION_LOGICAL_AND(_jitter_e1, _jitter_e2)  \
632   ((_jitter_e1) && (_jitter_e2))
633 #define JITTER_RULE_EXPRESSION_LOGICAL_OR(_jitter_e1, _jitter_e2)  \
634   ((_jitter_e1) || (_jitter_e2))
635 #define JITTER_RULE_EXPRESSION_LOGICAL_NOT(_jitter_e1)  \
636   (! (_jitter_e1))
637 
638 /* Expand to a template expression evaluating to an arithmetic expression
639    combining the given operands with the appropriate operation. */
640 #define JITTER_RULE_EXPRESSION_PLUS(_jitter_e1, _jitter_e2)  \
641   ((_jitter_e1) + (_jitter_e2))
642 #define JITTER_RULE_EXPRESSION_MINUS(_jitter_e1, _jitter_e2)  \
643   ((_jitter_e1) - (_jitter_e2))
644 #define JITTER_RULE_EXPRESSION_TIMES(_jitter_e1, _jitter_e2)  \
645   ((_jitter_e1) * (_jitter_e2))
646 #define JITTER_RULE_EXPRESSION_DIVIDED(_jitter_e1, _jitter_e2)  \
647   ((_jitter_e1) / (_jitter_e2))
648 #define JITTER_RULE_EXPRESSION_REMAINDER(_jitter_e1, _jitter_e2)  \
649   ((_jitter_e1) % (_jitter_e2))
650 
651 /* Expand to a template boolean expression comparing the given arithmetic
652    operands with the appropriate. */
653 #define JITTER_RULE_EXPRESSION_EQUAL(_jitter_e1, _jitter_e2)  \
654   ((_jitter_e1) == (_jitter_e2))
655 #define JITTER_RULE_EXPRESSION_NOTEQUAL(_jitter_e1, _jitter_e2)  \
656   ((_jitter_e1) != (_jitter_e2))
657 #define JITTER_RULE_EXPRESSION_LESS(_jitter_e1, _jitter_e2)  \
658   ((_jitter_e1) < (_jitter_e2))
659 #define JITTER_RULE_EXPRESSION_LESSEQUAL(_jitter_e1, _jitter_e2)  \
660   ((_jitter_e1) <= (_jitter_e2))
661 #define JITTER_RULE_EXPRESSION_GREATER(_jitter_e1, _jitter_e2)  \
662   ((_jitter_e1) > (_jitter_e2))
663 #define JITTER_RULE_EXPRESSION_GREATEREQUAL(_jitter_e1, _jitter_e2)  \
664   ((_jitter_e1) >= (_jitter_e2))
665 
666 
667 
668 
669 /* Rewriting macros for rule compilation: body.
670  * ************************************************************************** */
671 
672 /* Append the instruction opcode whose mangled suffix (see the comment for
673    VMPREFIX_APPEND_INSTRUCTION ) is given; the arguments, if any, need to be
674    added explicitly after calling this macro.  Not
675    do..while(false)-protected. */
676 #define JITTER_RULE_APPEND_INSTRUCTION_(_jitter_mangled_suffix)  \
677   JITTER_CONCATENATE_TWO(JITTER_VM_PREFIX_UPPER_CASE,            \
678                          _MUTABLE_ROUTINE_APPEND_INSTRUCTION)    \
679      (jitter_mutable_routine_p, _jitter_mangled_suffix)
680 
681 /* Append a copy of the parameter pointed by the named placeholder variable,
682    which must be non-NULL, to the current instruction.  Not
683    do..while(false)-protected. */
684 #define JITTER_RULE_APPEND_PLACEHOLDER_(_jitter_placeholder_name)          \
685   jitter_mutable_routine_append_parameter_copy (jitter_mutable_routine_p,  \
686                                 JITTER_PLACEHOLDER_NAME(                   \
687                                    _jitter_placeholder_name));
688 
689 
690 #endif // #ifndef JITTER_REWRITE_H_
691