2076-01-28 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gas / config / tc-i386.c
index 767e7e3bd056729c373c99eb67aa7e854785937e..5ac241c17eb97b0fc7f885150bbddac17eb234ce 100644 (file)
@@ -1,6 +1,6 @@
-/* i386.c -- Assemble code for the Intel 80386
+/* tc-i386.c -- Assemble code for the Intel 80386
    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 #endif
 #endif
 
-static INLINE unsigned int mode_from_disp_size PARAMS ((unsigned int));
-static INLINE int fits_in_signed_byte PARAMS ((offsetT));
-static INLINE int fits_in_unsigned_byte PARAMS ((offsetT));
-static INLINE int fits_in_unsigned_word PARAMS ((offsetT));
-static INLINE int fits_in_signed_word PARAMS ((offsetT));
-static INLINE int fits_in_unsigned_long PARAMS ((offsetT));
-static INLINE int fits_in_signed_long PARAMS ((offsetT));
-static int smallest_imm_type PARAMS ((offsetT));
-static offsetT offset_in_range PARAMS ((offsetT, int));
-static int add_prefix PARAMS ((unsigned int));
-static void set_code_flag PARAMS ((int));
-static void set_16bit_gcc_code_flag PARAMS ((int));
-static void set_intel_syntax PARAMS ((int));
-static void set_cpu_arch PARAMS ((int));
+static void set_code_flag (int);
+static void set_16bit_gcc_code_flag (int);
+static void set_intel_syntax (int);
+static void set_cpu_arch (int);
 #ifdef TE_PE
-static void pe_directive_secrel PARAMS ((int));
+static void pe_directive_secrel (int);
 #endif
-static void signed_cons PARAMS ((int));
-static char *output_invalid PARAMS ((int c));
-static int i386_operand PARAMS ((char *operand_string));
-static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float));
-static const reg_entry *parse_register PARAMS ((char *reg_string,
-                                               char **end_op));
-static char *parse_insn PARAMS ((char *, char *));
-static char *parse_operands PARAMS ((char *, const char *));
-static void swap_operands PARAMS ((void));
-static void swap_imm_operands PARAMS ((void));
-static void optimize_imm PARAMS ((void));
-static void optimize_disp PARAMS ((void));
-static int match_template PARAMS ((void));
-static int check_string PARAMS ((void));
-static int process_suffix PARAMS ((void));
-static int check_byte_reg PARAMS ((void));
-static int check_long_reg PARAMS ((void));
-static int check_qword_reg PARAMS ((void));
-static int check_word_reg PARAMS ((void));
-static int finalize_imm PARAMS ((void));
-static int process_operands PARAMS ((void));
-static const seg_entry *build_modrm_byte PARAMS ((void));
-static void output_insn PARAMS ((void));
-static void output_branch PARAMS ((void));
-static void output_jump PARAMS ((void));
-static void output_interseg_jump PARAMS ((void));
-static void output_imm PARAMS ((fragS *insn_start_frag,
-                               offsetT insn_start_off));
-static void output_disp PARAMS ((fragS *insn_start_frag,
-                                offsetT insn_start_off));
+static void signed_cons (int);
+static char *output_invalid (int c);
+static int i386_operand (char *);
+static int i386_intel_operand (char *, int);
+static const reg_entry *parse_register (char *, char **);
+static char *parse_insn (char *, char *);
+static char *parse_operands (char *, const char *);
+static void swap_operands (void);
+static void swap_2_operands (int, int);
+static void optimize_imm (void);
+static void optimize_disp (void);
+static int match_template (void);
+static int check_string (void);
+static int process_suffix (void);
+static int check_byte_reg (void);
+static int check_long_reg (void);
+static int check_qword_reg (void);
+static int check_word_reg (void);
+static int finalize_imm (void);
+static int process_operands (void);
+static const seg_entry *build_modrm_byte (void);
+static void output_insn (void);
+static void output_imm (fragS *, offsetT);
+static void output_disp (fragS *, offsetT);
 #ifndef I386COFF
-static void s_bss PARAMS ((int));
+static void s_bss (int);
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 static void handle_large_common (int small ATTRIBUTE_UNUSED);
@@ -272,8 +256,9 @@ static i386_insn i;
 /* Possible templates for current insn.  */
 static const templates *current_templates;
 
-/* Per instruction expressionS buffers: 2 displacements & 2 immediate max.  */
-static expressionS disp_expressions[2], im_expressions[2];
+/* Per instruction expressionS buffers: max displacements & immediates.  */
+static expressionS disp_expressions[MAX_MEMORY_OPERANDS];
+static expressionS im_expressions[MAX_IMMEDIATE_OPERANDS];
 
 /* Current operand we are working on.  */
 static int this_operand;
@@ -306,6 +291,9 @@ static int intel_syntax = 0;
 /* 1 if register prefix % not required.  */
 static int allow_naked_reg = 0;
 
+/* Register prefix used for error message.  */
+static const char *register_prefix = "%";
+
 /* Used in 16 bit gcc mode to add an l suffix to call, ret, enter,
    leave, push, and pop instructions so that gcc has the same stack
    frame as in 32 bit mode.  */
@@ -554,7 +542,7 @@ const pseudo_typeS md_pseudo_table[] =
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #else
-  {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
+  {"file", (void (*) (int)) dwarf2_directive_file, 0},
   {"loc", dwarf2_directive_loc, 0},
   {"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0},
 #endif
@@ -574,9 +562,7 @@ static struct hash_control *op_hash;
 static struct hash_control *reg_hash;
 \f
 void
-i386_align_code (fragP, count)
-     fragS *fragP;
-     int count;
+i386_align_code (fragS *fragP, int count)
 {
   /* Various efficient no-op patterns for aligning code labels.
      Note: Don't try to assemble the instructions in the comments.
@@ -885,42 +871,37 @@ i386_align_code (fragP, count)
 }
 
 static INLINE unsigned int
-mode_from_disp_size (t)
-     unsigned int t;
+mode_from_disp_size (unsigned int t)
 {
   return (t & Disp8) ? 1 : (t & (Disp16 | Disp32 | Disp32S)) ? 2 : 0;
 }
 
 static INLINE int
-fits_in_signed_byte (num)
-     offsetT num;
+fits_in_signed_byte (offsetT num)
 {
   return (num >= -128) && (num <= 127);
 }
 
 static INLINE int
-fits_in_unsigned_byte (num)
-     offsetT num;
+fits_in_unsigned_byte (offsetT num)
 {
   return (num & 0xff) == num;
 }
 
 static INLINE int
-fits_in_unsigned_word (num)
-     offsetT num;
+fits_in_unsigned_word (offsetT num)
 {
   return (num & 0xffff) == num;
 }
 
 static INLINE int
-fits_in_signed_word (num)
-     offsetT num;
+fits_in_signed_word (offsetT num)
 {
   return (-32768 <= num) && (num <= 32767);
 }
+
 static INLINE int
-fits_in_signed_long (num)
-     offsetT num ATTRIBUTE_UNUSED;
+fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED)
 {
 #ifndef BFD64
   return 1;
@@ -929,9 +910,9 @@ fits_in_signed_long (num)
          || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
 #endif
 }                              /* fits_in_signed_long() */
+
 static INLINE int
-fits_in_unsigned_long (num)
-     offsetT num ATTRIBUTE_UNUSED;
+fits_in_unsigned_long (offsetT num ATTRIBUTE_UNUSED)
 {
 #ifndef BFD64
   return 1;
@@ -940,9 +921,8 @@ fits_in_unsigned_long (num)
 #endif
 }                              /* fits_in_unsigned_long() */
 
-static int
-smallest_imm_type (num)
-     offsetT num;
+static unsigned int
+smallest_imm_type (offsetT num)
 {
   if (cpu_arch_flags != (Cpu186 | Cpu286 | Cpu386 | Cpu486 | CpuNo64))
     {
@@ -968,9 +948,7 @@ smallest_imm_type (num)
 }
 
 static offsetT
-offset_in_range (val, size)
-     offsetT val;
-     int size;
+offset_in_range (offsetT val, int size)
 {
   addressT mask;
 
@@ -1005,8 +983,7 @@ offset_in_range (val, size)
    class already exists, 1 if non rep/repne added, 2 if rep/repne
    added.  */
 static int
-add_prefix (prefix)
-     unsigned int prefix;
+add_prefix (unsigned int prefix)
 {
   int ret = 1;
   unsigned int q;
@@ -1073,8 +1050,7 @@ add_prefix (prefix)
 }
 
 static void
-set_code_flag (value)
-     int value;
+set_code_flag (int value)
 {
   flag_code = value;
   cpu_arch_flags &= ~(Cpu64 | CpuNo64);
@@ -1091,8 +1067,7 @@ set_code_flag (value)
 }
 
 static void
-set_16bit_gcc_code_flag (new_code_flag)
-     int new_code_flag;
+set_16bit_gcc_code_flag (int new_code_flag)
 {
   flag_code = new_code_flag;
   cpu_arch_flags &= ~(Cpu64 | CpuNo64);
@@ -1101,8 +1076,7 @@ set_16bit_gcc_code_flag (new_code_flag)
 }
 
 static void
-set_intel_syntax (syntax_flag)
-     int syntax_flag;
+set_intel_syntax (int syntax_flag)
 {
   /* Find out if register prefixing is specified.  */
   int ask_naked_reg = 0;
@@ -1133,11 +1107,11 @@ set_intel_syntax (syntax_flag)
 
   identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0;
   identifier_chars['$'] = intel_syntax ? '$' : 0;
+  register_prefix = allow_naked_reg ? "" : "%";
 }
 
 static void
-set_cpu_arch (dummy)
-     int dummy ATTRIBUTE_UNUSED;
+set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
 {
   SKIP_WHITESPACE ();
 
@@ -1349,8 +1323,7 @@ md_begin ()
 }
 
 void
-i386_print_statistics (file)
-     FILE *file;
+i386_print_statistics (FILE *file)
 {
   hash_print_statistics (file, "i386 opcode", op_hash);
   hash_print_statistics (file, "i386 register", reg_hash);
@@ -1359,16 +1332,13 @@ i386_print_statistics (file)
 #ifdef DEBUG386
 
 /* Debugging routines for md_assemble.  */
-static void pi PARAMS ((char *, i386_insn *));
-static void pte PARAMS ((template *));
-static void pt PARAMS ((unsigned int));
-static void pe PARAMS ((expressionS *));
-static void ps PARAMS ((symbolS *));
+static void pte (template *);
+static void pt (unsigned int);
+static void pe (expressionS *);
+static void ps (symbolS *);
 
 static void
-pi (line, x)
-     char *line;
-     i386_insn *x;
+pi (char *line, i386_insn *x)
 {
   unsigned int i;
 
@@ -1403,8 +1373,7 @@ pi (line, x)
 }
 
 static void
-pte (t)
-     template *t;
+pte (template *t)
 {
   unsigned int i;
   fprintf (stdout, " %d operands ", t->operands);
@@ -1425,8 +1394,7 @@ pte (t)
 }
 
 static void
-pe (e)
-     expressionS *e;
+pe (expressionS *e)
 {
   fprintf (stdout, "    operation     %d\n", e->X_op);
   fprintf (stdout, "    add_number    %ld (%lx)\n",
@@ -1446,8 +1414,7 @@ pe (e)
 }
 
 static void
-ps (s)
-     symbolS *s;
+ps (symbolS *s)
 {
   fprintf (stdout, "%s type %s%s",
           S_GET_NAME (s),
@@ -1610,8 +1577,7 @@ reloc (unsigned int size,
    some cases we force the original symbol to be used.  */
 
 int
-tc_i386_fix_adjustable (fixP)
-     fixS *fixP ATTRIBUTE_UNUSED;
+tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
 {
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   if (!IS_ELF)
@@ -1664,11 +1630,8 @@ tc_i386_fix_adjustable (fixP)
   return 1;
 }
 
-static int intel_float_operand PARAMS ((const char *mnemonic));
-
 static int
-intel_float_operand (mnemonic)
-     const char *mnemonic;
+intel_float_operand (const char *mnemonic)
 {
   /* Note that the value returned is meaningful only for opcodes with (memory)
      operands, hence the code here is free to improperly handle opcodes that
@@ -1753,11 +1716,11 @@ md_assemble (line)
 
   /* The order of the immediates should be reversed 
      for 2 immediates extrq and insertq instructions */
-  if ((i.imm_operands == 2) && 
-      ((strcmp (mnemonic, "extrq") == 0) 
-       || (strcmp (mnemonic, "insertq") == 0)))
+  if ((i.imm_operands == 2)
+      && ((strcmp (mnemonic, "extrq") == 0)
+         || (strcmp (mnemonic, "insertq") == 0)))
     {
-      swap_imm_operands ();  
+      swap_2_operands (0, 1);  
       /* "extrq" and insertq" are the only two instructions whose operands 
         have to be reversed even though they have two immediate operands.
       */
@@ -1772,7 +1735,8 @@ md_assemble (line)
      "enter".  We also don't reverse intersegment "jmp" and "call"
      instructions with 2 immediate operands so that the immediate segment
      precedes the offset, as it does when in AT&T mode. */
-  if (intel_syntax && i.operands > 1
+  if (intel_syntax
+      && i.operands > 1
       && (strcmp (mnemonic, "bound") != 0)
       && (strcmp (mnemonic, "invlpga") != 0)
       && !((i.types[0] & Imm) && (i.types[1] & Imm)))
@@ -1958,9 +1922,7 @@ md_assemble (line)
 }
 
 static char *
-parse_insn (line, mnemonic)
-     char *line;
-     char *mnemonic;
+parse_insn (char *line, char *mnemonic)
 {
   char *l = line;
   char *token_start = l;
@@ -2179,9 +2141,7 @@ parse_insn (line, mnemonic)
 }
 
 static char *
-parse_operands (l, mnemonic)
-     char *l;
-     const char *mnemonic;
+parse_operands (char *l, const char *mnemonic)
 {
   char *token_start;
 
@@ -2299,13 +2259,11 @@ parse_operands (l, mnemonic)
 }
 
 static void
-swap_imm_operands ()
+swap_2_operands (int xchg1, int xchg2)
 {
   union i386_op temp_op;
   unsigned int temp_type;
   enum bfd_reloc_code_real temp_reloc;
-  int xchg1 = 0;
-  int xchg2 = 1;
   
   temp_type = i.types[xchg2];
   i.types[xchg2] = i.types[xchg1];
@@ -2318,55 +2276,20 @@ swap_imm_operands ()
   i.reloc[xchg1] = temp_reloc;
 }
 
-
 static void
-swap_operands ()
+swap_operands (void)
 {
-  union i386_op temp_op;
-  unsigned int temp_type;
-  enum bfd_reloc_code_real temp_reloc;
-  int xchg1 = 0;
-  int xchg2 = 0;
-
-  if (i.operands == 4)
-    /* There will be two exchanges in a 4 operand instruction.
-       First exchange is the done inside this block.(1st and 4rth operand) 
-       The next exchange is done outside this block.(2nd and 3rd operand) */
-    {
-      xchg1 = 0;
-      xchg2 = 3;
-      temp_type = i.types[xchg2];
-      i.types[xchg2] = i.types[xchg1];
-      i.types[xchg1] = temp_type;
-      temp_op = i.op[xchg2];
-      i.op[xchg2] = i.op[xchg1];
-      i.op[xchg1] = temp_op;
-      temp_reloc = i.reloc[xchg2];
-      i.reloc[xchg2] = i.reloc[xchg1];
-      i.reloc[xchg1] = temp_reloc;
-      xchg1 = 1;
-      xchg2 = 2;
-    }
-
-  if (i.operands == 2)
-    {
-      xchg1 = 0;
-      xchg2 = 1;
-    }
-  else if (i.operands == 3)
+  switch (i.operands)
     {
-      xchg1 = 0;
-      xchg2 = 2;
+    case 4:
+      swap_2_operands (1, i.operands - 2);
+    case 3:
+    case 2:
+      swap_2_operands (0, i.operands - 1);
+      break;
+    default:
+      abort ();
     }
-  temp_type = i.types[xchg2];
-  i.types[xchg2] = i.types[xchg1];
-  i.types[xchg1] = temp_type;
-  temp_op = i.op[xchg2];
-  i.op[xchg2] = i.op[xchg1];
-  i.op[xchg1] = temp_op;
-  temp_reloc = i.reloc[xchg2];
-  i.reloc[xchg2] = i.reloc[xchg1];
-  i.reloc[xchg1] = temp_reloc;
 
   if (i.mem_operands == 2)
     {
@@ -2380,7 +2303,7 @@ swap_operands ()
 /* Try to ensure constant immediates are represented in the smallest
    opcode possible.  */
 static void
-optimize_imm ()
+optimize_imm (void)
 {
   char guess_suffix = 0;
   int op;
@@ -2500,7 +2423,7 @@ optimize_imm ()
 
 /* Try to use the smallest displacement type too.  */
 static void
-optimize_disp ()
+optimize_disp (void)
 {
   int op;
 
@@ -2564,15 +2487,20 @@ optimize_disp ()
 }
 
 static int
-match_template ()
+match_template (void)
 {
   /* Points to template once we've found it.  */
   const template *t;
-  unsigned int overlap0, overlap1, overlap2;
+  unsigned int overlap0, overlap1, overlap2, overlap3;
   unsigned int found_reverse_match;
   int suffix_check;
-  unsigned int operand_types [3];
+  unsigned int operand_types [MAX_OPERANDS];
   int addr_prefix_disp;
+  unsigned int j;
+
+#if MAX_OPERANDS != 4
+# error "MAX_OPERANDS must be 4."
+#endif
 
 #define MATCH(overlap, given, template)                                \
   ((overlap & ~JumpAbsolute)                                   \
@@ -2590,10 +2518,10 @@ match_template ()
   overlap0 = 0;
   overlap1 = 0;
   overlap2 = 0;
+  overlap3 = 0;
   found_reverse_match = 0;
-  operand_types [0] = 0;
-  operand_types [1] = 0;
-  operand_types [2] = 0;
+  for (j = 0; j < MAX_OPERANDS; j++)
+    operand_types [j] = 0;
   addr_prefix_disp = -1;
   suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
                  ? No_bSuf
@@ -2622,9 +2550,8 @@ match_template ()
               && (t->opcode_modifier & IgnoreSize)))
        continue;
 
-      operand_types [0] = t->operand_types [0];
-      operand_types [1] = t->operand_types [1];
-      operand_types [2] = t->operand_types [2];
+      for (j = 0; j < MAX_OPERANDS; j++)
+       operand_types [j] = t->operand_types [j];
 
       /* In general, don't allow 64-bit operands in 32-bit mode.  */
       if (i.suffix == QWORD_MNEM_SUFFIX
@@ -2652,7 +2579,7 @@ match_template ()
         into Disp32/Disp16/Disp32 operand.  */
       if (i.prefix[ADDR_PREFIX] != 0)
          {
-           unsigned int j, DispOn = 0, DispOff = 0;
+           unsigned int DispOn = 0, DispOff = 0;
 
            switch (flag_code)
            {
@@ -2670,7 +2597,7 @@ match_template ()
              break;
            }
 
-           for (j = 0; j < 3; j++)
+           for (j = 0; j < MAX_OPERANDS; j++)
              {
                /* There should be only one Disp operand.  */
                if ((operand_types[j] & DispOff))
@@ -2692,6 +2619,7 @@ match_template ()
          break;
        case 2:
        case 3:
+       case 4:
          overlap1 = i.types[1] & operand_types[1];
          if (!MATCH (overlap0, i.types[0], operand_types[0])
              || !MATCH (overlap1, i.types[1], operand_types[1])
@@ -2726,23 +2654,46 @@ match_template ()
                 we've found.  */
              found_reverse_match = t->opcode_modifier & (D | FloatDR);
            }
-         /* Found a forward 2 operand match here.  */
-         else if (t->operands == 3)
+         else
            {
-             /* Here we make use of the fact that there are no
-                reverse match 3 operand instructions, and all 3
-                operand instructions only need to be checked for
-                register consistency between operands 2 and 3.  */
-             overlap2 = i.types[2] & operand_types[2];
-             if (!MATCH (overlap2, i.types[2], operand_types[2])
-                 || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
-                                                operand_types[1],
-                                                overlap2, i.types[2],
-                                                operand_types[2]))
+             /* Found a forward 2 operand match here.  */
+             switch (t->operands)
+               {
+               case 4:
+                 overlap3 = i.types[3] & operand_types[3];
+               case 3:
+                 overlap2 = i.types[2] & operand_types[2];
+                 break;
+               }
 
-               continue;
+             switch (t->operands)
+               {
+               case 4:
+                 if (!MATCH (overlap3, i.types[3], operand_types[3])
+                     || !CONSISTENT_REGISTER_MATCH (overlap2,
+                                                    i.types[2],
+                                                    operand_types[2],
+                                                    overlap3,
+                                                    i.types[3],
+                                                    operand_types[3]))
+                   continue;
+               case 3:
+                 /* Here we make use of the fact that there are no
+                    reverse match 3 operand instructions, and all 3
+                    operand instructions only need to be checked for
+                    register consistency between operands 2 and 3.  */
+                 if (!MATCH (overlap2, i.types[2], operand_types[2])
+                     || !CONSISTENT_REGISTER_MATCH (overlap1,
+                                                    i.types[1],
+                                                    operand_types[1],
+                                                    overlap2,
+                                                    i.types[2],
+                                                    operand_types[2]))
+                   continue;
+                 break;
+               }
            }
-         /* Found either forward/reverse 2 or 3 operand match here:
+         /* Found either forward/reverse 2, 3 or 4 operand match here:
             slip through to break.  */
        }
       if (t->cpu_flags & ~cpu_arch_flags)
@@ -2803,7 +2754,7 @@ match_template ()
 }
 
 static int
-check_string ()
+check_string (void)
 {
   int mem_op = (i.types[0] & AnyMem) ? 0 : 1;
   if ((i.tm.operand_types[mem_op] & EsSeg) != 0)
@@ -3054,8 +3005,8 @@ check_byte_reg (void)
          if (flag_code == CODE_64BIT
              && (i.tm.operand_types[op] & InOutPortReg) == 0)
            {
-             as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
-                     i.op[op].regs->reg_name,
+             as_bad (_("Incorrect register `%s%s' used with `%c' suffix"),
+                     register_prefix, i.op[op].regs->reg_name,
                      i.suffix);
              return 0;
            }
@@ -3088,7 +3039,7 @@ check_byte_reg (void)
 }
 
 static int
-check_long_reg ()
+check_long_reg (void)
 {
   int op;
 
@@ -3113,8 +3064,8 @@ check_long_reg ()
           lowering is more complicated.  */
        if (flag_code == CODE_64BIT)
          {
-           as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
-                   i.op[op].regs->reg_name,
+           as_bad (_("Incorrect register `%s%s' used with `%c' suffix"),
+                   register_prefix, i.op[op].regs->reg_name,
                    i.suffix);
            return 0;
          }
@@ -3130,8 +3081,8 @@ check_long_reg ()
     else if ((i.types[op] & Reg64) != 0
             && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0)
       {
-       as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
-               i.op[op].regs->reg_name,
+       as_bad (_("Incorrect register `%s%s' used with `%c' suffix"),
+               register_prefix, i.op[op].regs->reg_name,
                i.suffix);
        return 0;
       }
@@ -3139,7 +3090,7 @@ check_long_reg ()
 }
 
 static int
-check_qword_reg ()
+check_qword_reg (void)
 {
   int op;
 
@@ -3162,8 +3113,8 @@ check_qword_reg ()
       {
        /* Prohibit these changes in the 64bit mode, since the
           lowering is more complicated.  */
-       as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
-               i.op[op].regs->reg_name,
+       as_bad (_("Incorrect register `%s%s' used with `%c' suffix"),
+               register_prefix, i.op[op].regs->reg_name,
                i.suffix);
        return 0;
       }
@@ -3171,7 +3122,7 @@ check_qword_reg ()
 }
 
 static int
-check_word_reg ()
+check_word_reg (void)
 {
   int op;
   for (op = i.operands; --op >= 0;)
@@ -3195,8 +3146,8 @@ check_word_reg ()
           lowering is more complicated.  */
        if (flag_code == CODE_64BIT)
          {
-           as_bad (_("Incorrect register `%%%s' used with `%c' suffix"),
-                   i.op[op].regs->reg_name,
+           as_bad (_("Incorrect register `%s%s' used with `%c' suffix"),
+                   register_prefix, i.op[op].regs->reg_name,
                    i.suffix);
            return 0;
          }
@@ -3212,7 +3163,7 @@ check_word_reg ()
 }
 
 static int
-finalize_imm ()
+finalize_imm (void)
 {
   unsigned int overlap0, overlap1, overlap2;
 
@@ -3290,7 +3241,7 @@ finalize_imm ()
 }
 
 static int
-process_operands ()
+process_operands (void)
 {
   /* Default segment register this instruction will use for memory
      accesses.  0 means unknown.  This is only for optimizing out
@@ -3304,10 +3255,12 @@ process_operands ()
     {
       unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
       /* Pretend we saw the extra register operand.  */
-      assert (i.op[first_reg_op + 1].regs == 0);
+      assert (i.reg_operands == 1
+             && i.op[first_reg_op + 1].regs == 0);
       i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
       i.types[first_reg_op + 1] = i.types[first_reg_op];
-      i.reg_operands = 2;
+      i.operands++;
+      i.reg_operands++;
     }
 
   if (i.tm.opcode_modifier & ShortForm)
@@ -3387,7 +3340,7 @@ process_operands ()
 }
 
 static const seg_entry *
-build_modrm_byte ()
+build_modrm_byte (void)
 {
   const seg_entry *default_seg = 0;
 
@@ -3396,15 +3349,33 @@ build_modrm_byte ()
   if (i.reg_operands == 2)
     {
       unsigned int source, dest;
-      source = ((i.types[0]
-                & (Reg | RegMMX | RegXMM
-                   | SReg2 | SReg3
-                   | Control | Debug | Test))
-               ? 0 : 1);
-
-      /* In 4 operands instructions with 2 immediate operands, the first two are immediate
-        bytes and hence source operand will be in the next byte after the immediates */
-      if ((i.operands == 4)&&(i.imm_operands=2)) source++; 
+
+      switch (i.operands)
+       {
+       case 2:
+         source = 0;
+         break;
+       case 3:
+         /* When there are 3 operands, one of them may be immediate,
+            which may be the first or the last operand.  Otherwise,
+            the first operand must be shift count register (cl). */
+         assert (i.imm_operands == 1
+                 || (i.imm_operands == 0
+                     && (i.types[0] & ShiftCount)));
+         source = (i.types[0] & (Imm | ShiftCount)) ? 1 : 0;
+         break;
+       case 4:
+         /* When there are 4 operands, the first two must be immediate
+            operands. The source operand will be the 3rd one.  */
+         assert (i.imm_operands == 2
+                 && (i.types[0] & Imm)
+                 && (i.types[1] & Imm));
+         source = 2;
+         break;
+       default:
+         abort ();
+       }
+
       dest = source + 1;
 
       i.rm.mode = 3;
@@ -3445,9 +3416,12 @@ build_modrm_byte ()
       if (i.mem_operands)
        {
          unsigned int fake_zero_displacement = 0;
-         unsigned int op = ((i.types[0] & AnyMem)
-                            ? 0
-                            : (i.types[1] & AnyMem) ? 1 : 2);
+         unsigned int op;
+         
+         for (op = 0; op < i.operands; op++)
+           if ((i.types[op] & AnyMem))
+             break;
+         assert (op < i.operands);
 
          default_seg = &ds;
 
@@ -3468,9 +3442,11 @@ build_modrm_byte ()
                      i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
                      i.sib.base = NO_BASE_REGISTER;
                      i.sib.index = NO_INDEX_REGISTER;
-                     i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) ? Disp32S : Disp32);
+                     i.types[op] = ((i.prefix[ADDR_PREFIX] == 0)
+                                    ? Disp32S : Disp32);
                    }
-                 else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
+                 else if ((flag_code == CODE_16BIT)
+                          ^ (i.prefix[ADDR_PREFIX] != 0))
                    {
                      i.rm.regmem = NO_BASE_REGISTER_16;
                      i.types[op] = Disp16;
@@ -3502,7 +3478,7 @@ build_modrm_byte ()
              i.rm.regmem = NO_BASE_REGISTER;
              i.types[op] &= ~ Disp;
              i.types[op] |= Disp32S;
-             i.flags[op] = Operand_PCrel;
+             i.flags[op] |= Operand_PCrel;
              if (! i.disp_operands)
                fake_zero_displacement = 1;
            }
@@ -3540,7 +3516,9 @@ build_modrm_byte ()
            {
              if (flag_code == CODE_64BIT
                  && (i.types[op] & Disp))
-               i.types[op] = (i.types[op] & Disp8) | (i.prefix[ADDR_PREFIX] == 0 ? Disp32S : Disp32);
+               i.types[op] = ((i.types[op] & Disp8)
+                              | (i.prefix[ADDR_PREFIX] == 0
+                                 ? Disp32S : Disp32));
 
              i.rm.regmem = i.base_reg->reg_num;
              if ((i.base_reg->reg_flags & RegRex) != 0)
@@ -3614,18 +3592,15 @@ build_modrm_byte ()
         registers are coded into the i.rm.reg field.  */
       if (i.reg_operands)
        {
-         unsigned int op =
-           ((i.types[0]
-             & (Reg | RegMMX | RegXMM
-                | SReg2 | SReg3
-                | Control | Debug | Test))
-            ? 0
-            : ((i.types[1]
-                & (Reg | RegMMX | RegXMM
-                   | SReg2 | SReg3
-                   | Control | Debug | Test))
-               ? 1
-               : 2));
+         unsigned int op;
+
+         for (op = 0; op < i.operands; op++)
+           if ((i.types[op] & (Reg | RegMMX | RegXMM
+                               | SReg2 | SReg3
+                               | Control | Debug | Test)))
+             break;
+         assert (op < i.operands);
+
          /* If there is an extension opcode to put here, the register
             number must be put into the regmem field.  */
          if (i.tm.extension_opcode != None)
@@ -3656,7 +3631,7 @@ build_modrm_byte ()
 }
 
 static void
-output_branch ()
+output_branch (void)
 {
   char *p;
   int code16;
@@ -3734,7 +3709,7 @@ output_branch ()
 }
 
 static void
-output_jump ()
+output_jump (void)
 {
   char *p;
   int size;
@@ -3800,7 +3775,7 @@ output_jump ()
 }
 
 static void
-output_interseg_jump ()
+output_interseg_jump (void)
 {
   char *p;
   int size;
@@ -3864,7 +3839,7 @@ output_interseg_jump ()
 }
 
 static void
-output_insn ()
+output_insn (void)
 {
   fragS *insn_start_frag;
   offsetT insn_start_off;
@@ -4257,9 +4232,7 @@ static enum bfd_reloc_code_real got_reloc = NO_RELOC;
 static int cons_sign = -1;
 
 void
-x86_cons_fix_new (fragS *frag,
-                 unsigned int off,
-                 unsigned int len,
+x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
                  expressionS *exp)
 {
   enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, got_reloc);
@@ -4394,9 +4367,7 @@ lex_got (enum bfd_reloc_code_real *reloc,
 }
 
 void
-x86_cons (exp, size)
-     expressionS *exp;
-     int size;
+x86_cons (expressionS *exp, int size)
 {
   if (size == 4 || (object_64bit && size == 8))
     {
@@ -4458,11 +4429,8 @@ pe_directive_secrel (dummy)
 }
 #endif
 
-static int i386_immediate PARAMS ((char *));
-
 static int
-i386_immediate (imm_start)
-     char *imm_start;
+i386_immediate (char *imm_start)
 {
   char *save_input_line_pointer;
   char *gotfree_input_line;
@@ -4472,7 +4440,8 @@ i386_immediate (imm_start)
 
   if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
     {
-      as_bad (_("only 1 or 2 immediate operands are allowed"));
+      as_bad (_("at most %d immediate operands are allowed"),
+             MAX_IMMEDIATE_OPERANDS);
       return 0;
     }
 
@@ -4548,11 +4517,8 @@ i386_immediate (imm_start)
   return 1;
 }
 
-static char *i386_scale PARAMS ((char *));
-
 static char *
-i386_scale (scale)
-     char *scale;
+i386_scale (char *scale)
 {
   offsetT val;
   char *save = input_line_pointer;
@@ -4599,12 +4565,8 @@ i386_scale (scale)
   return scale;
 }
 
-static int i386_displacement PARAMS ((char *, char *));
-
 static int
-i386_displacement (disp_start, disp_end)
-     char *disp_start;
-     char *disp_end;
+i386_displacement (char *disp_start, char *disp_end)
 {
   expressionS *exp;
   segT exp_seg = 0;
@@ -4613,6 +4575,13 @@ i386_displacement (disp_start, disp_end)
   int bigdisp, override;
   unsigned int types = Disp;
 
+  if (i.disp_operands == MAX_MEMORY_OPERANDS)
+    {
+      as_bad (_("at most %d displacement operands are allowed"),
+             MAX_MEMORY_OPERANDS);
+      return 0;
+    }
+
   if ((i.types[this_operand] & JumpAbsolute)
       || !(current_templates->start->opcode_modifier & (Jump | JumpDword)))
     {
@@ -4779,14 +4748,11 @@ i386_displacement (disp_start, disp_end)
   return 1;
 }
 
-static int i386_index_check PARAMS ((const char *));
-
 /* Make sure the memory operand we've been dealt is valid.
    Return 1 on success, 0 on a failure.  */
 
 static int
-i386_index_check (operand_string)
-     const char *operand_string;
+i386_index_check (const char *operand_string)
 {
   int ok;
 #if INFER_ADDR_PREFIX
@@ -4892,8 +4858,7 @@ i386_index_check (operand_string)
    on error.  */
 
 static int
-i386_operand (operand_string)
-     char *operand_string;
+i386_operand (char *operand_string)
 {
   const reg_entry *r;
   char *end_op;
@@ -5658,8 +5623,7 @@ md_atof (type, litP, sizeP)
 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
 
 static char *
-output_invalid (c)
-     int c;
+output_invalid (int c)
 {
   if (ISPRINT (c))
     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
@@ -5979,6 +5943,10 @@ md_show_usage (stream)
   fprintf (stream, _("\
   -s                      ignored\n"));
 #endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
+  fprintf (stream, _("\
+  --32/--64               generate 32bit/64bit code\n"));
+#endif
 #ifdef SVR4_COMMENT_CHARS
   fprintf (stream, _("\
   --divide                do not treat `/' as a comment character\n"));
@@ -6019,7 +5987,7 @@ x86_64_target_format (void)
 /* Pick the target format to use.  */
 
 const char *
-i386_target_format ()
+i386_target_format (void)
 {
   if (!strcmp (default_arch, "x86_64"))
     {
@@ -6073,7 +6041,8 @@ i386_target_format ()
 #endif /* OBJ_MAYBE_ more than one  */
 
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
-void i386_elf_emit_arch_note ()
+void
+i386_elf_emit_arch_note (void)
 {
   if (IS_ELF && cpu_arch_name != NULL)
     {
@@ -6164,8 +6133,7 @@ md_section_align (segment, size)
    size, since the offset is always the last part of the insn.  */
 
 long
-md_pcrel_from (fixP)
-     fixS *fixP;
+md_pcrel_from (fixS *fixP)
 {
   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
 }
@@ -6173,8 +6141,7 @@ md_pcrel_from (fixP)
 #ifndef I386COFF
 
 static void
-s_bss (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_bss (int ignore ATTRIBUTE_UNUSED)
 {
   int temp;
 
@@ -6190,8 +6157,7 @@ s_bss (ignore)
 #endif
 
 void
-i386_validate_fix (fixp)
-     fixS *fixp;
+i386_validate_fix (fixS *fixp)
 {
   if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol)
     {
@@ -6580,22 +6546,19 @@ static struct intel_token cur_token, prev_token;
 #define T_SHR          15
 
 /* Prototypes for intel parser functions.  */
-static int intel_match_token   PARAMS ((int code));
-static void intel_get_token    PARAMS ((void));
-static void intel_putback_token        PARAMS ((void));
-static int intel_expr          PARAMS ((void));
-static int intel_e04           PARAMS ((void));
-static int intel_e05           PARAMS ((void));
-static int intel_e06           PARAMS ((void));
-static int intel_e09           PARAMS ((void));
-static int intel_bracket_expr  PARAMS ((void));
-static int intel_e10           PARAMS ((void));
-static int intel_e11           PARAMS ((void));
+static int intel_match_token (int);
+static void intel_putback_token        (void);
+static void intel_get_token (void);
+static int intel_expr (void);
+static int intel_e04 (void);
+static int intel_e05 (void);
+static int intel_e06 (void);
+static int intel_e09 (void);
+static int intel_e10 (void);
+static int intel_e11 (void);
 
 static int
-i386_intel_operand (operand_string, got_a_float)
-     char *operand_string;
-     int got_a_float;
+i386_intel_operand (char *operand_string, int got_a_float)
 {
   int ret;
   char *p;
@@ -6705,7 +6668,7 @@ i386_intel_operand (operand_string, got_a_float)
    expr'  cmpOp e04 expr'
        | Empty  */
 static int
-intel_expr ()
+intel_expr (void)
 {
   /* XXX Implement the comparison operators.  */
   return intel_e04 ();
@@ -6716,7 +6679,7 @@ intel_expr ()
    e04'        addOp e05 e04'
        | Empty  */
 static int
-intel_e04 ()
+intel_e04 (void)
 {
   int nregs = -1;
 
@@ -6745,7 +6708,7 @@ intel_e04 ()
    e05'        binOp e06 e05'
        | Empty  */
 static int
-intel_e05 ()
+intel_e05 (void)
 {
   int nregs = ~NUM_ADDRESS_REGS;
 
@@ -6780,7 +6743,7 @@ intel_e05 ()
    e06'        mulOp e09 e06'
        | Empty  */
 static int
-intel_e06 ()
+intel_e06 (void)
 {
   int nregs = ~NUM_ADDRESS_REGS;
 
@@ -6826,7 +6789,7 @@ intel_e06 ()
        | : e10 e09'
        | Empty */
 static int
-intel_e09 ()
+intel_e09 (void)
 {
   int nregs = ~NUM_ADDRESS_REGS;
   int in_offset = 0;
@@ -7040,7 +7003,7 @@ intel_e09 ()
 }
 
 static int
-intel_bracket_expr ()
+intel_bracket_expr (void)
 {
   int was_offset = intel_parser.op_modifier & (1 << T_OFFSET);
   const char *start = intel_parser.op_string;
@@ -7116,7 +7079,7 @@ intel_bracket_expr ()
    e10'        [ expr ] e10'
        | Empty  */
 static int
-intel_e10 ()
+intel_e10 (void)
 {
   if (!intel_e11 ())
     return 0;
@@ -7146,7 +7109,7 @@ intel_e10 ()
        | id
        | constant  */
 static int
-intel_e11 ()
+intel_e11 (void)
 {
   switch (cur_token.code)
     {
@@ -7447,8 +7410,7 @@ intel_e11 ()
 /* Match the given token against cur_token. If they match, read the next
    token from the operand string.  */
 static int
-intel_match_token (code)
-     int code;
+intel_match_token (int code)
 {
   if (cur_token.code == code)
     {
@@ -7464,7 +7426,7 @@ intel_match_token (code)
 
 /* Read a new token from intel_parser.op_string and store it in cur_token.  */
 static void
-intel_get_token ()
+intel_get_token (void)
 {
   char *end_op;
   const reg_entry *reg;
@@ -7649,7 +7611,7 @@ intel_get_token ()
 /* Put cur_token back into the token stream and make cur_token point to
    prev_token.  */
 static void
-intel_putback_token ()
+intel_putback_token (void)
 {
   if (cur_token.code != T_NIL)
     {
This page took 0.038241 seconds and 4 git commands to generate.