static void swap_2_operands (unsigned int, unsigned int);
 static enum flag_code i386_addressing_mode (void);
 static void optimize_imm (void);
-static void optimize_disp (void);
+static bool optimize_disp (const insn_template *t);
 static const insn_template *match_template (char);
 static int check_string (void);
 static int process_suffix (void);
   if (i.imm_operands)
     optimize_imm ();
 
-  if (i.disp_operands && !want_disp32 (t)
-      && (!t->opcode_modifier.jump
-         || i.jumpabsolute || i.types[0].bitfield.baseindex))
-    {
-      for (j = 0; j < i.operands; ++j)
-       {
-         const expressionS *exp = i.op[j].disps;
-
-         if (!operand_type_check (i.types[j], disp))
-           continue;
-
-         if (exp->X_op != O_constant)
-           continue;
-
-         /* Since displacement is signed extended to 64bit, don't allow
-            disp32 if it is out of range.  */
-         if (fits_in_signed_long (exp->X_add_number))
-           continue;
-
-         i.types[j].bitfield.disp32 = 0;
-         if (i.types[j].bitfield.baseindex)
-           {
-             as_bad (_("0x%" PRIx64 " out of range of signed 32bit displacement"),
-                     (uint64_t) exp->X_add_number);
-             return;
-           }
-       }
-    }
-
-  /* Don't optimize displacement for movabs since it only takes 64bit
-     displacement.  */
-  if (i.disp_operands
-      && i.disp_encoding <= disp_encoding_8bit
-      && (flag_code != CODE_64BIT
-         || strcmp (mnemonic, "movabs") != 0))
-    optimize_disp ();
+  if (i.disp_operands && !optimize_disp (t))
+    return;
 
   /* Next, we find a template that matches the given insn,
      making sure the overlap of the given operands types is consistent
 }
 
 /* Try to use the smallest displacement type too.  */
-static void
-optimize_disp (void)
+static bool
+optimize_disp (const insn_template *t)
 {
-  int op;
+  unsigned int op;
 
-  for (op = i.operands; --op >= 0;)
+  if (!want_disp32 (t)
+      && (!t->opcode_modifier.jump
+         || i.jumpabsolute || i.types[0].bitfield.baseindex))
+    {
+      for (op = 0; op < i.operands; ++op)
+       {
+         const expressionS *exp = i.op[op].disps;
+
+         if (!operand_type_check (i.types[op], disp))
+           continue;
+
+         if (exp->X_op != O_constant)
+           continue;
+
+         /* Since displacement is signed extended to 64bit, don't allow
+            disp32 if it is out of range.  */
+         if (fits_in_signed_long (exp->X_add_number))
+           continue;
+
+         i.types[op].bitfield.disp32 = 0;
+         if (i.types[op].bitfield.baseindex)
+           {
+             as_bad (_("0x%" PRIx64 " out of range of signed 32bit displacement"),
+                     (uint64_t) exp->X_add_number);
+             return false;
+           }
+       }
+    }
+
+  /* Don't optimize displacement for movabs since it only takes 64bit
+     displacement.  */
+  if (i.disp_encoding > disp_encoding_8bit
+      || (flag_code == CODE_64BIT && t->mnem_off == MN_movabs))
+    return true;
+
+  for (op = i.operands; op-- > 0;)
     if (operand_type_check (i.types[op], disp))
       {
        if (i.op[op].disps->X_op == O_constant)
            /* Optimize 64-bit displacement to 32-bit for 64-bit BFD.  */
            if ((flag_code != CODE_64BIT
                 ? i.types[op].bitfield.disp32
-                : want_disp32 (current_templates->start)
-                  && (!current_templates->start->opcode_modifier.jump
+                : want_disp32 (t)
+                  && (!t->opcode_modifier.jump
                       || i.jumpabsolute || i.types[op].bitfield.baseindex))
                && fits_in_unsigned_long (op_disp))
              {
          /* We only support 64bit displacement on constants.  */
          i.types[op].bitfield.disp64 = 0;
       }
+
+  return true;
 }
 
 /* Return 1 if there is a match in broadcast bytes between operand