2008-01-30 Paul N. Hilfinger <hilfinger@adacore.com>

* valarith.c (value_binop): Add floating-point BINOP_MIN and
	BINOP_MAX cases.
	For BINOP_EXP, use length and signedness of left operand only for
	result, as for shifts.
	For integral operands to BINOP_EXP, use new integer_pow and
	uinteger_pow functions so as to get full range of results.
	(integer_pow): New function.
	(uinteger_pow): New function.

2008-01-30  Paul N. Hilfinger  <hilfinger@adacore.com>

	* gdb.ada/exprs: New test program.
	* gdb.ada/exprs.exp: New testcase.
This commit is contained in:
Paul N. Hilfinger 2008-01-30 07:28:16 +00:00
parent d56d46f5c7
commit d118ef8764
5 changed files with 185 additions and 14 deletions

View file

@ -1,3 +1,14 @@
2008-01-30 Paul N. Hilfinger <hilfinger@adacore.com>
* valarith.c (value_binop): Add floating-point BINOP_MIN and
BINOP_MAX cases.
For BINOP_EXP, use length and signedness of left operand only for
result, as for shifts.
For integral operands to BINOP_EXP, use new integer_pow and
uinteger_pow functions so as to get full range of results.
(integer_pow): New function.
(uinteger_pow): New function.
2008-01-30 Vladimir Prus <vladimir@codesourcery.com>
Use vector for varobj_list_children interface.

View file

@ -1,3 +1,8 @@
2008-01-30 Paul N. Hilfinger <hilfinger@adacore.com>
* gdb.ada/exprs: New test program.
* gdb.ada/exprs.exp: New testcase.
2008-01-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
* dfp-test.c (DELTA, DELTA_B): New definitions.

View file

@ -0,0 +1,50 @@
# Copyright 2005, 2007 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if $tracelevel then {
strace $tracelevel
}
load_lib "ada.exp"
set testdir "exprs"
set testfile "${testdir}/p"
set srcfile ${srcdir}/${subdir}/${testfile}.adb
set binfile ${objdir}/${subdir}/${testfile}
file mkdir ${objdir}/${subdir}/${testdir}
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
set bp_location [gdb_get_line_number "START" ${testdir}/p.adb]
runto "p.adb:$bp_location"
gdb_test "print X ** Y = Z" \
"true" \
"Long_Long_Integer ** Y"
gdb_test "print long_float'min (long_float (X), 8.0)" \
"7.0" \
"long_float'min"
gdb_test "print long_float'max (long_float (X), 8.0)" \
"8.0" \
"long_float'max"

View file

@ -0,0 +1,41 @@
-- Copyright 2008 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- Test Ada additions to core GDB evaluation.
with System;
with Text_IO; use Text_IO;
procedure P is
type Int is range System.Min_Int .. System.Max_Int;
X, Z : Int;
Y : Integer;
begin
X := 0;
-- Set X to 7 by disguised means lest a future optimizer interfere.
for I in 1 .. 7 loop
X := X + 1;
end loop;
Z := 1;
Y := 0;
while Z < Int'Last / X loop
Z := Z * X;
Y := Y + 1;
end loop;
Put_Line (Int'Image (X ** Y)); -- START
end P;

View file

@ -743,6 +743,66 @@ value_concat (struct value *arg1, struct value *arg2)
}
/* Integer exponentiation: V1**V2, where both arguments are
integers. Requires V1 != 0 if V2 < 0. Returns 1 for 0 ** 0. */
static LONGEST
integer_pow (LONGEST v1, LONGEST v2)
{
if (v2 < 0)
{
if (v1 == 0)
error (_("Attempt to raise 0 to negative power."));
else
return 0;
}
else
{
/* The Russian Peasant's Algorithm */
LONGEST v;
v = 1;
for (;;)
{
if (v2 & 1L)
v *= v1;
v2 >>= 1;
if (v2 == 0)
return v;
v1 *= v1;
}
}
}
/* Integer exponentiation: V1**V2, where both arguments are
integers. Requires V1 != 0 if V2 < 0. Returns 1 for 0 ** 0. */
static ULONGEST
uinteger_pow (ULONGEST v1, LONGEST v2)
{
if (v2 < 0)
{
if (v1 == 0)
error (_("Attempt to raise 0 to negative power."));
else
return 0;
}
else
{
/* The Russian Peasant's Algorithm */
ULONGEST v;
v = 1;
for (;;)
{
if (v2 & 1L)
v *= v1;
v2 >>= 1;
if (v2 == 0)
return v;
v1 *= v1;
}
}
}
/* Obtain decimal value of arguments for binary operation, converting from
other types if one of them is not decimal floating point. */
static void
@ -898,6 +958,14 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
error (_("Cannot perform exponentiation: %s"), safe_strerror (errno));
break;
case BINOP_MIN:
v = v1 < v2 ? v1 : v2;
break;
case BINOP_MAX:
v = v1 > v2 ? v1 : v2;
break;
default:
error (_("Integer-only operation on floating point number."));
}
@ -979,14 +1047,15 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
}
/* Determine type length of the result, and if the operation should
be done unsigned.
Use the signedness of the operand with the greater length.
be done unsigned. For exponentiation and shift operators,
use the length and type of the left operand. Otherwise,
use the signedness of the operand with the greater length.
If both operands are of equal length, use unsigned operation
if one of the operands is unsigned. */
if (op == BINOP_RSH || op == BINOP_LSH)
if (op == BINOP_RSH || op == BINOP_LSH || op == BINOP_EXP)
{
/* In case of the shift operators the type of the result only
depends on the type of the left operand. */
/* In case of the shift operators and exponentiation the type of
the result only depends on the type of the left operand. */
unsigned_operation = is_unsigned1;
result_len = promoted_len1;
}
@ -1008,9 +1077,10 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
if (unsigned_operation)
{
LONGEST v2_signed = value_as_long (arg2);
ULONGEST v1, v2, v = 0;
v1 = (ULONGEST) value_as_long (arg1);
v2 = (ULONGEST) value_as_long (arg2);
v2 = (ULONGEST) v2_signed;
/* Truncate values to the type length of the result. */
if (result_len < sizeof (ULONGEST))
@ -1042,10 +1112,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
break;
case BINOP_EXP:
errno = 0;
v = pow (v1, v2);
if (errno)
error (_("Cannot perform exponentiation: %s"), safe_strerror (errno));
v = uinteger_pow (v1, v2_signed);
break;
case BINOP_REM:
@ -1165,10 +1232,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
break;
case BINOP_EXP:
errno = 0;
v = pow (v1, v2);
if (errno)
error (_("Cannot perform exponentiation: %s"), safe_strerror (errno));
v = integer_pow (v1, v2);
break;
case BINOP_REM: