https://hal.archives-ouvertes.fr/hal-03445821
Raw File
arch.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_ARCH_H
#define __GDD_ARCH_H
/** \file arch.h
    \brief Architecture description */

#include <stdio.h>
#include <SCEDA/hashset.h>
#include "opcode.h"

/** Type of architecture */
typedef struct {
  SCEDA_HashSet *opcodes;
  SCEDA_HashSet *types;
} GDD_Arch;

/** Create a new architecture 

    @return an architecture */
GDD_Arch *GDD_arch_create();

/** Delete an architecture 

    @param[in] arch = architecture

    It will also delete the opcodes. */
void GDD_arch_delete(GDD_Arch *arch);

/** Add an opcode to an architecture.

    @param[in] arch = architecture
    @param[in] op = opcode

    @return 0 in case of success, 1 if opcode was already present (not
    changed), -1 otherwise
*/
int GDD_arch_add_opcode(GDD_Arch *arch, GDD_Opcode *op);

/** Get the opcode of given mnemonic.

    @param[in] arch = architecture
    @param[in] mnemo = mnemonic

    @return the opcode of given mnemonic or NULL if not found */
GDD_Opcode *GDD_arch_get_opcode(GDD_Arch *arch, const char *mnemo);

/** Add registers of given type to the architecture.
    
    @param[in] arch = architecture
    @param[in] type = considered type
    @param[in] nb = number of registers (should be > 0)

    @return 0 in case of success, 1 if registers of the given type
    were already in the architecture (not modified), -1 otherwise */
int GDD_arch_add_regtype(GDD_Arch *arch, const char *type, int nb);

/** Get the number of registers of given type. 

    @param[in] arch = architecture 
    @param[in] type = considered type 

    @return the number of registers of considered type */
int GDD_arch_get_regtype(GDD_Arch *arch, const char *type);

/** Modify the number of available registers of given type in the
    architecture.

    @param[in] arch = architecture
    @param[in] type = considered type
    @param[in] nb = new number of registers

    @return 0 in case of success, -1 otherwise */
int GDD_arch_set_regtype(GDD_Arch *arch, const char *type, int nb);

/** Print the description of an architecture.

    @param[in] stream = file stream where to print
    @param[in] arch = architecture */
void GDD_arch_fprint(FILE *stream, GDD_Arch *arch);

/** Iterator on architecture register types

    \hideinitializer */
typedef SCEDA_HashSetIterator GDD_ArchTypesIterator;

/** Initialise the iterator.

    @param[in] arch = architecture
    @param[in] iter = iterator 

    \hideinitializer */
#define GDD_arch_types_iterator_init(arch$, iter$) (SCEDA_hashset_iterator_init((arch$)->types, iter$))

/** Is there a next type?

    \hideinitializer */
#define GDD_arch_types_iterator_has_next SCEDA_hashset_iterator_has_next

/** Return the next type in the iterator.

    @param[in] iter = iterator

    @return the type */
char *GDD_arch_types_iterator_next(GDD_ArchTypesIterator *iter);

/** Clean up an architecture iterator.

    \hideinitializer */
#define GDD_arch_types_iterator_cleanup SCEDA_hashset_iterator_cleanup

/** Iterator on architecture opcodes

    \hideinitializer */
typedef SCEDA_HashSetIterator GDD_ArchOpcodesIterator;

/** Initialise the iterator.

    @param[in] arch = architecture
    @param[in] iter = iterator 

    \hideinitializer */
#define GDD_arch_opcodes_iterator_init(arch$, iter$) (SCEDA_hashset_iterator_init((arch$)->opcodes, iter$))

/** Is there a next opcode?

    \hideinitializer */
#define GDD_arch_opcodes_iterator_has_next SCEDA_hashset_iterator_has_next

/** Return the next opcode in the iterator.

    @param[in] iter = iterator

    @return the type */
#define GDD_arch_opcodes_iterator_next SCEDA_hashset_iterator_next

/** Clean up an architecture iterator.

    \hideinitializer */
#define GDD_arch_opcodes_iterator_cleanup SCEDA_hashset_iterator_cleanup

#endif

/** \page arch Architectures 

    \section arch_intro Introduction

    An architecture consists of a set of (register) types
    \f$\mathcal{T}\f$ and a set of opcodes.  For each type \f$t \in
    \mathcal{T}\f$, it has a certain number of registers of type
    \f$t\f$.

    \section arch_api API

    \code
    GDD_Arch *GDD_arch_create();
    \endcode

    Create a new (empty) architecture.

    \code
    void GDD_arch_delete(GDD_Arch *arch);
    \endcode

    Delete an architecture and all its opcodes.

    \code
    int GDD_arch_add_opcode(GDD_Arch *arch, GDD_Opcode *op);
    \endcode

    Add a new opcode to the architecture.

    \code
    GDD_Opcode *GDD_arch_get_opcode(GDD_Arch *arch, const char *mnemo);
    \endcode

    Return the opcode with the given mnemonic in the architecture.

    \code
    int GDD_arch_add_regtype(GDD_Arch *arch, const char *type, int nb);
    \endcode

    Add registers to an architecture.

    \code
    int GDD_arch_get_regtype(GDD_Arch *arch, const char *type);
    \endcode

    Return the number of registers of given type in the architecture.

    \code
    void fprint_arch(FILE *stream, GDD_Arch *arch);
    \endcode

    Print the architecture in the given stream.

    \code
    void GDD_arch_types_iterator_init(GDD_Arch *arch, GDD_ArchTypesIterator *iter);
    int GDD_arch_types_iterator_has_next(GDD_ArchTypesIterator *iter);
    char *GDD_arch_types_iterator_next(GDD_ArchTypesIterator *iter);
    void GDD_arch_types_iterator_cleanup(GDD_ArchTypesIterator *iter);
    \endcode

    Iterator over types supported by an architecture.

    \code
    void GDD_arch_opcodes_iterator_init(GDD_Arch *arch, GDD_ArchOpcodesIterator *iter);
    int GDD_arch_opcodes_iterator_has_next(GDD_ArchOpcodesIterator *iter);
    char *GDD_arch_opcodes_iterator_next(GDD_ArchOpcodesIterator *iter);
    void GDD_arch_opcodes_iterator_cleanup(GDD_ArchOpcodesIterator *iter);
    \endcode

    Iterator over opcodes within an architecture.

    \section arch_example Example

    The following piece of code creates an architecture composed of
    one opcode "add" and 32 registers of type "GR".

    It then prints it on standard output.

    Finally, the architecture is deleted.

    \include "arch/main.c"

*/
back to top