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