Wed, 29 Mar 2017 09:41:51 +0800
#4662 TieredCompilation is turned off.
TieredCompilation is not supported yet.
1 /*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "nativeInst_mips.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/handles.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "runtime/stubRoutines.hpp"
34 #include "utilities/ostream.hpp"
35 #ifdef COMPILER1
36 #include "c1/c1_Runtime1.hpp"
37 #endif
39 #include <sys/mman.h>
41 void NativeInstruction::wrote(int offset) {
42 ICache::invalidate_word(addr_at(offset));
43 }
45 void NativeInstruction::set_long_at(int offset, long i) {
46 address addr = addr_at(offset);
47 *(long*)addr = i;
48 #ifdef _LP64
49 ICache::invalidate_range(addr, 8);
50 #else
51 ICache::invalidate_word(addr);
52 #endif
53 }
55 static int illegal_instruction_bits = 0;
57 int NativeInstruction::illegal_instruction() {
58 if (illegal_instruction_bits == 0) {
59 ResourceMark rm;
60 char buf[40];
61 CodeBuffer cbuf((address)&buf[0], 20);
62 MacroAssembler* a = new MacroAssembler(&cbuf);
63 address ia = a->pc();
64 a->brk(11);
65 int bits = *(int*)ia;
66 illegal_instruction_bits = bits;
67 }
68 return illegal_instruction_bits;
69 }
71 bool NativeInstruction::is_int_branch() {
72 switch(Assembler::opcode(insn_word())) {
73 case Assembler::beq_op:
74 case Assembler::beql_op:
75 case Assembler::bgtz_op:
76 case Assembler::bgtzl_op:
77 case Assembler::blez_op:
78 case Assembler::blezl_op:
79 case Assembler::bne_op:
80 case Assembler::bnel_op:
81 return true;
82 case Assembler::regimm_op:
83 switch(Assembler::rt(insn_word())) {
84 case Assembler::bgez_op:
85 case Assembler::bgezal_op:
86 case Assembler::bgezall_op:
87 case Assembler::bgezl_op:
88 case Assembler::bltz_op:
89 case Assembler::bltzal_op:
90 case Assembler::bltzall_op:
91 case Assembler::bltzl_op:
92 return true;
93 }
94 }
96 return false;
97 }
99 bool NativeInstruction::is_float_branch() {
100 if (!is_op(Assembler::cop1_op) ||
101 !is_rs((Register)Assembler::bc1f_op)) return false;
103 switch(Assembler::rt(insn_word())) {
104 case Assembler::bcf_op:
105 case Assembler::bcfl_op:
106 case Assembler::bct_op:
107 case Assembler::bctl_op:
108 return true;
109 }
111 return false;
112 }
115 //-------------------------------------------------------------------
117 void NativeCall::verify() {
118 // make sure code pattern is actually a call instruction
119 #ifndef _LP64
120 if ( !is_op(Assembler::lui_op) ||
121 !is_op(int_at(4), Assembler::addiu_op) ||
122 !is_special_op(int_at(8), Assembler::jalr_op) ) {
123 fatal("not a call");
124 }
125 #else
127 // nop
128 // nop
129 // nop
130 // nop
131 // jal targe
132 // nop
133 if ( is_nop() &&
134 nativeInstruction_at(addr_at(4))->is_nop() &&
135 nativeInstruction_at(addr_at(8))->is_nop() &&
136 nativeInstruction_at(addr_at(12))->is_nop() &&
137 is_op(int_at(16), Assembler::jal_op) &&
138 nativeInstruction_at(addr_at(20))->is_nop() ) {
139 return;
140 }
142 // li64
143 if ( is_op(Assembler::lui_op) &&
144 is_op(int_at(4), Assembler::ori_op) &&
145 is_special_op(int_at(8), Assembler::dsll_op) &&
146 is_op(int_at(12), Assembler::ori_op) &&
147 is_special_op(int_at(16), Assembler::dsll_op) &&
148 is_op(int_at(20), Assembler::ori_op) &&
149 is_special_op(int_at(24), Assembler::jalr_op) ) {
150 return;
151 }
153 //lui dst, imm16
154 //ori dst, dst, imm16
155 //dsll dst, dst, 16
156 //ori dst, dst, imm16
157 if ( is_op(Assembler::lui_op) &&
158 is_op (int_at(4), Assembler::ori_op) &&
159 is_special_op(int_at(8), Assembler::dsll_op) &&
160 is_op (int_at(12), Assembler::ori_op) &&
161 is_special_op(int_at(16), Assembler::jalr_op) ) {
162 return;
163 }
165 //ori dst, R0, imm16
166 //dsll dst, dst, 16
167 //ori dst, dst, imm16
168 //nop
169 if ( is_op(Assembler::ori_op) &&
170 is_special_op(int_at(4), Assembler::dsll_op) &&
171 is_op (int_at(8), Assembler::ori_op) &&
172 nativeInstruction_at(addr_at(12))->is_nop() &&
173 is_special_op(int_at(16), Assembler::jalr_op) ) {
174 return;
175 }
177 //ori dst, R0, imm16
178 //dsll dst, dst, 16
179 //nop
180 //nop
181 if ( is_op(Assembler::ori_op) &&
182 is_special_op(int_at(4), Assembler::dsll_op) &&
183 nativeInstruction_at(addr_at(8))->is_nop() &&
184 nativeInstruction_at(addr_at(12))->is_nop() &&
185 is_special_op(int_at(16), Assembler::jalr_op) ) {
186 return;
187 }
189 //daddiu dst, R0, imm16
190 //nop
191 //nop
192 //nop
193 if ( is_op(Assembler::daddiu_op) &&
194 nativeInstruction_at(addr_at(4))->is_nop() &&
195 nativeInstruction_at(addr_at(8))->is_nop() &&
196 nativeInstruction_at(addr_at(12))->is_nop() &&
197 is_special_op(int_at(16), Assembler::jalr_op) ) {
198 return;
199 }
201 //lui dst, imm16
202 //ori dst, dst, imm16
203 //nop
204 //nop
205 if ( is_op(Assembler::lui_op) &&
206 is_op (int_at(4), Assembler::ori_op) &&
207 nativeInstruction_at(addr_at(8))->is_nop() &&
208 nativeInstruction_at(addr_at(12))->is_nop() &&
209 is_special_op(int_at(16), Assembler::jalr_op) ) {
210 return;
211 }
213 //lui dst, imm16
214 //nop
215 //nop
216 //nop
217 if ( is_op(Assembler::lui_op) &&
218 nativeInstruction_at(addr_at(4))->is_nop() &&
219 nativeInstruction_at(addr_at(8))->is_nop() &&
220 nativeInstruction_at(addr_at(12))->is_nop() &&
221 is_special_op(int_at(16), Assembler::jalr_op) ) {
222 return;
223 }
225 //daddiu dst, R0, imm16
226 //nop
227 if ( is_op(Assembler::daddiu_op) &&
228 nativeInstruction_at(addr_at(4))->is_nop() &&
229 is_special_op(int_at(8), Assembler::jalr_op) ) {
230 return;
231 }
233 //lui dst, imm16
234 //ori dst, dst, imm16
235 if ( is_op(Assembler::lui_op) &&
236 is_op (int_at(4), Assembler::ori_op) &&
237 is_special_op(int_at(8), Assembler::jalr_op) ) {
238 return;
239 }
241 //lui dst, imm16
242 //nop
243 if ( is_op(Assembler::lui_op) &&
244 nativeInstruction_at(addr_at(4))->is_nop() &&
245 is_special_op(int_at(8), Assembler::jalr_op) ) {
246 return;
247 }
249 fatal("not a call");
250 #endif
251 }
253 address NativeCall::destination() const {
254 #ifndef _LP64
255 return (address)Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
256 #else
258 // nop
259 // nop
260 // nop
261 // nop
262 // jal target
263 // nop
264 if ( nativeInstruction_at(addr_at(0))->is_nop() &&
265 nativeInstruction_at(addr_at(4))->is_nop() &&
266 nativeInstruction_at(addr_at(8))->is_nop() &&
267 nativeInstruction_at(addr_at(12))->is_nop() &&
268 is_op(int_at(16), Assembler::jal_op) &&
269 nativeInstruction_at(addr_at(20))->is_nop()) {
270 int instr_index = int_at(16) & 0x3ffffff;
271 intptr_t target_high = ((intptr_t)addr_at(20)) & 0xfffffffff0000000;
272 intptr_t target = target_high | (instr_index << 2);
273 return (address)target;
274 }
276 // li64
277 if ( is_op(Assembler::lui_op) &&
278 is_op(int_at(4), Assembler::ori_op) &&
279 is_special_op(int_at(8), Assembler::dsll_op) &&
280 is_op(int_at(12), Assembler::ori_op) &&
281 is_special_op(int_at(16), Assembler::dsll_op) &&
282 is_op(int_at(20), Assembler::ori_op) ) {
284 return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
285 (intptr_t)(int_at(12) & 0xffff),
286 (intptr_t)(int_at(4) & 0xffff),
287 (intptr_t)(int_at(0) & 0xffff));
288 }
290 //lui dst, imm16
291 //ori dst, dst, imm16
292 //dsll dst, dst, 16
293 //ori dst, dst, imm16
294 if ( is_op(Assembler::lui_op) &&
295 is_op (int_at(4), Assembler::ori_op) &&
296 is_special_op(int_at(8), Assembler::dsll_op) &&
297 is_op (int_at(12), Assembler::ori_op) ) {
299 return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
300 (intptr_t)(int_at(4) & 0xffff),
301 (intptr_t)(int_at(0) & 0xffff),
302 (intptr_t)0);
303 }
305 //ori dst, R0, imm16
306 //dsll dst, dst, 16
307 //ori dst, dst, imm16
308 //nop
309 if ( is_op(Assembler::ori_op) &&
310 is_special_op(int_at(4), Assembler::dsll_op) &&
311 is_op (int_at(8), Assembler::ori_op) &&
312 nativeInstruction_at(addr_at(12))->is_nop()) {
314 return (address)Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
315 (intptr_t)(int_at(0) & 0xffff),
316 (intptr_t)0,
317 (intptr_t)0);
318 }
320 //ori dst, R0, imm16
321 //dsll dst, dst, 16
322 //nop
323 //nop
324 if ( is_op(Assembler::ori_op) &&
325 is_special_op(int_at(4), Assembler::dsll_op) &&
326 nativeInstruction_at(addr_at(8))->is_nop() &&
327 nativeInstruction_at(addr_at(12))->is_nop()) {
329 return (address)Assembler::merge( (intptr_t)(0),
330 (intptr_t)(int_at(0) & 0xffff),
331 (intptr_t)0,
332 (intptr_t)0);
333 }
335 //daddiu dst, R0, imm16
336 //nop
337 //nop <-- optional
338 //nop <-- optional
339 if ( is_op(Assembler::daddiu_op) &&
340 nativeInstruction_at(addr_at(4))->is_nop() ) {
342 int sign = int_at(0) & 0x8000;
343 if (sign == 0) {
344 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
345 (intptr_t)0,
346 (intptr_t)0,
347 (intptr_t)0);
348 } else {
349 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
350 (intptr_t)(0xffff),
351 (intptr_t)(0xffff),
352 (intptr_t)(0xffff));
353 }
354 }
356 //lui dst, imm16
357 //ori dst, dst, imm16
358 //nop <-- optional
359 //nop <-- optional
360 if ( is_op(Assembler::lui_op) &&
361 is_op (int_at(4), Assembler::ori_op) ) {
363 int sign = int_at(0) & 0x8000;
364 if (sign == 0) {
365 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
366 (intptr_t)(int_at(0) & 0xffff),
367 (intptr_t)0,
368 (intptr_t)0);
369 } else {
370 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
371 (intptr_t)(int_at(0) & 0xffff),
372 (intptr_t)(0xffff),
373 (intptr_t)(0xffff));
374 }
375 }
377 //lui dst, imm16
378 //nop
379 //nop <-- optional
380 //nop <-- optional
381 if ( is_op(Assembler::lui_op) &&
382 nativeInstruction_at(addr_at(4))->is_nop() ) {
384 int sign = int_at(0) & 0x8000;
385 if (sign == 0) {
386 return (address)Assembler::merge( (intptr_t)0,
387 (intptr_t)(int_at(0) & 0xffff),
388 (intptr_t)0,
389 (intptr_t)0);
390 } else {
391 return (address)Assembler::merge( (intptr_t)0,
392 (intptr_t)(int_at(0) & 0xffff),
393 (intptr_t)(0xffff),
394 (intptr_t)(0xffff));
395 }
396 }
398 fatal("not a call");
399 #endif
400 }
402 /* 2013/6/14 Jin: manual implementation of GSSQ
403 *
404 * 00000001200009c0 <atomic_store128>:
405 * 1200009c0: 0085202d daddu a0, a0, a1
406 * 1200009c4: e8860027 gssq a2, a3, 0(a0)
407 * 1200009c8: 03e00008 jr ra
408 * 1200009cc: 00000000 nop
409 */
410 typedef void (* atomic_store128_ptr)(long *addr, int offset, long low64, long hi64);
412 static int *buf;
414 static atomic_store128_ptr get_atomic_store128_func() {
415 assert(UseLoongsonISA, "UseLoongsonISA must be true");
416 static atomic_store128_ptr p = NULL;
417 if (p != NULL)
418 return p;
420 buf = (int *)mmap(NULL, 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS,
421 -1, 0);
422 buf[0] = 0x0085202d;
423 buf[1] = (0x3a << 26) | (4 << 21) | (6 << 16) | 0x27; /* gssq $a2, $a3, 0($a0) */
424 buf[2] = 0x03e00008;
425 buf[3] = 0;
427 p = (atomic_store128_ptr)buf;
428 return p;
429 }
431 void NativeCall::patch_on_jal_gs(address dst) {
432 #ifdef _LP64
433 long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
434 #else
435 long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
436 #endif
437 if ((dest >= 0) && (dest < (1<<26))) {
438 jint jal_inst = (Assembler::jal_op << 26) | dest;
439 set_int_at(16, jal_inst);
440 ICache::invalidate_range(addr_at(16), 4);
441 } else {
442 ShouldNotReachHere();
443 }
444 }
446 void NativeCall::patch_on_jal(address dst) {
447 patch_on_jal_gs(dst);
448 }
450 void NativeCall::patch_on_jalr_gs(address dst) {
451 patch_set48_gs(dst);
452 }
454 void NativeCall::patch_on_jalr(address dst) {
455 patch_set48(dst);
456 }
458 void NativeCall::patch_set48_gs(address dest) {
459 jlong value = (jlong) dest;
460 int rt_reg = (int_at(0) & (0x1f << 16));
462 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
464 int rs_reg = rt_reg << 5;
465 int rd_reg = rt_reg >> 5;
467 int hi = (int)(value >> 32);
468 int lo = (int)(value & ~0);
470 int count = 0;
472 int insts[4] = {0, 0, 0, 0};
474 if (value == lo) { // 32-bit integer
475 if (Assembler::is_simm16(value)) {
476 //daddiu(d, R0, value);
477 //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
478 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
479 count += 1;
480 } else {
481 //lui(d, split_low(value >> 16));
482 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
483 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
484 count += 1;
485 if (Assembler::split_low(value)) {
486 //ori(d, d, split_low(value));
487 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
488 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
489 count += 1;
490 }
491 }
492 } else if (hi == 0) { // hardware zero-extends to upper 32
493 //ori(d, R0, julong(value) >> 16);
494 //set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
495 insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
496 count += 1;
497 //dsll(d, d, 16);
498 //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
499 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
500 count += 1;
501 if (Assembler::split_low(value)) {
502 //ori(d, d, split_low(value));
503 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
504 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
505 count += 1;
506 }
507 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
508 //lui(d, value >> 32);
509 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
510 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
511 count += 1;
512 //ori(d, d, split_low(value >> 16));
513 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
514 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
515 count += 1;
516 //dsll(d, d, 16);
517 //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
518 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
519 count += 1;
520 //ori(d, d, split_low(value));
521 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
522 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
523 count += 1;
524 } else {
525 tty->print_cr("dest = 0x%x", value);
526 guarantee(false, "Not supported yet !");
527 }
529 for (count; count < 4; count++) {
530 //nop();
531 //set_int_at(count << 2, 0);
532 insts[count] = 0;
533 }
535 atomic_store128_ptr func = get_atomic_store128_func();
536 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
538 ICache::invalidate_range(addr_at(0), 16);
539 }
541 void NativeCall::patch_set32_gs(address dest) {
542 jlong value = (jlong) dest;
543 int rt_reg = (int_at(0) & (0x1f << 16));
545 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
547 int rs_reg = rt_reg << 5;
548 int rd_reg = rt_reg >> 5;
550 int hi = (int)(value >> 32);
551 int lo = (int)(value & ~0);
553 int count = 0;
555 int insts[2] = {0, 0};
557 if (value == lo) { // 32-bit integer
558 if (Assembler::is_simm16(value)) {
559 //daddiu(d, R0, value);
560 //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
561 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
562 count += 1;
563 } else {
564 //lui(d, split_low(value >> 16));
565 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
566 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
567 count += 1;
568 if (Assembler::split_low(value)) {
569 //ori(d, d, split_low(value));
570 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
571 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
572 count += 1;
573 }
574 }
575 } else {
576 tty->print_cr("dest = 0x%x", value);
577 guarantee(false, "Not supported yet !");
578 }
580 for (count; count < 2; count++) {
581 //nop();
582 //set_int_at(count << 2, 0);
583 insts[count] = 0;
584 }
586 long inst = insts[1];
587 inst = inst << 32;
588 inst = inst + insts[0];
590 set_long_at(0, inst);
591 }
593 void NativeCall::patch_set48(address dest) {
594 jlong value = (jlong) dest;
595 int rt_reg = (int_at(0) & (0x1f << 16));
597 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
599 int rs_reg = rt_reg << 5;
600 int rd_reg = rt_reg >> 5;
602 int hi = (int)(value >> 32);
603 int lo = (int)(value & ~0);
605 int count = 0;
607 if (value == lo) { // 32-bit integer
608 if (Assembler::is_simm16(value)) {
609 //daddiu(d, R0, value);
610 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
611 count += 1;
612 } else {
613 //lui(d, split_low(value >> 16));
614 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
615 count += 1;
616 if (Assembler::split_low(value)) {
617 //ori(d, d, split_low(value));
618 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
619 count += 1;
620 }
621 }
622 } else if (hi == 0) { // hardware zero-extends to upper 32
623 //ori(d, R0, julong(value) >> 16);
624 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
625 count += 1;
626 //dsll(d, d, 16);
627 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
628 count += 1;
629 if (Assembler::split_low(value)) {
630 //ori(d, d, split_low(value));
631 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
632 count += 1;
633 }
634 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
635 //lui(d, value >> 32);
636 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
637 count += 1;
638 //ori(d, d, split_low(value >> 16));
639 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
640 count += 1;
641 //dsll(d, d, 16);
642 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
643 count += 1;
644 //ori(d, d, split_low(value));
645 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
646 count += 1;
647 } else {
648 tty->print_cr("dest = 0x%x", value);
649 guarantee(false, "Not supported yet !");
650 }
652 for (count; count < 4; count++) {
653 //nop();
654 set_int_at(count << 2, 0);
655 }
657 ICache::invalidate_range(addr_at(0), 16);
658 }
660 void NativeCall::patch_set32(address dest) {
661 patch_set32_gs(dest);
662 }
664 void NativeCall::set_destination(address dest) {
665 #ifndef _LP64
666 OrderAccess::fence();
667 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
668 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
669 ICache::invalidate_range(addr_at(0), 8);
670 #else
671 OrderAccess::fence();
673 // li64
674 if (is_special_op(int_at(16), Assembler::dsll_op)) {
675 int first_word = int_at(0);
676 set_int_at(0, 0x1000ffff); /* .1: b .1 */
677 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 32) & 0xffff));
678 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 16) & 0xffff));
679 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
680 set_int_at(0, (first_word & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 48) & 0xffff));
681 ICache::invalidate_range(addr_at(0), 24);
682 } else if (is_op(int_at(16), Assembler::jal_op)) {
683 if (UseLoongsonISA) {
684 patch_on_jal_gs(dest);
685 } else {
686 patch_on_jal(dest);
687 }
688 } else if (is_special_op(int_at(16), Assembler::jalr_op)) {
689 if (UseLoongsonISA) {
690 guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
691 patch_on_jalr_gs(dest);
692 } else {
693 patch_on_jalr(dest);
694 }
695 } else if (is_special_op(int_at(8), Assembler::jalr_op)) {
696 guarantee(!os::is_MP() || (((long)addr_at(0) % 8) == 0), "destination must be aligned by 8");
697 if (UseLoongsonISA) {
698 patch_set32_gs(dest);
699 } else {
700 patch_set32(dest);
701 }
702 ICache::invalidate_range(addr_at(0), 8);
703 } else {
704 fatal("not a call");
705 }
706 #endif
707 }
709 void NativeCall::print() {
710 tty->print_cr(PTR_FORMAT ": call " PTR_FORMAT,
711 instruction_address(), destination());
712 }
714 // Inserts a native call instruction at a given pc
715 void NativeCall::insert(address code_pos, address entry) {
716 NativeCall *call = nativeCall_at(code_pos);
717 CodeBuffer cb(call->addr_at(0), instruction_size);
718 MacroAssembler masm(&cb);
719 #define __ masm.
720 #ifndef _LP64
721 __ lui(T9, Assembler::split_high((int)entry));
722 __ addiu(T9, T9, Assembler::split_low((int)entry));
723 #else
724 __ patchable_set48(T9, (long)entry);
725 #endif
726 __ jalr ();
727 __ delayed()->nop();
728 #undef __
730 ICache::invalidate_range(call->addr_at(0), instruction_size);
731 }
733 // MT-safe patching of a call instruction.
734 // First patches first word of instruction to two jmp's that jmps to them
735 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
736 // the jmp's with the first 4 byte of the new instruction.
737 void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
738 Unimplemented();
739 }
741 //-------------------------------------------------------------------
743 void NativeMovConstReg::verify() {
744 #ifndef _LP64
745 if ( !is_op(Assembler::lui_op) ||
746 !is_op(int_at(4), Assembler::addiu_op) )
747 fatal("not a mov reg, imm32")
748 #else
749 // li64
750 if ( is_op(Assembler::lui_op) &&
751 is_op(int_at(4), Assembler::ori_op) &&
752 is_special_op(int_at(8), Assembler::dsll_op) &&
753 is_op(int_at(12), Assembler::ori_op) &&
754 is_special_op(int_at(16), Assembler::dsll_op) &&
755 is_op(int_at(20), Assembler::ori_op) ) {
756 return;
757 }
759 //lui dst, imm16
760 //ori dst, dst, imm16
761 //dsll dst, dst, 16
762 //ori dst, dst, imm16
763 if ( is_op(Assembler::lui_op) &&
764 is_op (int_at(4), Assembler::ori_op) &&
765 is_special_op(int_at(8), Assembler::dsll_op) &&
766 is_op (int_at(12), Assembler::ori_op) ) {
767 return;
768 }
770 //ori dst, R0, imm16
771 //dsll dst, dst, 16
772 //ori dst, dst, imm16
773 //nop
774 if ( is_op(Assembler::ori_op) &&
775 is_special_op(int_at(4), Assembler::dsll_op) &&
776 is_op (int_at(8), Assembler::ori_op) &&
777 nativeInstruction_at(addr_at(12))->is_nop()) {
778 return;
779 }
781 //ori dst, R0, imm16
782 //dsll dst, dst, 16
783 //nop
784 //nop
785 if ( is_op(Assembler::ori_op) &&
786 is_special_op(int_at(4), Assembler::dsll_op) &&
787 nativeInstruction_at(addr_at(8))->is_nop() &&
788 nativeInstruction_at(addr_at(12))->is_nop()) {
789 return;
790 }
792 //daddiu dst, R0, imm16
793 //nop
794 //nop
795 //nop
796 if ( is_op(Assembler::daddiu_op) &&
797 nativeInstruction_at(addr_at(4))->is_nop() &&
798 nativeInstruction_at(addr_at(8))->is_nop() &&
799 nativeInstruction_at(addr_at(12))->is_nop() ) {
800 return;
801 }
803 //lui dst, imm16
804 //ori dst, dst, imm16
805 //nop
806 //nop
807 if ( is_op(Assembler::lui_op) &&
808 is_op (int_at(4), Assembler::ori_op) &&
809 nativeInstruction_at(addr_at(8))->is_nop() &&
810 nativeInstruction_at(addr_at(12))->is_nop() ) {
811 return;
812 }
814 //lui dst, imm16
815 //nop
816 //nop
817 //nop
818 if ( is_op(Assembler::lui_op) &&
819 nativeInstruction_at(addr_at(4))->is_nop() &&
820 nativeInstruction_at(addr_at(8))->is_nop() &&
821 nativeInstruction_at(addr_at(12))->is_nop() ) {
822 return;
823 }
825 fatal("not a mov reg, imm64/imm48");
826 #endif
827 }
829 void NativeMovConstReg::print() {
830 tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT,
831 instruction_address(), data());
832 }
834 intptr_t NativeMovConstReg::data() const {
835 #ifndef _LP64
836 return Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
837 #else
838 // li64
839 if ( is_op(Assembler::lui_op) &&
840 is_op(int_at(4), Assembler::ori_op) &&
841 is_special_op(int_at(8), Assembler::dsll_op) &&
842 is_op(int_at(12), Assembler::ori_op) &&
843 is_special_op(int_at(16), Assembler::dsll_op) &&
844 is_op(int_at(20), Assembler::ori_op) ) {
846 return Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
847 (intptr_t)(int_at(12) & 0xffff),
848 (intptr_t)(int_at(4) & 0xffff),
849 (intptr_t)(int_at(0) & 0xffff));
850 }
852 //lui dst, imm16
853 //ori dst, dst, imm16
854 //dsll dst, dst, 16
855 //ori dst, dst, imm16
856 if ( is_op(Assembler::lui_op) &&
857 is_op (int_at(4), Assembler::ori_op) &&
858 is_special_op(int_at(8), Assembler::dsll_op) &&
859 is_op (int_at(12), Assembler::ori_op) ) {
861 return Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
862 (intptr_t)(int_at(4) & 0xffff),
863 (intptr_t)(int_at(0) & 0xffff),
864 (intptr_t)0);
865 }
867 //ori dst, R0, imm16
868 //dsll dst, dst, 16
869 //ori dst, dst, imm16
870 //nop
871 if ( is_op(Assembler::ori_op) &&
872 is_special_op(int_at(4), Assembler::dsll_op) &&
873 is_op (int_at(8), Assembler::ori_op) &&
874 nativeInstruction_at(addr_at(12))->is_nop()) {
876 return Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
877 (intptr_t)(int_at(0) & 0xffff),
878 (intptr_t)0,
879 (intptr_t)0);
880 }
882 //ori dst, R0, imm16
883 //dsll dst, dst, 16
884 //nop
885 //nop
886 if ( is_op(Assembler::ori_op) &&
887 is_special_op(int_at(4), Assembler::dsll_op) &&
888 nativeInstruction_at(addr_at(8))->is_nop() &&
889 nativeInstruction_at(addr_at(12))->is_nop()) {
891 return Assembler::merge( (intptr_t)(0),
892 (intptr_t)(int_at(0) & 0xffff),
893 (intptr_t)0,
894 (intptr_t)0);
895 }
897 //daddiu dst, R0, imm16
898 //nop
899 //nop
900 //nop
901 if ( is_op(Assembler::daddiu_op) &&
902 nativeInstruction_at(addr_at(4))->is_nop() &&
903 nativeInstruction_at(addr_at(8))->is_nop() &&
904 nativeInstruction_at(addr_at(12))->is_nop() ) {
906 int sign = int_at(0) & 0x8000;
907 if (sign == 0) {
908 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
909 (intptr_t)0,
910 (intptr_t)0,
911 (intptr_t)0);
912 } else {
913 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
914 (intptr_t)(0xffff),
915 (intptr_t)(0xffff),
916 (intptr_t)(0xffff));
917 }
918 }
920 //lui dst, imm16
921 //ori dst, dst, imm16
922 //nop
923 //nop
924 if ( is_op(Assembler::lui_op) &&
925 is_op (int_at(4), Assembler::ori_op) &&
926 nativeInstruction_at(addr_at(8))->is_nop() &&
927 nativeInstruction_at(addr_at(12))->is_nop() ) {
929 int sign = int_at(0) & 0x8000;
930 if (sign == 0) {
931 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
932 (intptr_t)(int_at(0) & 0xffff),
933 (intptr_t)0,
934 (intptr_t)0);
935 } else {
936 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
937 (intptr_t)(int_at(0) & 0xffff),
938 (intptr_t)(0xffff),
939 (intptr_t)(0xffff));
940 }
941 }
943 //lui dst, imm16
944 //nop
945 //nop
946 //nop
947 if ( is_op(Assembler::lui_op) &&
948 nativeInstruction_at(addr_at(4))->is_nop() &&
949 nativeInstruction_at(addr_at(8))->is_nop() &&
950 nativeInstruction_at(addr_at(12))->is_nop() ) {
952 int sign = int_at(0) & 0x8000;
953 if (sign == 0) {
954 return Assembler::merge( (intptr_t)0,
955 (intptr_t)(int_at(0) & 0xffff),
956 (intptr_t)0,
957 (intptr_t)0);
958 } else {
959 return Assembler::merge( (intptr_t)0,
960 (intptr_t)(int_at(0) & 0xffff),
961 (intptr_t)(0xffff),
962 (intptr_t)(0xffff));
963 }
964 }
966 fatal("not a mov reg, imm64/imm48");
968 #endif
969 }
971 void NativeMovConstReg::patch_set48(intptr_t x) {
972 jlong value = (jlong) x;
973 int rt_reg = (int_at(0) & (0x1f << 16));
974 int rs_reg = rt_reg << 5;
975 int rd_reg = rt_reg >> 5;
977 int hi = (int)(value >> 32);
978 int lo = (int)(value & ~0);
980 int count = 0;
982 if (value == lo) { // 32-bit integer
983 if (Assembler::is_simm16(value)) {
984 //daddiu(d, R0, value);
985 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
986 count += 1;
987 } else {
988 //lui(d, split_low(value >> 16));
989 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
990 count += 1;
991 if (Assembler::split_low(value)) {
992 //ori(d, d, split_low(value));
993 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
994 count += 1;
995 }
996 }
997 } else if (hi == 0) { // hardware zero-extends to upper 32
998 //ori(d, R0, julong(value) >> 16);
999 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
1000 count += 1;
1001 //dsll(d, d, 16);
1002 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1003 count += 1;
1004 if (Assembler::split_low(value)) {
1005 //ori(d, d, split_low(value));
1006 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1007 count += 1;
1008 }
1009 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1010 //lui(d, value >> 32);
1011 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
1012 count += 1;
1013 //ori(d, d, split_low(value >> 16));
1014 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
1015 count += 1;
1016 //dsll(d, d, 16);
1017 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1018 count += 1;
1019 //ori(d, d, split_low(value));
1020 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1021 count += 1;
1022 } else {
1023 tty->print_cr("value = 0x%x", value);
1024 guarantee(false, "Not supported yet !");
1025 }
1027 for (count; count < 4; count++) {
1028 //nop();
1029 set_int_at(count << 2, 0);
1030 }
1031 }
1033 void NativeMovConstReg::set_data(intptr_t x) {
1034 #ifndef _LP64
1035 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
1036 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
1037 ICache::invalidate_range(addr_at(0), 8);
1038 #else
1039 /* li64 or li48 */
1040 if (is_special_op(int_at(16), Assembler::dsll_op) && is_op(long_at(20), Assembler::ori_op)) {
1041 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 48) & 0xffff));
1042 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 32) & 0xffff));
1043 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 16) & 0xffff));
1044 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)x) & 0xffff));
1045 } else {
1046 patch_set48(x);
1047 }
1049 ICache::invalidate_range(addr_at(0), 24);
1050 #endif
1051 }
1053 //-------------------------------------------------------------------
1055 int NativeMovRegMem::offset() const{
1056 if (is_immediate())
1057 return (short)(int_at(instruction_offset)&0xffff);
1058 else
1059 return Assembler::merge(int_at(hiword_offset)&0xffff, long_at(instruction_offset)&0xffff);
1060 }
1062 void NativeMovRegMem::set_offset(int x) {
1063 if (is_immediate()) {
1064 assert(Assembler::is_simm16(x), "just check");
1065 set_int_at(0, (int_at(0)&0xffff0000) | (x&0xffff) );
1066 if (is_64ldst()) {
1067 assert(Assembler::is_simm16(x+4), "just check");
1068 set_int_at(4, (int_at(4)&0xffff0000) | ((x+4)&0xffff) );
1069 }
1070 } else {
1071 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
1072 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
1073 }
1074 ICache::invalidate_range(addr_at(0), 8);
1075 }
1077 void NativeMovRegMem::verify() {
1078 int offset = 0;
1080 if ( Assembler::opcode(int_at(0)) == Assembler::lui_op ) {
1081 #ifndef _LP64
1082 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op) ||
1083 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
1084 (Assembler::special(int_at(8)) != Assembler::add_op))
1085 #else
1086 /* Jin: fit MIPS64 */
1087 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op &&
1088 Assembler::opcode(int_at(4)) != Assembler::daddiu_op ) ||
1089 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
1090 (Assembler::special(int_at(8)) != Assembler::add_op
1091 && Assembler::special(int_at(8)) != Assembler::dadd_op))
1092 #endif
1093 fatal ("not a mov [reg+offs], reg instruction");
1094 offset += 12;
1095 }
1097 switch(Assembler::opcode(int_at(offset))) {
1098 case Assembler::lb_op:
1099 case Assembler::lbu_op:
1100 case Assembler::lh_op:
1101 case Assembler::lhu_op:
1102 case Assembler::lw_op:
1103 LP64_ONLY(case Assembler::ld_op:)
1104 case Assembler::lwc1_op:
1105 LP64_ONLY(case Assembler::ldc1_op:)
1106 case Assembler::sb_op:
1107 case Assembler::sh_op:
1108 case Assembler::sw_op:
1109 LP64_ONLY(case Assembler::sd_op:)
1110 case Assembler::swc1_op:
1111 LP64_ONLY(case Assembler::sdc1_op:)
1112 break;
1113 default:
1114 fatal ("not a mov [reg+offs], reg instruction");
1115 }
1116 }
1119 void NativeMovRegMem::print() {
1120 tty->print_cr("0x%x: mov reg, [reg + %x]", instruction_address(), offset());
1121 }
1125 void NativeIllegalInstruction::insert(address code_pos) {
1126 CodeBuffer cb(code_pos, instruction_size);
1127 MacroAssembler masm(&cb);
1128 #define __ masm.
1129 __ brk(11);
1130 #undef __
1132 ICache::invalidate_range(code_pos, instruction_size);
1133 }
1135 void NativeGeneralJump::verify() {
1136 assert(((NativeInstruction *)this)->is_jump() ||
1137 ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction");
1138 }
1140 void NativeGeneralJump::patch_set48_gs(address dest) {
1141 jlong value = (jlong) dest;
1142 int rt_reg = (int_at(0) & (0x1f << 16));
1144 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
1146 int rs_reg = rt_reg << 5;
1147 int rd_reg = rt_reg >> 5;
1149 int hi = (int)(value >> 32);
1150 int lo = (int)(value & ~0);
1152 int count = 0;
1154 int insts[4] = {0, 0, 0, 0};
1156 if (value == lo) { // 32-bit integer
1157 if (Assembler::is_simm16(value)) {
1158 //daddiu(d, R0, value);
1159 //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
1160 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
1161 count += 1;
1162 } else {
1163 //lui(d, split_low(value >> 16));
1164 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
1165 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
1166 count += 1;
1167 if (Assembler::split_low(value)) {
1168 //ori(d, d, split_low(value));
1169 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1170 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1171 count += 1;
1172 }
1173 }
1174 } else if (hi == 0) { // hardware zero-extends to upper 32
1175 //ori(d, R0, julong(value) >> 16);
1176 //set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
1177 insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
1178 count += 1;
1179 //dsll(d, d, 16);
1180 //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1181 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
1182 count += 1;
1183 if (Assembler::split_low(value)) {
1184 //ori(d, d, split_low(value));
1185 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1186 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1187 count += 1;
1188 }
1189 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1190 //lui(d, value >> 32);
1191 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
1192 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
1193 count += 1;
1194 //ori(d, d, split_low(value >> 16));
1195 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
1196 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
1197 count += 1;
1198 //dsll(d, d, 16);
1199 //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1200 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
1201 count += 1;
1202 //ori(d, d, split_low(value));
1203 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1204 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1205 count += 1;
1206 } else {
1207 tty->print_cr("dest = 0x%x", value);
1208 guarantee(false, "Not supported yet !");
1209 }
1211 for (count; count < 4; count++) {
1212 //nop();
1213 //set_int_at(count << 2, 0);
1214 insts[count] = 0;
1215 }
1217 atomic_store128_ptr func = get_atomic_store128_func();
1218 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
1220 ICache::invalidate_range(addr_at(0), 16);
1221 }
1223 void NativeGeneralJump::patch_set48(address dest) {
1224 jlong value = (jlong) dest;
1225 int rt_reg = (int_at(0) & (0x1f << 16));
1226 int rs_reg = rt_reg << 5;
1227 int rd_reg = rt_reg >> 5;
1229 int hi = (int)(value >> 32);
1230 int lo = (int)(value & ~0);
1232 int count = 0;
1234 if (value == lo) { // 32-bit integer
1235 if (Assembler::is_simm16(value)) {
1236 //daddiu(d, R0, value);
1237 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
1238 count += 1;
1239 } else {
1240 //lui(d, split_low(value >> 16));
1241 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
1242 count += 1;
1243 if (Assembler::split_low(value)) {
1244 //ori(d, d, split_low(value));
1245 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1246 count += 1;
1247 }
1248 }
1249 } else if (hi == 0) { // hardware zero-extends to upper 32
1250 //ori(d, R0, julong(value) >> 16);
1251 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
1252 count += 1;
1253 //dsll(d, d, 16);
1254 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1255 count += 1;
1256 if (Assembler::split_low(value)) {
1257 //ori(d, d, split_low(value));
1258 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1259 count += 1;
1260 }
1261 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1262 //lui(d, value >> 32);
1263 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
1264 count += 1;
1265 //ori(d, d, split_low(value >> 16));
1266 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
1267 count += 1;
1268 //dsll(d, d, 16);
1269 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1270 count += 1;
1271 //ori(d, d, split_low(value));
1272 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1273 count += 1;
1274 } else {
1275 tty->print_cr("dest = 0x%x", value);
1276 guarantee(false, "Not supported yet !");
1277 }
1279 for (count; count < 4; count++) {
1280 //nop();
1281 set_int_at(count << 2, 0);
1282 }
1284 ICache::invalidate_range(addr_at(0), 16);
1285 }
1288 void NativeGeneralJump::patch_on_j_gs(address dst) {
1289 #ifdef _LP64
1290 long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
1291 #else
1292 long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
1293 #endif
1294 if ((dest >= 0) && (dest < (1<<26))) {
1295 jint j_inst = (Assembler::j_op << 26) | dest;
1296 set_int_at(16, j_inst);
1297 ICache::invalidate_range(addr_at(16), 4);
1298 } else {
1299 ShouldNotReachHere();
1300 }
1301 }
1303 void NativeGeneralJump::patch_on_j(address dst) {
1304 patch_on_j_gs(dst);
1305 }
1307 void NativeGeneralJump::patch_on_jr_gs(address dst) {
1308 patch_set48_gs(dst);
1309 ICache::invalidate_range(addr_at(0), 16);
1310 }
1312 void NativeGeneralJump::patch_on_jr(address dst) {
1313 patch_set48(dst);
1314 ICache::invalidate_range(addr_at(0), 16);
1315 }
1318 void NativeGeneralJump::set_jump_destination(address dest) {
1319 //tty->print_cr("NativeGeneralJump::set_jump_destination dest=%lx", dest);
1320 OrderAccess::fence();
1322 if (is_short()) {
1323 assert(Assembler::is_simm16(dest-addr_at(4)), "change this code");
1324 set_int_at(0, (int_at(0) & 0xffff0000) | (dest - addr_at(4)) & 0xffff );
1325 ICache::invalidate_range(addr_at(0), 4);
1326 #ifdef _LP64
1327 } else if (is_b_far()) {
1328 int offset = dest - addr_at(12);
1329 set_int_at(12, (int_at(12) & 0xffff0000) | (offset >> 16));
1330 set_int_at(16, (int_at(16) & 0xffff0000) | (offset & 0xffff));
1331 #endif
1332 } else {
1333 #ifndef _LP64
1334 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
1335 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
1336 ICache::invalidate_range(addr_at(0), 8);
1337 #else
1338 if (is_op(int_at(16), Assembler::j_op)) {
1339 if (UseLoongsonISA) {
1340 patch_on_j_gs(dest);
1341 } else {
1342 patch_on_j(dest);
1343 }
1344 } else if (is_special_op(int_at(16), Assembler::jr_op)) {
1345 if (UseLoongsonISA) {
1346 guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
1347 patch_on_jr_gs(dest);
1348 } else {
1349 patch_on_jr(dest);
1350 }
1351 }
1352 #endif
1353 }
1354 }
1356 // we now use b to do this. be careful when using this method
1357 // by yjl 9/16/2005
1358 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
1359 CodeBuffer cb(code_pos, instruction_size);
1360 MacroAssembler masm(&cb);
1361 #define __ masm.
1362 #ifdef _LP64
1363 if (Assembler::is_simm16((entry - code_pos - 4) / 4))
1364 {
1365 __ b(entry);
1366 __ delayed()->nop();
1367 }
1368 else
1369 {
1370 /* a simplified b_far */
1371 int offset = entry - code_pos;
1373 // FIXME: need to preserve RA?
1374 __ emit_long(0x4110001); //__ emit_long(Assembler::insn_ORRI(Assembler::regimm_op, 0, Assembler::bgezal_op, 1));
1375 __ lui(T9, (offset - 8) >> 16); // delay slot
1376 __ ori(T9, T9, (offset - 8) & 0xffff);
1377 __ daddu(T9, T9, RA);
1378 __ jr(T9);
1379 __ nop();
1380 }
1381 #else
1382 __ b(entry);
1383 __ delayed()->nop();
1384 #endif
1385 #undef __
1387 ICache::invalidate_range(code_pos, instruction_size);
1388 }
1390 #ifdef _LP64
1391 bool NativeGeneralJump::is_b_far() {
1392 /*
1393 0x000000556809f198: dadd at, ra, zero
1394 0x000000556809f19c: [4110001]bgezal zero, 0x000000556809f1a4
1396 0x000000556809f1a0: nop
1397 0x000000556809f1a4: lui t9, 0xfffffffd
1398 0x000000556809f1a8: ori t9, t9, 0x14dc
1399 0x000000556809f1ac: daddu t9, t9, ra
1400 0x000000556809f1b0: dadd ra, at, zero
1401 0x000000556809f1b4: jr t9
1402 0x000000556809f1b8: nop
1403 ;; ImplicitNullCheckStub slow case
1404 0x000000556809f1bc: lui t9, 0x55
1405 */
1406 return is_op(int_at(12), Assembler::lui_op);
1407 }
1408 #endif
1410 address NativeGeneralJump::jump_destination() {
1411 if ( is_short() ) {
1412 return addr_at(4) + Assembler::imm_off(int_at(instruction_offset)) * 4;
1413 }
1414 #ifndef _LP64
1415 return (address)Assembler::merge(int_at(4)&0xffff, long_at(instruction_offset)&0xffff);
1416 #else
1417 /* 2012/4/19 Jin: Assembler::merge() is not correct in MIPS_64!
1419 Example:
1420 hi16 = 0xfffd,
1421 lo16 = f7a4,
1423 offset=0xfffdf7a4 (Right)
1424 Assembler::merge = 0xfffcf7a4 (Wrong)
1425 */
1426 if ( is_b_far() ) {
1427 int hi16 = int_at(12)&0xffff;
1428 int low16 = int_at(16)&0xffff;
1429 address target = addr_at(12) + (hi16 << 16) + low16;
1430 return target;
1431 }
1433 // nop
1434 // nop
1435 // nop
1436 // nop
1437 // j target
1438 // nop
1439 if ( nativeInstruction_at(addr_at(0))->is_nop() &&
1440 nativeInstruction_at(addr_at(4))->is_nop() &&
1441 nativeInstruction_at(addr_at(8))->is_nop() &&
1442 nativeInstruction_at(addr_at(12))->is_nop() &&
1443 is_op(int_at(16), Assembler::j_op) &&
1444 nativeInstruction_at(addr_at(20))->is_nop()) {
1445 int instr_index = int_at(16) & 0x3ffffff;
1446 intptr_t target_high = ((intptr_t)addr_at(20)) & 0xfffffffff0000000;
1447 intptr_t target = target_high | (instr_index << 2);
1448 return (address)target;
1449 }
1451 // li64
1452 if ( is_op(Assembler::lui_op) &&
1453 is_op(int_at(4), Assembler::ori_op) &&
1454 is_special_op(int_at(8), Assembler::dsll_op) &&
1455 is_op(int_at(12), Assembler::ori_op) &&
1456 is_special_op(int_at(16), Assembler::dsll_op) &&
1457 is_op(int_at(20), Assembler::ori_op) ) {
1459 return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
1460 (intptr_t)(int_at(12) & 0xffff),
1461 (intptr_t)(int_at(4) & 0xffff),
1462 (intptr_t)(int_at(0) & 0xffff));
1463 }
1465 //lui dst, imm16
1466 //ori dst, dst, imm16
1467 //dsll dst, dst, 16
1468 //ori dst, dst, imm16
1469 if ( is_op(Assembler::lui_op) &&
1470 is_op (int_at(4), Assembler::ori_op) &&
1471 is_special_op(int_at(8), Assembler::dsll_op) &&
1472 is_op (int_at(12), Assembler::ori_op) ) {
1474 return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
1475 (intptr_t)(int_at(4) & 0xffff),
1476 (intptr_t)(int_at(0) & 0xffff),
1477 (intptr_t)0);
1478 }
1480 //ori dst, R0, imm16
1481 //dsll dst, dst, 16
1482 //ori dst, dst, imm16
1483 //nop
1484 if ( is_op(Assembler::ori_op) &&
1485 is_special_op(int_at(4), Assembler::dsll_op) &&
1486 is_op (int_at(8), Assembler::ori_op) &&
1487 nativeInstruction_at(addr_at(12))->is_nop()) {
1489 return (address)Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
1490 (intptr_t)(int_at(0) & 0xffff),
1491 (intptr_t)0,
1492 (intptr_t)0);
1493 }
1495 //ori dst, R0, imm16
1496 //dsll dst, dst, 16
1497 //nop
1498 //nop
1499 if ( is_op(Assembler::ori_op) &&
1500 is_special_op(int_at(4), Assembler::dsll_op) &&
1501 nativeInstruction_at(addr_at(8))->is_nop() &&
1502 nativeInstruction_at(addr_at(12))->is_nop()) {
1504 return (address)Assembler::merge( (intptr_t)(0),
1505 (intptr_t)(int_at(0) & 0xffff),
1506 (intptr_t)0,
1507 (intptr_t)0);
1508 }
1510 //daddiu dst, R0, imm16
1511 //nop
1512 //nop
1513 //nop
1514 if ( is_op(Assembler::daddiu_op) &&
1515 nativeInstruction_at(addr_at(4))->is_nop() &&
1516 nativeInstruction_at(addr_at(8))->is_nop() &&
1517 nativeInstruction_at(addr_at(12))->is_nop() ) {
1519 int sign = int_at(0) & 0x8000;
1520 if (sign == 0) {
1521 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
1522 (intptr_t)0,
1523 (intptr_t)0,
1524 (intptr_t)0);
1525 } else {
1526 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
1527 (intptr_t)(0xffff),
1528 (intptr_t)(0xffff),
1529 (intptr_t)(0xffff));
1530 }
1531 }
1533 //lui dst, imm16
1534 //ori dst, dst, imm16
1535 //nop
1536 //nop
1537 if ( is_op(Assembler::lui_op) &&
1538 is_op (int_at(4), Assembler::ori_op) &&
1539 nativeInstruction_at(addr_at(8))->is_nop() &&
1540 nativeInstruction_at(addr_at(12))->is_nop() ) {
1542 int sign = int_at(0) & 0x8000;
1543 if (sign == 0) {
1544 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
1545 (intptr_t)(int_at(0) & 0xffff),
1546 (intptr_t)0,
1547 (intptr_t)0);
1548 } else {
1549 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
1550 (intptr_t)(int_at(0) & 0xffff),
1551 (intptr_t)(0xffff),
1552 (intptr_t)(0xffff));
1553 }
1554 }
1556 //lui dst, imm16
1557 //nop
1558 //nop
1559 //nop
1560 if ( is_op(Assembler::lui_op) &&
1561 nativeInstruction_at(addr_at(4))->is_nop() &&
1562 nativeInstruction_at(addr_at(8))->is_nop() &&
1563 nativeInstruction_at(addr_at(12))->is_nop() ) {
1565 int sign = int_at(0) & 0x8000;
1566 if (sign == 0) {
1567 return (address)Assembler::merge( (intptr_t)0,
1568 (intptr_t)(int_at(0) & 0xffff),
1569 (intptr_t)0,
1570 (intptr_t)0);
1571 } else {
1572 return (address)Assembler::merge( (intptr_t)0,
1573 (intptr_t)(int_at(0) & 0xffff),
1574 (intptr_t)(0xffff),
1575 (intptr_t)(0xffff));
1576 }
1577 }
1579 #endif
1580 }
1582 // MT-safe patching of a long jump instruction.
1583 // First patches first word of instruction to two jmp's that jmps to them
1584 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
1585 // the jmp's with the first 4 byte of the new instruction.
1586 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
1587 NativeGeneralJump* h_jump = nativeGeneralJump_at (instr_addr);
1588 assert(NativeGeneralJump::instruction_size == NativeCall::instruction_size,
1589 "note::Runtime1::patch_code uses NativeCall::instruction_size");
1591 /* 2013/6/13 Jin: ensure 100% atomicity */
1592 guarantee(!os::is_MP() || (((long)instr_addr % BytesPerWord) == 0), "destination must be aligned for SD");
1594 int *p = (int *)instr_addr;
1595 int jr_word = p[4];
1597 p[4] = 0x1000fffb; /* .1: --; --; --; --; b .1; nop */
1598 memcpy(instr_addr, code_buffer, NativeCall::instruction_size - 8);
1599 *(long *)(instr_addr + 16) = *(long *)(code_buffer + 16);
1600 }
1602 /* Must ensure atomicity */
1603 void NativeGeneralJump::patch_verified_entry(address entry, address verified_entry, address dest) {
1604 /* 2013/11/5 Jin: ensure 100% atomicity.
1605 * The destination is fixed and can be cached in JavaThread.
1606 */
1607 guarantee(!os::is_MP() || (((long)verified_entry % BytesPerWord) == 0), "destination must be aligned for SD");
1609 int code_buffer[4];
1611 CodeBuffer cb((address)code_buffer, instruction_size);
1612 MacroAssembler masm(&cb);
1613 #define __ masm.
1614 __ ld(T9, TREG, in_bytes(JavaThread::handle_wrong_method_stub_offset()));
1615 __ jr(T9);
1616 __ delayed()->nop();
1617 __ nop();
1619 atomic_store128_ptr func = get_atomic_store128_func();
1620 (*func)((long *)verified_entry, 0, *(long *)&code_buffer[0], *(long *)&code_buffer[2]);
1622 ICache::invalidate_range(verified_entry, instruction_size);
1623 }
1625 bool NativeInstruction::is_jump()
1626 {
1627 #ifndef _LP64
1628 return ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode) ||
1629 (is_op(int_at(0), Assembler::lui_op) &&
1630 is_op(int_at(4), Assembler::addiu_op) &&
1631 is_special_op(int_at(8), Assembler::jr_op));
1632 #else
1633 // lui rd, imm(63...48);
1634 // ori rd, rd, imm(47...32);
1635 // dsll rd, rd, 16;
1636 // ori rd, rd, imm(31...16);
1637 // dsll rd, rd, 16;
1638 // ori rd, rd, imm(15...0);
1639 // jalr rd
1640 // nop
1641 //
1642 if ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode)
1643 return true;
1644 if (is_op(int_at(4), Assembler::lui_op)) /* simplified b_far */
1645 return true;
1646 if (is_op(int_at(12), Assembler::lui_op)) /* original b_far */
1647 return true;
1649 // nop
1650 // nop
1651 // nop
1652 // nop
1653 // j target
1654 // nop
1655 if ( is_nop() &&
1656 nativeInstruction_at(addr_at(4))->is_nop() &&
1657 nativeInstruction_at(addr_at(8))->is_nop() &&
1658 nativeInstruction_at(addr_at(12))->is_nop() &&
1659 nativeInstruction_at(addr_at(16))->is_op(Assembler::j_op) &&
1660 nativeInstruction_at(addr_at(20))->is_nop() ) {
1661 return true;
1662 }
1664 if (is_op(int_at(0), Assembler::lui_op) &&
1665 is_op(int_at(4), Assembler::ori_op) &&
1666 is_special_op(int_at(8), Assembler::dsll_op) &&
1667 is_op(int_at(12), Assembler::ori_op) &&
1668 is_special_op(int_at(16), Assembler::dsll_op) &&
1669 is_op(int_at(20), Assembler::ori_op))
1670 return true;
1671 if (is_op(int_at(0), Assembler::lui_op) &&
1672 is_op(int_at(4), Assembler::ori_op) &&
1673 is_special_op(int_at(8), Assembler::dsll_op) &&
1674 is_op(int_at(12), Assembler::ori_op))
1675 return true;
1677 //ori dst, R0, imm16
1678 //dsll dst, dst, 16
1679 //ori dst, dst, imm16
1680 //nop
1681 if ( is_op(Assembler::ori_op) &&
1682 is_special_op(int_at(4), Assembler::dsll_op) &&
1683 is_op (int_at(8), Assembler::ori_op) &&
1684 nativeInstruction_at(addr_at(12))->is_nop()) {
1685 return true;
1686 }
1688 //ori dst, R0, imm16
1689 //dsll dst, dst, 16
1690 //nop
1691 //nop
1692 if ( is_op(Assembler::ori_op) &&
1693 is_special_op(int_at(4), Assembler::dsll_op) &&
1694 nativeInstruction_at(addr_at(8))->is_nop() &&
1695 nativeInstruction_at(addr_at(12))->is_nop()) {
1696 return true;
1697 }
1699 //daddiu dst, R0, imm16
1700 //nop
1701 //nop
1702 //nop
1703 if ( is_op(Assembler::daddiu_op) &&
1704 nativeInstruction_at(addr_at(4))->is_nop() &&
1705 nativeInstruction_at(addr_at(8))->is_nop() &&
1706 nativeInstruction_at(addr_at(12))->is_nop() ) {
1707 return true;
1708 }
1710 //lui dst, imm16
1711 //ori dst, dst, imm16
1712 //nop
1713 //nop
1714 if ( is_op(Assembler::lui_op) &&
1715 is_op (int_at(4), Assembler::ori_op) &&
1716 nativeInstruction_at(addr_at(8))->is_nop() &&
1717 nativeInstruction_at(addr_at(12))->is_nop() ) {
1718 return true;
1719 }
1721 //lui dst, imm16
1722 //nop
1723 //nop
1724 //nop
1725 if ( is_op(Assembler::lui_op) &&
1726 nativeInstruction_at(addr_at(4))->is_nop() &&
1727 nativeInstruction_at(addr_at(8))->is_nop() &&
1728 nativeInstruction_at(addr_at(12))->is_nop() ) {
1729 return true;
1730 }
1732 return false;
1733 #endif
1734 }
1736 bool NativeInstruction::is_dtrace_trap() {
1737 //return (*(int32_t*)this & 0xff) == 0xcc;
1738 Unimplemented();
1739 return false;
1740 }
1742 bool NativeInstruction::is_safepoint_poll() {
1743 #ifdef _LP64
1744 /*
1745 390 li T2, 0x0000000000400000 #@loadConP
1746 394 sw [SP + #12], V1 # spill 9
1747 398 Safepoint @ [T2] : poll for GC @ safePoint_poll # spec.benchmarks.compress.Decompressor::decompress @ bci:224 L[0]=A6 L[1]=_ L[2]=sp + #28 L[3]=_ L[4]=V1
1749 0x000000ffe5815130: lui t2, 0x40
1750 0x000000ffe5815134: sw v1, 0xc(sp) ; OopMap{a6=Oop off=920}
1751 ;*goto
1752 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
1754 0x000000ffe5815138: lw at, 0x0(t2) ;*goto <--- PC
1755 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
1756 */
1758 // Since there may be some spill instructions between the safePoint_poll and loadConP,
1759 // we check the safepoint instruction like the this.
1760 return is_op(Assembler::lw_op) && is_rt(AT);
1761 #else
1762 return is_op(int_at(-4), Assembler::lui_op) &&
1763 is_op(Assembler::lw_op) &&
1764 is_rt(AT);
1765 #endif
1766 }