This interface can be implemented by other classes than processors, but it is likely to be found mostly in processors.
Registers are identified by a number, and there are two functions to translate from register names to register numbers and back. The translation need not be one-to-one, which means that one register can have several names. A register name can, however, only translate to a single register number.
Often, registers are grouped in register banks, where registers in the bank are numbered from 0 up. Registers in a bank should have consecutive numbers (unless their numbering is very sparse). This allows a user to deduce register numbers by calling get_number for the first register only. The first register numbers should be used for the general-purpose integer registers, if possible (so that integer register rN has number N).
Using this interface to read or write registers does not cause any side effects, such as triggering interrupts or signalling haps.
get_number translates a register name to its number.
get_name translates a register number to its canonical name.
read reads a register value.
write writes a new register value.
all_registers returns a list of all register numbers that can be used for this object.
register_info returns information about a single register. The information return depends on the info parameter.
typedef enum {
Sim_RegInfo_Catchable
} ireg_info_t;
typedef struct {
int (*get_number)(conf_object_t *NOTNULL obj,
const char *NOTNULL name);
const char *(*get_name)(conf_object_t *NOTNULL obj, int reg);
uinteger_t (*read)(conf_object_t *NOTNULL obj, int reg);
void (*write)(conf_object_t *NOTNULL obj, int reg, uinteger_t val);
attr_value_t (*all_registers)(conf_object_t *NOTNULL obj);
int (*register_info)(conf_object_t *NOTNULL obj, int reg,
ireg_info_t info);
} int_register_interface_t;
#define INT_REGISTER_INTERFACE "int_register"