hotspot/src/cpu/x86/vm/nativeInst_x86.hpp

Print this page
rev 611 : Merge

@@ -1,10 +1,7 @@
-#ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)nativeInst_x86.hpp   1.81 07/09/17 09:28:55 JVM"
-#endif
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -51,10 +48,11 @@
     nop_instruction_code        = 0x90,
     nop_instruction_size        =    1
   };
 
   bool is_nop()                        { return ubyte_at(0) == nop_instruction_code; }
+  bool is_dtrace_trap();
   inline bool is_call();
   inline bool is_illegal();
   inline bool is_return();
   inline bool is_jump();
   inline bool is_cond_jump();

@@ -235,39 +233,41 @@
     #endif
     return test;
   }
 };
 
-#ifndef AMD64
-
 // An interface for accessing/manipulating native moves of the form:
-//      mov[b/w/l] [reg + offset], reg   (instruction_code_reg2mem)
-//      mov[b/w/l] reg, [reg+offset]     (instruction_code_mem2reg
-//      mov[s/z]x[w/b] [reg + offset], reg 
+//      mov[b/w/l/q] [reg + offset], reg   (instruction_code_reg2mem)
+//      mov[b/w/l/q] reg, [reg+offset]     (instruction_code_mem2reg
+//      mov[s/z]x[w/b/q] [reg + offset], reg
 //      fld_s  [reg+offset]
 //      fld_d  [reg+offset]
 //      fstp_s [reg + offset]
 //      fstp_d [reg + offset]
+//      mov_literal64  scratch,<pointer> ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch)
 //
 // Warning: These routines must be able to handle any instruction sequences
 // that are generated as a result of the load/store byte,word,long
 // macros.  For example: The load_unsigned_byte instruction generates
 // an xor reg,reg inst prior to generating the movb instruction.  This
 // class must skip the xor instruction.  
 
 class NativeMovRegMem: public NativeInstruction {
  public:
   enum Intel_specific_constants {
+    instruction_prefix_wide_lo          = Assembler::REX,
+    instruction_prefix_wide_hi          = Assembler::REX_WRXB,
     instruction_code_xor                = 0x33,
     instruction_extended_prefix         = 0x0F,
+    instruction_code_mem2reg_movslq     = 0x63,
     instruction_code_mem2reg_movzxb     = 0xB6,
     instruction_code_mem2reg_movsxb     = 0xBE,
     instruction_code_mem2reg_movzxw     = 0xB7,
     instruction_code_mem2reg_movsxw     = 0xBF,
     instruction_operandsize_prefix      = 0x66,
-    instruction_code_reg2meml           = 0x89,
-    instruction_code_mem2regl           = 0x8b,
+    instruction_code_reg2mem            = 0x89,
+    instruction_code_mem2reg            = 0x8b,
     instruction_code_reg2memb           = 0x88,
     instruction_code_mem2regb           = 0x8a,
     instruction_code_float_s            = 0xd9,
     instruction_code_float_d            = 0xdd,
     instruction_code_long_volatile      = 0xdf,

@@ -282,77 +282,22 @@
     instruction_offset                  = 0,
     data_offset                         = 2,
     next_instruction_offset             = 4
   };
 
-  address instruction_address() const { 
-    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix && 
-        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
-      return addr_at(instruction_offset+1); // Not SSE instructions
-    }
-    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
-      return addr_at(instruction_offset+1);
-    }
-    else if (*addr_at(instruction_offset) == instruction_code_xor) {
-      return addr_at(instruction_offset+2);
-    }
-    else return addr_at(instruction_offset);
-  }
-
-  address next_instruction_address() const {
-    switch (*addr_at(instruction_offset)) {
-    case instruction_operandsize_prefix:
-      if (*addr_at(instruction_offset+1) == instruction_code_xmm_code)
-        return instruction_address() + instruction_size; // SSE instructions
-    case instruction_extended_prefix:
-      return instruction_address() + instruction_size + 1;
-    case instruction_code_reg2meml:
-    case instruction_code_mem2regl:
-    case instruction_code_reg2memb:
-    case instruction_code_mem2regb:
-    case instruction_code_xor:
-      return instruction_address() + instruction_size + 2;
-    default:
-      return instruction_address() + instruction_size;
-    }
-  }
-  int   offset() const{ 
-    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix && 
-        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
-      return int_at(data_offset+1); // Not SSE instructions
-    }
-    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
-      return int_at(data_offset+1); 
-    }
-    else if (*addr_at(instruction_offset) == instruction_code_xor || 
-             *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix ||
-             *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix ||
-             *addr_at(instruction_offset) == instruction_operandsize_prefix) {
-      return int_at(data_offset+2); 
-    }
-    else return int_at(data_offset); 
-  }
-
-  void  set_offset(int x) {
-    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix && 
-        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
-      set_int_at(data_offset+1, x); // Not SSE instructions
-    }
-    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
-      set_int_at(data_offset+1, x); 
-    }
-    else if (*addr_at(instruction_offset) == instruction_code_xor || 
-             *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix ||
-             *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix ||
-             *addr_at(instruction_offset) == instruction_operandsize_prefix) {
-      set_int_at(data_offset+2, x); 
-    }
-    else set_int_at(data_offset, x); 
-  }
+  // helper
+  int instruction_start() const;
+
+  address instruction_address() const;
+
+  address next_instruction_address() const;
+
+  int   offset() const;
+
+  void  set_offset(int x);
 
   void  add_offset_in_bytes(int add_offset)     { set_offset ( ( offset() + add_offset ) ); }
-  void  copy_instruction_to(address new_instruction_address);
 
   void verify();
   void print ();
 
   // unit test stuff

@@ -385,13 +330,23 @@
 
 // An interface for accessing/manipulating native leal instruction of form:
 //        leal reg, [reg + offset]
 
 class NativeLoadAddress: public NativeMovRegMem {
+#ifdef AMD64
+  static const bool has_rex = true;
+  static const int rex_size = 1;
+#else
+  static const bool has_rex = false;
+  static const int rex_size = 0;
+#endif // AMD64
  public:
   enum Intel_specific_constants {
-    instruction_code            = 0x8D
+    instruction_prefix_wide             = Assembler::REX_W,
+    instruction_prefix_wide_extended    = Assembler::REX_WB,
+    lea_instruction_code                = 0x8D,
+    mov64_instruction_code              = 0xB8
   };
 
   void verify();
   void print ();
 

@@ -406,12 +361,10 @@
     #endif
     return test;
   }
 };
 
-#endif // AMD64
-
 // jump rel32off
 
 class NativeJump: public NativeInstruction {
  public:
   enum Intel_specific_constants {

@@ -424,26 +377,27 @@
 
   address instruction_address() const       { return addr_at(instruction_offset); }
   address next_instruction_address() const  { return addr_at(next_instruction_offset); }  
   address jump_destination() const          {
      address dest = (int_at(data_offset)+next_instruction_address());
-#ifdef AMD64 // What is this about?
+     // 32bit used to encode unresolved jmp as jmp -1
+     // 64bit can't produce this so it used jump to self.
+     // Now 32bit and 64bit use jump to self as the unresolved address
+     // which the inline cache code (and relocs) know about
+
      // return -1 if jump to self
     dest = (dest == (address) this) ? (address) -1 : dest;
-#endif // AMD64
     return dest;
   }
 
   void  set_jump_destination(address dest)  {
     intptr_t val = dest - next_instruction_address();
-#ifdef AMD64
-    if (dest == (address) -1) { // can't encode jump to -1
+    if (dest == (address) -1) {
       val = -5; // jump to self
-    } else {
-      assert((labs(val)  & 0xFFFFFFFF00000000) == 0,
-             "must be 32bit offset");
     }
+#ifdef AMD64
+    assert((labs(val)  & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1");
 #endif // AMD64
     set_int_at(data_offset, (jint)val);
   }
 
   // Creation

@@ -568,15 +522,19 @@
                                                           ubyte_at(0) == 0xEB; /* short jump */ }
 inline bool NativeInstruction::is_cond_jump()    { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
                                                           (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
 inline bool NativeInstruction::is_safepoint_poll() {
 #ifdef AMD64
-  return ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-         ubyte_at(1) == 0x05 && // 00 rax 101
-         ((intptr_t) addr_at(6)) + int_at(2) == (intptr_t) os::get_polling_page();
+  if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+       ubyte_at(1) == 0x05 ) { // 00 rax 101
+     address fault = addr_at(6) + int_at(2);
+     return os::is_poll_address(fault);
+  } else {
+    return false;
+  }
 #else
-  return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2regl ||
+  return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
            ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
            (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */
            (os::is_poll_address((address)int_at(2)));
 #endif // AMD64
 }

@@ -587,6 +545,5 @@
           (ubyte_at(1) & (0xff ^ NativeMovConstReg::register_mask)) == 0xB8);
 #else
   return false;
 #endif // AMD64
 }
-