1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/linux_x86/vm/linux_x86_64.ad Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,173 @@ 1.4 +// 1.5 +// Copyright 2003-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 +// AMD64 Linux Architecture Description File 1.29 + 1.30 +//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- 1.31 +// This block specifies the encoding classes used by the compiler to 1.32 +// output byte streams. Encoding classes generate functions which are 1.33 +// called by Machine Instruction Nodes in order to generate the bit 1.34 +// encoding of the instruction. Operands specify their base encoding 1.35 +// interface with the interface keyword. There are currently 1.36 +// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1.37 +// COND_INTER. REG_INTER causes an operand to generate a function 1.38 +// which returns its register number when queried. CONST_INTER causes 1.39 +// an operand to generate a function which returns the value of the 1.40 +// constant when queried. MEMORY_INTER causes an operand to generate 1.41 +// four functions which return the Base Register, the Index Register, 1.42 +// the Scale Value, and the Offset Value of the operand when queried. 1.43 +// COND_INTER causes an operand to generate six functions which return 1.44 +// the encoding code (ie - encoding bits for the instruction) 1.45 +// associated with each basic boolean condition for a conditional 1.46 +// instruction. Instructions specify two basic values for encoding. 1.47 +// They use the ins_encode keyword to specify their encoding class 1.48 +// (which must be one of the class names specified in the encoding 1.49 +// block), and they use the opcode keyword to specify, in order, their 1.50 +// primary, secondary, and tertiary opcode. Only the opcode sections 1.51 +// which a particular instruction needs for encoding need to be 1.52 +// specified. 1.53 +encode %{ 1.54 + // Build emit functions for each basic byte or larger field in the intel 1.55 + // encoding scheme (opcode, rm, sib, immediate), and call them from C++ 1.56 + // code in the enc_class source block. Emit functions will live in the 1.57 + // main source block for now. In future, we can generalize this by 1.58 + // adding a syntax that specifies the sizes of fields in an order, 1.59 + // so that the adlc can build the emit functions automagically 1.60 + 1.61 + enc_class Java_To_Runtime(method meth) 1.62 + %{ 1.63 + // No relocation needed 1.64 + 1.65 + // movq r10, <meth> 1.66 + emit_opcode(cbuf, Assembler::REX_WB); 1.67 + emit_opcode(cbuf, 0xB8 | (R10_enc - 8)); 1.68 + emit_d64(cbuf, (int64_t) $meth$$method); 1.69 + 1.70 + // call (r10) 1.71 + emit_opcode(cbuf, Assembler::REX_B); 1.72 + emit_opcode(cbuf, 0xFF); 1.73 + emit_opcode(cbuf, 0xD0 | (R10_enc - 8)); 1.74 + %} 1.75 + 1.76 + enc_class linux_breakpoint 1.77 + %{ 1.78 + MacroAssembler* masm = new MacroAssembler(&cbuf); 1.79 + masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); 1.80 + %} 1.81 + 1.82 + enc_class call_epilog 1.83 + %{ 1.84 + if (VerifyStackAtCalls) { 1.85 + // Check that stack depth is unchanged: find majik cookie on stack 1.86 + int framesize = 1.87 + ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word)); 1.88 + if (framesize) { 1.89 + if (framesize < 0x80) { 1.90 + emit_opcode(cbuf, Assembler::REX_W); 1.91 + emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood 1.92 + emit_d8(cbuf, 0x7C); 1.93 + emit_d8(cbuf, 0x24); 1.94 + emit_d8(cbuf, framesize); // Find majik cookie from ESP 1.95 + emit_d32(cbuf, 0xbadb100d); 1.96 + } else { 1.97 + emit_opcode(cbuf, Assembler::REX_W); 1.98 + emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood 1.99 + emit_d8(cbuf, 0xBC); 1.100 + emit_d8(cbuf, 0x24); 1.101 + emit_d32(cbuf, framesize); // Find majik cookie from ESP 1.102 + emit_d32(cbuf, 0xbadb100d); 1.103 + } 1.104 + } 1.105 + // jmp EQ around INT3 1.106 + // QQQ TODO 1.107 + const int jump_around = 5; // size of call to breakpoint, 1 for CC 1.108 + emit_opcode(cbuf, 0x74); 1.109 + emit_d8(cbuf, jump_around); 1.110 + // QQQ temporary 1.111 + emit_break(cbuf); 1.112 + // Die if stack mismatch 1.113 + // emit_opcode(cbuf,0xCC); 1.114 + } 1.115 + %} 1.116 + 1.117 +%} 1.118 + 1.119 +// INSTRUCTIONS -- Platform dependent 1.120 + 1.121 +//----------OS and Locking Instructions---------------------------------------- 1.122 + 1.123 +// This name is KNOWN by the ADLC and cannot be changed. 1.124 +// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 1.125 +// for this guy. 1.126 +instruct tlsLoadP(r15_RegP dst) 1.127 +%{ 1.128 + match(Set dst (ThreadLocal)); 1.129 + effect(DEF dst); 1.130 + 1.131 + size(0); 1.132 + format %{ "# TLS is in R15" %} 1.133 + ins_encode( /*empty encoding*/ ); 1.134 + ins_pipe(ialu_reg_reg); 1.135 +%} 1.136 + 1.137 +// Die now 1.138 +instruct ShouldNotReachHere() 1.139 +%{ 1.140 + match(Halt); 1.141 + 1.142 + // Use the following format syntax 1.143 + format %{ "int3\t# ShouldNotReachHere" %} 1.144 + // QQQ TODO for now call breakpoint 1.145 + // opcode(0xCC); 1.146 + // ins_encode(Opc); 1.147 + ins_encode(linux_breakpoint); 1.148 + ins_pipe(pipe_slow); 1.149 +%} 1.150 + 1.151 + 1.152 +// Platform dependent source 1.153 + 1.154 +source 1.155 +%{ 1.156 + 1.157 +int MachCallRuntimeNode::ret_addr_offset() { 1.158 + return 13; // movq r10,#addr; callq (r10) 1.159 +} 1.160 + 1.161 +// emit an interrupt that is caught by the debugger 1.162 +void emit_break(CodeBuffer& cbuf) { 1.163 + // Debugger doesn't really catch this but best we can do so far QQQ 1.164 + MacroAssembler* masm = new MacroAssembler(&cbuf); 1.165 + masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); 1.166 +} 1.167 + 1.168 +void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1.169 + emit_break(cbuf); 1.170 +} 1.171 + 1.172 +uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const { 1.173 + return 5; 1.174 +} 1.175 + 1.176 +%}