1# Copyright 2016, VIXL authors
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
6#
7#   * Redistributions of source code must retain the above copyright notice,
8#     this list of conditions and the following disclaimer.
9#   * Redistributions in binary form must reproduce the above copyright notice,
10#     this list of conditions and the following disclaimer in the documentation
11#     and/or other materials provided with the distribution.
12#   * Neither the name of ARM Limited nor the names of its contributors may be
13#     used to endorse or promote products derived from this software without
14#     specific prior written permission.
15#
16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27class OperandBase(object):
28  """
29  Base class for operands. An operand represents an argument passed to the
30  macro-assembler to generate an instruction. For example, registers, conditions
31  or C++ `Operand` and `MemOperand` objects are operands. We can think of them
32  as "assemble-time" data.
33
34  An operand is described with a type name, corresponding to the C++ type used
35  to represent it (e.g. "Register", "ShiftType", "MemOperand", ...) and a name
36  to identify it.
37
38  Attributes:
39    name      Name for the operand. It is used to declare variable names.
40    type_name C++ type for the operand.
41  """
42
43  def __init__(self, name, type_name):
44    self.name = name
45    self.type_name = type_name
46
47  @staticmethod
48  def __iter__():
49    """
50    Operand types have to act as an iterator so that `generator.OperandList` can
51    unwrap them (see `OperandWrapper` and `generator.OperandList.unwrap()`).
52    """
53    raise NotImplementedError()
54
55  @staticmethod
56  def GetArgumentType():
57    """
58    Return the type to be printed when passing this operand as an argument. For
59    example, we could pass it by value or by reference.
60    """
61    raise NotImplementedError()
62
63  @staticmethod
64  def Declare():
65    """
66    Generate code to declare the operand `struct Operands`.
67    """
68    raise NotImplementedError()
69
70  @staticmethod
71  def Instantiate():
72    """
73    Generate code to instantiate the operand from inside a `kTests` loop, with
74    `i` being the index variable.
75    """
76    raise NotImplementedError()
77
78
79class Operand(OperandBase):
80  """
81  Representation of a single operand. An operand has different variants
82  (e.g. "r0", "r1", "LSL", ...) and a default one.
83
84  Attributes:
85    variants  List of variants the operand can take.
86    default   Default variant to use.
87
88  Note that the `variants` and `default` attributes are not used from inside the
89  class. They are public fields used by the `TestCase` object to generate C++.
90  """
91
92  def __init__(self, name, type_name, variants, default):
93    super().__init__(name, type_name)
94    self.variants = variants
95    self.default = default
96
97  def __iter__(self):
98    """
99    Iterating over a single operand just yields the operand object.
100    """
101    yield self
102
103  def GetArgumentType(self):
104    """
105    A single operand is passed to the macro-assembler by value. We just print
106    the type name as it is.
107    """
108    return self.type_name
109
110  def Declare(self):
111    """
112    Generate code to declare the operand as a single member in
113    `struct Operands`.
114    """
115    return "{type_name} {name};".format(type_name=self.type_name,
116                                        name=self.name)
117
118  def Instantiate(self):
119    """
120    Generate code to instantiate the operand as a single local variable.
121    """
122    code = "{type_name} {name} = kTests[i].operands.{name};"
123    return code.format(type_name=self.type_name, name=self.name)
124
125
126class OperandWrapper(OperandBase):
127  """
128  Representation for an operand type which wraps a list of more operands. It
129  corresponds to C++ objects such as `Operand` or `MemOperand`.
130
131  Attributes:
132    operand_list  List of operand that this object wraps.
133  """
134
135  def __init__(self, name, type_name, operand_list):
136    super().__init__(name, type_name)
137    self.operand_list = operand_list
138
139  def __iter__(self):
140    """
141    Iterate through the list of operands. This is required by
142    `OperandList.unwrap()`.
143    """
144    return iter(self.operand_list)
145
146  def GetArgumentType(self):
147    """
148    An operand wrapper object will be passed to the macro-assembler by
149    reference.
150    """
151    return "const " + self.type_name + "&"
152
153  def Declare(self):
154    """
155    An `OperandWrapper` object does not need to be declared in
156    `struct Operands`. Although we do need to declare all underlying operands.
157    """
158    return "\n".join([operand.Declare() for operand in self.operand_list])
159
160  def Instantiate(self):
161    """
162    Instantiate the underlying operands first and then finally instantiate the
163    wrapper object.
164
165    For example, if the object represents a C++ `Operand` type for a shifted
166    register we would get:
167
168    ~~~
169    Register rm = kTests[i].operands.rm;
170    Shift shift_type = kTests[i].operands.shift_type;
171    uint32_t amount = kTests[i].operands.amount;
172    Operand op(rm, shift_type, amount);
173    ~~~
174    """
175    instantiate_wrapped_operands = "\n".join([
176        operand.Instantiate()
177        for operand in self.operand_list
178    ])
179    instantiate_this = "{type_name} {name}({arguments});".format(
180        type_name=self.type_name,
181        name=self.name,
182        arguments=", ".join([operand.name for operand in self.operand_list]))
183    return instantiate_wrapped_operands + "\n" + instantiate_this
184
185
186class Input(object):
187  """
188  Base class for all input types instantiated from a JSON description. This
189  class should not be instantiated directly, instead, we create subclasses for
190  each kind of input we have.
191
192  As opposed to operands, an input represents data passed to an instruction at
193  runtime. For example, it will be the value you write to a register before
194  executing the instruction under test.
195
196  Attributes:
197    name    Name of the input. It is used to declare variable names.
198
199    values  List of values this input can take.
200    default Default value to use.
201  """
202
203  def __init__(self, name, values, default):
204    self.name = name
205
206    self.values = values
207    self.default = default
208
209  @staticmethod
210  def Prologue():
211    """
212    Return a string describing what C++ code to emit before the instruction
213    under test is emitted.
214    """
215    raise NotImplementedError()
216
217  @staticmethod
218  def Epilogue():
219    """
220    Return a string describing what C++ code to emit after the instruction under
221    test is emitted.
222    """
223    raise NotImplementedError()
224
225  @staticmethod
226  def Declare():
227    """
228    Generate code to declare the input in `struct Inputs`.
229    """
230    raise NotImplementedError()
231
232  @staticmethod
233  def PrintInput(suffix = ""):
234    """
235    Generate code to print the input referred to by `self.name`. Optionally add
236    `suffix` to the input's name.
237    """
238    raise NotImplementedError()
239
240  @staticmethod
241  def PrintOutput():
242    """
243    Generate code to print the input from the result buffer, indexed with `i`
244    and `j`.
245    """
246    raise NotImplementedError()
247
248  @staticmethod
249  def InstantiateResult(suffix = ""):
250    """
251    Generate code to instantiate an input from the result buffer, indexed with
252    `i`. Optionally add `suffix` to the input's name.
253    """
254    raise NotImplementedError()
255
256  @staticmethod
257  def InstantiateInput(suffix = ""):
258    """
259    Generate code to instantiate an input from the input buffer, indexed with
260    `i`. Optionally add `suffix` to the input's name.
261    """
262    raise NotImplementedError()
263
264  @staticmethod
265  def InstantiateReference(suffix = ""):
266    """
267    Generate code to instantiate an input from the reference buffer, indexed
268    with `i`. Optionally add `suffix` to the input's name.
269    """
270    raise NotImplementedError()
271
272  @staticmethod
273  def Compare(left_suffix, operand, right_suffix):
274    """
275    Generate code as a C++ expression comparing two inputs of this type.
276    """
277    raise NotImplementedError()
278
279
280class Scalar(Input):
281  """
282  Base class for inputs that are represented as a single scalar value.
283  Subclasses should implement `TypeName()`, `Pri()` and `NDigit()` to specify
284  how they should be represented and printed, see the `U32` class for an
285  example.
286  """
287
288  @staticmethod
289  def TypeName():
290    """
291    Return the type name as used to declare and instantiate this input.
292    """
293    raise NotImplementedError()
294
295  @staticmethod
296  def Pri():
297    """
298    Return the format string used to generate a call to `printf` to print this
299    input type. For example, "PRIx32".
300    """
301    raise NotImplementedError()
302
303  @staticmethod
304  def NDigit():
305    """
306    Return the number of digits to use to print this input type.
307    """
308    raise NotImplementedError()
309
310  def Declare(self):
311    """
312    A scalar input is declared as a single member in `struct Inputs`.
313    """
314    return "{type_name} {name};".format(type_name=self.TypeName(),
315                                        name=self.name)
316
317  def PrintInput(self, suffix = ""):
318    code = "printf(\"0x%0{n_digit}\" {pri}, {name});"
319    return code.format(n_digit=self.NDigit(), pri=self.Pri(),
320                       name=self.name + suffix)
321
322  def PrintOutput(self):
323    code = "printf(\"0x%0{n_digit}\" {pri}, results[i]->outputs[j].{name});"
324    return code.format(n_digit=self.NDigit(), pri=self.Pri(), name=self.name)
325
326  def InstantiateResult(self, suffix = ""):
327    code = "{type_name} {name}{suffix} = results[i]->outputs[j].{name};"
328    return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix)
329
330  def InstantiateInput(self, suffix = ""):
331    code = "{type_name} {name}{suffix} = kTests[i].inputs[j].{name};"
332    return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix)
333
334  def InstantiateReference(self, suffix = ""):
335    code = "{type_name} {name}{suffix} = reference[i].outputs[j].{name};"
336    return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix)
337
338  def Compare(self, left_suffix, operand, right_suffix):
339    return """
340      ({name}{left_suffix} {operand} {name}{right_suffix})
341      """.format(name=self.name, left_suffix=left_suffix, operand=operand,
342                 right_suffix=right_suffix)
343
344
345class U32(Scalar):
346  """
347  Base class for inputs that can be represented as 32 bit unsigned words.
348  """
349
350  @staticmethod
351  def TypeName():
352    return "uint32_t"
353
354  @staticmethod
355  def Pri():
356    return "PRIx32"
357
358  @staticmethod
359  def NDigit():
360    return 8
361
362
363class F64(Scalar):
364  @staticmethod
365  def TypeName():
366    return "uint64_t"
367
368  @staticmethod
369  def Pri():
370    return "PRIx64"
371
372  @staticmethod
373  def NDigit():
374    return 16
375
376  def PrintInput(self, suffix = ""):
377    code = "printf(\"0x%0{n_digit}\" {pri} \"(%g)\", {name}, RawbitsToDouble({name}));"
378    return code.format(n_digit=self.NDigit(), pri=self.Pri(),
379                       name=self.name + suffix)
380
381
382class Register(U32):
383  """
384  Description of a Register input. The `Prologue` and `Epilogue` methods
385  describe what C++ code to emit to set and record the value of a register
386  before and after executing an instruction.
387  """
388
389  def Prologue(self):
390    code = "__ Ldr({name}, MemOperand(input_ptr, offsetof(Inputs, {name})));"
391    return code.format(name=self.name)
392
393  def Epilogue(self):
394    code = "__ Str({name}, MemOperand(result_ptr, offsetof(Inputs, {name})));"
395    return code.format(name=self.name)
396
397
398class DRegisterF64(F64):
399  def Prologue(self):
400    code = "__ Vldr({name}, MemOperand(input_ptr, offsetof(Inputs, {name})));"
401    return code.format(name=self.name)
402
403  def Epilogue(self):
404    code = "__ Vstr({name}, MemOperand(result_ptr, offsetof(Inputs, {name})));"
405    return code.format(name=self.name)
406
407
408class NZCV(U32):
409  """
410  Description of NZCV flags as inputs to an instruction.
411
412  The `Prologue` and `Epilogue` methods describe what C++ code to emit to set
413  and record the NZCV flags before and after emitting the instruction under
414  test.
415  """
416
417  def Prologue(self):
418    # When setting the `NZCV` flags, we need to make sure we do not override the
419    # `Q` bit. Therefore we use two scratch registers that we push on the stack
420    # first to allow the instruction to use them as operands.
421    code = """{{
422          UseScratchRegisterScope temp_registers(&masm);
423          Register nzcv_bits = temp_registers.Acquire();
424          Register saved_q_bit = temp_registers.Acquire();
425          // Save the `Q` bit flag.
426          __ Mrs(saved_q_bit, APSR);
427          __ And(saved_q_bit, saved_q_bit, QFlag);
428          // Set the `NZCV` and `Q` flags together.
429          __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, {})));
430          __ Orr(nzcv_bits, nzcv_bits, saved_q_bit);
431          __ Msr(APSR_nzcvq, nzcv_bits);
432        }}
433        """
434    return code.format(self.name)
435
436  def Epilogue(self):
437    code = """{{
438          UseScratchRegisterScope temp_registers(&masm);
439          Register nzcv_bits = temp_registers.Acquire();
440          __ Mrs(nzcv_bits, APSR);
441          // Only record the NZCV bits.
442          __ And(nzcv_bits, nzcv_bits, NZCVFlag);
443          __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, {})));
444        }}
445        """
446    return code.format(self.name)
447
448
449class Q(U32):
450  """
451  Description of the Q flag as inputs to an instruction.
452
453  The `Prologue` and `Epilogue` methods describe what C++ code to emit to set
454  and record the Q flag before and after emitting the instruction under test.
455  """
456
457  def Prologue(self):
458    # When clearing or setting the `Q` bit, we need to make sure the `NZCV`
459    # flags are not overriden. Therefore we use two scratch registers that we
460    # push on the stack first to allow the instruction to use them as operands.
461    code = """{{
462          UseScratchRegisterScope temp_registers(&masm);
463          Register q_bit = temp_registers.Acquire();
464          Register saved_nzcv_bits = temp_registers.Acquire();
465          // Save the `NZCV` flags.
466          __ Mrs(saved_nzcv_bits, APSR);
467          __ And(saved_nzcv_bits, saved_nzcv_bits, NZCVFlag);
468          // Set the `NZCV` and `Q` flags together.
469          __ Ldr(q_bit, MemOperand(input_ptr, offsetof(Inputs, {})));
470          __ Orr(q_bit, q_bit, saved_nzcv_bits);
471          __ Msr(APSR_nzcvq, q_bit);
472        }}
473        """
474    return code.format(self.name)
475
476  def Epilogue(self):
477    code = """{{
478          UseScratchRegisterScope temp_registers(&masm);
479          Register q_bit = temp_registers.Acquire();
480          __ Mrs(q_bit, APSR);
481          // Only record the Q bit.
482          __ And(q_bit, q_bit, QFlag);
483          __ Str(q_bit, MemOperand(result_ptr, offsetof(Inputs, {})));
484        }}
485        """
486    return code.format(self.name)
487
488
489class GE(U32):
490  """
491  Description of the GE flag as inputs to an instruction.
492
493  The `Prologue` and `Epilogue` methods describe what C++ code to emit to set
494  and record the GE flags before and after emitting the instruction under test.
495  """
496
497  def Prologue(self):
498    # We need a scratch register to load the `GE` flags.
499    code = """{{
500          UseScratchRegisterScope temp_registers(&masm);
501          Register ge_bits = temp_registers.Acquire();
502          __ Ldr(ge_bits, MemOperand(input_ptr, offsetof(Inputs, {})));
503          __ Msr(APSR_g, ge_bits);
504        }}
505        """
506    return code.format(self.name)
507
508  def Epilogue(self):
509    code = """{{
510          UseScratchRegisterScope temp_registers(&masm);
511          Register ge_bits = temp_registers.Acquire();
512          __ Mrs(ge_bits, APSR);
513          // Only record the GE bits.
514          __ And(ge_bits, ge_bits, GEFlags);
515          __ Str(ge_bits, MemOperand(result_ptr, offsetof(Inputs, {})));
516        }}
517        """
518    return code.format(self.name)
519
520
521class FPSCR(U32):
522  def Prologue(self):
523    # We need a scratch register to load the `FPCSR` flags.
524    code = """{{
525          UseScratchRegisterScope temp_registers(&masm);
526          Register fpsr_bits = temp_registers.Acquire();
527          __ Ldr(fpsr_bits, MemOperand(input_ptr, offsetof(Inputs, {})));
528          __ Vmsr(FPSCR, fpsr_bits);
529        }}
530        """
531    return code.format(self.name)
532
533  def Epilogue(self):
534    code = """{{
535          UseScratchRegisterScope temp_registers(&masm);
536          Register fpsr_bits = temp_registers.Acquire();
537          __ Vmrs(RegisterOrAPSR_nzcv(fpsr_bits.GetCode()), FPSCR);
538          __ Str(fpsr_bits, MemOperand(result_ptr, offsetof(Inputs, {})));
539        }}
540        """
541    return code.format(self.name)
542
543
544class MemOperand(Input):
545  """
546  Description of a memory location input, used to test a `MemOperand` operand.
547
548  A memory location input is a compound type and is represented as an
549  array of two `uint32_t` values, an "offset" and a "data":
550
551  ~~~
552  {
553    0x0,       // Offset used to record the base register in case it was
554               // updated.
555    0xabababab // 32 bit value in memory the instruction should work with.
556  }
557  ~~~
558  """
559
560  def Declare(self):
561    """
562    Declare the input as a two element array.
563    """
564    return "uint32_t {name}[2];".format(name=self.name)
565
566  def PrintInput(self, suffix = ""):
567    code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}",
568                     {name}[0], {name}[1]);'''
569    return code.format(name=self.name + suffix)
570
571  def PrintOutput(self):
572    code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}",
573                     results[i]->outputs[j].{name}[0],
574                     results[i]->outputs[j].{name}[1]);'''
575    return code.format(name=self.name)
576
577  def InstantiateResult(self, suffix = ""):
578    code = """uint32_t {name}{suffix}[2] = {{
579        results[i]->outputs[j].{name}[0],
580        results[i]->outputs[j].{name}[1]
581      }};
582      """
583    return code.format(name=self.name, suffix=suffix)
584
585  def InstantiateInput(self, suffix = ""):
586    code = """uint32_t {name}{suffix}[2] = {{
587        kTests[i].inputs[j].{name}[0],
588        kTests[i].inputs[j].{name}[1]
589      }};
590      """
591    return code.format(name=self.name, suffix=suffix)
592
593  def InstantiateReference(self, suffix = ""):
594    code = """uint32_t {name}{suffix}[2] = {{
595        results[i]->outputs[j].{name}[0],
596        results[i]->outputs[j].{name}[1]
597      }};
598      """
599    return code.format(name=self.name, suffix=suffix)
600
601  def Compare(self, left_suffix, operand, right_suffix):
602    return """
603      (({name}{left_suffix}[0] {operand} {name}{right_suffix}[0]) &&
604       ({name}{left_suffix}[1] {operand} {name}{right_suffix}[1]))
605      """.format(name=self.name, left_suffix=left_suffix, operand=operand,
606                 right_suffix=right_suffix)
607
608  def Prologue(self):
609    return """
610      // Allocate 4 bytes for the instruction to work with.
611      scratch_memory_buffers[i] = new byte[4];
612      {{
613        UseScratchRegisterScope temp_registers(&masm);
614
615        Register {name}_tmp = temp_registers.Acquire();
616        Register base_register = {name}.GetBaseRegister();
617
618        // Write the expected data into the scratch buffer.
619        __ Mov(base_register, Operand::From(scratch_memory_buffers[i]));
620        __ Ldr({name}_tmp, MemOperand(input_ptr, offsetof(Inputs, {name}) + 4));
621        __ Str({name}_tmp, MemOperand(base_register));
622
623        // Compute the address to put into the base register so that the
624        // `MemOperand` points to the right location.
625        // TODO: Support more kinds of `MemOperand`.
626        if (!{name}.IsPostIndex()) {{
627          if ({name}.IsImmediate()) {{
628            if ({name}.GetSign().IsPlus()) {{
629              __ Mov({name}_tmp, {name}.GetOffsetImmediate());
630              __ Sub(base_register, base_register, {name}_tmp);
631            }} else {{
632              __ Mov({name}_tmp, -{name}.GetOffsetImmediate());
633              __ Add(base_register, base_register, {name}_tmp);
634            }}
635          }} else if ({name}.IsShiftedRegister()) {{
636            __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(),
637                                       {name}.GetShift(),
638                                       {name}.GetShiftAmount()));
639            if ({name}.GetSign().IsPlus()) {{
640              __ Sub(base_register, base_register, {name}_tmp);
641            }} else {{
642              __ Add(base_register, base_register, {name}_tmp);
643            }}
644          }}
645        }}
646      }}
647      """.format(name=self.name)
648
649  def Epilogue(self):
650    # TODO: This generated code does not support recording the state for
651    # instructions where the base register is the same as another register used
652    # in the instruction. It is possible to do so but requires more temporary
653    # registers which is not trivial to implement without
654    # `UseScratchRegisterScope`. We will be able to lift this restriction when
655    # it is implemented.
656    return """{{
657        UseScratchRegisterScope temp_registers(&masm);
658        Register {name}_tmp = temp_registers.Acquire();
659        Register base_register = {name}.GetBaseRegister();
660
661        // Compute the address of the scratch buffer by from the base register. If
662        // the instruction has updated the base register, we will be able to
663        // record it.
664        if (!{name}.IsPostIndex()) {{
665          if ({name}.IsImmediate()) {{
666            if ({name}.GetSign().IsPlus()) {{
667              __ Mov({name}_tmp, {name}.GetOffsetImmediate());
668              __ Add(base_register, base_register, {name}_tmp);
669            }} else {{
670              __ Mov({name}_tmp, -{name}.GetOffsetImmediate());
671              __ Sub(base_register, base_register, {name}_tmp);
672            }}
673          }} else if ({name}.IsShiftedRegister()) {{
674            __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(),
675                                       {name}.GetShift(),
676                                       {name}.GetShiftAmount()));
677            if ({name}.GetSign().IsPlus()) {{
678              __ Add(base_register, base_register, {name}_tmp);
679            }} else {{
680              __ Sub(base_register, base_register, {name}_tmp);
681            }}
682          }}
683        }}
684
685        // Record the value of the base register, as an offset from the scratch
686        // buffer's address.
687        __ Mov({name}_tmp, Operand::From(scratch_memory_buffers[i]));
688        __ Sub(base_register, base_register, {name}_tmp);
689        __ Str(base_register, MemOperand(result_ptr, offsetof(Inputs, {name})));
690
691        // Record the 32 bit word from memory.
692        __ Ldr({name}_tmp, MemOperand({name}_tmp));
693        __ Str({name}_tmp, MemOperand(result_ptr, offsetof(Inputs, {name}) + 4));
694      }}
695      """.format(name=self.name)
696