Commit d4168aa8 authored by Michael Beck's avatar Michael Beck
Browse files

Tarval:

- fixed decimal output (used '-' for negatives)
- Changed output back to hex for jack C-Backend ...
- Float implementation uses double (for compiling with cygnus) yet

[r1049]
parent a465ef46
......@@ -5,7 +5,7 @@
/*
* TODO:
*
* This code uses the C-type long double to respesent floating
* This code uses the C-type LLDBL to respesent floating
* point values. This is bad because:
*
* 1.) It depends on IEEE arithmetic on the compilation engine (hardly a problem)
......@@ -20,20 +20,32 @@
#include <stdlib.h>
#include <stdio.h>
#ifdef USE_LONG_DOUBLE
/* have long double type */
/* only defined in C99 mode */
extern long double strtold(const char *str, char **end);
#define strtoLLD strtold
#else
/* don't have long double type */
extern double strtod(const char *str, char **end);
#define strtoLLD strtod
#endif
/********
* globals
********/
static long double value;
//#define CAST_IN(val) ({ long double xxx = *(long double *)(val); printf("CAST to %Lg\n", xxx); xxx; })
static LLDBL value;
#define CAST_IN(val) (*((long double *)((val))))
#define CAST_IN(val) (*((LLDBL *)((val))))
#define CAST_OUT(val) ((void *)&(val))
#define CLEAR_BUFFER() memset((char*)&value, 0, sizeof(long double))
#define CLEAR_BUFFER() memset((char*)&value, 0, sizeof(LLDBL))
/********
* private functions
********/
......@@ -48,22 +60,22 @@ const void *fc_get_buffer(void)
const int fc_get_buffer_length(void)
{
return sizeof(long double);
return sizeof(LLDBL);
}
void fc_val_from_str(const char *str, unsigned int len)
{
CLEAR_BUFFER();
value = strtold(str, NULL);
value = strtoLLD(str, NULL);
}
void fc_val_from_float(long double l)
void fc_val_from_float(LLDBL l)
{
CLEAR_BUFFER();
value = l;
}
long double fc_val_to_float(const void *val)
LLDBL fc_val_to_float(const void *val)
{
return CAST_IN(val);
}
......@@ -106,13 +118,13 @@ void fc_get_max(unsigned int num_bits)
void fc_get_nan(void)
{
value = strtold("nan", NULL);
value = strtoLLD("nan", NULL);
}
void fc_get_inf(void)
{
value = strtold("inf", NULL);
value = strtoLLD("inf", NULL);
}
void fc_calc(const void *a, const void *b, int opcode)
......@@ -146,13 +158,17 @@ int fc_comp(const void *a, const void *b)
char *fc_print_dec(const void *a, char *buf, int buflen)
{
#ifdef USE_LONG_DOUBLE
snprintf(buf, buflen, "%1.30Lg", CAST_IN(a));
#else
snprintf(buf, buflen, "%1.30g", CAST_IN(a));
#endif
return buf;
}
unsigned char fc_sub_bits(const void *value, unsigned num_bits, unsigned byte_ofs)
{
long double val = CAST_IN(value);
LLDBL val = CAST_IN(value);
float f;
double d;
......
#ifndef _FLTCALC_H_
#define _FLTCALC_H_
#ifdef USE_LONG_DOUBLE
typedef long double LLDBL;
#else
typedef double LLDBL;
#endif
enum {
FC_ADD,
FC_SUB,
......@@ -19,8 +25,8 @@ const void *fc_get_buffer(void);
const int fc_get_buffer_length(void);
void fc_val_from_str(const char *str, unsigned int len);
void fc_val_from_float(long double l);
long double fc_val_to_float(const void *val);
void fc_val_from_float(LLDBL l);
LLDBL fc_val_to_float(const void *val);
void fc_get_min(unsigned int num_bits);
void fc_get_max(unsigned int num_bits);
......
......@@ -17,10 +17,6 @@
/*
* 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)
#define CLEAR_CALC_BUFFER() assert(calc_buffer); memset(calc_buffer, SC_0, CALC_BUFFER_SIZE)
#define _val(a) ((a)-SC_0)
#define _digit(a) ((a)+SC_0)
......@@ -441,7 +437,7 @@ static void _bitand(const char *val1, const char *val2, char *buffer)
static int _sign(const char *val)
{
return (val[CALC_BUFFER_SIZE-1] < SC_7) ? (1) : (-1);
return (val[CALC_BUFFER_SIZE-1] <= SC_7) ? (1) : (-1);
}
static void _inc(char *val, char *buffer)
......@@ -1240,7 +1236,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base)
char div1_res[CALC_BUFFER_SIZE];
char div2_res[CALC_BUFFER_SIZE];
char rem_res[CALC_BUFFER_SIZE];
int counter, nibbles, i;
int counter, nibbles, i, sign;
char x;
const char *val = (const char *)value;
......@@ -1307,16 +1303,27 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base)
memset(base_val, SC_0, CALC_BUFFER_SIZE);
base_val[0] = base == SC_DEC ? SC_A : SC_8;
m = val;
sign = 0;
if (base == SC_DEC) {
/* check for negative values */
if (_sign(val) == -1) {
_negate(val, div2_res);
sign = 1;
m = div2_res;
}
}
/* transfer data into oscilating buffers */
memset(div1_res, SC_0, CALC_BUFFER_SIZE);
for (counter = 0; counter < nibbles; ++counter)
div1_res[counter] = val[counter];
div1_res[counter] = m[counter];
/* last nibble must be masked */
/* last nibble must be masked */
if (bits & 3) {
++counter;
div1_res[counter] = and_table[_val(val[counter])][bits & 3];
div1_res[counter] = and_table[_val(m[counter])][bits & 3];
}
m = div1_res;
......@@ -1335,6 +1342,8 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base)
if (x == 0)
break;
}
if (sign)
*(--pos) = '-';
break;
default:
......
......@@ -120,6 +120,6 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs);
const char *sc_print(const void *val1, unsigned bits, enum base_t base);
void init_strcalc(int precision_in_bytes);
int get_precision();
int get_precision(void);
#endif /* _STRCALC_H_ */
......@@ -910,8 +910,8 @@ int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
{
case int_number:
case character:
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
return XPF1R("%s", str);
str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
return XPF1R("0x%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