Commit 54ce4eb3 authored by Michael Beck's avatar Michael Beck
Browse files

Added decimal/octal/binary output for integer values

[r1046]
parent 184eddec
......@@ -14,9 +14,9 @@
#include <stdio.h> /* output for error messages */
#include <stdlib.h>
/*****************************************************************************
/*
* local definitions and macros
*****************************************************************************/
*/
#define BIT_PATTERN_SIZE (8 * BIGGEST_INTEGER_SIZE_IN_BYTES)
#define CALC_BUFFER_SIZE (4 * BIGGEST_INTEGER_SIZE_IN_BYTES)
#define MAX_VALUE_SIZE (2 * BIGGEST_INTEGER_SIZE_IN_BYTES)
......@@ -28,15 +28,22 @@
#define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__, __LINE__)
/* shortcut output for debugging only, gices always full precisition */
#define sc_print_hex(a) sc_print((a), 0, SC_HEX)
#define sc_print_dec(a) sc_print((a), 0, SC_DEC)
#define sc_print_oct(a) sc_print((a), 0, SC_OCT)
#define sc_print_bin(a) sc_print((a), 0, SC_BIN)
#if 0
# define DEBUGPRINTF(x) printf x
#else
# define DEBUGPRINTF(x) ((void)0)
#endif
/*****************************************************************************
/*
* private variables
*****************************************************************************/
*/
static char calc_buffer[CALC_BUFFER_SIZE]; /* buffer holding all results */
......@@ -378,6 +385,13 @@ static char const shrs_table[16][4][2] = {
{ {SC_E, SC_0}, {SC_7, SC_0}, {SC_3, SC_8}, {SC_1, SC_C} },
{ {SC_F, SC_0}, {SC_7, SC_8}, {SC_3, SC_C}, {SC_1, SC_E} }
};
/* for converting to binary string */
static const char *binary_table[16] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};
/*****************************************************************************
* private functions
*****************************************************************************/
......@@ -580,7 +594,8 @@ static void _divmod(const char *dividend, const char *divisor, char *quot, char
memset(rem, SC_0, CALC_BUFFER_SIZE);
/* if the dividend is zero result is zero (quot is zero)*/
if (sc_comp(dividend, quot) == 0) return;
if (sc_comp(dividend, quot) == 0)
return;
/* if the divisor is zero this won't work (quot is zero) */
if (sc_comp(divisor, quot) == 0) assert(0 && "quotision by zero!");
......@@ -1213,34 +1228,123 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
return res;
}
const char *sc_print(const void *value, unsigned base)
/*
* convert to a string
*/
const char *sc_print(const void *value, unsigned bits, enum base_t base)
{
int counter;
char base_val[CALC_BUFFER_SIZE];
char div1_res[CALC_BUFFER_SIZE];
char div2_res[CALC_BUFFER_SIZE];
char rem_res[CALC_BUFFER_SIZE];
int counter, nibbles, i;
char x;
const char *val = (const char *)value;
const char *p;
char *m, *n, *t;
char *pos;
static char *buf = NULL;
if (buf != NULL) free(buf);
buf = malloc(BIT_PATTERN_SIZE);
if (! buf) {
/* TODO: this buffer could be allocated in the initialising phase too */
buf = malloc(BIT_PATTERN_SIZE + 1);
if (! buf)
return NULL;
}
pos = buf + BIT_PATTERN_SIZE - 1;
pos = buf + BIT_PATTERN_SIZE;
*pos = '\0';
switch (base)
{
case SC_HEX:
for (counter = 0; counter < MAX_VALUE_SIZE; counter++)
{
if (val[counter] < SC_A)
*(--pos) = val[counter] + '0';
else
*(--pos) = val[counter] + 'a' - 10;
}
break;
/* special case */
if (bits == 0)
bits = BIT_PATTERN_SIZE;
default:
assert(0);
}
nibbles = bits >> 2;
switch (base) {
case SC_HEX:
for (counter = 0; counter < nibbles; ++counter)
*(--pos) = "0123456789abcdef"[_val(val[counter])];
/* last nibble must be masked */
if (bits & 3) {
x = and_table[_val(val[++counter])][bits & 3];
*(--pos) = "0123456789abcdef"[_val(x)];
}
/* now kill zeros */
for (; counter > 1; --counter, ++pos)
if (pos[0] != '0')
break;
break;
case SC_BIN:
for (counter = 0; counter < nibbles; ++counter) {
pos -= 4;
p = binary_table[_val(val[counter])];
pos[0] = p[0];
pos[1] = p[1];
pos[2] = p[2];
pos[3] = p[3];
}
/* last nibble must be masked */
if (bits & 3) {
x = and_table[_val(val[++counter])][bits & 3];
pos -= 4;
p = binary_table[_val(x)];
pos[0] = p[0];
pos[1] = p[1];
pos[2] = p[2];
pos[3] = p[3];
}
/* now kill zeros */
for (counter <<= 2; counter > 1; --counter, ++pos)
if (pos[0] != '0')
break;
break;
case SC_DEC:
case SC_OCT:
memset(base_val, SC_0, CALC_BUFFER_SIZE);
base_val[0] = base == SC_DEC ? SC_A : SC_8;
/* transfer data into oscilating buffers */
memset(div1_res, SC_0, CALC_BUFFER_SIZE);
for (counter = 0; counter < nibbles; ++counter)
div1_res[counter] = val[counter];
/* last nibble must be masked */
if (bits & 3) {
++counter;
div1_res[counter] = and_table[_val(val[counter])][bits & 3];
}
m = div1_res;
n = div2_res;
for (;;) {
_divmod(m, base_val, n, rem_res);
t = m;
m = n;
n = t;
*(--pos) = "0123456789abcdef"[_val(rem_res[0])];
x = 0;
for (i = 0; i < sizeof(div1_res); ++i)
x |= _val(m[i]);
if (x == 0)
break;
}
break;
default:
assert(0);
return NULL;
}
return pos;
}
......@@ -43,33 +43,39 @@ enum {
SC_F,
};
/**
* Possible operations on integer values.
*/
enum {
SC_ADD = 0,
SC_SUB,
SC_NEG,
SC_MUL,
SC_DIV,
SC_MOD,
SC_SHL,
SC_SHR,
SC_SHRS,
SC_ROT,
SC_AND,
SC_OR,
SC_NOT,
SC_XOR,
SC_ADD = 0, /**< Addition */
SC_SUB, /**< Substraction */
SC_NEG, /**< Unary Minus */
SC_MUL, /**< Multiplication */
SC_DIV, /**< Integer Division (with rounding toward zero ?) */
SC_MOD, /**< Devision Remainder */
SC_SHL, /**< Left Shift */
SC_SHR, /**< Logical (unsigned) Right Shift */
SC_SHRS, /**< Arithmetic (signed) Right Shift */
SC_ROT, /**< Rotation (both directions) */
SC_AND, /**< Bitwise And */
SC_OR, /**< Bitwise Or */
SC_NOT, /**< Bitwise Not */
SC_XOR, /**< Bitwise Exclusive Or */
};
enum {
SC_HEX,
SC_DEC,
SC_OKT,
SC_BIN,
/**
* The output mode for ntger values.
*/
enum base_t {
SC_HEX, /**< hexadecimal output */
SC_DEC, /**< decimal output */
SC_OCT, /**< octal output */
SC_BIN, /**< binary output */
};
/*****************************************************************************
/*
* definitions and macros
*****************************************************************************/
*/
#define sc_add(a, b) sc_calc((a), (b), SC_ADD)
#define sc_sub(a, b) sc_calc((a), (b), SC_SUB)
#define sc_neg(a) sc_calc((a), NULL, SC_NEG)
......@@ -85,13 +91,9 @@ enum {
#define sc_shrs(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_SHRS)
#define sc_rot(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_ROT)
#define sc_print_hex(a) sc_print((a), SC_HEX)
#define sc_print_dec(a) sc_print((a), SC_DEC)
#define sc_print_okt(a) sc_print((a), SC_OKT)
#define sc_print_bin(a) sc_print((a), SC_BIN)
/*****************************************************************************
/*
* function declarations
*****************************************************************************/
*/
const void *sc_get_buffer(void);
const int sc_get_buffer_length(void);
......@@ -107,6 +109,13 @@ int sc_comp(const void *val1, const void *val2);
unsigned char sc_sub_bits(const void *val, int len, unsigned byte_ofs);
const char *sc_print(const void *val1, unsigned base);
/**
* Converts a tarval into a string.
*
* @param val1 the value pointer
* @param bits number of valid bits in this value
* @param base output base
*/
const char *sc_print(const void *val1, unsigned bits, enum base_t base);
#endif /* _STRCALC_H_ */
......@@ -896,7 +896,6 @@ int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
ANNOUNCE();
tarval *tv;
const char *str;
int offset;
char buf[100];
tv = XP_GETARG(tarval *, 0);
......@@ -904,9 +903,8 @@ int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
{
case int_number:
case character:
offset = 16 - (get_mode_size_bits(tv->mode)/4);
str = sc_print_hex(tv->value);
return XPF1R("0x%s", str + offset);
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
return XPF1R("%s", str);
case float_number:
return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf)));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment