+/* Compute the result of int accumulator cut (SCUTSS). */
+SI
+frvbf_iacc_cut (SIM_CPU *current_cpu, DI acc, SI cut_point)
+{
+ DI lower, upper;
+
+ /* The cut point is the lower 7 bits (signed) of what we are passed. */
+ cut_point = cut_point << 25 >> 25;
+
+ /* Conceptually, the operation is on a 128-bit sign-extension of ACC.
+ The top bit of the return value corresponds to bit (63 - CUT_POINT)
+ of this 128-bit value.
+
+ Since we can't deal with 128-bit values very easily, convert the
+ operation into an equivalent 64-bit one. */
+ if (cut_point < 0)
+ {
+ /* Avoid an undefined shift operation. */
+ if (cut_point == -64)
+ acc >>= 63;
+ else
+ acc >>= -cut_point;
+ cut_point = 0;
+ }
+
+ /* Get the shifted but unsaturated result. Set LOWER to the lowest
+ 32 bits of the result and UPPER to the result >> 31. */
+ if (cut_point < 32)
+ {
+ /* The cut loses the (32 - CUT_POINT) least significant bits.
+ Round the result up if the most significant of these lost bits
+ is 1. */
+ lower = acc >> (32 - cut_point);
+ if (lower < 0x7fffffff)
+ if (acc & LSBIT64 (32 - cut_point - 1))
+ lower++;
+ upper = lower >> 31;
+ }
+ else
+ {
+ lower = acc << (cut_point - 32);
+ upper = acc >> (63 - cut_point);
+ }
+
+ /* Saturate the result. */
+ if (upper < -1)
+ return ~0x7fffffff;
+ else if (upper > 0)
+ return 0x7fffffff;
+ else
+ return lower;
+}
+
+/* Compute the result of shift-left-arithmetic-with-saturation (SLASS). */
+SI
+frvbf_shift_left_arith_saturate (SIM_CPU *current_cpu, SI arg1, SI arg2)
+{
+ int neg_arg1;
+
+ /* FIXME: what to do with negative shift amt? */
+ if (arg2 <= 0)
+ return arg1;
+
+ if (arg1 == 0)
+ return 0;
+
+ /* Signed shift by 31 or greater saturates by definition. */
+ if (arg2 >= 31)
+ if (arg1 > 0)
+ return (SI) 0x7fffffff;
+ else
+ return (SI) 0x80000000;
+
+ /* OK, arg2 is between 1 and 31. */
+ neg_arg1 = (arg1 < 0);
+ do {
+ arg1 <<= 1;
+ /* Check for sign bit change (saturation). */
+ if (neg_arg1 && (arg1 >= 0))
+ return (SI) 0x80000000;
+ else if (!neg_arg1 && (arg1 < 0))
+ return (SI) 0x7fffffff;
+ } while (--arg2 > 0);
+
+ return arg1;
+}
+