--- old/src/os_cpu/linux_x86/vm/linux_x86_32.ad Tue Sep 13 12:29:14 2011 +++ /dev/null Tue Sep 13 12:28:50 2011 @@ -1,160 +0,0 @@ -// -// Copyright (c) 1999, 2008, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// X86 Linux 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 linux_tlsencode (eRegP dst) %{ - Register dstReg = as_Register($dst$$reg); - MacroAssembler* masm = new MacroAssembler(&cbuf); - masm->get_thread(dstReg); - %} - - enc_class linux_breakpoint %{ - MacroAssembler* masm = new MacroAssembler(&cbuf); - masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); - %} - - 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 = 5; // size of call to breakpoint, 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(eRegP dst, eFlagsReg cr) %{ - match(Set dst (ThreadLocal)); - effect(DEF dst, KILL cr); - - format %{ "MOV $dst, Thread::current()" %} - ins_encode( linux_tlsencode(dst) ); - ins_pipe( ialu_reg_fat ); -%} - -instruct TLS(eRegP 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(linux_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 MachNode::size(ra_); -} - -%} --- /dev/null Tue Sep 13 12:28:50 2011 +++ new/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad Tue Sep 13 12:29:14 2011 @@ -0,0 +1,160 @@ +// +// Copyright (c) 1999, 2008, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// + +// X86 Bsd 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 bsd_tlsencode (eRegP dst) %{ + Register dstReg = as_Register($dst$$reg); + MacroAssembler* masm = new MacroAssembler(&cbuf); + masm->get_thread(dstReg); + %} + + enc_class bsd_breakpoint %{ + MacroAssembler* masm = new MacroAssembler(&cbuf); + masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); + %} + + 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 = 5; // size of call to breakpoint, 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(eRegP dst, eFlagsReg cr) %{ + match(Set dst (ThreadLocal)); + effect(DEF dst, KILL cr); + + format %{ "MOV $dst, Thread::current()" %} + ins_encode( bsd_tlsencode(dst) ); + ins_pipe( ialu_reg_fat ); +%} + +instruct TLS(eRegP 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(bsd_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; +} + +%}