src/cpu/x86/vm/nativeInst_x86.hpp

changeset 739
dc7f315e41f7
parent 631
d1605aabd0a1
child 749
3a26e9e4be71
     1.1 --- a/src/cpu/x86/vm/nativeInst_x86.hpp	Tue Aug 26 15:49:40 2008 -0700
     1.2 +++ b/src/cpu/x86/vm/nativeInst_x86.hpp	Wed Aug 27 00:21:55 2008 -0700
     1.3 @@ -235,16 +235,15 @@
     1.4    }
     1.5  };
     1.6  
     1.7 -#ifndef AMD64
     1.8 -
     1.9  // An interface for accessing/manipulating native moves of the form:
    1.10 -//      mov[b/w/l] [reg + offset], reg   (instruction_code_reg2mem)
    1.11 -//      mov[b/w/l] reg, [reg+offset]     (instruction_code_mem2reg
    1.12 -//      mov[s/z]x[w/b] [reg + offset], reg
    1.13 +//      mov[b/w/l/q] [reg + offset], reg   (instruction_code_reg2mem)
    1.14 +//      mov[b/w/l/q] reg, [reg+offset]     (instruction_code_mem2reg
    1.15 +//      mov[s/z]x[w/b/q] [reg + offset], reg
    1.16  //      fld_s  [reg+offset]
    1.17  //      fld_d  [reg+offset]
    1.18  //      fstp_s [reg + offset]
    1.19  //      fstp_d [reg + offset]
    1.20 +//      mov_literal64  scratch,<pointer> ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch)
    1.21  //
    1.22  // Warning: These routines must be able to handle any instruction sequences
    1.23  // that are generated as a result of the load/store byte,word,long
    1.24 @@ -255,15 +254,18 @@
    1.25  class NativeMovRegMem: public NativeInstruction {
    1.26   public:
    1.27    enum Intel_specific_constants {
    1.28 +    instruction_prefix_wide_lo          = Assembler::REX,
    1.29 +    instruction_prefix_wide_hi          = Assembler::REX_WRXB,
    1.30      instruction_code_xor                = 0x33,
    1.31      instruction_extended_prefix         = 0x0F,
    1.32 +    instruction_code_mem2reg_movslq     = 0x63,
    1.33      instruction_code_mem2reg_movzxb     = 0xB6,
    1.34      instruction_code_mem2reg_movsxb     = 0xBE,
    1.35      instruction_code_mem2reg_movzxw     = 0xB7,
    1.36      instruction_code_mem2reg_movsxw     = 0xBF,
    1.37      instruction_operandsize_prefix      = 0x66,
    1.38 -    instruction_code_reg2meml           = 0x89,
    1.39 -    instruction_code_mem2regl           = 0x8b,
    1.40 +    instruction_code_reg2mem            = 0x89,
    1.41 +    instruction_code_mem2reg            = 0x8b,
    1.42      instruction_code_reg2memb           = 0x88,
    1.43      instruction_code_mem2regb           = 0x8a,
    1.44      instruction_code_float_s            = 0xd9,
    1.45 @@ -282,73 +284,18 @@
    1.46      next_instruction_offset             = 4
    1.47    };
    1.48  
    1.49 -  address instruction_address() const {
    1.50 -    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix &&
    1.51 -        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
    1.52 -      return addr_at(instruction_offset+1); // Not SSE instructions
    1.53 -    }
    1.54 -    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
    1.55 -      return addr_at(instruction_offset+1);
    1.56 -    }
    1.57 -    else if (*addr_at(instruction_offset) == instruction_code_xor) {
    1.58 -      return addr_at(instruction_offset+2);
    1.59 -    }
    1.60 -    else return addr_at(instruction_offset);
    1.61 -  }
    1.62 +  // helper
    1.63 +  int instruction_start() const;
    1.64  
    1.65 -  address next_instruction_address() const {
    1.66 -    switch (*addr_at(instruction_offset)) {
    1.67 -    case instruction_operandsize_prefix:
    1.68 -      if (*addr_at(instruction_offset+1) == instruction_code_xmm_code)
    1.69 -        return instruction_address() + instruction_size; // SSE instructions
    1.70 -    case instruction_extended_prefix:
    1.71 -      return instruction_address() + instruction_size + 1;
    1.72 -    case instruction_code_reg2meml:
    1.73 -    case instruction_code_mem2regl:
    1.74 -    case instruction_code_reg2memb:
    1.75 -    case instruction_code_mem2regb:
    1.76 -    case instruction_code_xor:
    1.77 -      return instruction_address() + instruction_size + 2;
    1.78 -    default:
    1.79 -      return instruction_address() + instruction_size;
    1.80 -    }
    1.81 -  }
    1.82 -  int   offset() const{
    1.83 -    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix &&
    1.84 -        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
    1.85 -      return int_at(data_offset+1); // Not SSE instructions
    1.86 -    }
    1.87 -    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
    1.88 -      return int_at(data_offset+1);
    1.89 -    }
    1.90 -    else if (*addr_at(instruction_offset) == instruction_code_xor ||
    1.91 -             *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix ||
    1.92 -             *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix ||
    1.93 -             *addr_at(instruction_offset) == instruction_operandsize_prefix) {
    1.94 -      return int_at(data_offset+2);
    1.95 -    }
    1.96 -    else return int_at(data_offset);
    1.97 -  }
    1.98 +  address instruction_address() const;
    1.99  
   1.100 -  void  set_offset(int x) {
   1.101 -    if (*addr_at(instruction_offset)   == instruction_operandsize_prefix &&
   1.102 -        *addr_at(instruction_offset+1) != instruction_code_xmm_code) {
   1.103 -      set_int_at(data_offset+1, x); // Not SSE instructions
   1.104 -    }
   1.105 -    else if (*addr_at(instruction_offset) == instruction_extended_prefix) {
   1.106 -      set_int_at(data_offset+1, x);
   1.107 -    }
   1.108 -    else if (*addr_at(instruction_offset) == instruction_code_xor ||
   1.109 -             *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix ||
   1.110 -             *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix ||
   1.111 -             *addr_at(instruction_offset) == instruction_operandsize_prefix) {
   1.112 -      set_int_at(data_offset+2, x);
   1.113 -    }
   1.114 -    else set_int_at(data_offset, x);
   1.115 -  }
   1.116 +  address next_instruction_address() const;
   1.117 +
   1.118 +  int   offset() const;
   1.119 +
   1.120 +  void  set_offset(int x);
   1.121  
   1.122    void  add_offset_in_bytes(int add_offset)     { set_offset ( ( offset() + add_offset ) ); }
   1.123 -  void  copy_instruction_to(address new_instruction_address);
   1.124  
   1.125    void verify();
   1.126    void print ();
   1.127 @@ -385,9 +332,19 @@
   1.128  //        leal reg, [reg + offset]
   1.129  
   1.130  class NativeLoadAddress: public NativeMovRegMem {
   1.131 +#ifdef AMD64
   1.132 +  static const bool has_rex = true;
   1.133 +  static const int rex_size = 1;
   1.134 +#else
   1.135 +  static const bool has_rex = false;
   1.136 +  static const int rex_size = 0;
   1.137 +#endif // AMD64
   1.138   public:
   1.139    enum Intel_specific_constants {
   1.140 -    instruction_code            = 0x8D
   1.141 +    instruction_prefix_wide             = Assembler::REX_W,
   1.142 +    instruction_prefix_wide_extended    = Assembler::REX_WB,
   1.143 +    lea_instruction_code                = 0x8D,
   1.144 +    mov64_instruction_code              = 0xB8
   1.145    };
   1.146  
   1.147    void verify();
   1.148 @@ -406,8 +363,6 @@
   1.149    }
   1.150  };
   1.151  
   1.152 -#endif // AMD64
   1.153 -
   1.154  // jump rel32off
   1.155  
   1.156  class NativeJump: public NativeInstruction {
   1.157 @@ -424,22 +379,20 @@
   1.158    address next_instruction_address() const  { return addr_at(next_instruction_offset); }
   1.159    address jump_destination() const          {
   1.160       address dest = (int_at(data_offset)+next_instruction_address());
   1.161 -#ifdef AMD64 // What is this about?
   1.162 +     // 32bit used to encode unresolved jmp as jmp -1
   1.163 +     // 64bit can't produce this so it used jump to self.
   1.164 +     // Now 32bit and 64bit use jump to self as the unresolved address
   1.165 +     // which the inline cache code (and relocs) know about
   1.166 +
   1.167       // return -1 if jump to self
   1.168      dest = (dest == (address) this) ? (address) -1 : dest;
   1.169 -#endif // AMD64
   1.170      return dest;
   1.171    }
   1.172  
   1.173    void  set_jump_destination(address dest)  {
   1.174      intptr_t val = dest - next_instruction_address();
   1.175  #ifdef AMD64
   1.176 -    if (dest == (address) -1) { // can't encode jump to -1
   1.177 -      val = -5; // jump to self
   1.178 -    } else {
   1.179 -      assert((labs(val)  & 0xFFFFFFFF00000000) == 0,
   1.180 -             "must be 32bit offset");
   1.181 -    }
   1.182 +    assert((labs(val)  & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1");
   1.183  #endif // AMD64
   1.184      set_int_at(data_offset, (jint)val);
   1.185    }
   1.186 @@ -568,11 +521,15 @@
   1.187                                                            (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
   1.188  inline bool NativeInstruction::is_safepoint_poll() {
   1.189  #ifdef AMD64
   1.190 -  return ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
   1.191 -         ubyte_at(1) == 0x05 && // 00 rax 101
   1.192 -         ((intptr_t) addr_at(6)) + int_at(2) == (intptr_t) os::get_polling_page();
   1.193 +  if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
   1.194 +       ubyte_at(1) == 0x05 ) { // 00 rax 101
   1.195 +     address fault = addr_at(6) + int_at(2);
   1.196 +     return os::is_poll_address(fault);
   1.197 +  } else {
   1.198 +    return false;
   1.199 +  }
   1.200  #else
   1.201 -  return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2regl ||
   1.202 +  return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
   1.203             ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
   1.204             (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */
   1.205             (os::is_poll_address((address)int_at(2)));

mercurial