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
7a404958
Commit
7a404958
authored
Nov 20, 2008
by
Michael Beck
Browse files
- a new and more correct tarval_carry()
[r23859]
parent
a96975d0
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/tv/strcalc.c
View file @
7a404958
...
...
@@ -1275,6 +1275,15 @@ int sc_get_lowest_set_bit(const void *value) {
return
-
1
;
}
int
sc_get_bit_at
(
const
void
*
value
,
unsigned
pos
)
{
const
char
*
val
=
value
;
unsigned
nibble
=
pos
>>
2
;
if
(
and_table
[
val
[
nibble
]][
shift_table
[
pos
&
3
]]
!=
SC_0
)
return
1
;
return
0
;
}
int
sc_is_zero
(
const
void
*
value
)
{
const
char
*
val
=
(
const
char
*
)
value
;
int
counter
;
...
...
ir/tv/strcalc.h
View file @
7a404958
...
...
@@ -212,7 +212,6 @@ int sc_get_highest_set_bit(const void *value);
int
sc_get_lowest_set_bit
(
const
void
*
value
);
int
sc_is_zero
(
const
void
*
value
);
int
sc_is_negative
(
const
void
*
value
);
int
sc_had_carry
(
void
);
/**
* Return the bits of a tarval at a given byte-offset.
...
...
@@ -244,4 +243,10 @@ void init_strcalc(int precision_in_bytes);
void
finish_strcalc
(
void
);
int
sc_get_precision
(
void
);
/** Return the bit at a given position. */
int
sc_get_bit_at
(
const
void
*
value
,
unsigned
pos
);
/* Strange semantics */
int
sc_had_carry
(
void
);
#endif
/* FIRM_TV_STRCALC_H */
ir/tv/tv.c
View file @
7a404958
...
...
@@ -97,6 +97,9 @@ static struct set *tarvals = NULL;
/** A set containing all existing values. */
static
struct
set
*
values
=
NULL
;
/** The carry flag for SOME operations. -1 means UNDEFINED here */
static
int
carry_flag
=
-
1
;
/** The integer overflow mode. */
static
tarval_int_overflow_mode_t
int_overflow_mode
=
TV_OVERFLOW_WRAP
;
...
...
@@ -697,8 +700,6 @@ tarval *get_tarval_minus_inf(ir_mode *mode) {
* test if negative number, 1 means 'yes'
*/
int
tarval_is_negative
(
tarval
*
a
)
{
assert
(
a
);
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
panic
(
"vector arithmetic not implemented yet"
);
...
...
@@ -753,8 +754,7 @@ int tarval_is_minus_one(tarval *a) {
* comparison
*/
pn_Cmp
tarval_cmp
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
carry_flag
=
-
1
;
if
(
a
==
tarval_bad
||
b
==
tarval_bad
)
{
panic
(
"Comparison with tarval_bad"
);
...
...
@@ -818,6 +818,8 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode) {
fp_value
*
res
;
const
ieee_descriptor_t
*
desc
;
carry_flag
=
-
1
;
assert
(
src
);
assert
(
dst_mode
);
...
...
@@ -926,7 +928,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode) {
tarval
*
tarval_not
(
tarval
*
a
)
{
char
*
buffer
;
assert
(
a
)
;
carry_flag
=
-
1
;
/* works for vector mode without changes */
...
...
@@ -956,9 +958,10 @@ tarval *tarval_not(tarval *a) {
tarval
*
tarval_neg
(
tarval
*
a
)
{
char
*
buffer
;
assert
(
a
);
assert
(
mode_is_num
(
a
->
mode
));
/* negation only for numerical values */
carry_flag
=
-
1
;
/* note: negation is allowed even for unsigned modes. */
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
...
...
@@ -991,8 +994,7 @@ tarval *tarval_neg(tarval *a) {
tarval
*
tarval_add
(
tarval
*
a
,
tarval
*
b
)
{
char
*
buffer
;
assert
(
a
);
assert
(
b
);
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
b
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
...
...
@@ -1013,6 +1015,7 @@ tarval *tarval_add(tarval *a, tarval *b) {
/* modes of a,b are equal, so result has mode of a as this might be the character */
buffer
=
alloca
(
sc_get_buffer_length
());
sc_add
(
a
->
value
,
b
->
value
,
buffer
);
carry_flag
=
sc_get_bit_at
(
buffer
,
get_mode_size_bits
(
a
->
mode
));
return
get_tarval_overflow
(
buffer
,
a
->
length
,
a
->
mode
);
case
irms_float_number
:
...
...
@@ -1033,8 +1036,7 @@ tarval *tarval_add(tarval *a, tarval *b) {
tarval
*
tarval_sub
(
tarval
*
a
,
tarval
*
b
,
ir_mode
*
dst_mode
)
{
char
*
buffer
;
assert
(
a
);
assert
(
b
);
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
b
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
...
...
@@ -1055,6 +1057,7 @@ tarval *tarval_sub(tarval *a, tarval *b, ir_mode *dst_mode) {
/* modes of a,b are equal, so result has mode of a as this might be the character */
buffer
=
alloca
(
sc_get_buffer_length
());
sc_sub
(
a
->
value
,
b
->
value
,
buffer
);
carry_flag
=
sc_get_bit_at
(
buffer
,
get_mode_size_bits
(
a
->
mode
));
return
get_tarval_overflow
(
buffer
,
a
->
length
,
a
->
mode
);
case
irms_float_number
:
...
...
@@ -1075,10 +1078,10 @@ tarval *tarval_sub(tarval *a, tarval *b, ir_mode *dst_mode) {
tarval
*
tarval_mul
(
tarval
*
a
,
tarval
*
b
)
{
char
*
buffer
;
assert
(
a
);
assert
(
b
);
assert
(
a
->
mode
==
b
->
mode
);
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1107,10 +1110,10 @@ tarval *tarval_mul(tarval *a, tarval *b) {
* floating point division
*/
tarval
*
tarval_quo
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
((
a
->
mode
==
b
->
mode
)
&&
mode_is_float
(
a
->
mode
));
carry_flag
=
-
1
;
if
(
no_float
)
return
tarval_bad
;
...
...
@@ -1128,10 +1131,10 @@ tarval *tarval_quo(tarval *a, tarval *b) {
* overflow is impossible, but look out for division by zero
*/
tarval
*
tarval_div
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
((
a
->
mode
==
b
->
mode
)
&&
mode_is_int
(
a
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1149,10 +1152,10 @@ tarval *tarval_div(tarval *a, tarval *b) {
* overflow is impossible, but look out for division by zero
*/
tarval
*
tarval_mod
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
((
a
->
mode
==
b
->
mode
)
&&
mode_is_int
(
a
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1174,10 +1177,10 @@ tarval *tarval_divmod(tarval *a, tarval *b, tarval **mod) {
char
*
div_res
=
alloca
(
len
);
char
*
mod_res
=
alloca
(
len
);
assert
(
a
);
assert
(
b
);
assert
((
a
->
mode
==
b
->
mode
)
&&
mode_is_int
(
a
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1198,7 +1201,7 @@ tarval *tarval_divmod(tarval *a, tarval *b, tarval **mod) {
tarval
*
tarval_abs
(
tarval
*
a
)
{
char
*
buffer
;
assert
(
a
)
;
carry_flag
=
-
1
;
assert
(
mode_is_num
(
a
->
mode
));
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
...
...
@@ -1236,11 +1239,10 @@ tarval *tarval_abs(tarval *a) {
* bitwise and
*/
tarval
*
tarval_and
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
(
a
->
mode
==
b
->
mode
);
/* works even for vector modes */
carry_flag
=
0
;
switch
(
get_mode_sort
(
a
->
mode
))
{
case
irms_internal_boolean
:
...
...
@@ -1260,11 +1262,10 @@ tarval *tarval_and(tarval *a, tarval *b) {
* bitwise or
*/
tarval
*
tarval_or
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
(
a
->
mode
==
b
->
mode
);
/* works even for vector modes */
carry_flag
=
0
;
switch
(
get_mode_sort
(
a
->
mode
))
{
case
irms_internal_boolean
:
...
...
@@ -1284,11 +1285,10 @@ tarval *tarval_or(tarval *a, tarval *b) {
* bitwise exclusive or (xor)
*/
tarval
*
tarval_eor
(
tarval
*
a
,
tarval
*
b
)
{
assert
(
a
);
assert
(
b
);
assert
((
a
->
mode
==
b
->
mode
));
/* works even for vector modes */
carry_flag
=
0
;
switch
(
get_mode_sort
(
a
->
mode
))
{
case
irms_internal_boolean
:
...
...
@@ -1310,10 +1310,10 @@ tarval *tarval_eor(tarval *a, tarval *b) {
tarval
*
tarval_shl
(
tarval
*
a
,
tarval
*
b
)
{
char
*
temp_val
=
NULL
;
assert
(
a
);
assert
(
b
);
assert
(
mode_is_int
(
a
->
mode
)
&&
mode_is_int
(
b
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1337,10 +1337,10 @@ tarval *tarval_shl(tarval *a, tarval *b) {
tarval
*
tarval_shr
(
tarval
*
a
,
tarval
*
b
)
{
char
*
temp_val
=
NULL
;
assert
(
a
);
assert
(
b
);
assert
(
mode_is_int
(
a
->
mode
)
&&
mode_is_int
(
b
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1364,10 +1364,10 @@ tarval *tarval_shr(tarval *a, tarval *b) {
tarval
*
tarval_shrs
(
tarval
*
a
,
tarval
*
b
)
{
char
*
temp_val
=
NULL
;
assert
(
a
);
assert
(
b
);
assert
(
mode_is_int
(
a
->
mode
)
&&
mode_is_int
(
b
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1391,10 +1391,10 @@ tarval *tarval_shrs(tarval *a, tarval *b) {
tarval
*
tarval_rotl
(
tarval
*
a
,
tarval
*
b
)
{
char
*
temp_val
=
NULL
;
assert
(
a
);
assert
(
b
);
assert
(
mode_is_int
(
a
->
mode
)
&&
mode_is_int
(
b
->
mode
));
carry_flag
=
-
1
;
if
(
get_mode_n_vector_elems
(
a
->
mode
)
>
1
||
get_mode_n_vector_elems
(
a
->
mode
)
>
1
)
{
/* vector arithmetic not implemented yet */
return
tarval_bad
;
...
...
@@ -1416,8 +1416,9 @@ tarval *tarval_rotl(tarval *a, tarval *b) {
* carry flag of the last operation
*/
int
tarval_carry
(
void
)
{
panic
(
"tarval_carry() requetsed: not implemented on all operations"
);
return
sc_had_carry
();
if
(
carry_flag
==
-
1
)
panic
(
"Carry undefined for the last operation"
);
return
carry_flag
;
}
/*
...
...
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