diff options
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r-- | src/arch/immediate.c | 87 |
1 files changed, 70 insertions, 17 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 3720bff..4c9ea84 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -32,6 +32,7 @@ #include "operand-int.h" +#include "../common/asm.h" #include "../common/extstr.h" #include "../format/format.h" @@ -739,12 +740,15 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt const char *zpad; /* Remplissage par des zéros */ const char *lmod; /* Modification de longueur */ const char *conv; /* Opérateur de conversion */ - char format[16]; /* Format d'impression final */ + char binval[65]; /* Conversion intégrée */ + unsigned int max; /* Indice du plus fort bit */ + unsigned int i; /* Boucle de parcours #1 */ + char format[16 + 65]; /* Format d'impression final */ static const char *zpad_defs[] = { "", "02", "04", "08", "016" }; static const char *lmod_defs[] = { "hh", "hh", "h", "", __PRI64_PREFIX }; - static const char *conv_si_defs[] = { "c", "d", "x", "o" }; - static const char *conv_us_defs[] = { "c", "u", "x", "o" }; + static const char *conv_si_defs[] = { "", "o", "d", "x", "c" }; + static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; result = 0; /* Gcc... */ @@ -762,28 +766,77 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt suffix = ""; } - /* Préfix de forme '0x' ou '0' */ - if (operand->display == IOD_HEX) - alternate = "0x"; - else if (operand->display == IOD_OCT) - alternate = "0"; - else - alternate = ""; + /* Préfix de forme '0x', 'b' ou '0' */ + switch (operand->display) + { + case IOD_BIN: + alternate = "b"; + break; + case IOD_OCT: + alternate = "0"; + break; + case IOD_HEX: + alternate = "0x"; + break; + default: + alternate = ""; + break; + } /* Drapeau de remplissage ? */ - if (operand->display == IOD_HEX) - zpad = (operand->zpad ? zpad_defs[range] : ""); - else - zpad = ""; + switch (operand->display) + { + case IOD_BIN: + case IOD_CHAR: + zpad = ""; + break; + default: + zpad = (operand->zpad ? zpad_defs[range] : ""); + break; + } /* Modification de la longueur fournie */ lmod = lmod_defs[range]; /* Spécification de la conversion */ - if (MDS_IS_SIGNED(operand->size)) - conv = conv_si_defs[operand->display]; + + if (operand->display != IOD_BIN) + { + if (MDS_IS_SIGNED(operand->size)) + conv = conv_si_defs[operand->display]; + else + conv = conv_us_defs[operand->display]; + + } else - conv = conv_us_defs[operand->display]; + { + if (operand->zpad) + max = range * 8 + 1; + else + { + if (!msb_64(operand->raw, &max)) + { + conv = "0"; + max = 0; + } + else + max++; + } + + if (max > 0) + { + conv = binval; + + for (i = max; i > 0; i--) + binval[max - i] = (operand->raw & (1 << (i - 1)) ? '1' : '0'); + + binval[max] = '\0'; + + } + + } + + /* Impression finale */ snprintf(format, sizeof(format), "%s%s%%%s%s%s%s", prefix, alternate, zpad, lmod, conv, suffix); |