static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
static rtx expand_builtin_frame_address PARAMS ((tree));
static tree stabilize_va_list PARAMS ((tree, int));
+static rtx expand_builtin_expect PARAMS ((tree, rtx));
/* Return the alignment in bits of EXP, a pointer valued expression.
But don't return more than MAX_ALIGN no matter what.
calls may traverse the arc back to this label. */
current_function_has_nonlocal_label = 1;
- nonlocal_goto_handler_labels =
- gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
+ nonlocal_goto_handler_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
/* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
abort ();
return target;
}
+
+/* Expand a call to __builtin_expect. We return our argument and
+ emit a NOTE_INSN_EXPECTED_VALUE note. */
+
+static rtx
+expand_builtin_expect (arglist, target)
+ tree arglist;
+ rtx target;
+{
+ tree exp, c;
+ rtx note, rtx_c;
+
+ if (arglist == NULL_TREE
+ || TREE_CHAIN (arglist) == NULL_TREE)
+ return const0_rtx;
+ exp = TREE_VALUE (arglist);
+ c = TREE_VALUE (TREE_CHAIN (arglist));
+
+ if (TREE_CODE (c) != INTEGER_CST)
+ {
+ error ("second arg to `__builtin_expect' must be a constant");
+ c = integer_zero_node;
+ }
+
+ target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
+
+ /* Don't bother with expected value notes for integral constants. */
+ if (GET_CODE (target) != CONST_INT)
+ {
+ /* We do need to force this into a register so that we can be
+ moderately sure to be able to correctly interpret the branch
+ condition later. */
+ target = force_reg (GET_MODE (target), target);
+
+ rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
+
+ note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
+ NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
+ }
+
+ return target;
+}
\f
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
return expand_builtin_va_end (arglist);
case BUILT_IN_VA_COPY:
return expand_builtin_va_copy (arglist);
+ case BUILT_IN_EXPECT:
+ return expand_builtin_expect (arglist, target);
default: /* just do library call, if unknown builtin */
error ("built-in function `%s' not currently supported",