Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
d13f67ce
Commit
d13f67ce
authored
Nov 22, 2013
by
Matthias Braun
Browse files
introduce tarval_to_ascii and ascii_to_tarval and use it in irio
parent
9027d36c
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/ir/irio.c
View file @
d13f67ce
...
...
@@ -23,7 +23,7 @@
#include
"irgmod.h"
#include
"irflag_t.h"
#include
"irgwalk.h"
#include
"tv.h"
#include
"tv
_t
.h"
#include
"array.h"
#include
"error.h"
#include
"typerep.h"
...
...
@@ -416,16 +416,12 @@ static void write_mode_ref(write_env_t *env, ir_mode *mode)
static
void
write_tarval
(
write_env_t
*
env
,
ir_tarval
*
tv
)
{
write_mode_ref
(
env
,
get_tarval_mode
(
tv
));
if
(
tv
==
tarval_bad
)
{
write_symbol
(
env
,
"bad"
);
}
else
{
fputs
(
"0x"
,
env
->
file
);
char
buf
[
1024
];
tarval_snprintf
(
buf
,
sizeof
(
buf
),
tv
);
fputs
(
buf
,
env
->
file
);
fputc
(
' '
,
env
->
file
);
}
ir_mode
*
mode
=
get_tarval_mode
(
tv
);
write_mode_ref
(
env
,
mode
);
char
buf
[
128
];
const
char
*
ascii
=
ir_tarval_to_ascii
(
buf
,
sizeof
(
buf
),
tv
);
fputs
(
ascii
,
env
->
file
);
fputc
(
' '
,
env
->
file
);
}
static
void
write_align
(
write_env_t
*
env
,
ir_align
align
)
...
...
@@ -1608,12 +1604,7 @@ static ir_tarval *read_tarval(read_env_t *env)
{
ir_mode
*
tvmode
=
read_mode_ref
(
env
);
char
*
str
=
read_word
(
env
);
ir_tarval
*
tv
;
if
(
strcmp
(
str
,
"bad"
)
==
0
)
return
tarval_bad
;
tv
=
new_tarval_from_str
(
str
,
strlen
(
str
),
tvmode
);
if
(
tv
==
tarval_bad
)
parse_error
(
env
,
"problem while parsing tarval '%s'
\n
"
,
str
);
ir_tarval
*
tv
=
ir_tarval_from_ascii
(
str
,
tvmode
);
obstack_free
(
&
env
->
obst
,
str
);
return
tv
;
...
...
ir/tv/tv.c
View file @
d13f67ce
...
...
@@ -1259,6 +1259,89 @@ int tarval_snprintf(char *buf, size_t len, ir_tarval *tv)
}
}
static
char
hexchar
(
unsigned
val
)
{
if
(
val
<
10
)
return
val
+
'0'
;
return
(
val
-
10
)
+
'A'
;
}
static
unsigned
hexval
(
char
c
)
{
if
(
c
>=
'0'
&&
c
<=
'9'
)
return
c
-
'0'
;
return
(
c
-
'A'
)
+
10
;
}
const
char
*
ir_tarval_to_ascii
(
char
*
buf
,
size_t
len
,
ir_tarval
*
tv
)
{
ir_mode
*
mode
=
get_tarval_mode
(
tv
);
switch
(
get_mode_sort
(
mode
))
{
case
irms_internal_boolean
:
case
irms_reference
:
case
irms_int_number
:
return
sc_print_buf
(
buf
,
len
,
tv
->
value
,
get_mode_size_bits
(
mode
),
SC_HEX
,
0
);
case
irms_float_number
:
{
/* fc_print is not specific enough for nans/infs, so we simply dump the
* bit representation in hex. */
unsigned
size
=
get_mode_size_bytes
(
mode
);
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
uint8_t
bits
=
get_tarval_sub_bits
(
tv
,
(
int
)
i
);
buf
[
i
*
2
]
=
hexchar
(
bits
&
0xf
);
buf
[
i
*
2
+
1
]
=
hexchar
(
bits
>>
4
);
}
buf
[
size
*
2
]
=
'\0'
;
return
buf
;
}
case
irms_data
:
case
irms_auxiliary
:
if
(
tv
==
tarval_bad
)
return
"bad"
;
else
if
(
tv
==
tarval_undefined
)
return
"undefined"
;
else
if
(
tv
==
tarval_reachable
)
return
"reachable"
;
else
if
(
tv
==
tarval_unreachable
)
return
"unreachable"
;
break
;
}
panic
(
"invalid tarval"
);
}
ir_tarval
*
ir_tarval_from_ascii
(
const
char
*
buf
,
ir_mode
*
mode
)
{
size_t
len
=
strlen
(
buf
);
switch
(
get_mode_sort
(
mode
))
{
case
irms_reference
:
case
irms_internal_boolean
:
case
irms_int_number
:
return
new_integer_tarval_from_str
(
buf
,
len
,
1
,
16
,
mode
);
case
irms_float_number
:
{
unsigned
size
=
get_mode_size_bytes
(
mode
);
unsigned
char
*
temp
=
ALLOCAN
(
unsigned
char
,
size
);
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
unsigned
char
val
=
hexval
(
buf
[
i
*
2
])
|
(
hexval
(
buf
[
i
*
2
+
1
])
<<
4
);
temp
[
i
]
=
val
;
}
fc_val_from_ieee754_buf
(
NULL
,
temp
,
get_descriptor
(
mode
));
return
get_tarval_from_fp_value
(
fc_get_buffer
(),
mode
);
}
case
irms_data
:
case
irms_auxiliary
:
if
(
strcmp
(
buf
,
"bad"
)
==
0
)
return
tarval_bad
;
else
if
(
strcmp
(
buf
,
"undefined"
)
==
0
)
return
tarval_undefined
;
else
if
(
strcmp
(
buf
,
"reachable"
)
==
0
)
return
tarval_reachable
;
else
if
(
strcmp
(
buf
,
"unreachable"
)
==
0
)
return
tarval_unreachable
;
break
;
}
panic
(
"invalid mode for tarval_from_ascii"
);
}
char
*
get_tarval_bitpattern
(
ir_tarval
*
tv
)
{
int
n
=
get_mode_size_bits
(
tv
->
mode
);
...
...
ir/tv/tv_t.h
View file @
d13f67ce
...
...
@@ -116,6 +116,20 @@ static inline int _is_tarval(const void *thing)
return
get_kind
(
thing
)
==
k_tarval
;
}
/**
* Converts tarval to ascii representation (in contrast to tarval_snprintf()
* this is meant to be machine readble).
* If the output is bigger than buf_len the behaviour is undefined. The
* final value may be near the end of the buffer, use the return value!
*/
const
char
*
ir_tarval_to_ascii
(
char
*
buf
,
size_t
buf_len
,
ir_tarval
*
tv
);
/**
* Converts ascii representation to tarval with specified mode. Compatible with
* ir_tarval_to_ascii().
*/
ir_tarval
*
ir_tarval_from_ascii
(
const
char
*
buf
,
ir_mode
*
mode
);
uint64_t
get_tarval_uint64
(
ir_tarval
*
tv
);
bool
tarval_is_uint64
(
ir_tarval
*
tv
);
...
...
unittests/tarval_ascii.c
0 → 100644
View file @
d13f67ce
#include
"tv_t.h"
#include
"irprintf.h"
#include
"firm.h"
#include
<assert.h>
#include
<float.h>
static
char
buf
[
1024
];
static
void
test_tv
(
ir_tarval
*
tv
)
{
const
char
*
res
=
ir_tarval_to_ascii
(
buf
,
sizeof
(
buf
),
tv
);
ir_tarval
*
back
=
ir_tarval_from_ascii
(
res
,
get_tarval_mode
(
tv
));
if
(
tv
!=
back
)
{
ir_printf
(
"%T [mode %s]
\n
"
,
tv
,
get_mode_name
(
get_tarval_mode
(
tv
)));
printf
(
" encoded: %s
\n
"
,
res
);
assert
(
tv
==
back
);
}
}
static
void
test_mode
(
ir_mode
*
mode
)
{
test_tv
(
get_mode_null
(
mode
));
test_tv
(
get_mode_one
(
mode
));
if
(
mode_is_signed
(
mode
))
test_tv
(
get_mode_minus_one
(
mode
));
test_tv
(
get_mode_min
(
mode
));
test_tv
(
get_mode_max
(
mode
));
if
(
mode_is_float
(
mode
))
{
test_tv
(
get_mode_infinite
(
mode
));
test_tv
(
tarval_neg
(
get_mode_infinite
(
mode
)));
test_tv
(
get_mode_NAN
(
mode
));
if
(
mode
==
mode_F
)
{
test_tv
(
new_tarval_from_double
(
FLT_MIN
,
mode
));
test_tv
(
new_tarval_from_double
(
FLT_EPSILON
,
mode
));
}
if
(
mode
==
mode_D
)
{
test_tv
(
new_tarval_from_double
(
DBL_MIN
,
mode
));
test_tv
(
new_tarval_from_double
(
DBL_EPSILON
,
mode
));
}
test_tv
(
new_tarval_from_str
(
"-4.3"
,
4
,
mode
));
test_tv
(
new_tarval_from_str
(
"84.1"
,
4
,
mode
));
}
else
{
test_tv
(
get_mode_all_one
(
mode
));
}
}
int
main
(
void
)
{
ir_init
();
test_mode
(
mode_Bs
);
test_mode
(
mode_Bu
);
test_mode
(
mode_Hs
);
test_mode
(
mode_Hu
);
test_mode
(
mode_Is
);
test_mode
(
mode_Iu
);
test_mode
(
mode_Ls
);
test_mode
(
mode_Lu
);
test_mode
(
mode_F
);
test_mode
(
mode_D
);
test_mode
(
mode_P
);
ir_mode
*
mode_E
=
new_float_mode
(
"E"
,
irma_x86_extended_float
,
15
,
64
,
ir_overflow_indefinite
);
test_mode
(
mode_E
);
test_tv
(
tarval_bad
);
test_tv
(
tarval_undefined
);
test_tv
(
tarval_reachable
);
test_tv
(
tarval_unreachable
);
return
0
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment