Add merge_bits.

This commit is contained in:
Thomas Koenig 2024-08-08 20:10:33 +02:00
parent d5c05281ba
commit 8366ec0e2f
4 changed files with 64 additions and 10 deletions

View File

@ -4443,20 +4443,54 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask)
&& !gfc_boz2int (j, i->ts.kind))
return false;
if (!type_check (i, 0, BT_INTEGER))
return false;
if (flag_unsigned)
{
/* If i is BOZ and j is unsigned, convert i to type of j. */
if (i->ts.type == BT_BOZ && j->ts.type == BT_UNSIGNED
&& !gfc_boz2uint (i, j->ts.kind))
return false;
if (!type_check (j, 1, BT_INTEGER))
return false;
/* If j is BOZ and i is unsigned, convert j to type of i. */
if (j->ts.type == BT_BOZ && i->ts.type == BT_UNSIGNED
&& !gfc_boz2int (j, i->ts.kind))
return false;
if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED))
return false;
if (!type_check2 (j, 1, BT_INTEGER, BT_UNSIGNED))
return false;
}
else
{
if (!type_check (i, 0, BT_INTEGER))
return false;
if (!type_check (j, 1, BT_INTEGER))
return false;
}
if (!same_type_check (i, 0, j, 1))
return false;
if (mask->ts.type == BT_BOZ && !gfc_boz2int(mask, i->ts.kind))
return false;
if (mask->ts.type == BT_BOZ)
{
if (i->ts.type == BT_INTEGER && !gfc_boz2int (mask, i->ts.kind))
return false;
if (i->ts.type == BT_UNSIGNED && !gfc_boz2uint (mask, i->ts.kind))
return false;
}
if (!type_check (mask, 2, BT_INTEGER))
return false;
if (flag_unsigned)
{
if (!type_check2 (mask, 2, BT_INTEGER, BT_UNSIGNED))
return false;
}
else
{
if (!type_check (mask, 2, BT_INTEGER))
return false;
}
if (!same_type_check (i, 0, mask, 2))
return false;

View File

@ -2000,7 +2000,9 @@ gfc_resolve_merge_bits (gfc_expr *f, gfc_expr *i,
gfc_expr *mask ATTRIBUTE_UNUSED)
{
f->ts = i->ts;
f->value.function.name = gfc_get_string ("__merge_bits_i%d", i->ts.kind);
const char *name = i->ts.kind == BT_UNSIGNED ? "__merge_bits_u%d" :
"__merge_bits_i%d";
f->value.function.name = gfc_get_string (name, i->ts.kind);
}

View File

@ -5221,7 +5221,7 @@ gfc_simplify_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask_expr)
|| mask_expr->expr_type != EXPR_CONSTANT)
return NULL;
result = gfc_get_constant_expr (BT_INTEGER, i->ts.kind, &i->where);
result = gfc_get_constant_expr (i->ts.type, i->ts.kind, &i->where);
/* Convert all argument to unsigned. */
mpz_init_set (arg1, i->value.integer);

View File

@ -0,0 +1,18 @@
! { dg-do run }
! { dg-options "-funsigned" }
! Test basic functionality of merge_bits.
program main
unsigned(kind=4) :: a, b, c
if (merge_bits(15u,51u,85u) /= 39u) stop 1
a = 15u
b = 51u
c = 85u
if (merge_bits(a,b,c) /= 39u) stop 2
if (merge_bits(4026531840u,3422552064u,2852126720u) /= 3825205248u) stop 3
a = 4026531840u_4
b = 3422552064u_4
c = 2852126720u_4
if (merge_bits(a,b,c) /= 3825205248u) stop 4
end program