https://hal.archives-ouvertes.fr/hal-03445821
Raw File
opcode.h
/*
   Copyright Universite de Versailles Saint-Quentin en Yvelines 2009
   AUTHORS: Sebastien Briais, Sid Touati

   This file is part of GDD.
   
   GDD is free software: you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.
   
   GDD is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   
   You should have received a copy of the GNU Lesser General Public
   License along with GDD.  If not, see
   <http://www.gnu.org/licenses/>.
*/
#ifndef __GDD_OPCODE_H
#define __GDD_OPCODE_H
/** \file opcode.h
    \brief Opcode description */

#include <stdio.h>
#include <SCEDA/hashmap.h>

/** Type of opcodes */
typedef struct  {
  char *mnemo;
  int latency;
  int dflt_dr;
  SCEDA_HashMap *delta_r;
  SCEDA_HashMap *delta_w;
} GDD_Opcode;

/** Create a new opcode .

    @param[in] mnemo = mnemonic
    @param[in] latency = latency 
    @param[in] dflt_dr = default read delay offset

    @return the opcode */
GDD_Opcode *GDD_opcode_create(const char *mnemo, int latency, int dflt_dr);

/** Delete an opcode.

    @param[in] op = opcode */
void GDD_opcode_delete(GDD_Opcode *op);

/** Extend delta_r function (read delay offset) of given opcode.

    @param[in] op = opcode
    @param[in] type = considered type
    @param[in] read = read delay offset for type

    @return 0 in case of success, or -1 in case of failure (e.g. if
    trying to redefine delta_r with another value).
*/
int GDD_opcode_extend_delta_r(GDD_Opcode *op, const char *type, int read);

/** Extend delta_w function (write delay offset) of given opcode.

    @param[in] op = opcode
    @param[in] type = considered type
    @param[in] write = write delay offset for type

    @return 0 in case of success, or -1 in case of failure (e.g. if
    trying to redefine delta_r with another value).
*/
int GDD_opcode_extend_delta_w(GDD_Opcode *op, const char *type, int write);

/** Get the value of read delay offset 

    @param[in] op = opcode
    @param[in] type = considered type

    @return read delay offset (or default read delay offset) 
    if type == NULL, return default read delay offset
*/
int GDD_opcode_delta_r(GDD_Opcode *op, const char *type);

/** Get the value of write delay offset 

    @param[in] op = opcode
    @param[in] type = considered type

    @return write delay offset (0 by default) */
int GDD_opcode_delta_w(GDD_Opcode *op, const char *type);

/** Test whether an opcode is a value of given type.

    @param[in] op = opcode
    @param[in] type = type

    @return TRUE if op is a value of type type, FALSE otherwise */
int GDD_opcode_is_value(GDD_Opcode *op, const char *type);

/** Print the description of an opcode, including its delay offsets.

    @param[in] stream = file stream where to print
    @param[in] op = opcode to print */
void GDD_opcode_fprint(FILE *stream, GDD_Opcode *op);

/** Get the mnemonic of an opcode 

    @param[in] op = opcode

    @return the mnemonic of op

    \hideinitializer */
#define GDD_opcode_mnemonic(op) ((op)->mnemo)

/** Get the latency of an opcode 

    @param[in] op = opcode

    @return the latency of op

    \hideinitializer */
#define GDD_opcode_latency(op) ((op)->latency)

#endif

/** \page opcode Opcodes
    
    \section opcode_intro Introduction

    An opcode is defined by its mnemonic and its latency. If \f$o\f$
    is an opcode, we write \f$\mathop{mnemo}(o)\f$ for its mnemonic
    and \f$\mathop{lat}(o)\f$ for its latency.

    In our processor model, an opcode may also have different read or
    write delay offsets for each register type. A default read delay
    offset may be defined. If \f$t \in \mathcal{T}\f$ is a register
    type, we write \f$\delta_r^t(o)\f$ for the read delay offset and
    \f$\delta_w^t(o)\f$ for the write delay offset.

    If, for a given type \f$t\f$, the write delay offset is not
    defined, this means that the opcode does not produce a value of
    type \f$t\f$. Otherwise, we say, by abuse of language, that it \em is
    a value of type \f$t\f$.

    Implicitly, we assume that the following inequalities hold \f$0 \leq
    \delta_r^t(o) \leq \delta_w^t(o) < \mathop{lat}(o)\f$ (when
    defined).

    For convenient memory management, opcodes may be gathered into an
    architecture (see \ref arch).

    \section opcode_api API

    \code
    GDD_Opcode *GDD_opcode_create(const char *mnemo, int latency, int dflt_dr);
    \endcode

    Create a new opcode, with given mnemonic, latency and default read
    delay offset.

    \code 
    void GDD_opcode_delete(GDD_Opcode *op);
    \endcode

    Delete an opcode.

    \code
    int GDD_opcode_extend_delta_r(GDD_Opcode *op, const char *type, int read);
    int GDD_opcode_extend_delta_w(GDD_Opcode *op, const char *type, int write);
    \endcode
    
    Define a read (resp. write) delay offset for the given register
    type.

    \code
    int GDD_opcode_delta_r(GDD_Opcode *op, const char *type);
    int GDD_opcode_delta_w(GDD_Opcode *op, const char *type);
    \endcode

    Return the read (resp. write) delay offset for the given register
    type. 

    The default read delay offset is returned when delta_r is not defined on the given type.

    When delta_w is not defined on the given type, it returns 0.

    \code
    int GDD_opcode_is_value(GDD_Opcode *op, const char *type);
    \endcode

    Test whether the given opcode procudes a value of given type. It
    returns TRUE if and only if delta_w is defined on given type.

    \code 
    char *GDD_opcode_mnemonic(GDD_Opcode *op);
    \endcode

    Return the mnemonic of the given opcode.

    \code
    int GDD_opcode_latency(GDD_Opcode *op);
    \endcode

    Return the latency of the given opcode.

    \code
    void GDD_opcode_fprint(FILE *stream, GDD_Opcode *op);
    \endcode

    Print the opcode on the given stream.

    \section opcode_example Example

    The following example creates an opcode for mnemonic "add" with a
    latency of 2 and a default read delay offset of 0. 

    It then defines a read delay offset of 1 for register type "FR"
    and a write delay offset of 1 for register types "GR" and "FR".

    It then prints it on standard output.

    Finally, the opcode is deleted.

    \include "opcode/main.c"
    
*/
back to top