Tue, 03 Aug 2010 08:13:38 -0400
6953477: Increase portability and flexibility of building Hotspot
Summary: A collection of portability improvements including shared code support for PPC, ARM platforms, software floating point, cross compilation support and improvements in error crash detail.
Reviewed-by: phh, never, coleenp, dholmes
duke@435 | 1 | // |
trims@1907 | 2 | // Copyright (c) 1999, 2006, Oracle and/or its affiliates. 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 | // |
trims@1907 | 19 | // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | // or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | // questions. |
duke@435 | 22 | // |
duke@435 | 23 | // |
duke@435 | 24 | |
duke@435 | 25 | // X86 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 tlsencode (eRegP dst, eRegP src) %{ |
duke@435 | 57 | emit_rm(cbuf, 0x2, $dst$$reg, $src$$reg); |
duke@435 | 58 | emit_d32(cbuf, ThreadLocalStorage::get_thread_ptr_offset() ); |
duke@435 | 59 | %} |
duke@435 | 60 | |
duke@435 | 61 | enc_class call_epilog %{ |
duke@435 | 62 | if( VerifyStackAtCalls ) { |
duke@435 | 63 | // Check that stack depth is unchanged: find majik cookie on stack |
duke@435 | 64 | int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word)); |
duke@435 | 65 | if(framesize >= 128) { |
duke@435 | 66 | emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood |
duke@435 | 67 | emit_d8(cbuf,0xBC); |
duke@435 | 68 | emit_d8(cbuf,0x24); |
duke@435 | 69 | emit_d32(cbuf,framesize); // Find majik cookie from ESP |
duke@435 | 70 | emit_d32(cbuf, 0xbadb100d); |
duke@435 | 71 | } |
duke@435 | 72 | else { |
duke@435 | 73 | emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood |
duke@435 | 74 | emit_d8(cbuf,0x7C); |
duke@435 | 75 | emit_d8(cbuf,0x24); |
duke@435 | 76 | emit_d8(cbuf,framesize); // Find majik cookie from ESP |
duke@435 | 77 | emit_d32(cbuf, 0xbadb100d); |
duke@435 | 78 | } |
duke@435 | 79 | // jmp EQ around INT3 |
duke@435 | 80 | emit_opcode(cbuf,0x74); |
duke@435 | 81 | emit_d8(cbuf,1); |
duke@435 | 82 | // Die if stack mismatch |
duke@435 | 83 | emit_opcode(cbuf,0xCC); |
duke@435 | 84 | } |
duke@435 | 85 | %} |
duke@435 | 86 | |
duke@435 | 87 | %} |
duke@435 | 88 | |
duke@435 | 89 | // INSTRUCTIONS -- Platform dependent |
duke@435 | 90 | |
duke@435 | 91 | |
duke@435 | 92 | //----------OS and Locking Instructions---------------------------------------- |
duke@435 | 93 | |
duke@435 | 94 | // The prefix of this name is KNOWN by the ADLC and cannot be changed. |
duke@435 | 95 | instruct tlsLoadP_prefixLoadP(eRegP t1) %{ |
duke@435 | 96 | effect(DEF t1); |
duke@435 | 97 | |
duke@435 | 98 | format %{ "MOV $t1,FS:[0x00] "%} |
duke@435 | 99 | opcode(0x8B, 0x64); |
duke@435 | 100 | ins_encode(OpcS, OpcP, conmemref(t1)); |
duke@435 | 101 | ins_pipe( ialu_reg_fat ); |
duke@435 | 102 | %} |
duke@435 | 103 | |
duke@435 | 104 | // This name is KNOWN by the ADLC and cannot be changed. |
duke@435 | 105 | // The ADLC forces a 'TypeRawPtr::BOTTOM' output type |
duke@435 | 106 | // for this guy. |
duke@435 | 107 | // %%% Should do this with a clause like: bottom_type(TypeRawPtr::BOTTOM); |
duke@435 | 108 | instruct tlsLoadP(eRegP dst, eRegP t1) %{ |
duke@435 | 109 | effect(DEF dst, USE t1); |
duke@435 | 110 | |
duke@435 | 111 | format %{ "MOV $dst,[$t1 + TLS::thread_ptr_offset()]" %} |
duke@435 | 112 | opcode(0x8B); |
duke@435 | 113 | ins_encode(OpcP, tlsencode(dst, t1)); |
duke@435 | 114 | ins_pipe( ialu_reg_reg_fat ); |
duke@435 | 115 | %} |
duke@435 | 116 | |
duke@435 | 117 | instruct TLS(eRegP dst) %{ |
duke@435 | 118 | match(Set dst (ThreadLocal)); |
duke@435 | 119 | expand %{ |
duke@435 | 120 | eRegP t1; |
duke@435 | 121 | tlsLoadP_prefixLoadP(t1); |
duke@435 | 122 | tlsLoadP(dst, t1); |
duke@435 | 123 | %} |
duke@435 | 124 | %} |
duke@435 | 125 | |
duke@435 | 126 | // Die now |
duke@435 | 127 | instruct ShouldNotReachHere( ) |
duke@435 | 128 | %{ |
duke@435 | 129 | match(Halt); |
duke@435 | 130 | // Use the following format syntax |
duke@435 | 131 | format %{ "INT3 ; ShouldNotReachHere" %} |
duke@435 | 132 | opcode(0xCC); |
duke@435 | 133 | ins_encode(OpcP); |
duke@435 | 134 | ins_pipe( pipe_slow ); |
duke@435 | 135 | %} |
duke@435 | 136 | |
duke@435 | 137 | // |
duke@435 | 138 | // Platform dependent source |
duke@435 | 139 | // |
duke@435 | 140 | source %{ |
duke@435 | 141 | |
duke@435 | 142 | // emit an interrupt that is caught by the debugger |
duke@435 | 143 | void emit_break(CodeBuffer &cbuf) { |
duke@435 | 144 | *(cbuf.code_end()) = (unsigned char)(0xcc); |
duke@435 | 145 | cbuf.set_code_end(cbuf.code_end() + 1); |
duke@435 | 146 | } |
duke@435 | 147 | |
duke@435 | 148 | void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
duke@435 | 149 | emit_break(cbuf); |
duke@435 | 150 | } |
duke@435 | 151 | |
duke@435 | 152 | |
duke@435 | 153 | uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { |
duke@435 | 154 | return 1; |
duke@435 | 155 | } |
duke@435 | 156 | |
duke@435 | 157 | |
duke@435 | 158 | %} |