Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
b93f313a
Commit
b93f313a
authored
Sep 07, 2007
by
Michael Beck
Browse files
Add support for float->int conversion (no overflow handling yet)
[r15709]
parent
81f1a041
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/tv/fltcalc.c
View file @
b93f313a
...
...
@@ -1636,6 +1636,61 @@ fp_value *fc_rnd(const fp_value *a, fp_value *result) {
return
result
;
}
/*
* convert a floating point value into an sc value ...
*/
int
fc_flt2int
(
const
fp_value
*
a
,
void
*
result
,
ir_mode
*
dst_mode
)
{
if
(
a
->
desc
.
clss
==
NORMAL
)
{
int
exp_bias
=
(
1
<<
(
a
->
desc
.
exponent_size
-
1
))
-
1
;
int
exp_val
=
sc_val_to_long
(
_exp
(
a
))
-
exp_bias
;
int
shift
,
highest
;
if
(
a
->
sign
&&
!
mode_is_signed
(
dst_mode
))
{
/* FIXME: for now we cannot convert this */
return
0
;
}
assert
(
exp_val
>=
0
&&
"floating point value not integral before fc_flt2int() call"
);
shift
=
a
->
desc
.
mantissa_size
-
exp_val
+
2
;
sc_shrI
(
_mant
(
a
),
shift
,
64
,
0
,
result
);
/* check for overflow */
highest
=
sc_get_highest_set_bit
(
result
);
if
(
mode_is_signed
(
dst_mode
))
{
if
(
highest
==
sc_get_lowest_set_bit
(
result
))
{
/* need extra test for MIN_INT */
if
(
highest
>=
get_mode_size_bits
(
dst_mode
))
{
/* FIXME: handle overflow */
return
0
;
}
}
else
{
if
(
highest
>=
get_mode_size_bits
(
dst_mode
)
-
1
)
{
/* FIXME: handle overflow */
return
0
;
}
}
}
else
{
if
(
highest
>=
get_mode_size_bits
(
dst_mode
))
{
/* FIXME: handle overflow */
return
0
;
}
}
if
(
a
->
sign
)
sc_neg
(
result
,
result
);
return
1
;
}
else
if
(
a
->
desc
.
clss
==
ZERO
)
{
sc_zero
(
result
);
return
1
;
}
return
0
;
}
unsigned
fc_set_immediate_precision
(
unsigned
bits
)
{
unsigned
old
=
immediate_prec
;
...
...
ir/tv/fltcalc.h
View file @
b93f313a
...
...
@@ -28,6 +28,7 @@
#define FIRM_TV_FLTCALC_H
#include "firm_config.h"
#include "firm_types.h"
#ifdef HAVE_LONG_DOUBLE
/* XXX Set this via autoconf */
...
...
@@ -170,6 +171,11 @@ char *fc_print(const fp_value *a, char *buf, int buflen, unsigned base);
*/
int
fc_comp
(
const
fp_value
*
a
,
const
fp_value
*
b
);
/**
* Converts an floating point value into an integer value.
*/
int
fc_flt2int
(
const
fp_value
*
a
,
void
*
result
,
ir_mode
*
dst_mode
);
/**
* Returns non-zero if the mantissa is zero, i.e. 1.0Exxx
*/
...
...
ir/tv/strcalc.c
View file @
b93f313a
...
...
@@ -1503,7 +1503,6 @@ void sc_sub(const void *value1, const void *value2, void *buffer) {
}
void
sc_neg
(
const
void
*
value1
,
void
*
buffer
)
{
CLEAR_BUFFER
(
calc_buffer
);
carry_flag
=
0
;
DEBUGPRINTF_COMPUTATION
((
"- %s ->"
,
sc_print_hex
(
value1
)));
...
...
@@ -1662,9 +1661,7 @@ void sc_shl(const void *val1, const void *val2, int radius, int sign, void *buff
}
}
void
sc_shr
(
const
void
*
val1
,
const
void
*
val2
,
int
radius
,
int
sign
,
void
*
buffer
)
{
long
offset
=
sc_val_to_long
(
val2
);
void
sc_shrI
(
const
void
*
val1
,
long
offset
,
int
radius
,
int
sign
,
void
*
buffer
)
{
carry_flag
=
0
;
DEBUGPRINTF_COMPUTATION
((
"%s >>u %ld "
,
sc_print_hex
(
value1
),
offset
));
...
...
@@ -1677,6 +1674,12 @@ void sc_shr(const void *val1, const void *val2, int radius, int sign, void *buff
}
}
void
sc_shr
(
const
void
*
val1
,
const
void
*
val2
,
int
radius
,
int
sign
,
void
*
buffer
)
{
long
offset
=
sc_val_to_long
(
val2
);
sc_shrI
(
val1
,
offset
,
radius
,
sign
,
buffer
);
}
void
sc_shrs
(
const
void
*
val1
,
const
void
*
val2
,
int
radius
,
int
sign
,
void
*
buffer
)
{
long
offset
=
sc_val_to_long
(
val2
);
...
...
@@ -1706,3 +1709,10 @@ void sc_rot(const void *val1, const void *val2, int radius, int sign, void *buff
memmove
(
buffer
,
calc_buffer
,
calc_buffer_size
);
}
}
void
sc_zero
(
void
*
buffer
)
{
if
(
buffer
==
NULL
)
buffer
=
calc_buffer
;
CLEAR_BUFFER
(
buffer
);
carry_flag
=
0
;
}
ir/tv/strcalc.h
View file @
b93f313a
...
...
@@ -148,6 +148,11 @@ void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *m
*/
void
sc_shl
(
const
void
*
value1
,
const
void
*
value2
,
int
radius
,
int
sign
,
void
*
buffer
);
/**
* buffer = value1 >>u offset
*/
void
sc_shrI
(
const
void
*
val1
,
long
offset
,
int
radius
,
int
sign
,
void
*
buffer
);
/**
* buffer = value1 >>u value2
*/
...
...
@@ -163,6 +168,11 @@ void sc_shrs(const void *value1, const void *value2, int radius, int sign, void
*/
void
sc_rot
(
const
void
*
value1
,
const
void
*
value2
,
int
radius
,
int
sign
,
void
*
buffer
);
/**
* buffer = 0
*/
void
sc_zero
(
void
*
buffer
);
/*
* function declarations
*/
...
...
ir/tv/tv.c
View file @
b93f313a
...
...
@@ -782,13 +782,14 @@ pn_Cmp tarval_cmp(tarval *a, tarval *b) {
/*
* convert to other mode
*/
tarval
*
tarval_convert_to
(
tarval
*
src
,
ir_mode
*
m
)
{
tarval
*
tarval_convert_to
(
tarval
*
src
,
ir_mode
*
dst_mode
)
{
char
*
buffer
;
fp_value
*
res
;
assert
(
src
);
assert
(
m
);
assert
(
dst_mode
);
if
(
src
->
mode
==
m
)
return
src
;
if
(
src
->
mode
==
dst_mode
)
return
src
;
if
(
get_mode_n_vector_elems
(
src
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
...
...
@@ -803,9 +804,9 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
/* cast float to something */
case
irms_float_number
:
switch
(
get_mode_sort
(
m
))
{
switch
(
get_mode_sort
(
dst_mode
))
{
case
irms_float_number
:
switch
(
get_mode_size_bits
(
m
))
{
switch
(
get_mode_size_bits
(
dst_mode
))
{
case
32
:
fc_cast
(
src
->
value
,
8
,
23
,
NULL
);
break
;
...
...
@@ -818,25 +819,23 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
default:
break
;
}
return
get_tarval
(
fc_get_buffer
(),
fc_get_buffer_length
(),
m
);
return
get_tarval
(
fc_get_buffer
(),
fc_get_buffer_length
(),
dst_mode
);
case
irms_int_number
:
switch
(
GET_FLOAT_TO_INT_MODE
())
{
case
TRUNCATE
:
fc_int
(
src
->
value
,
NULL
);
res
=
fc_int
(
src
->
value
,
NULL
);
break
;
case
ROUND
:
fc_rnd
(
src
->
value
,
NULL
);
res
=
fc_rnd
(
src
->
value
,
NULL
);
break
;
default:
assert
(
0
);
break
;
}
/* FIXME: floating point unit can't produce a value in integer
* representation
* an intermediate representation is needed here first. */
/* return get_tarval(); */
return
tarval_bad
;
if
(
!
fc_flt2int
(
res
,
sc_get_buffer
(),
dst_mode
))
return
tarval_bad
;
return
get_tarval
(
sc_get_buffer
(),
sc_get_buffer_length
(),
dst_mode
);
default:
/* the rest can't be converted */
...
...
@@ -846,14 +845,14 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
/* cast int/characters to something */
case
irms_int_number
:
switch
(
get_mode_sort
(
m
))
{
switch
(
get_mode_sort
(
dst_mode
))
{
case
irms_reference
:
case
irms_int_number
:
buffer
=
alloca
(
sc_get_buffer_length
());
memcpy
(
buffer
,
src
->
value
,
sc_get_buffer_length
());
sign_extend
(
buffer
,
m
);
return
get_tarval_overflow
(
buffer
,
src
->
length
,
m
);
sign_extend
(
buffer
,
dst_mode
);
return
get_tarval_overflow
(
buffer
,
src
->
length
,
dst_mode
);
case
irms_internal_boolean
:
/* XXX C semantics */
...
...
@@ -870,7 +869,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
snprintf
(
buffer
,
100
,
"%s"
,
sc_print
(
src
->
value
,
get_mode_size_bits
(
src
->
mode
),
SC_DEC
,
mode_is_signed
(
src
->
mode
)));
buffer
[
100
-
1
]
=
'\0'
;
switch
(
get_mode_size_bits
(
m
))
{
switch
(
get_mode_size_bits
(
dst_mode
))
{
case
32
:
fc_val_from_str
(
buffer
,
0
,
8
,
23
,
NULL
);
break
;
...
...
@@ -881,7 +880,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
fc_val_from_str
(
buffer
,
0
,
15
,
64
,
NULL
);
break
;
}
return
get_tarval
(
fc_get_buffer
(),
fc_get_buffer_length
(),
m
);
return
get_tarval
(
fc_get_buffer
(),
fc_get_buffer_length
(),
dst_mode
);
default:
break
;
...
...
@@ -890,16 +889,16 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) {
case
irms_internal_boolean
:
/* beware: this is C semantic for the INTERNAL boolean mode */
if
(
get_mode_sort
(
m
)
==
irms_int_number
)
return
src
==
tarval_b_true
?
get_mode_one
(
m
)
:
get_mode_null
(
m
);
if
(
get_mode_sort
(
dst_mode
)
==
irms_int_number
)
return
src
==
tarval_b_true
?
get_mode_one
(
dst_mode
)
:
get_mode_null
(
dst_mode
);
break
;
case
irms_reference
:
if
(
get_mode_sort
(
m
)
==
irms_int_number
)
{
if
(
get_mode_sort
(
dst_mode
)
==
irms_int_number
)
{
buffer
=
alloca
(
sc_get_buffer_length
());
memcpy
(
buffer
,
src
->
value
,
sc_get_buffer_length
());
sign_extend
(
buffer
,
src
->
mode
);
return
get_tarval_overflow
(
buffer
,
src
->
length
,
m
);
return
get_tarval_overflow
(
buffer
,
src
->
length
,
dst_mode
);
}
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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