https://hal.archives-ouvertes.fr/hal-03445821
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"
*/