#!/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 => Defs12To15RdRnRsRmNotPc
#                         Rsb_Rule_144_A1_P288
#                         cccc0000011snnnnddddssss0tt1mmmm
#                         RegsNotPc
# | 0100x      -        = Binary4RegisterShiftedOp => Defs12To15RdRnRsRmNotPc
#                         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):
#
#    baseline - The name of the class decoder that should be used for testing.
#    actual - 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 baseli
ne is optional. The remaining fields provide
# additional documentation and information for testing (which is used
# by this file). If the actual is not specified (prefixed by '=>')
# then it is assumed to have the same value as the baseline.
#
# If these two rows had a mergable bit pattern (which they do not),
# t
hese 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 'actual'. 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 'actual' field). These named classes correspond
# to what sel_ldr will select.
#
# The named version of each named InstClass is:
#
#  class NamedInstClass : public NamedClassDecoder {
#   public:
#    NamedInstClass()
#        : NamedClassDecoder(decoder_, "InstClass")
#    {}
#
# private:
#  Binary3RegisterShiftedTest decoder_;
#  NACL_DISALLOW_COPY_AND_ASSIGN(NamedInstClass);
#};
#
# This makes sure that each decoder class can be identified using a
# separate class decoder. For rows without rules, the corresponding
# named class 'NamedInstClass' will be used. If a row also has
# a rule, the 'NamedInstClass' is converted to 'NamedRuleInstClass' where
# 'Rule' is the name of the rule.
#
# 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();
#  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 inst) 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_core
import dgen_opt
import dgen_output
import dgen_decoder
import dgen_actuals
import dgen_baselines

"""The current command line arguments to use"""
_cl_args = {}

# The following defines naming conventions used for identifiers.
# Note: DECODER will be replaced by 'actual' and 'baseline', defining
# how both types of symbols are generated.

CLASS = '%(DECODER)s_%(rule)s'
NAMED_CLASS = 'Named%(DECODER)s_%(rule)s'
INSTANCE = '%(DECODER_class)s_instance_'
BASE_TESTER='%(decoder_base)sTester%(base_test_case)s'
BASE_BASE_TESTER='%(decoder_base)sTester%(qualifier)s'
DECODER_TESTER='%(baseline)sTester_%(test_case)s'

def _safety_to_check(safety):
  return [s for s in safety if not isinstance(s, str)]

def _interesting_patterns(patterns):
  """ Filters out non-interesting patterns."""
  # Only include rows not corresponding to rule pattern,
  # and not always true.
  return [ p for p in patterns if (
      (not p.column or p.column.name() != '$pattern')
      and not p.matches_any())]

def _install_action(decoder, action, values):
  """Install common names needed to generate code for the given action,
     and adds it to the values map.
     """
  # This code is somewhat inefficient in that most cases, most of the
  # added strings are not needed. On the other hand, by having a
  # single routine that generates all action specific names at one
  # spot, it is much easier to change definitions.
  values['baseline'] = action.baseline()
  values['actual'] = action.actual()
  values['decoder_