#!/usr/bin/env python3
#
# Copyright © 2020 Google, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

from mako.template import Template
from isa import ISA
import argparse
import os
import sys

class FieldDecode(object):
    def __init__(self, name, map_expr):
        self.name = name
        self.map_expr = map_expr

    def get_c_name(self):
        return self.name.lower().replace('-', '_')

# State and helpers used by the template:
class State(object):
    def __init__(self, isa):
        self.isa = isa

    def case_name(self, bitset, name):
        return bitset.encode.case_prefix + name.upper().replace('.', '_').replace('-', '_').replace('#', '')

    # Return a list of all <map> entries for a leaf bitset, with the child
    # bitset overriding the parent bitset's entries. Because we can't resolve
    # which <map>s are used until we resolve which overload is used, we
    # generate code for encoding all of these and then at runtime select which
    # one to call based on the display.
    def decode_fields(self, bitset):
        if bitset.get_root().decode is None:
            return

        seen_fields = set()
        if bitset.encode is not None:
            for name, expr in bitset.encode.maps.items():
                seen_fields.add(name)
                yield FieldDecode(name, expr)

        if bitset.extends is not None:
            for field in self.decode_fields(self.isa.bitsets[bitset.extends]):
                if field.name not in seen_fields:
                    yield field

    # A limited resolver for field type which doesn't properly account for
    # overrides.  In particular, if a field is defined differently in multiple
    # different cases, this just blindly picks the last one.
    #
    # TODO to do this properly, I don't think there is an alternative than
    # to emit code which evaluates the case.expr
    def resolve_simple_field(self, bitset, name):
        field = None
        for case in bitset.cases:
            if name in case.fields:
                field = case.fields[name]
        if field is not None:
            return field
        if bitset.extends is not None:
            return self.resolve_simple_field(bitset.isa.bitsets[bitset.extends], name)
        return None

template = """\
/* Copyright (C) 2020 Google, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "${header}"

#include <stdint.h>
#include <util/bitset.h>

#define BITMASK_WORDS BITSET_WORDS(${isa.bitsize})

typedef struct {
    BITSET_WORD bitset[BITMASK_WORDS];
} bitmask_t;


#define BITSET_FORMAT ${isa.format()}
#define BITSET_VALUE(v) ${isa.value()}

static inline void
next_instruction(bitmask_t *instr, BITSET_WORD *start)
{
    %for i in range(0, int(isa.bitsize / 32)):
    instr->bitset[${i}] = *(start + ${i});
    %endfor
}

static inline uint64_t
bitmask_to_uint64_t(bitmask_t mask)
{
%   if isa.bitsize <= 32:
    return mask.bitset[0];
%   else:
    return ((uint64_t)mask.bitset[1] << 32) | mask.bitset[0];
%   endif
}

static inline bitmask_t
uint64_t_to_bitmask(uint64_t val)
{
    bitmask_t mask = {
        .bitset[0] = val & 0xffffffff,
%   if isa.bitsize > 32:
        .bitset[1] = (val >> 32) & 0xffffffff,
%   endif
    };

    return mask;
}

#include "isaspec_decode_decl.h"

static uint64_t
isa_decode_field(struct decode_scope *scope, const char *field_name);

/*
 * enum tables, these don't have any link back to other tables so just
 * dump them up front before the bitset tables
 */

%for name, enum in isa.enums.items():
static const struct isa_enum ${enum.get_c_name()} = {
    .num_values = ${len(enum.values)},
    .values = {
%   for val, display in enum.values.items():
        { .val = ${val}, .display = "${display}" },
%   endfor
    },
};
%endfor

/*
 * generated expression functions, can be linked from bitset tables, so
 * also dump them up front
 */

%for name, expr in isa.expressions.items():
static uint64_t
${expr.get_c_name()}(struct decode_scope *scope)
{
%   for fieldname in sorted(expr.fieldnames):
    int64_t ${fieldname} = isa_decode_field(scope, "${fieldname}");
%   endfor
    return ${expr.expr};
}
%endfor

/* forward-declarations of bitset decode functions */
%for name, bitset in isa.all_bitsets():
%   for df in s.decode_fields(bitset):
static void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()}(void *out, struct decode_scope *scope, uint64_t val);
%   endfor
static const struct isa_field_decode decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields[] = {
%   for df in s.decode_fields(bitset):
    {
        .name = "${df.name}",
        .decode = decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()},
    },
%   endfor
};
static void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}(void *out, struct decode_scope *scope);
%endfor

/*
 * Forward-declarations (so we don't have to figure out which order to
 * emit various tables when they have pointers to each other)
 */

%for name, bitset in isa.all_bitsets():
static const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min};
%endfor

%for root_name, root in isa.roots.items():
static const struct isa_bitset *${root.get_c_name()}[];
%endfor

/*
 * bitset tables:
 */

%for name, bitset in isa.all_bitsets():
%   for case in bitset.cases:
%      for field_name, field in case.fields.items():
%         if field.get_c_typename() == 'TYPE_BITSET':
%            if len(field.params) > 0:
static const struct isa_field_params ${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()} = {
       .num_params = ${len(field.params)},
       .params = {
%               for param in field.params:
           { .name= "${param[0]}",  .as = "${param[1]}" },
%               endfor

       },
};
%            endif
%         endif
%      endfor
static const struct isa_case ${case.get_c_name()}_gen_${bitset.gen_min} = {
%   if case.expr is not None:
       .expr     = &${isa.expressions[case.expr].get_c_name()},
%   endif
%   if case.display is not None:
       .display  = "${case.display}",
%   endif
       .num_fields = ${len(case.fields)},
       .fields   = {
%   for field_name, field in case.fields.items():
          { .name = "${field_name}", .low = ${field.low}, .high = ${field.high},
%      if field.expr is not None:
            .expr = &${isa.expressions[field.expr].get_c_name()},
%      endif
%      if field.display is not None:
            .display = "${field.display}",
%      endif
            .type = ${field.get_c_typename()},
%      if field.get_c_typename() == 'TYPE_BITSET':
            .bitsets = ${isa.roots[field.type].get_c_name()},
%         if len(field.params) > 0:
            .params = &${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()},
%         endif
%      endif
%      if field.get_c_typename() == 'TYPE_ENUM':
            .enums = &${isa.enums[field.type].get_c_name()},
%      endif
%      if field.get_c_typename() == 'TYPE_ASSERT':
            .val.bitset = { ${', '.join(isa.split_bits(field.val, 32))} },
%      endif
%      if field.get_c_typename() == 'TYPE_BRANCH' or field.get_c_typename() == 'TYPE_ABSBRANCH':
            .call = ${str(field.call).lower()},
%      endif
          },
%   endfor
       },
};
%   endfor
static const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min} = {
<% pattern = bitset.get_pattern() %>
%   if bitset.extends is not None:
       .parent   = &bitset_${isa.bitsets[bitset.extends].get_c_name()}_gen_${isa.bitsets[bitset.extends].gen_min},
%   endif
       .name     = "${bitset.display_name}",
       .gen      = {
           .min  = ${bitset.get_gen_min()},
           .max  = ${bitset.get_gen_max()},
       },
       .match.bitset    = { ${', '.join(isa.split_bits(pattern.match, 32))} },
       .dontcare.bitset = { ${', '.join(isa.split_bits(pattern.dontcare, 32))} },
       .mask.bitset     = { ${', '.join(isa.split_bits(pattern.mask, 32))} },
       .decode = decode_${bitset.get_c_name()}_gen_${bitset.gen_min},
       .num_decode_fields = ARRAY_SIZE(decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields),
       .decode_fields = decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields,
       .num_cases = ${len(bitset.cases)},
       .cases    = {
%   for case in bitset.cases:
            &${case.get_c_name()}_gen_${bitset.gen_min},
%   endfor
       },
};
%endfor

/*
 * bitset hierarchy root tables (where decoding starts from):
 */

%for root_name, root in isa.roots.items():
static const struct isa_bitset *${root.get_c_name()}[] = {
%   for leaf_name, leafs in isa.leafs.items():
%      for leaf in leafs:
%         if leaf.get_root() == root:
             &bitset_${leaf.get_c_name()}_gen_${leaf.gen_min},
%         endif
%      endfor
%   endfor
    (void *)0
};
%endfor

#include "isaspec_decode_impl.c"

%for name, bitset in isa.all_bitsets():
%   for df in s.decode_fields(bitset):
<%  field = s.resolve_simple_field(bitset, df.name) %>
static void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()}(void *out, struct decode_scope *scope, uint64_t val)
{
%       if bitset.get_root().decode is not None and field is not None:
    ${bitset.get_root().encode.type} src = *(${bitset.get_root().encode.type} *)out;
%           if field.get_c_typename() == 'TYPE_BITSET':
    isa_decode_bitset(&${df.map_expr}, ${isa.roots[field.type].get_c_name()}, scope, uint64_t_to_bitmask(val));
%           elif field.get_c_typename() in ['TYPE_BRANCH', 'TYPE_INT', 'TYPE_OFFSET']:
    ${df.map_expr} = util_sign_extend(val, ${field.get_size()});
%           else:
    ${df.map_expr} = val;
%           endif
    *(${bitset.get_root().encode.type} *)out = src;
%       endif
}

%   endfor
static void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}(void *out, struct decode_scope *scope)
{
%   if bitset.get_root().decode is not None:
    UNUSED ${bitset.get_root().encode.type} src;
%       if bitset.get_root().encode.type.endswith('*') and name in isa.leafs and bitset.get_root().encode.case_prefix is not None:
    src = ${bitset.get_root().get_c_name()}_create(${s.case_name(bitset.get_root(), bitset.name)});
    *(${bitset.get_root().encode.type} *)out = src;
%       endif
%   endif
}
%endfor

void ${prefix}_isa_disasm(void *bin, int sz, FILE *out, const struct isa_decode_options *options)
{
    isa_disasm(bin, sz, out, options);
}

bool ${prefix}_isa_decode(void *out, void *bin, const struct isa_decode_options *options)
{
    return isa_decode(out, bin, options);
}

uint32_t ${prefix}_isa_get_gpu_id(struct decode_scope *scope)
{
    return isa_get_gpu_id(scope);
}
"""

header = """\
/* Copyright (C) 2020 Google, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#ifndef _${guard}_
#define _${guard}_

#include "compiler/isaspec/isaspec.h"

#ifdef __cplusplus
extern "C" {
#endif

void ${prefix}_isa_disasm(void *bin, int sz, FILE *out, const struct isa_decode_options *options);
bool ${prefix}_isa_decode(void *out, void *bin, const struct isa_decode_options *options);

struct decode_scope;

uint32_t ${prefix}_isa_get_gpu_id(struct decode_scope *scope);

/**
 * Allows to use gpu_id in expr functions
 */
#define ISA_GPU_ID() ${prefix}_isa_get_gpu_id(scope)

#ifdef __cplusplus
}
#endif

#endif /* _${guard}_ */

"""

def guard(p):
    return os.path.basename(p).upper().replace("-", "_").replace(".", "_")

def prefix(p):
    return os.path.basename(p).lower().replace("-", "_").replace(".", "_").split('_')[0]

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--xml', required=True, help='isaspec XML file.')
    parser.add_argument('--out-c', required=True, help='Output C file.')
    parser.add_argument('--out-h', required=True, help='Output H file.')
    args = parser.parse_args()

    isa = ISA(args.xml)
    s = State(isa)

    try:
        with open(args.out_c, 'w', encoding='utf-8') as f:
            out_h_basename = os.path.basename(args.out_h)
            f.write(Template(template).render(isa=isa, s=s, header=out_h_basename, prefix=prefix(args.out_h)))

        with open(args.out_h, 'w', encoding='utf-8') as f:
            f.write(Template(header).render(isa=isa, guard=guard(args.out_h), prefix=prefix(args.out_h)))

    except Exception:
        # In the event there's an error, this imports some helpers from mako
        # to print a useful stack trace and prints it, then exits with
        # status 1, if python is run with debug; otherwise it just raises
        # the exception
        import sys
        from mako import exceptions
        print(exceptions.text_error_template().render(), file=sys.stderr)
        sys.exit(1)

if __name__ == '__main__':
    main()
