summaryrefslogtreecommitdiff
path: root/src/arch/immediate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r--src/arch/immediate.c194
1 files changed, 172 insertions, 22 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index a6f080f..5d3b844 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -56,13 +56,26 @@ struct _GImmOperand
uint64_t raw; /* Valeur transtypée */
MemoryDataSize size; /* Taille de l'opérande */
- bool zpad; /* Ajoute des 0 à l'impression */
ImmOperandDisplay def_display; /* Type par défaut d'affichage */
ImmOperandDisplay display; /* Format général d'affichage */
+ unsigned char misc; /* Informations diverses */
};
+#define IMM_GET_DEF_ZERO_PADDING(op) ((op)->misc & (1 << 0))
+#define IMM_SET_DEF_ZERO_PADDING(op, v) (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0)
+
+#define IMM_HAS_ZERO_PADDING(op) ((op)->misc & (1 << 1))
+#define IMM_SET_ZERO_PADDING(op) (op)->misc |= (1 << 1)
+
+#define IMM_GET_ZERO_PADDING_VALUE(op) ((op)->misc & (1 << 2))
+#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0)
+
+#define IMM_HAS_DISPLAY(op) ((op)->misc & (1 << 3))
+#define IMM_SET_DISPLAY(op) (op)->misc |= (1 << 3)
+
+
/* Définition d'un opérande de valeur numérique (classe) */
struct _GImmOperandClass
{
@@ -92,6 +105,9 @@ static void g_imm_operand_quickly_copy(const GImmOperand *, GImmOperand *);
/* Compare un opérande avec un autre. */
static int g_imm_operand_compare(const GImmOperand * const *, const GImmOperand * const *);
+/* Indique si une valeur est complétée par des zéros. */
+static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay);
+
/* Construit la chaîne de caractères correspondant à l'opérande. */
static size_t _g_imm_operand_to_string(const GImmOperand *, AsmSyntax, ImmOperandDisplay, char [IMM_MAX_SIZE]);
@@ -168,10 +184,10 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
static void g_imm_operand_init(GImmOperand *operand)
{
- operand->zpad = false;
-
operand->def_display = IOD_HEX;
- operand->display = IOD_HEX;
+ operand->misc = 0;
+
+ IMM_SET_DEF_ZERO_PADDING(operand, false);
}
@@ -403,9 +419,9 @@ static void g_imm_operand_quickly_copy(const GImmOperand *operand, GImmOperand *
template->raw = operand->raw;
template->size = operand->size;
- template->zpad = operand->zpad;
template->def_display = operand->def_display;
template->display = operand->display;
+ template->misc = operand->misc;
}
@@ -454,12 +470,6 @@ static int g_imm_operand_compare(const GImmOperand * const *a, const GImmOperand
goto gioc_done;
}
- if (imm_a->zpad != imm_b->zpad)
- {
- result = (imm_a->zpad ? 1 : -1);
- goto gioc_done;
- }
-
if (imm_a->def_display < imm_b->def_display)
{
result = -1;
@@ -471,17 +481,47 @@ static int g_imm_operand_compare(const GImmOperand * const *a, const GImmOperand
goto gioc_done;
}
- if (imm_a->display < imm_b->display)
+ if (IMM_HAS_DISPLAY(imm_a) != IMM_HAS_DISPLAY(imm_b))
{
- result = -1;
+ result = (IMM_HAS_DISPLAY(imm_a) ? 1 : -1);
goto gioc_done;
}
- else if (imm_a->display > imm_b->display)
+
+ if (IMM_HAS_DISPLAY(imm_a))
{
- result = 1;
+ if (imm_a->display < imm_b->display)
+ {
+ result = -1;
+ goto gioc_done;
+ }
+ else if (imm_a->display > imm_b->display)
+ {
+ result = 1;
+ goto gioc_done;
+ }
+ }
+
+ if (IMM_GET_DEF_ZERO_PADDING(imm_a) != IMM_GET_DEF_ZERO_PADDING(imm_b))
+ {
+ result = (IMM_GET_DEF_ZERO_PADDING(imm_a) ? 1 : -1);
goto gioc_done;
}
+ if (IMM_HAS_ZERO_PADDING(imm_a) != IMM_HAS_ZERO_PADDING(imm_b))
+ {
+ result = (IMM_HAS_ZERO_PADDING(imm_a) ? 1 : -1);
+ goto gioc_done;
+ }
+
+ if (IMM_HAS_ZERO_PADDING(imm_a))
+ {
+ if (IMM_GET_ZERO_PADDING_VALUE(imm_a) != IMM_GET_ZERO_PADDING_VALUE(imm_b))
+ {
+ result = (IMM_GET_ZERO_PADDING_VALUE(imm_a) ? 1 : -1);
+ goto gioc_done;
+ }
+ }
+
result = 0;
gioc_done:
@@ -660,6 +700,60 @@ void g_imm_operand_set_value(GImmOperand **operand, MemoryDataSize size, uint64_
* *
******************************************************************************/
+void g_imm_operand_pad_by_default(GImmOperand **operand, bool state, GShareContainer *container)
+{
+ GSharedInstance *shared; /* Instace de travail partagée */
+ GImmOperand fake; /* Transport d'informations */
+
+ shared = G_SHARED_INSTANCE(*operand);
+
+ g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+
+ IMM_SET_DEF_ZERO_PADDING(&fake, state);
+
+ shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);
+
+ *operand = G_IMM_OPERAND(shared);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Indique si une valeur est complétée par des zéros par défaut.*
+* *
+* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_imm_operand_does_padding_by_default(const GImmOperand *operand)
+{
+ bool result; /* Statut à retourner */
+
+ result = IMM_GET_DEF_ZERO_PADDING(operand);
+
+ return result;
+
+}
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à actualiser. [OUT]*
+* state = true si des zéro sont à ajouter, false sinon. *
+* container = propriétaire d'origine à tenir au courant. *
+* *
+* Description : Précise si des zéro doivent compléter l'affichage ou non. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *container)
{
GSharedInstance *shared; /* Instace de travail partagée */
@@ -669,7 +763,8 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta
g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
- fake.zpad = state;
+ IMM_SET_ZERO_PADDING(&fake);
+ IMM_SET_ZERO_PADDING_VALUE(&fake, state);
shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);
@@ -682,7 +777,7 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta
* *
* Paramètres : operand = structure dont le contenu est à consulter. *
* *
-* Description : Indique le signe d'une valeur immédiate. *
+* Description : Indique si une valeur est complétée par des zéros. *
* *
* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
* *
@@ -692,7 +787,47 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta
bool g_imm_operand_does_padding(const GImmOperand *operand)
{
- return operand->zpad;
+ bool result; /* Statut à retourner */
+
+ if (IMM_HAS_ZERO_PADDING(operand))
+ result = IMM_GET_ZERO_PADDING_VALUE(operand);
+ else
+ result = IMM_GET_DEF_ZERO_PADDING(operand);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* display = type d'affichage à considérer. *
+* *
+* Description : Indique si une valeur est complétée par des zéros. *
+* *
+* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display)
+{
+ bool result; /* Statut à retourner */
+
+ result = g_imm_operand_does_padding(operand);
+
+ if (result)
+ {
+ display = g_imm_operand_get_display(operand);
+
+ if (display != IOD_BIN && display != IOD_HEX)
+ result = false;
+
+ }
+
+ return result;
}
@@ -771,6 +906,7 @@ void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display,
g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+ IMM_SET_DISPLAY(&fake);
fake.display = display;
shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);
@@ -794,7 +930,14 @@ void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display,
ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
{
- return operand->display;
+ ImmOperandDisplay result; /* Affichage à retourner */
+
+ if (IMM_HAS_DISPLAY(operand))
+ result = operand->display;
+ else
+ result = operand->def_display;
+
+ return result;
}
@@ -880,6 +1023,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn
const char *suffix; /* Sortie de matière */
const char *alternate; /* Préfixe de forme alternative*/
const char *intro; /* Introduction du formatage */
+ bool do_padding; /* Indication de bourrage */
const char *zpad; /* Remplissage par des zéros */
const char *lmod; /* Modification de longueur */
const char *conv; /* Opérateur de conversion */
@@ -933,6 +1077,9 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn
intro = "";
/* Drapeau de remplissage ? */
+
+ do_padding = g_imm_operand_does_padding_for_display(operand, display);
+
switch (display)
{
case IOD_BIN:
@@ -942,7 +1089,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn
zpad = "";
break;
default:
- zpad = (operand->zpad ? zpad_defs[range] : "");
+ zpad = (do_padding ? zpad_defs[range] : "");
break;
}
@@ -965,7 +1112,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn
}
else
{
- if (operand->zpad)
+ if (do_padding)
max = range * 8;
else
@@ -1071,8 +1218,11 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn
size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[IMM_MAX_SIZE])
{
size_t result; /* Longueur à retourner */
+ ImmOperandDisplay display; /* Type d'affichage courant */
+
+ display = g_imm_operand_get_display(operand);
- result = _g_imm_operand_to_string(operand, syntax, operand->display, value);
+ result = _g_imm_operand_to_string(operand, syntax, display, value);
return result;