| Index: src/trusted/validator_arm/dgen_test_output.py
 | 
| diff --git a/src/trusted/validator_arm/dgen_test_output.py b/src/trusted/validator_arm/dgen_test_output.py
 | 
| deleted file mode 100644
 | 
| index d6421b70ae1b60699c211935b26c935312bc32e4..0000000000000000000000000000000000000000
 | 
| --- a/src/trusted/validator_arm/dgen_test_output.py
 | 
| +++ /dev/null
 | 
| @@ -1,647 +0,0 @@
 | 
| -#!/usr/bin/python
 | 
| -#
 | 
| -# Copyright (c) 2012 The Native Client Authors. All rights reserved.
 | 
| -# Use of this source code is governed by a BSD-style license that can be
 | 
| -# found in the LICENSE file.
 | 
| -#
 | 
| -
 | 
| -"""
 | 
| -Responsible for generating the testing decoders based on
 | 
| -parsed table representations.
 | 
| -"""
 | 
| -
 | 
| -# This file generates testing code for our class decoder. The decoder
 | 
| -# tables are specifically written to minimize the number of decoder
 | 
| -# classes needed to parse valid ARM instructions. For testing, this is
 | 
| -# a problem. We can't (easily) tell if the intended instruction rules
 | 
| -# of ARM are being met, since there is not a one-to-one mapping from
 | 
| -# class decoders to rules.
 | 
| -#
 | 
| -# For example, consider the following two rows (from armv7.table):
 | 
| -#
 | 
| -# | 0011x      -        = Binary4RegisterShiftedOp
 | 
| -#                         Rsb_Rule_144_A1_P288
 | 
| -#                         cccc0000011snnnnddddssss0tt1mmmm
 | 
| -#                         RegsNotPc
 | 
| -# | 0100x      -        = Binary4RegisterShiftedOp
 | 
| -#                         Add_Rule_7_A1_P26
 | 
| -#                         cccc0000100snnnnddddssss0tt1mmmm
 | 
| -#                         RegsNotPc
 | 
| -#
 | 
| -# Both rows state to return a Binary4RegisterShiftedOp class decoder.
 | 
| -# The sequence of four symbols correspond to (in order presented):
 | 
| -#
 | 
| -#    name - The name of the class decoder to use in sel_ldr
 | 
| -#    rule - A unique name identifying the rule from the manual that
 | 
| -#       defines what the selected class decoder is to decode.
 | 
| -#    pattern - The sequence of bits defines by the rule (above)
 | 
| -#    constraints - Any additional constraints assumed by the rule.
 | 
| -#
 | 
| -# All but the name is optional. The remaining fields provide
 | 
| -# additional documentation and information for testing (which is
 | 
| -# used by this file).
 | 
| -#
 | 
| -# If these two rows had a mergable bit pattern (which they do not),
 | 
| -# these rows would still not mergable since the actions are
 | 
| -# different. However, for sel_ldr, they both state to use a
 | 
| -# Binary4RegisterShiftedOp. The remaining identifiers are added data
 | 
| -# for testing only.
 | 
| -#
 | 
| -# We fix this by defining a notion of "action_filter" where one can
 | 
| -# choose to keep only those fields that are applicable. For sel_ldr,
 | 
| -# it's only 'name'. For testing, it will include other fields,
 | 
| -# depending on the context.
 | 
| -#
 | 
| -# Note: The current ARM instruction table has both new and old
 | 
| -# actions. Old actions only define the 'InstClass' entry. If the
 | 
| -# remaining fields are omitted, the corresponding testing for those
 | 
| -# entries are omitted.
 | 
| -#
 | 
| -# Note: See dgen_decoder_output.py for more details on how we build a
 | 
| -# decoder for sel_ldr.
 | 
| -#
 | 
| -# For testing, we would like to know the specific instruction rule
 | 
| -# that was being tested. Further, we would like to know what
 | 
| -# instruction rule was chosen for each decoder class selection made by
 | 
| -# the parse tables.  To do this, we do two levels of wrapping.
 | 
| -#
 | 
| -# This file generates a set of wrapper classes, each a subclass of
 | 
| -# NamedClassDecoder. One is generated for each InstClass needed by
 | 
| -# sel_ldr (i.e. only the 'name' field). These named classes correspond
 | 
| -# to what sel_ldr will select.
 | 
| -#
 | 
| -# The named version of each named InstClass is:
 | 
| -#
 | 
| -#  class NamedInstClass : public NamedClassDecoder {
 | 
| -#   public:
 | 
| -#    inline NamedInstClass()
 | 
| -#        : NamedClassDecoder(decoder_, "InstClass")
 | 
| -#    {}
 | 
| -#  virtual ~NamedInstClass() {}
 | 
| -# protected:
 | 
| -#   explicit inline NamedInstClass(const char* name)
 | 
| -#       : NamedClassDecoder(decoder_, name) {}
 | 
| -# private:
 | 
| -#  Binary3RegisterShiftedTest decoder_;
 | 
| -#};
 | 
| -#
 | 
| -# This makes sure that each decoder class can be identified using a
 | 
| -# separate class decoder. The public constructor is for table rows
 | 
| -# that don't have rule names. The protected constructor is for table
 | 
| -# rows that have a rule name, and will be a subclass of this class.
 | 
| -# The class defined for rows with a Rule name is:
 | 
| -#
 | 
| -# class NamedRuleInstClass : public NamedInstClass {
 | 
| -#  public:
 | 
| -#   inline NamedRuleInstClass()
 | 
| -#    : NamedInstClass("RuleInstClass")
 | 
| -#   {}
 | 
| -#  virtual ~NamedRuleInstClass() {}
 | 
| -#};
 | 
| -#
 | 
| -# The base class for NamedClassDecoder is specified in
 | 
| -# "named_class_decoder.h".  This file defines a class that takes a
 | 
| -# ClassDecoder (reference) C and a print name NAME, and builds a
 | 
| -# corresponding ClassDecoder that acts like C, but will print out
 | 
| -# NAME. The behaviour of C is maintained by dispatching each virtual
 | 
| -# on the NamedClassDecoder to the corresponding virtual on C.
 | 
| -#
 | 
| -# We then define the class decoder Decoder, by defining a derived
 | 
| -# instance of DecoderState as follows:
 | 
| -#
 | 
| -# class NamedDecoder : DecoderState {
 | 
| -#  public:
 | 
| -#   explicit NamedDecoder();
 | 
| -#   virtual ~NamedDecoder();
 | 
| -#  const NamedClassDecoder& decode_named(const Instruction) const;
 | 
| -#  virtual const ClassDecoder& decode(const Instruction) const;
 | 
| -#  ...
 | 
| -# };
 | 
| -#
 | 
| -# The method decode is the expected API for the NamedDecoder, which is
 | 
| -# an instance of DecoderState (defined in decode.h). The method
 | 
| -# decode_named is the same, but returns NamedClassDecoder's so that
 | 
| -# good error messages can be generated by the test harnesses for
 | 
| -# ClassDecoder's (see decoder_tester.h for more details on
 | 
| -# ClassDecoder test harnesses).
 | 
| -#
 | 
| -# To the NamedDecoder, we add a constant field NamedClassDecoder for
 | 
| -# each possible class decoder method decode_named could return, or
 | 
| -# that we could use in automatically generated tests. These fields
 | 
| -# allow us to only create the corresponding decoder classes once
 | 
| -# (during constructor initialization).
 | 
| -#
 | 
| -# Finally, we add a method corresponding to each defined decoder
 | 
| -# table.  The forms of these decoders is:
 | 
| -#
 | 
| -#  inline const NamedClassDecoder& decode_TABLE(
 | 
| -#     const nacl_arm_dec::Instruction insn) const;
 | 
| -#
 | 
| -# Each of these methods are defined as inline methods so that they can
 | 
| -# be optimized away in the corresponding top level methods (i.e.
 | 
| -# decode_named and decode).
 | 
| -#
 | 
| -# For testing, there are three files generated:
 | 
| -#
 | 
| -#     decoder_named_classes.h
 | 
| -#     decoder_named_decoder.h
 | 
| -#     decoder_named.cc
 | 
| -#     decoder_tests.cc
 | 
| -#
 | 
| -# File decoder_named_classes.h defines the class declarations for the
 | 
| -# generated Rule classes, and named class decoder classes. File
 | 
| -# decoder_named_decoder.h defines the decoder class NamedDecoder
 | 
| -# (discussed above). decoder_named.cc contains the corresponding
 | 
| -# implementations of the constructors and methods of these classes.
 | 
| -#
 | 
| -# decoder_tests.cc generates an automatic test harness executable,
 | 
| -# that will test each instruction Rule. Each test generates all
 | 
| -# possible matches the the corresponding Pattern of the table rule,
 | 
| -# and calls the corresponding tester associated with the class decoder
 | 
| -# of that row. By default, the tester is presumed to be named.
 | 
| -#
 | 
| -#    InstClassTester
 | 
| -#
 | 
| -# If the row defines a Constraints identifier, then the tester
 | 
| -#
 | 
| -#    InstClassTesterConstraints
 | 
| -#
 | 
| -# is used instead.
 | 
| -
 | 
| -import dgen_opt
 | 
| -import dgen_output
 | 
| -
 | 
| -# Defines the header for decoder_named_classes.h
 | 
| -NAMED_CLASSES_H_HEADER="""
 | 
| -%(FILE_HEADER)s
 | 
| -%(NOT_TCB_MESSAGE)s
 | 
| -
 | 
| -#ifndef %(IFDEF_NAME)s
 | 
| -#define %(IFDEF_NAME)s
 | 
| -
 | 
| -#include "native_client/src/trusted/validator_arm/named_class_decoder.h"
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -RULE_CLASSES_HEADER="""
 | 
| -/*
 | 
| - * Define rule decoder classes.
 | 
| - */
 | 
| -namespace nacl_arm_dec {
 | 
| -"""
 | 
| -
 | 
| -RULE_CLASS="""
 | 
| -class %(rule)s%(decoder)s
 | 
| -   : public %(decoder)s {
 | 
| - public:
 | 
| -  virtual ~%(rule)s%(decoder)s() {}
 | 
| -};
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -RULE_CLASSES_FOOTER="""
 | 
| -}  // nacl_arm_dec
 | 
| -"""
 | 
| -
 | 
| -NAMED_H_NAMESPACE="""
 | 
| -namespace nacl_arm_test {
 | 
| -"""
 | 
| -
 | 
| -NAMED_DECODERS_HEADER="""
 | 
| -/*
 | 
| - * Define named class decoders for each class decoder.
 | 
| - * The main purpose of these classes is to introduce
 | 
| - * instances that are named specifically to the class decoder
 | 
| - * and/or rule that was used to parse them. This makes testing
 | 
| - * much easier in that error messages use these named classes
 | 
| - * to clarify what row in the corresponding table was used
 | 
| - * to select this decoder. Without these names, debugging the
 | 
| - * output of the test code would be nearly impossible
 | 
| - */
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -NAMED_DECODER_DECLARE="""
 | 
| -class Named%(decoder)s : public NamedClassDecoder {
 | 
| - public:
 | 
| -  inline Named%(decoder)s()
 | 
| -    : NamedClassDecoder(decoder_, "%(decoder)s")
 | 
| -  {}
 | 
| -  virtual ~Named%(decoder)s() {}
 | 
| - protected:
 | 
| -  explicit inline Named%(decoder)s(const char* name)
 | 
| -    : NamedClassDecoder(decoder_, name) {}
 | 
| - private:
 | 
| -  nacl_arm_dec::%(decoder)s decoder_;
 | 
| -};
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -NAMED_RULE_DECLARE="""
 | 
| -class Named%(rule)s%(decoder)s
 | 
| -    : public Named%(decoder)s {
 | 
| - public:
 | 
| -  inline Named%(rule)s%(decoder)s()
 | 
| -    : Named%(decoder)s("%(rule)s%(decoder)s")
 | 
| -  {}
 | 
| -  virtual ~Named%(rule)s%(decoder)s() {}
 | 
| -};
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -NAMED_CLASSES_H_FOOTER="""
 | 
| -} // namespace nacl_arm_test
 | 
| -#endif  // %(IFDEF_NAME)s
 | 
| -"""
 | 
| -
 | 
| -def generate_named_classes_h(decoder, decoder_name, filename, out):
 | 
| -  """Defines named classes needed for decoder testing.
 | 
| -
 | 
| -  Args:
 | 
| -    tables: list of Table objects to process.
 | 
| -    decoder_name: The name of the decoder state to build.
 | 
| -    filename: The (localized) name for the .h file.
 | 
| -    out: a COutput object to write to.
 | 
| -  """
 | 
| -  if not decoder.primary: raise Exception('No tables provided.')
 | 
| -
 | 
| -  values = {
 | 
| -      'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
 | 
| -      'NOT_TCB_MESSAGE' : dgen_output.NOT_TCB_BOILERPLATE,
 | 
| -      'IFDEF_NAME' : dgen_output.ifdef_name(filename),
 | 
| -      'decoder_name': decoder_name,
 | 
| -      }
 | 
| -  out.write(NAMED_CLASSES_H_HEADER % values)
 | 
| -  _generate_rule_classes(decoder, values, out)
 | 
| -  out.write(NAMED_H_NAMESPACE)
 | 
| -  _generate_named_decoder_classes(decoder, values, out)
 | 
| -  out.write(NAMED_CLASSES_H_FOOTER % values)
 | 
| -
 | 
| -def _generate_named_decoder_classes(decoder, values, out):
 | 
| -  out.write(NAMED_DECODERS_HEADER)
 | 
| -  # Generate one for each type of decoder in the decoder.
 | 
| -  for d in decoder.action_filter(['name']).decoders():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = ''
 | 
| -    out.write(NAMED_DECODER_DECLARE % values)
 | 
| -  # Now generate one for each decoder that has a rule associated with it.
 | 
| -  for d in decoder.action_filter(['name', 'rule']).rules():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = d.rule
 | 
| -    out.write(NAMED_RULE_DECLARE % values)
 | 
| -
 | 
| -def _generate_rule_classes(decoder, values, out):
 | 
| -  # Note: we generate these classes in nacl_arm_dec, so that
 | 
| -  # all decoder classes generated by the pareser are in the
 | 
| -  # same namesapce.
 | 
| -  out.write(RULE_CLASSES_HEADER)
 | 
| -  for action in decoder.action_filter(['name', 'rule']).rules():
 | 
| -    values['decoder'] = action.name
 | 
| -    values['rule'] = action.rule
 | 
| -    out.write(RULE_CLASS % values)
 | 
| -  out.write(RULE_CLASSES_FOOTER)
 | 
| -
 | 
| -NAMED_DECODER_H_HEADER="""
 | 
| -%(FILE_HEADER)s
 | 
| -%(NOT_TCB_MESSAGE)s
 | 
| -
 | 
| -#ifndef %(IFDEF_NAME)s
 | 
| -#define %(IFDEF_NAME)s
 | 
| -
 | 
| -#include "native_client/src/trusted/validator_arm/decode.h"
 | 
| -#include "%(FILENAME_BASE)s_classes.h"
 | 
| -#include "native_client/src/trusted/validator_arm/named_class_decoder.h"
 | 
| -
 | 
| -namespace nacl_arm_test {
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_HEADER="""
 | 
| -// Defines a (named) decoder class selector for instructions
 | 
| -class Named%(decoder_name)s : nacl_arm_dec::DecoderState {
 | 
| - public:
 | 
| -  explicit Named%(decoder_name)s();
 | 
| -  virtual ~Named%(decoder_name)s();
 | 
| -
 | 
| -  // Parses the given instruction, returning the named class
 | 
| -  // decoder to use.
 | 
| -  const NamedClassDecoder& decode_named(
 | 
| -     const nacl_arm_dec::Instruction) const;
 | 
| -
 | 
| -  // Parses the given instruction, returning the class decoder
 | 
| -  // to use.
 | 
| -  virtual const nacl_arm_dec::ClassDecoder& decode(
 | 
| -     const nacl_arm_dec::Instruction) const;
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_FIELD_COMMENTS="""
 | 
| -  // The following fields define the set of class decoders
 | 
| -  // that can be returned by the API function "decode_named". They
 | 
| -  // are created once as instance fields, and then returned
 | 
| -  // by the table methods above. This speeds up the code since
 | 
| -  // the class decoders need to only be bulit once (and reused
 | 
| -  // for each call to "decode_named").
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_FIELD="""
 | 
| -  const Named%(rule)s%(decoder)s %(rule)s%(decoder)s_instance_;
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_PRIVATE="""
 | 
| - private:
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_DECODER_COMMENTS="""
 | 
| -  // The following list of methods correspond to each decoder table,
 | 
| -  // and implements the pattern matching of the corresponding bit
 | 
| -  // patterns. After matching the corresponding bit patterns, they
 | 
| -  // either call other methods in this list (corresponding to another
 | 
| -  // decoder table), or they return the instance field that implements
 | 
| -  // the class decoder that should be used to decode the particular
 | 
| -  // instruction.
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_DECODER="""
 | 
| -  inline const NamedClassDecoder& decode_%(table)s(
 | 
| -      const nacl_arm_dec::Instruction insn) const;
 | 
| -"""
 | 
| -
 | 
| -DECODER_STATE_FOOTER="""
 | 
| -};
 | 
| -"""
 | 
| -
 | 
| -NAMED_DECODER_H_FOOTER="""
 | 
| -} // namespace nacl_arm_test
 | 
| -#endif  // %(IFDEF_NAME)s
 | 
| -"""
 | 
| -
 | 
| -def generate_named_decoder_h(decoder, decoder_name, filename, out):
 | 
| -    """Generates the named decoder for testing.
 | 
| -
 | 
| -    Args:
 | 
| -        tables: list of Table objects to process.
 | 
| -        decoder_name: The name of the decoder state to build.
 | 
| -        filename: The (localized) name for the .h file.
 | 
| -        out: a COutput object to write to.
 | 
| -    """
 | 
| -    if not decoder.primary: raise Exception('No tables provided.')
 | 
| -    assert filename.endswith('_decoder.h')
 | 
| -
 | 
| -    values = {
 | 
| -        'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
 | 
| -        'NOT_TCB_MESSAGE' : dgen_output.NOT_TCB_BOILERPLATE,
 | 
| -        'IFDEF_NAME' : dgen_output.ifdef_name(filename),
 | 
| -        'FILENAME_BASE': filename[:-len('_decoder.h')],
 | 
| -        'decoder_name': decoder_name,
 | 
| -        }
 | 
| -    out.write(NAMED_DECODER_H_HEADER % values)
 | 
| -    _generate_decoder_state_class(decoder, values, out)
 | 
| -    out.write(NAMED_DECODER_H_FOOTER % values)
 | 
| -
 | 
| -def _generate_decoder_state_class(decoder, values, out):
 | 
| -  # Generate a field for each type of decoder in the decoder.
 | 
| -  out.write(DECODER_STATE_HEADER % values)
 | 
| -  out.write(DECODER_STATE_FIELD_COMMENTS);
 | 
| -  for d in decoder.action_filter(['name']).decoders():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = ''
 | 
| -    out.write(DECODER_STATE_FIELD % values)
 | 
| -  # Now generate one for each decoder that has a rule associated with it.
 | 
| -  for d in decoder.action_filter(['name', 'rule']).rules():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = d.rule
 | 
| -    out.write(DECODER_STATE_FIELD % values)
 | 
| -  out.write(DECODER_STATE_PRIVATE);
 | 
| -  out.write(DECODER_STATE_DECODER_COMMENTS)
 | 
| -  for table in decoder.tables():
 | 
| -    values['table'] = table.name
 | 
| -    out.write(DECODER_STATE_DECODER % values)
 | 
| -  out.write(DECODER_STATE_FOOTER % values)
 | 
| -
 | 
| -# Defines the source for DECODER_named.cc
 | 
| -NAMED_CC_HEADER="""
 | 
| -%(FILE_HEADER)s
 | 
| -%(NOT_TCB_MESSAGE)s
 | 
| -#include "%(FILENAME_BASE)s_decoder.h"
 | 
| -
 | 
| -#include <stdio.h>
 | 
| -
 | 
| -using nacl_arm_dec::ClassDecoder;
 | 
| -using nacl_arm_dec::Instruction;
 | 
| -
 | 
| -namespace nacl_arm_test {
 | 
| -"""
 | 
| -
 | 
| -PARSE_CONSTRUCT_HEADER="""
 | 
| -Named%(decoder_name)s::Named%(decoder_name)s()
 | 
| -  : nacl_arm_dec::DecoderState()
 | 
| -"""
 | 
| -
 | 
| -PARSE_CONSTRUCT_FIELDS="""
 | 
| -  , %(rule)s%(decoder)s_instance_()
 | 
| -"""
 | 
| -
 | 
| -PARSE_CONSTRUCT_FOOTER="""
 | 
| -{}
 | 
| -
 | 
| -Named%(decoder_name)s::~Named%(decoder_name)s() {}
 | 
| -"""
 | 
| -
 | 
| -PARSE_TABLE_METHOD_HEADER="""
 | 
| -/*
 | 
| - * Implementation of table %(table_name)s.
 | 
| - * Specified by: %(citation)s
 | 
| - */
 | 
| -const NamedClassDecoder& Named%(decoder_name)s::decode_%(table_name)s(
 | 
| -     const nacl_arm_dec::Instruction insn) const {
 | 
| -"""
 | 
| -
 | 
| -PARSE_TABLE_METHOD_ROW="""
 | 
| -  if (%(tests)s) {
 | 
| -   return %(action)s;
 | 
| -  }
 | 
| -"""
 | 
| -
 | 
| -PARSE_TABLE_METHOD_FOOTER="""
 | 
| -  // Catch any attempt to fall through...
 | 
| -  fprintf(stderr, "TABLE IS INCOMPLETE: %(table_name)s could not parse %%08X",
 | 
| -          insn.bits(31,0));
 | 
| -  return Forbidden_instance_;
 | 
| -}
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -NAMED_CC_FOOTER="""
 | 
| -const NamedClassDecoder& Named%(decoder_name)s::
 | 
| -decode_named(const nacl_arm_dec::Instruction insn) const {
 | 
| -  return decode_%(entry_table_name)s(insn);
 | 
| -}
 | 
| -
 | 
| -const nacl_arm_dec::ClassDecoder& Named%(decoder_name)s::
 | 
| -decode(const nacl_arm_dec::Instruction insn) const {
 | 
| -  return decode_named(insn).named_decoder();
 | 
| -}
 | 
| -
 | 
| -}  // namespace nacl_arm_test
 | 
| -"""
 | 
| -
 | 
| -def generate_named_cc(decoder, decoder_name, filename, out):
 | 
| -    """Implementation of the test decoder in .cc file
 | 
| -
 | 
| -    Args:
 | 
| -        tables: list of Table objects to process.
 | 
| -        decoder_name: The name of the decoder state to build.
 | 
| -        filename: The (localized) name for the .h file.
 | 
| -        out: a COutput object to write to.
 | 
| -    """
 | 
| -    if not decoder.primary: raise Exception('No tables provided.')
 | 
| -    assert filename.endswith('.cc')
 | 
| -
 | 
| -    values = {
 | 
| -        'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
 | 
| -        'NOT_TCB_MESSAGE' : dgen_output.NOT_TCB_BOILERPLATE,
 | 
| -        'FILENAME_BASE' : filename[:-len('.cc')],
 | 
| -        'decoder_name': decoder_name,
 | 
| -        'entry_table_name': decoder.primary.name,
 | 
| -        }
 | 
| -    out.write(NAMED_CC_HEADER % values)
 | 
| -    _generate_decoder_constructors(decoder, values, out)
 | 
| -    _generate_decoder_method_bodies(decoder, values, out)
 | 
| -    out.write(NAMED_CC_FOOTER % values)
 | 
| -
 | 
| -def _generate_decoder_constructors(decoder, values, out):
 | 
| -  out.write(PARSE_CONSTRUCT_HEADER % values)
 | 
| -  # Initialize each type of decoder in the decoder.
 | 
| -  for d in decoder.action_filter(['name']).decoders():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = ''
 | 
| -    out.write(PARSE_CONSTRUCT_FIELDS % values)
 | 
| -  # Now initialize fields for each decoder with a rule.
 | 
| -  for d in decoder.action_filter(['name', 'rule']).rules():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = d.rule
 | 
| -    out.write(PARSE_CONSTRUCT_FIELDS % values)
 | 
| -  out.write(PARSE_CONSTRUCT_FOOTER % values)
 | 
| -
 | 
| -def _generate_decoder_method_bodies(decoder, values, out):
 | 
| -  for table in decoder.tables():
 | 
| -    opt_rows = dgen_opt.optimize_rows(
 | 
| -        table.action_filter(['name', 'rule']).rows)
 | 
| -    print ("Table %s: %d rows minimized to %d"
 | 
| -           % (table.name, len(table.rows), len(opt_rows)))
 | 
| -
 | 
| -    values['table_name'] = table.name
 | 
| -    values['citation'] = table.citation,
 | 
| -    out.write(PARSE_TABLE_METHOD_HEADER % values)
 | 
| -
 | 
| -    # Add message to stop compilation warnings if this table
 | 
| -    # doesn't require subtables to select a class decoder.
 | 
| -    if not [r for r in opt_rows
 | 
| -            if r.action.__class__.__name__ == 'DecoderMethod']:
 | 
| -      out.write("  UNREFERENCED_PARAMETER(insn);")
 | 
| -
 | 
| -    for row in opt_rows:
 | 
| -      if row.action.__class__.__name__ == 'DecoderAction':
 | 
| -        values['decoder'] = row.action.name
 | 
| -        values['rule'] = row.action.rule if row.action.rule else ''
 | 
| -        action = '%(rule)s%(decoder)s_instance_' % values
 | 
| -      elif row.action.__class__.__name__ == 'DecoderMethod':
 | 
| -        action = 'decode_%s(insn)' % row.action.name
 | 
| -      else:
 | 
| -        raise Exception('Bad table action: %s' % row.action)
 | 
| -      # Each row consists of a set of bit patterns defining if the row
 | 
| -      # is applicable. Convert this into a sequence of anded C test
 | 
| -      # expressions. For example, convert the following pair of bit
 | 
| -      # patterns:
 | 
| -      #
 | 
| -      #   xxxx1010xxxxxxxxxxxxxxxxxxxxxxxx
 | 
| -      #   xxxxxxxxxxxxxxxxxxxxxxxxxxxx0101
 | 
| -      #
 | 
| -      # Each instruction is masked to get the the bits, and then
 | 
| -      # tested against the corresponding expected bits. Hence, the
 | 
| -      # above example is converted to:
 | 
| -      #
 | 
| -      #    ((insn & 0x0F000000) != 0x0C000000) &&
 | 
| -      #    ((insn & 0x0000000F) != 0x00000005)
 | 
| -      values['tests'] = ' && '.join(['(%s)' % p.to_c_expr('insn')
 | 
| -                                     for p in row.patterns])
 | 
| -      values['action'] = action
 | 
| -      out.write(PARSE_TABLE_METHOD_ROW % values)
 | 
| -    out.write(PARSE_TABLE_METHOD_FOOTER % values)
 | 
| -
 | 
| -# Define the source for DECODER_tests.cc
 | 
| -TEST_CC_HEADER="""
 | 
| -%(FILE_HEADER)s
 | 
| -%(NOT_TCB_MESSAGE)s
 | 
| -
 | 
| -#include "gtest/gtest.h"
 | 
| -#include "native_client/src/trusted/validator_arm/inst_classes_testers.h"
 | 
| -
 | 
| -namespace nacl_arm_test {
 | 
| -
 | 
| -"""
 | 
| -
 | 
| -TESTER_CLASS="""
 | 
| -class %(rule)s%(decoder)sTester%(constraints)s
 | 
| -    : public %(decoder)sTester%(constraints)s {
 | 
| - public:
 | 
| -  %(rule)s%(decoder)sTester%(constraints)s()
 | 
| -    : %(decoder)sTester%(constraints)s(
 | 
| -      state_.%(rule)s%(decoder)s_instance_)
 | 
| -  {}
 | 
| -};
 | 
| -"""
 | 
| -
 | 
| -TEST_HARNESS="""
 | 
| -// Defines a gtest testing harness for tests.
 | 
| -class %(decoder_name)sTests : public ::testing::Test {
 | 
| - protected:
 | 
| -  %(decoder_name)sTests() {}
 | 
| -};
 | 
| -"""
 | 
| -
 | 
| -TEST_FUNCTION="""
 | 
| -TEST_F(%(decoder_name)sTests,
 | 
| -       %(rule)s%(decoder)s%(constraints)s_%(pattern)s_Test) {
 | 
| -  %(rule)s%(decoder)sTester%(constraints)s tester;
 | 
| -  tester.Test("%(pattern)s");
 | 
| -}
 | 
| -"""
 | 
| -
 | 
| -
 | 
| -TEST_CC_FOOTER="""
 | 
| -}  // namespace nacl_arm_test
 | 
| -
 | 
| -int main(int argc, char* argv[]) {
 | 
| -  testing::InitGoogleTest(&argc, argv);
 | 
| -  return RUN_ALL_TESTS();
 | 
| -}
 | 
| -"""
 | 
| -
 | 
| -def generate_tests_cc(decoder, decoder_name, out):
 | 
| -  if not decoder.primary: raise Exception('No tables provided.')
 | 
| -  values = {
 | 
| -      'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
 | 
| -      'NOT_TCB_MESSAGE' : dgen_output.NOT_TCB_BOILERPLATE,
 | 
| -      'decoder_name': decoder_name,
 | 
| -      }
 | 
| -  out.write(TEST_CC_HEADER % values)
 | 
| -  _generate_rule_testers(decoder, values, out)
 | 
| -  out.write(TEST_HARNESS % values)
 | 
| -  _generate_test_patterns(decoder, values, out)
 | 
| -  out.write(TEST_CC_FOOTER % values)
 | 
| -
 | 
| -def _generate_rule_testers(decoder, values, out):
 | 
| -  for d in decoder.action_filter(['name', 'rule', 'constraints']).rules():
 | 
| -    values['decoder'] = d.name
 | 
| -    values['rule'] = d.rule
 | 
| -    values['constraints'] = d.constraints if d.constraints else ''
 | 
| -    out.write(TESTER_CLASS % values)
 | 
| -
 | 
| -def _generate_test_patterns(decoder, values, out):
 | 
| -  for d in decoder.decoders():
 | 
| -    if d.pattern:
 | 
| -      values['decoder'] = d.name
 | 
| -      values['rule'] = d.rule if d.rule else ''
 | 
| -      values['constraints'] = d.constraints if d.constraints else ''
 | 
| -      values['pattern'] = d.pattern
 | 
| -      out.write(TEST_FUNCTION % values)
 | 
| 
 |