1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/windows_x86/vm/windows_x86_32.ad Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,158 @@ 1.4 +// 1.5 +// Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 +// 1.8 +// This code is free software; you can redistribute it and/or modify it 1.9 +// under the terms of the GNU General Public License version 2 only, as 1.10 +// published by the Free Software Foundation. 1.11 +// 1.12 +// This code is distributed in the hope that it will be useful, but WITHOUT 1.13 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 +// version 2 for more details (a copy is included in the LICENSE file that 1.16 +// accompanied this code). 1.17 +// 1.18 +// You should have received a copy of the GNU General Public License version 1.19 +// 2 along with this work; if not, write to the Free Software Foundation, 1.20 +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 +// 1.22 +// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 +// CA 95054 USA or visit www.sun.com if you need additional information or 1.24 +// have any questions. 1.25 +// 1.26 +// 1.27 + 1.28 +// X86 Win32 Architecture Description File 1.29 + 1.30 +//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------------------- 1.31 +// This block specifies the encoding classes used by the compiler to output 1.32 +// byte streams. Encoding classes generate functions which are called by 1.33 +// Machine Instruction Nodes in order to generate the bit encoding of the 1.34 +// instruction. Operands specify their base encoding interface with the 1.35 +// interface keyword. There are currently supported four interfaces, 1.36 +// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 1.37 +// operand to generate a function which returns its register number when 1.38 +// queried. CONST_INTER causes an operand to generate a function which 1.39 +// returns the value of the constant when queried. MEMORY_INTER causes an 1.40 +// operand to generate four functions which return the Base Register, the 1.41 +// Index Register, the Scale Value, and the Offset Value of the operand when 1.42 +// queried. COND_INTER causes an operand to generate six functions which 1.43 +// return the encoding code (ie - encoding bits for the instruction) 1.44 +// associated with each basic boolean condition for a conditional instruction. 1.45 +// Instructions specify two basic values for encoding. They use the 1.46 +// ins_encode keyword to specify their encoding class (which must be one of 1.47 +// the class names specified in the encoding block), and they use the 1.48 +// opcode keyword to specify, in order, their primary, secondary, and 1.49 +// tertiary opcode. Only the opcode sections which a particular instruction 1.50 +// needs for encoding need to be specified. 1.51 +encode %{ 1.52 + // Build emit functions for each basic byte or larger field in the intel 1.53 + // encoding scheme (opcode, rm, sib, immediate), and call them from C++ 1.54 + // code in the enc_class source block. Emit functions will live in the 1.55 + // main source block for now. In future, we can generalize this by 1.56 + // adding a syntax that specifies the sizes of fields in an order, 1.57 + // so that the adlc can build the emit functions automagically 1.58 + 1.59 + enc_class tlsencode (eRegP dst, eRegP src) %{ 1.60 + emit_rm(cbuf, 0x2, $dst$$reg, $src$$reg); 1.61 + emit_d32(cbuf, ThreadLocalStorage::get_thread_ptr_offset() ); 1.62 + %} 1.63 + 1.64 + enc_class call_epilog %{ 1.65 + if( VerifyStackAtCalls ) { 1.66 + // Check that stack depth is unchanged: find majik cookie on stack 1.67 + int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word)); 1.68 + if(framesize >= 128) { 1.69 + emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood 1.70 + emit_d8(cbuf,0xBC); 1.71 + emit_d8(cbuf,0x24); 1.72 + emit_d32(cbuf,framesize); // Find majik cookie from ESP 1.73 + emit_d32(cbuf, 0xbadb100d); 1.74 + } 1.75 + else { 1.76 + emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood 1.77 + emit_d8(cbuf,0x7C); 1.78 + emit_d8(cbuf,0x24); 1.79 + emit_d8(cbuf,framesize); // Find majik cookie from ESP 1.80 + emit_d32(cbuf, 0xbadb100d); 1.81 + } 1.82 + // jmp EQ around INT3 1.83 + emit_opcode(cbuf,0x74); 1.84 + emit_d8(cbuf,1); 1.85 + // Die if stack mismatch 1.86 + emit_opcode(cbuf,0xCC); 1.87 + } 1.88 + %} 1.89 + 1.90 +%} 1.91 + 1.92 +// INSTRUCTIONS -- Platform dependent 1.93 + 1.94 + 1.95 +//----------OS and Locking Instructions---------------------------------------- 1.96 + 1.97 +// The prefix of this name is KNOWN by the ADLC and cannot be changed. 1.98 +instruct tlsLoadP_prefixLoadP(eRegP t1) %{ 1.99 + effect(DEF t1); 1.100 + 1.101 + format %{ "MOV $t1,FS:[0x00] "%} 1.102 + opcode(0x8B, 0x64); 1.103 + ins_encode(OpcS, OpcP, conmemref(t1)); 1.104 + ins_pipe( ialu_reg_fat ); 1.105 +%} 1.106 + 1.107 +// This name is KNOWN by the ADLC and cannot be changed. 1.108 +// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 1.109 +// for this guy. 1.110 +// %%% Should do this with a clause like: bottom_type(TypeRawPtr::BOTTOM); 1.111 +instruct tlsLoadP(eRegP dst, eRegP t1) %{ 1.112 + effect(DEF dst, USE t1); 1.113 + 1.114 + format %{ "MOV $dst,[$t1 + TLS::thread_ptr_offset()]" %} 1.115 + opcode(0x8B); 1.116 + ins_encode(OpcP, tlsencode(dst, t1)); 1.117 + ins_pipe( ialu_reg_reg_fat ); 1.118 +%} 1.119 + 1.120 +instruct TLS(eRegP dst) %{ 1.121 + match(Set dst (ThreadLocal)); 1.122 + expand %{ 1.123 + eRegP t1; 1.124 + tlsLoadP_prefixLoadP(t1); 1.125 + tlsLoadP(dst, t1); 1.126 + %} 1.127 +%} 1.128 + 1.129 +// Die now 1.130 +instruct ShouldNotReachHere( ) 1.131 +%{ 1.132 + match(Halt); 1.133 + // Use the following format syntax 1.134 + format %{ "INT3 ; ShouldNotReachHere" %} 1.135 + opcode(0xCC); 1.136 + ins_encode(OpcP); 1.137 + ins_pipe( pipe_slow ); 1.138 +%} 1.139 + 1.140 +// 1.141 +// Platform dependent source 1.142 +// 1.143 +source %{ 1.144 + 1.145 +// emit an interrupt that is caught by the debugger 1.146 +void emit_break(CodeBuffer &cbuf) { 1.147 + *(cbuf.code_end()) = (unsigned char)(0xcc); 1.148 + cbuf.set_code_end(cbuf.code_end() + 1); 1.149 +} 1.150 + 1.151 +void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.152 + emit_break(cbuf); 1.153 +} 1.154 + 1.155 + 1.156 +uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1.157 + return 1; 1.158 +} 1.159 + 1.160 + 1.161 +%}