1 // |
1 // |
2 // Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. |
2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 // |
4 // |
5 // This code is free software; you can redistribute it and/or modify it |
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 |
6 // under the terms of the GNU General Public License version 2 only, as |
7 // published by the Free Software Foundation. |
7 // published by the Free Software Foundation. |
53 // code in the enc_class source block. Emit functions will live in the |
53 // code in the enc_class source block. Emit functions will live in the |
54 // main source block for now. In future, we can generalize this by |
54 // main source block for now. In future, we can generalize this by |
55 // adding a syntax that specifies the sizes of fields in an order, |
55 // adding a syntax that specifies the sizes of fields in an order, |
56 // so that the adlc can build the emit functions automagically |
56 // so that the adlc can build the emit functions automagically |
57 |
57 |
58 enc_class Java_To_Runtime(method meth) |
58 enc_class Java_To_Runtime(method meth) %{ |
59 %{ |
|
60 // No relocation needed |
59 // No relocation needed |
61 |
60 |
62 // movq r10, <meth> |
61 // movq r10, <meth> |
63 emit_opcode(cbuf, Assembler::REX_WB); |
62 emit_opcode(cbuf, Assembler::REX_WB); |
64 emit_opcode(cbuf, 0xB8 | (R10_enc - 8)); |
63 emit_opcode(cbuf, 0xB8 | (R10_enc - 8)); |
68 emit_opcode(cbuf, Assembler::REX_B); |
67 emit_opcode(cbuf, Assembler::REX_B); |
69 emit_opcode(cbuf, 0xFF); |
68 emit_opcode(cbuf, 0xFF); |
70 emit_opcode(cbuf, 0xD0 | (R10_enc - 8)); |
69 emit_opcode(cbuf, 0xD0 | (R10_enc - 8)); |
71 %} |
70 %} |
72 |
71 |
73 enc_class bsd_breakpoint |
|
74 %{ |
|
75 MacroAssembler* masm = new MacroAssembler(&cbuf); |
|
76 masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); |
|
77 %} |
|
78 |
|
79 enc_class call_epilog |
|
80 %{ |
|
81 if (VerifyStackAtCalls) { |
|
82 // Check that stack depth is unchanged: find majik cookie on stack |
|
83 int framesize = |
|
84 ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word)); |
|
85 if (framesize) { |
|
86 if (framesize < 0x80) { |
|
87 emit_opcode(cbuf, Assembler::REX_W); |
|
88 emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood |
|
89 emit_d8(cbuf, 0x7C); |
|
90 emit_d8(cbuf, 0x24); |
|
91 emit_d8(cbuf, framesize); // Find majik cookie from ESP |
|
92 emit_d32(cbuf, 0xbadb100d); |
|
93 } else { |
|
94 emit_opcode(cbuf, Assembler::REX_W); |
|
95 emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood |
|
96 emit_d8(cbuf, 0xBC); |
|
97 emit_d8(cbuf, 0x24); |
|
98 emit_d32(cbuf, framesize); // Find majik cookie from ESP |
|
99 emit_d32(cbuf, 0xbadb100d); |
|
100 } |
|
101 } |
|
102 // jmp EQ around INT3 |
|
103 // QQQ TODO |
|
104 const int jump_around = 5; // size of call to breakpoint, 1 for CC |
|
105 emit_opcode(cbuf, 0x74); |
|
106 emit_d8(cbuf, jump_around); |
|
107 // QQQ temporary |
|
108 emit_break(cbuf); |
|
109 // Die if stack mismatch |
|
110 // emit_opcode(cbuf,0xCC); |
|
111 } |
|
112 %} |
|
113 |
|
114 %} |
|
115 |
|
116 // INSTRUCTIONS -- Platform dependent |
|
117 |
|
118 //----------OS and Locking Instructions---------------------------------------- |
|
119 |
|
120 // This name is KNOWN by the ADLC and cannot be changed. |
|
121 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type |
|
122 // for this guy. |
|
123 instruct tlsLoadP(r15_RegP dst) |
|
124 %{ |
|
125 match(Set dst (ThreadLocal)); |
|
126 effect(DEF dst); |
|
127 |
|
128 size(0); |
|
129 format %{ "# TLS is in R15" %} |
|
130 ins_encode( /*empty encoding*/ ); |
|
131 ins_pipe(ialu_reg_reg); |
|
132 %} |
|
133 |
|
134 // Die now |
|
135 instruct ShouldNotReachHere() |
|
136 %{ |
|
137 match(Halt); |
|
138 |
|
139 // Use the following format syntax |
|
140 format %{ "int3\t# ShouldNotReachHere" %} |
|
141 // QQQ TODO for now call breakpoint |
|
142 // opcode(0xCC); |
|
143 // ins_encode(Opc); |
|
144 ins_encode(bsd_breakpoint); |
|
145 ins_pipe(pipe_slow); |
|
146 %} |
72 %} |
147 |
73 |
148 |
74 |
149 // Platform dependent source |
75 // Platform dependent source |
150 |
76 |
151 source |
77 source %{ |
152 %{ |
|
153 |
78 |
154 int MachCallRuntimeNode::ret_addr_offset() { |
79 int MachCallRuntimeNode::ret_addr_offset() { |
155 return 13; // movq r10,#addr; callq (r10) |
80 return 13; // movq r10,#addr; callq (r10) |
156 } |
81 } |
157 |
82 |
158 // emit an interrupt that is caught by the debugger |
|
159 void emit_break(CodeBuffer& cbuf) { |
|
160 // Debugger doesn't really catch this but best we can do so far QQQ |
|
161 MacroAssembler* masm = new MacroAssembler(&cbuf); |
|
162 masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); |
|
163 } |
|
164 |
|
165 void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { |
|
166 emit_break(cbuf); |
|
167 } |
|
168 |
|
169 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const { |
|
170 return 5; |
|
171 } |
|
172 |
|
173 %} |
83 %} |