//
// Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
//
// This code is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// version 2 for more details (a copy is included in the LICENSE file that
// accompanied this code).
//
// You should have received a copy of the GNU General Public License version
// 2 along with this work; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
//
//

// X86 Solaris Architecture Description File

//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
// This block specifies the encoding classes used by the compiler to output
// byte streams.  Encoding classes generate functions which are called by
// Machine Instruction Nodes in order to generate the bit encoding of the
// instruction.  Operands specify their base encoding interface with the
// interface keyword.  There are currently supported four interfaces,
// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
// operand to generate a function which returns its register number when
// queried.   CONST_INTER causes an operand to generate a function which
// returns the value of the constant when queried.  MEMORY_INTER causes an
// operand to generate four functions which return the Base Register, the
// Index Register, the Scale Value, and the Offset Value of the operand when
// queried.  COND_INTER causes an operand to generate six functions which
// return the encoding code (ie - encoding bits for the instruction)
// associated with each basic boolean condition for a conditional instruction.
// Instructions specify two basic values for encoding.  They use the
// ins_encode keyword to specify their encoding class (which must be one of
// the class names specified in the encoding block), and they use the
// opcode keyword to specify, in order, their primary, secondary, and
// tertiary opcode.  Only the opcode sections which a particular instruction
// needs for encoding need to be specified.
encode %{
  // Build emit functions for each basic byte or larger field in the intel
  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
  // code in the enc_class source block.  Emit functions will live in the
  // main source block for now.  In future, we can generalize this by
  // adding a syntax that specifies the sizes of fields in an order,
  // so that the adlc can build the emit functions automagically

  enc_class solaris_tlsencode (eRegP dst) %{
    Register dstReg = as_Register($dst$$reg);
    MacroAssembler* masm = new MacroAssembler(&cbuf);
    masm->get_thread(dstReg);
  %}

  enc_class solaris_breakpoint  %{
    MacroAssembler* masm = new MacroAssembler(&cbuf);
    // Really need to fix this
    masm->push(rax);
    masm->push(rcx);
    masm->push(rdx);
    masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
    masm->pop(rdx);
    masm->pop(rcx);
    masm->pop(rax);
  %}

  enc_class call_epilog %{
    if( VerifyStackAtCalls ) {
      // Check that stack depth is unchanged: find majik cookie on stack
      int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
      if(framesize >= 128) {
        emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
        emit_d8(cbuf,0xBC);
        emit_d8(cbuf,0x24);
        emit_d32(cbuf,framesize); // Find majik cookie from ESP
        emit_d32(cbuf, 0xbadb100d);
      }
      else {
        emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
        emit_d8(cbuf,0x7C);
        emit_d8(cbuf,0x24);
        emit_d8(cbuf,framesize); // Find majik cookie from ESP
        emit_d32(cbuf, 0xbadb100d);
      }
      // jmp EQ around INT3
      // QQQ TODO
      const int jump_around = 11; // size of call to breakpoint (and register preserve), 1 for CC
      emit_opcode(cbuf,0x74);
      emit_d8(cbuf, jump_around);
      // QQQ temporary
      emit_break(cbuf);
      // Die if stack mismatch
      // emit_opcode(cbuf,0xCC);
    }
  %}

%}

// INSTRUCTIONS -- Platform dependent

//----------OS and Locking Instructions----------------------------------------

// This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
// for this guy.
instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
  match(Set dst (ThreadLocal));
  effect(DEF dst, KILL cr);

  format %{ "MOV    EAX, Thread::current()" %}
  ins_encode( solaris_tlsencode(dst) );
  ins_pipe( ialu_reg_fat );
%}

instruct TLS(eAXRegP dst) %{
  match(Set dst (ThreadLocal));

  expand %{
    tlsLoadP(dst);
  %}
%}

// Die now
instruct ShouldNotReachHere( )
%{
  match(Halt);

  // Use the following format syntax
  format %{ "INT3   ; ShouldNotReachHere" %}
  // QQQ TODO for now call breakpoint
  // opcode(0xCC);
  // ins_encode(Opc);
  ins_encode(solaris_breakpoint);
  ins_pipe( pipe_slow );
%}



// Platform dependent source

source %{

// emit an interrupt that is caught by the debugger
void emit_break(CodeBuffer &cbuf) {

  // Debugger doesn't really catch this but best we can do so far QQQ
  MacroAssembler* masm = new MacroAssembler(&cbuf);
  masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
}

void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  emit_break(cbuf);
}


uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
  return 5;
}

%}
