Handle indirect branches for AMD64 and Intel64
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index b0ade382f8e14b638ea4e82e86521c1a155b7f84..da20d36204b2d6ed64bef8096344be5b2b3e01d8 100644 (file)
@@ -258,7 +258,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Edw { OP_E, dw_mode }
 #define Edqd { OP_E, dqd_mode }
 #define Eq { OP_E, q_mode }
-#define indirEv { OP_indirE, stack_v_mode }
+#define indirEv { OP_indirE, indir_v_mode }
 #define indirEp { OP_indirE, f_mode }
 #define stackEv { OP_E, stack_v_mode }
 #define Em { OP_E, m_mode }
@@ -561,6 +561,8 @@ enum
   /* 4- or 6-byte pointer operand */
   f_mode,
   const_1_mode,
+  /* v_mode for indirect branch opcodes.  */
+  indir_v_mode,
   /* v_mode for stack-related opcodes.  */
   stack_v_mode,
   /* non-quad operand size depends on prefixes */
@@ -2483,6 +2485,9 @@ struct dis386 {
          suffix_always is true (lcall/ljmp).
    '@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending
          on operand size prefix.
+   '&' => print 'q' in 64bit mode for Intel64 ISA or if instruction
+         has no operand size prefix for AMD64 ISA, behave as 'P'
+         otherwise
 
    2 upper case letter macros:
    "XY" => print 'x' or 'y' if suffix_always is true or no register
@@ -3531,9 +3536,9 @@ static const struct dis386 reg_table[][8] = {
   {
     { "incQ",  { Evh1 }, 0 },
     { "decQ",  { Evh1 }, 0 },
-    { "call{T|}", { indirEv, BND }, 0 },
+    { "call{&|}", { indirEv, BND }, 0 },
     { MOD_TABLE (MOD_FF_REG_3) },
-    { "jmp{T|}", { indirEv, BND }, 0 },
+    { "jmp{&|}", { indirEv, BND }, 0 },
     { MOD_TABLE (MOD_FF_REG_5) },
     { "pushU", { stackEv }, 0 },
     { Bad_Opcode },
@@ -14296,6 +14301,15 @@ case_L:
          if (!(rex & REX_W))
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
+       case '&':
+         if (!intel_syntax
+             && address_mode == mode_64bit
+             && isa64 == intel64)
+           {
+             *obufp++ = 'q';
+             break;
+           }
+         /* Fall through.  */
        case 'T':
          if (!intel_syntax
              && address_mode == mode_64bit
@@ -14816,6 +14830,12 @@ intel_operand_size (int bytemode, int sizeflag)
     case dqw_swap_mode:
       oappend ("WORD PTR ");
       break;
+    case indir_v_mode:
+      if (address_mode == mode_64bit && isa64 == intel64)
+       {
+         oappend ("QWORD PTR ");
+         break;
+       }
     case stack_v_mode:
       if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
@@ -15193,6 +15213,12 @@ OP_E_register (int bytemode, int sizeflag)
     case bnd_mode:
       names = names_bnd;
       break;
+    case indir_v_mode:
+      if (address_mode == mode_64bit && isa64 == intel64)
+       {
+         names = names64;
+         break;
+       }
     case stack_v_mode:
       if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
This page took 0.026638 seconds and 4 git commands to generate.