Sat, 01 Dec 2007 00:00:00 +0000
Initial load
duke@435 | 1 | // |
duke@435 | 2 | // Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | // |
duke@435 | 5 | // This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | // under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | // published by the Free Software Foundation. |
duke@435 | 8 | // |
duke@435 | 9 | // This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | // version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | // accompanied this code). |
duke@435 | 14 | // |
duke@435 | 15 | // You should have received a copy of the GNU General Public License version |
duke@435 | 16 | // 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | // |
duke@435 | 19 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | // CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | // have any questions. |
duke@435 | 22 | // |
duke@435 | 23 | // |
duke@435 | 24 | |
duke@435 | 25 | // AMD64 Win32 Architecture Description File |
duke@435 | 26 | |
duke@435 | 27 | //----------OS-DEPENDENT ENCODING BLOCK----------------------------------------------------- |
duke@435 | 28 | // This block specifies the encoding classes used by the compiler to output |
duke@435 | 29 | // byte streams. Encoding classes generate functions which are called by |
duke@435 | 30 | // Machine Instruction Nodes in order to generate the bit encoding of the |
duke@435 | 31 | // instruction. Operands specify their base encoding interface with the |
duke@435 | 32 | // interface keyword. There are currently supported four interfaces, |
duke@435 | 33 | // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an |
duke@435 | 34 | // operand to generate a function which returns its register number when |
duke@435 | 35 | // queried. CONST_INTER causes an operand to generate a function which |
duke@435 | 36 | // returns the value of the constant when queried. MEMORY_INTER causes an |
duke@435 | 37 | // operand to generate four functions which return the Base Register, the |
duke@435 | 38 | // Index Register, the Scale Value, and the Offset Value of the operand when |
duke@435 | 39 | // queried. COND_INTER causes an operand to generate six functions which |
duke@435 | 40 | // return the encoding code (ie - encoding bits for the instruction) |
duke@435 | 41 | // associated with each basic boolean condition for a conditional instruction. |
duke@435 | 42 | // Instructions specify two basic values for encoding. They use the |
duke@435 | 43 | // ins_encode keyword to specify their encoding class (which must be one of |
duke@435 | 44 | // the class names specified in the encoding block), and they use the |
duke@435 | 45 | // opcode keyword to specify, in order, their primary, secondary, and |
duke@435 | 46 | // tertiary opcode. Only the opcode sections which a particular instruction |
duke@435 | 47 | // needs for encoding need to be specified. |
duke@435 | 48 | encode %{ |
duke@435 | 49 | // Build emit functions for each basic byte or larger field in the intel |
duke@435 | 50 | // encoding scheme (opcode, rm, sib, immediate), and call them from C++ |
duke@435 | 51 | // code in the enc_class source block. Emit functions will live in the |
duke@435 | 52 | // main source block for now. In future, we can generalize this by |
duke@435 | 53 | // adding a syntax that specifies the sizes of fields in an order, |
duke@435 | 54 | // so that the adlc can build the emit functions automagically |
duke@435 | 55 | |
duke@435 | 56 | enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime |
duke@435 | 57 | // No relocation needed |
duke@435 | 58 | |
duke@435 | 59 | // movq r10, <meth> |
duke@435 | 60 | emit_opcode(cbuf, Assembler::REX_WB); |
duke@435 | 61 | emit_opcode(cbuf, 0xB8 | (R10_enc - 8)); |
duke@435 | 62 | emit_d64(cbuf, (int64_t) $meth$$method); |
duke@435 | 63 | |
duke@435 | 64 | // call (r10) |
duke@435 | 65 | emit_opcode(cbuf, Assembler::REX_B); |
duke@435 | 66 | emit_opcode(cbuf, 0xFF); |
duke@435 | 67 | emit_opcode(cbuf, 0xD0 | (R10_enc - 8)); |
duke@435 | 68 | %} |
duke@435 | 69 | |
duke@435 | 70 | enc_class call_epilog %{ |
duke@435 | 71 | if (VerifyStackAtCalls) { |
duke@435 | 72 | // Check that stack depth is unchanged: find majik cookie on stack |
duke@435 | 73 | int framesize = |
duke@435 | 74 | ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word)); |
duke@435 | 75 | if (framesize) { |
duke@435 | 76 | if (framesize < 0x80) { |
duke@435 | 77 | emit_opcode(cbuf, Assembler::REX_W); |
duke@435 | 78 | emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood |
duke@435 | 79 | emit_d8(cbuf, 0x7C); |
duke@435 | 80 | emit_d8(cbuf, 0x24); |
duke@435 | 81 | emit_d8(cbuf, framesize); // Find majik cookie from ESP |
duke@435 | 82 | emit_d32(cbuf, 0xbadb100d); |
duke@435 | 83 | } else { |
duke@435 | 84 | emit_opcode(cbuf, Assembler::REX_W); |
duke@435 | 85 | emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood |
duke@435 | 86 | emit_d8(cbuf, 0xBC); |
duke@435 | 87 | emit_d8(cbuf, 0x24); |
duke@435 | 88 | emit_d32(cbuf, framesize); // Find majik cookie from ESP |
duke@435 | 89 | emit_d32(cbuf, 0xbadb100d); |
duke@435 | 90 | } |
duke@435 | 91 | } |
duke@435 | 92 | // jmp EQ around INT3 |
duke@435 | 93 | // QQQ TODO |
duke@435 | 94 | const int jump_around = 5; // size of call to breakpoint, 1 for CC |
duke@435 | 95 | emit_opcode(cbuf, 0x74); |
duke@435 | 96 | emit_d8(cbuf, jump_around); |
duke@435 | 97 | // QQQ temporary |
duke@435 | 98 | emit_break(cbuf); |
duke@435 | 99 | // Die if stack mismatch |
duke@435 | 100 | // emit_opcode(cbuf,0xCC); |
duke@435 | 101 | } |
duke@435 | 102 | %} |
duke@435 | 103 | %} |
duke@435 | 104 | |
duke@435 | 105 | // INSTRUCTIONS -- Platform dependent |
duke@435 | 106 | |
duke@435 | 107 | |
duke@435 | 108 | //----------OS and Locking Instructions---------------------------------------- |
duke@435 | 109 | |
duke@435 | 110 | // This name is KNOWN by the ADLC and cannot be changed. |
duke@435 | 111 | // The ADLC forces a 'TypeRawPtr::BOTTOM' output type |
duke@435 | 112 | // for this guy. |
duke@435 | 113 | instruct tlsLoadP(r15_RegP dst) |
duke@435 | 114 | %{ |
duke@435 | 115 | match(Set dst (ThreadLocal)); |
duke@435 | 116 | effect(DEF dst); |
duke@435 | 117 | |
duke@435 | 118 | size(0); |
duke@435 | 119 | format %{ "# TLS is in R15" %} |
duke@435 | 120 | ins_encode( /*empty encoding*/ ); |
duke@435 | 121 | ins_pipe(ialu_reg_reg); |
duke@435 | 122 | %} |
duke@435 | 123 | |
duke@435 | 124 | // Die now |
duke@435 | 125 | instruct ShouldNotReachHere( ) |
duke@435 | 126 | %{ |
duke@435 | 127 | match(Halt); |
duke@435 | 128 | // Use the following format syntax |
duke@435 | 129 | format %{ "INT3 ; ShouldNotReachHere" %} |
duke@435 | 130 | opcode(0xCC); |
duke@435 | 131 | ins_encode(OpcP); |
duke@435 | 132 | ins_pipe( pipe_slow ); |
duke@435 | 133 | %} |
duke@435 | 134 | |
duke@435 | 135 | // |
duke@435 | 136 | // Platform dependent source |
duke@435 | 137 | // |
duke@435 | 138 | source %{ |
duke@435 | 139 | |
duke@435 | 140 | int MachCallRuntimeNode::ret_addr_offset() |
duke@435 | 141 | { |
duke@435 | 142 | return 13; // movq r10,#addr; callq (r10) |
duke@435 | 143 | } |
duke@435 | 144 | |
duke@435 | 145 | // emit an interrupt that is caught by the debugger |
duke@435 | 146 | void emit_break(CodeBuffer &cbuf) { |
duke@435 | 147 | *(cbuf.code_end()) = (unsigned char)(0xcc); |
duke@435 | 148 | cbuf.set_code_end(cbuf.code_end() + 1); |
duke@435 | 149 | } |
duke@435 | 150 | |
duke@435 | 151 | void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
duke@435 | 152 | emit_break(cbuf); |
duke@435 | 153 | } |
duke@435 | 154 | |
duke@435 | 155 | uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { |
duke@435 | 156 | return 1; |
duke@435 | 157 | } |
duke@435 | 158 | |
duke@435 | 159 | %} |