Mercurial > hg > truffle
diff src/os_cpu/windows_x86/vm/windows_x86_64.ad @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/windows_x86/vm/windows_x86_64.ad Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,159 @@ +// +// Copyright 2003-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. +// +// + +// AMD64 Win32 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 Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime + // No relocation needed + + // movq r10, <meth> + emit_opcode(cbuf, Assembler::REX_WB); + emit_opcode(cbuf, 0xB8 | (R10_enc - 8)); + emit_d64(cbuf, (int64_t) $meth$$method); + + // call (r10) + emit_opcode(cbuf, Assembler::REX_B); + emit_opcode(cbuf, 0xFF); + emit_opcode(cbuf, 0xD0 | (R10_enc - 8)); + %} + + 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) { + if (framesize < 0x80) { + emit_opcode(cbuf, Assembler::REX_W); + emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood + emit_d8(cbuf, 0x7C); + emit_d8(cbuf, 0x24); + emit_d8(cbuf, framesize); // Find majik cookie from ESP + emit_d32(cbuf, 0xbadb100d); + } else { + emit_opcode(cbuf, Assembler::REX_W); + emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood + emit_d8(cbuf, 0xBC); + emit_d8(cbuf, 0x24); + emit_d32(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(r15_RegP dst) +%{ + match(Set dst (ThreadLocal)); + effect(DEF dst); + + size(0); + format %{ "# TLS is in R15" %} + ins_encode( /*empty encoding*/ ); + ins_pipe(ialu_reg_reg); +%} + +// Die now +instruct ShouldNotReachHere( ) +%{ + match(Halt); + // Use the following format syntax + format %{ "INT3 ; ShouldNotReachHere" %} + opcode(0xCC); + ins_encode(OpcP); + ins_pipe( pipe_slow ); +%} + +// +// Platform dependent source +// +source %{ + +int MachCallRuntimeNode::ret_addr_offset() +{ + return 13; // movq r10,#addr; callq (r10) +} + +// emit an interrupt that is caught by the debugger +void emit_break(CodeBuffer &cbuf) { + *(cbuf.code_end()) = (unsigned char)(0xcc); + cbuf.set_code_end(cbuf.code_end() + 1); +} + +void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { + emit_break(cbuf); +} + +uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { + return 1; +} + +%}