Hello!

> 2013-11-15  Ilya Enkovich  <ilya.enkov...@intel.com>
>
> * config/i386/i386-builtin-types.def (BND): New.
> (ULONG): New.
> (BND_FTYPE_PCVOID_ULONG): New.
> (VOID_FTYPE_BND_PCVOID): New.
> (VOID_FTYPE_PCVOID_PCVOID_BND): New.
> (BND_FTYPE_PCVOID_PCVOID): New.
> (BND_FTYPE_PCVOID): New.
> (BND_FTYPE_BND_BND): New.
> (PVOID_FTYPE_PVOID_PVOID_ULONG): New.
> (PVOID_FTYPE_PCVOID_BND_ULONG): New.
> (ULONG_FTYPE_VOID): New.
> (PVOID_FTYPE_BND): New.
> * config/i386/i386.c: Include tree-chkp.h, rtl-chkp.h.
> (ix86_builtins): Add
> IX86_BUILTIN_BNDMK, IX86_BUILTIN_BNDSTX,
> IX86_BUILTIN_BNDLDX, IX86_BUILTIN_BNDCL,
> IX86_BUILTIN_BNDCU, IX86_BUILTIN_BNDRET,
> IX86_BUILTIN_BNDSET, IX86_BUILTIN_BNDNARROW,
> IX86_BUILTIN_BNDINT, IX86_BUILTIN_ARG_BND,
> IX86_BUILTIN_SIZEOF, IX86_BUILTIN_BNDLOWER,
> IX86_BUILTIN_BNDUPPER.
> (builtin_isa): Add leaf_p and nothrow_p fields.
> (def_builtin): Initialize leaf_p and nothrow_p.
> (ix86_add_new_builtins): Handle leaf_p and nothrow_p
> flags.
> (bdesc_mpx): New.
> (bdesc_mpx_const): New.
> (ix86_init_mpx_builtins): New.
> (ix86_init_builtins): Call ix86_init_mpx_builtins.
> (ix86_expand_builtin): expand IX86_BUILTIN_BNDMK,
> IX86_BUILTIN_BNDSTX, IX86_BUILTIN_BNDLDX,
> IX86_BUILTIN_BNDCL, IX86_BUILTIN_BNDCU,
> IX86_BUILTIN_BNDRET, IX86_BUILTIN_BNDSET,
> IX86_BUILTIN_BNDNARROW, IX86_BUILTIN_BNDINT,
> IX86_BUILTIN_ARG_BND, IX86_BUILTIN_SIZEOF,
> IX86_BUILTIN_BNDLOWER, IX86_BUILTIN_BNDUPPER.

+      if (decl)
+ {
+  DECL_ATTRIBUTES (decl) = build_tree_list (get_identifier ("leaf"),
+    NULL_TREE);
+  TREE_NOTHROW (decl) = 1;
+ }
+      else
+ {
+  ix86_builtins_isa[(int)d->code].leaf_p = true;
+  ix86_builtins_isa[(int)d->code].nothrow_p = true;
+ }

Is there a reason these builtins need to be leaf and nothrow? It is
not clear from the source what is the reason. I'd suggest a comment
explaining this fact.

+      /* Builtin arg1 is size of block but instruction op1 should be
(size - 1).  */
+      op0 = expand_normal (arg0);
+      op1 = expand_normal (fold_build2 (PLUS_EXPR, TREE_TYPE (arg1),
+ arg1, integer_minus_one_node));
+      op0 = force_reg (Pmode, op0);
+      op1 = force_reg (Pmode, op1);

A tree expert should say if the above approach of operand fixups in
the patch is OK.

+      /* Avoid registers which connot be used as index.  */
+      if (REGNO (op1) == VIRTUAL_INCOMING_ARGS_REGNUM
+  || REGNO (op1) == VIRTUAL_STACK_VARS_REGNUM
+  || REGNO (op1) == VIRTUAL_OUTGOING_ARGS_REGNUM)

As said elsewhere, you want to check with index_register_operand predicate here.

+      /* If op1 was a register originally then it may have
+ mode other than Pmode.  We need to extend in such
+ case because bndldx may work only with Pmode regs.  */
+      if (GET_MODE (op1) != Pmode)
+ {
+  rtx ext = gen_rtx_ZERO_EXTEND (Pmode, op1);
+  op1 = gen_reg_rtx (Pmode);
+  emit_move_insn (op1, ext);
+ }

Please use ix86_zero_extend_to_Pmode.

+    case IX86_BUILTIN_BNDNARROW:
+      {
+ enum machine_mode mode = BNDmode;
+ enum machine_mode hmode = Pmode;

No need for static temporaries, use mode directly.

+ /* Generate mem expression to be used for access to LB and UB.  */
+ m1h1 = gen_rtx_MEM (hmode, XEXP (m1, 0));
+ m1h2 = gen_rtx_MEM (hmode,
+    gen_rtx_PLUS (Pmode, XEXP (m1, 0),
+  GEN_INT (GET_MODE_SIZE (hmode))));

Use subreg infrastructure here?

+ if (TARGET_CMOVE)
+  {
+    t2 = ix86_expand_compare (LTU, t1, lb);
+    emit_insn (gen_rtx_SET (VOIDmode, t1,
+    gen_rtx_IF_THEN_ELSE (hmode, t2, lb, t1)));
+  }
+ else
+  {
+    rtx nomove = gen_label_rtx ();
+    emit_cmp_and_jump_insns (t1, lb, GEU, const0_rtx, hmode, 1, nomove);
+    emit_insn (gen_rtx_SET (VOIDmode, t1, lb));
+    emit_label (nomove);
+  }
+ emit_move_insn (m1h1, t1);

This is used in a couple of places. Perhaps make a helper function?

+    m1 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);

Please use assign_i386_stack_local (mode, SLOT_TEMP)

+ m1h1 = gen_rtx_MEM (hmode, XEXP (m1, 0));
+ m1h2 = gen_rtx_MEM (hmode,
+    gen_rtx_PLUS (Pmode, XEXP (m1, 0),
+  GEN_INT (GET_MODE_SIZE (hmode))));
+ m2h1 = gen_rtx_MEM (hmode, XEXP (m2, 0));
+ m2h2 = gen_rtx_MEM (hmode,
+    gen_rtx_PLUS (Pmode, XEXP (m2, 0),
+  GEN_INT (GET_MODE_SIZE (hmode))));
+ rh1 = gen_rtx_MEM (hmode, XEXP (res, 0));
+ rh2 = gen_rtx_MEM (hmode,
+   gen_rtx_PLUS (Pmode, XEXP (res, 0),
+ GEN_INT (GET_MODE_SIZE (hmode))));

subergs, or plus_constant.

Uros.

Reply via email to