+ -- Otherwise we need to figure out the correct result type size
+ -- First figure out the effective sizes of the operands. Normally
+ -- the effective size of an operand is the RM_Size of the operand.
+ -- But a special case arises with operands whose size is known at
+ -- compile time. In this case, we can use the actual value of the
+ -- operand to get its size if it would fit in 8 or 16 bits.
+
+ -- Note: if both operands are known at compile time (can that
+ -- happen?) and both were equal to the power of 2, then we would
+ -- be one bit off in this test, so for the left operand, we only
+ -- go up to the power of 2 - 1. This ensures that we do not get
+ -- this anomolous case, and in practice the right operand is by
+ -- far the more likely one to be the constant.
+
+ Left_Size := UI_To_Int (RM_Size (Left_Type));
+
+ if Compile_Time_Known_Value (L) then
+ declare
+ Val : constant Uint := Expr_Value (L);
+
+ begin
+ if Val < Int'(2 ** 8) then
+ Left_Size := 8;
+ elsif Val < Int'(2 ** 16) then
+ Left_Size := 16;
+ end if;
+ end;
+ end if;
+
+ Right_Size := UI_To_Int (RM_Size (Right_Type));
+
+ if Compile_Time_Known_Value (R) then
+ declare
+ Val : constant Uint := Expr_Value (R);
+
+ begin
+ if Val <= Int'(2 ** 8) then
+ Right_Size := 8;
+ elsif Val <= Int'(2 ** 16) then
+ Right_Size := 16;
+ end if;
+ end;
+ end if;
+
+ -- Now the result size must be at least twice the longer of
+ -- the two sizes, to accomodate all possible results.