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)));