Thu, 24 May 2018 19:49:50 +0800
some C1 fix
Contributed-by: chenhaoxuan, zhaixiang, aoqi
1 /*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2018, 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 void NativeCall::verify() {
116 // make sure code pattern is actually a call instruction
117 #ifndef _LP64
118 if ( !is_op(Assembler::lui_op) ||
119 !is_op(int_at(4), Assembler::addiu_op) ||
120 !is_special_op(int_at(8), Assembler::jalr_op) ) {
121 fatal("not a call");
122 }
123 #else
125 // nop
126 // nop
127 // nop
128 // nop
129 // jal targe
130 // nop
131 if ( is_nop() &&
132 nativeInstruction_at(addr_at(4))->is_nop() &&
133 nativeInstruction_at(addr_at(8))->is_nop() &&
134 nativeInstruction_at(addr_at(12))->is_nop() &&
135 is_op(int_at(16), Assembler::jal_op) &&
136 nativeInstruction_at(addr_at(20))->is_nop() ) {
137 return;
138 }
140 // jal targe
141 // nop
142 if ( is_op(int_at(0), Assembler::jal_op) &&
143 nativeInstruction_at(addr_at(4))->is_nop() ) {
144 return;
145 }
147 // li64
148 if ( is_op(Assembler::lui_op) &&
149 is_op(int_at(4), Assembler::ori_op) &&
150 is_special_op(int_at(8), Assembler::dsll_op) &&
151 is_op(int_at(12), Assembler::ori_op) &&
152 is_special_op(int_at(16), Assembler::dsll_op) &&
153 is_op(int_at(20), Assembler::ori_op) &&
154 is_special_op(int_at(24), Assembler::jalr_op) ) {
155 return;
156 }
158 //lui dst, imm16
159 //ori dst, dst, imm16
160 //dsll dst, dst, 16
161 //ori dst, dst, imm16
162 if ( is_op(Assembler::lui_op) &&
163 is_op (int_at(4), Assembler::ori_op) &&
164 is_special_op(int_at(8), Assembler::dsll_op) &&
165 is_op (int_at(12), Assembler::ori_op) &&
166 is_special_op(int_at(16), Assembler::jalr_op) ) {
167 return;
168 }
170 //ori dst, R0, imm16
171 //dsll dst, dst, 16
172 //ori dst, dst, imm16
173 //nop
174 if ( is_op(Assembler::ori_op) &&
175 is_special_op(int_at(4), Assembler::dsll_op) &&
176 is_op (int_at(8), Assembler::ori_op) &&
177 nativeInstruction_at(addr_at(12))->is_nop() &&
178 is_special_op(int_at(16), Assembler::jalr_op) ) {
179 return;
180 }
182 //ori dst, R0, imm16
183 //dsll dst, dst, 16
184 //nop
185 //nop
186 if ( is_op(Assembler::ori_op) &&
187 is_special_op(int_at(4), Assembler::dsll_op) &&
188 nativeInstruction_at(addr_at(8))->is_nop() &&
189 nativeInstruction_at(addr_at(12))->is_nop() &&
190 is_special_op(int_at(16), Assembler::jalr_op) ) {
191 return;
192 }
194 //daddiu dst, R0, imm16
195 //nop
196 //nop
197 //nop
198 if ( is_op(Assembler::daddiu_op) &&
199 nativeInstruction_at(addr_at(4))->is_nop() &&
200 nativeInstruction_at(addr_at(8))->is_nop() &&
201 nativeInstruction_at(addr_at(12))->is_nop() &&
202 is_special_op(int_at(16), Assembler::jalr_op) ) {
203 return;
204 }
206 //daddiu dst, R0, imm16
207 //nop
208 //nop
209 //nop
210 if ( is_op(Assembler::daddiu_op) &&
211 nativeInstruction_at(addr_at(4))->is_nop() &&
212 nativeInstruction_at(addr_at(8))->is_nop() &&
213 nativeInstruction_at(addr_at(12))->is_nop() &&
214 is_special_op(int_at(16), Assembler::jr_op) ) {
215 return;
216 }
218 //lui dst, imm16
219 //ori dst, dst, imm16
220 //nop
221 //nop
222 if ( is_op(Assembler::lui_op) &&
223 is_op (int_at(4), Assembler::ori_op) &&
224 nativeInstruction_at(addr_at(8))->is_nop() &&
225 nativeInstruction_at(addr_at(12))->is_nop() &&
226 is_special_op(int_at(16), Assembler::jalr_op) ) {
227 return;
228 }
230 //lui dst, imm16
231 //nop
232 //nop
233 //nop
234 if ( is_op(Assembler::lui_op) &&
235 nativeInstruction_at(addr_at(4))->is_nop() &&
236 nativeInstruction_at(addr_at(8))->is_nop() &&
237 nativeInstruction_at(addr_at(12))->is_nop() &&
238 is_special_op(int_at(16), Assembler::jalr_op) ) {
239 return;
240 }
242 //daddiu dst, R0, imm16
243 //nop
244 if ( is_op(Assembler::daddiu_op) &&
245 nativeInstruction_at(addr_at(4))->is_nop() &&
246 is_special_op(int_at(8), Assembler::jalr_op) ) {
247 return;
248 }
250 //lui dst, imm16
251 //ori dst, dst, imm16
252 if ( is_op(Assembler::lui_op) &&
253 is_op (int_at(4), Assembler::ori_op) &&
254 is_special_op(int_at(8), Assembler::jalr_op) ) {
255 return;
256 }
258 //lui dst, imm16
259 //nop
260 if ( is_op(Assembler::lui_op) &&
261 nativeInstruction_at(addr_at(4))->is_nop() &&
262 is_special_op(int_at(8), Assembler::jalr_op) ) {
263 return;
264 }
266 fatal("not a call");
267 #endif
268 }
270 address NativeCall::destination() const {
271 #ifndef _LP64
272 return (address)Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
273 #else
274 // jal target
275 // nop
276 if ( is_op(int_at(0), Assembler::jal_op) &&
277 nativeInstruction_at(addr_at(4))->is_nop()) {
278 int instr_index = int_at(0) & 0x3ffffff;
279 intptr_t target_high = ((intptr_t)addr_at(4)) & 0xfffffffff0000000;
280 intptr_t target = target_high | (instr_index << 2);
281 return (address)target;
282 }
284 // nop
285 // nop
286 // nop
287 // nop
288 // jal target
289 // nop
290 if ( nativeInstruction_at(addr_at(0))->is_nop() &&
291 nativeInstruction_at(addr_at(4))->is_nop() &&
292 nativeInstruction_at(addr_at(8))->is_nop() &&
293 nativeInstruction_at(addr_at(12))->is_nop() &&
294 is_op(int_at(16), Assembler::jal_op) &&
295 nativeInstruction_at(addr_at(20))->is_nop()) {
296 int instr_index = int_at(16) & 0x3ffffff;
297 intptr_t target_high = ((intptr_t)addr_at(20)) & 0xfffffffff0000000;
298 intptr_t target = target_high | (instr_index << 2);
299 return (address)target;
300 }
302 // li64
303 if ( is_op(Assembler::lui_op) &&
304 is_op(int_at(4), Assembler::ori_op) &&
305 is_special_op(int_at(8), Assembler::dsll_op) &&
306 is_op(int_at(12), Assembler::ori_op) &&
307 is_special_op(int_at(16), Assembler::dsll_op) &&
308 is_op(int_at(20), Assembler::ori_op) ) {
310 return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
311 (intptr_t)(int_at(12) & 0xffff),
312 (intptr_t)(int_at(4) & 0xffff),
313 (intptr_t)(int_at(0) & 0xffff));
314 }
316 //lui dst, imm16
317 //ori dst, dst, imm16
318 //dsll dst, dst, 16
319 //ori dst, dst, imm16
320 if ( is_op(Assembler::lui_op) &&
321 is_op (int_at(4), Assembler::ori_op) &&
322 is_special_op(int_at(8), Assembler::dsll_op) &&
323 is_op (int_at(12), Assembler::ori_op) ) {
325 return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
326 (intptr_t)(int_at(4) & 0xffff),
327 (intptr_t)(int_at(0) & 0xffff),
328 (intptr_t)0);
329 }
331 //ori dst, R0, imm16
332 //dsll dst, dst, 16
333 //ori dst, dst, imm16
334 //nop
335 if ( is_op(Assembler::ori_op) &&
336 is_special_op(int_at(4), Assembler::dsll_op) &&
337 is_op (int_at(8), Assembler::ori_op) &&
338 nativeInstruction_at(addr_at(12))->is_nop()) {
340 return (address)Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
341 (intptr_t)(int_at(0) & 0xffff),
342 (intptr_t)0,
343 (intptr_t)0);
344 }
346 //ori dst, R0, imm16
347 //dsll dst, dst, 16
348 //nop
349 //nop
350 if ( is_op(Assembler::ori_op) &&
351 is_special_op(int_at(4), Assembler::dsll_op) &&
352 nativeInstruction_at(addr_at(8))->is_nop() &&
353 nativeInstruction_at(addr_at(12))->is_nop()) {
355 return (address)Assembler::merge( (intptr_t)(0),
356 (intptr_t)(int_at(0) & 0xffff),
357 (intptr_t)0,
358 (intptr_t)0);
359 }
361 //daddiu dst, R0, imm16
362 //nop
363 //nop <-- optional
364 //nop <-- optional
365 if ( is_op(Assembler::daddiu_op) &&
366 nativeInstruction_at(addr_at(4))->is_nop() ) {
368 int sign = int_at(0) & 0x8000;
369 if (sign == 0) {
370 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
371 (intptr_t)0,
372 (intptr_t)0,
373 (intptr_t)0);
374 } else {
375 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
376 (intptr_t)(0xffff),
377 (intptr_t)(0xffff),
378 (intptr_t)(0xffff));
379 }
380 }
382 //lui dst, imm16
383 //ori dst, dst, imm16
384 //nop <-- optional
385 //nop <-- optional
386 if ( is_op(Assembler::lui_op) &&
387 is_op (int_at(4), Assembler::ori_op) ) {
389 int sign = int_at(0) & 0x8000;
390 if (sign == 0) {
391 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
392 (intptr_t)(int_at(0) & 0xffff),
393 (intptr_t)0,
394 (intptr_t)0);
395 } else {
396 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
397 (intptr_t)(int_at(0) & 0xffff),
398 (intptr_t)(0xffff),
399 (intptr_t)(0xffff));
400 }
401 }
403 //lui dst, imm16
404 //nop
405 //nop <-- optional
406 //nop <-- optional
407 if ( is_op(Assembler::lui_op) &&
408 nativeInstruction_at(addr_at(4))->is_nop() ) {
410 int sign = int_at(0) & 0x8000;
411 if (sign == 0) {
412 return (address)Assembler::merge( (intptr_t)0,
413 (intptr_t)(int_at(0) & 0xffff),
414 (intptr_t)0,
415 (intptr_t)0);
416 } else {
417 return (address)Assembler::merge( (intptr_t)0,
418 (intptr_t)(int_at(0) & 0xffff),
419 (intptr_t)(0xffff),
420 (intptr_t)(0xffff));
421 }
422 }
424 fatal("not a call");
425 #endif
426 }
428 /* 2013/6/14 Jin: manual implementation of GSSQ
429 *
430 * 00000001200009c0 <atomic_store128>:
431 * 1200009c0: 0085202d daddu a0, a0, a1
432 * 1200009c4: e8860027 gssq a2, a3, 0(a0)
433 * 1200009c8: 03e00008 jr ra
434 * 1200009cc: 00000000 nop
435 */
436 typedef void (* atomic_store128_ptr)(long *addr, int offset, long low64, long hi64);
438 static int *buf;
440 static atomic_store128_ptr get_atomic_store128_func() {
441 assert(UseLoongsonISA, "UseLoongsonISA must be true");
442 static atomic_store128_ptr p = NULL;
443 if (p != NULL)
444 return p;
446 buf = (int *)mmap(NULL, 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS,
447 -1, 0);
448 buf[0] = 0x0085202d;
449 buf[1] = (0x3a << 26) | (4 << 21) | (6 << 16) | 0x27; /* gssq $a2, $a3, 0($a0) */
450 buf[2] = 0x03e00008;
451 buf[3] = 0;
453 asm("sync");
454 p = (atomic_store128_ptr)buf;
455 return p;
456 }
458 void NativeCall::patch_on_jal_only(address dst) {
459 #ifdef _LP64
460 long dest = ((long)dst - (((long)addr_at(4)) & 0xfffffffff0000000))>>2;
461 #else
462 long dest = ((long)dst - (((long)addr_at(4)) & 0xf0000000))>>2;
463 #endif
464 if ((dest >= 0) && (dest < (1<<26))) {
465 jint jal_inst = (Assembler::jal_op << 26) | dest;
466 set_int_at(0, jal_inst);
467 ICache::invalidate_range(addr_at(0), 4);
468 } else {
469 ShouldNotReachHere();
470 }
471 }
473 void NativeCall::patch_on_jal_gs(address dst) {
474 #ifdef _LP64
475 long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
476 #else
477 long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
478 #endif
479 if ((dest >= 0) && (dest < (1<<26))) {
480 jint jal_inst = (Assembler::jal_op << 26) | dest;
481 set_int_at(16, jal_inst);
482 ICache::invalidate_range(addr_at(16), 4);
483 } else {
484 ShouldNotReachHere();
485 }
486 }
488 void NativeCall::patch_on_jal(address dst) {
489 patch_on_jal_gs(dst);
490 }
492 void NativeCall::patch_on_jalr_gs(address dst) {
493 patch_set48_gs(dst);
494 }
496 void NativeCall::patch_on_jalr(address dst) {
497 patch_set48(dst);
498 }
500 void NativeCall::patch_set48_gs(address dest) {
501 jlong value = (jlong) dest;
502 int rt_reg = (int_at(0) & (0x1f << 16));
504 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
506 int rs_reg = rt_reg << 5;
507 int rd_reg = rt_reg >> 5;
509 int hi = (int)(value >> 32);
510 int lo = (int)(value & ~0);
511 int count = 0;
512 int insts[4] = {0, 0, 0, 0};
514 if (value == lo) { // 32-bit integer
515 if (Assembler::is_simm16(value)) {
516 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
517 count += 1;
518 } else {
519 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
520 count += 1;
521 if (Assembler::split_low(value)) {
522 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
523 count += 1;
524 }
525 }
526 } else if (hi == 0) { // hardware zero-extends to upper 32
527 insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
528 count += 1;
529 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
530 count += 1;
531 if (Assembler::split_low(value)) {
532 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
533 count += 1;
534 }
535 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
536 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
537 count += 1;
538 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
539 count += 1;
540 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
541 count += 1;
542 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
543 count += 1;
544 } else {
545 tty->print_cr("dest = 0x%x", value);
546 guarantee(false, "Not supported yet !");
547 }
549 for (count; count < 4; count++) {
550 insts[count] = 0;
551 }
553 atomic_store128_ptr func = get_atomic_store128_func();
554 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
556 ICache::invalidate_range(addr_at(0), 16);
557 }
559 void NativeCall::patch_set32_gs(address dest) {
560 jlong value = (jlong) dest;
561 int rt_reg = (int_at(0) & (0x1f << 16));
563 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
565 int rs_reg = rt_reg << 5;
566 int rd_reg = rt_reg >> 5;
568 int hi = (int)(value >> 32);
569 int lo = (int)(value & ~0);
571 int count = 0;
573 int insts[2] = {0, 0};
575 if (value == lo) { // 32-bit integer
576 if (Assembler::is_simm16(value)) {
577 //daddiu(d, R0, value);
578 //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
579 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
580 count += 1;
581 } else {
582 //lui(d, split_low(value >> 16));
583 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
584 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
585 count += 1;
586 if (Assembler::split_low(value)) {
587 //ori(d, d, split_low(value));
588 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
589 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
590 count += 1;
591 }
592 }
593 } else {
594 tty->print_cr("dest = 0x%x", value);
595 guarantee(false, "Not supported yet !");
596 }
598 for (count; count < 2; count++) {
599 //nop();
600 //set_int_at(count << 2, 0);
601 insts[count] = 0;
602 }
604 long inst = insts[1];
605 inst = inst << 32;
606 inst = inst + insts[0];
608 set_long_at(0, inst);
609 }
611 void NativeCall::patch_set48(address dest) {
612 jlong value = (jlong) dest;
613 int rt_reg = (int_at(0) & (0x1f << 16));
615 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
617 int rs_reg = rt_reg << 5;
618 int rd_reg = rt_reg >> 5;
620 int hi = (int)(value >> 32);
621 int lo = (int)(value & ~0);
623 int count = 0;
625 if (value == lo) { // 32-bit integer
626 if (Assembler::is_simm16(value)) {
627 //daddiu(d, R0, value);
628 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
629 count += 1;
630 } else {
631 //lui(d, split_low(value >> 16));
632 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
633 count += 1;
634 if (Assembler::split_low(value)) {
635 //ori(d, d, split_low(value));
636 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
637 count += 1;
638 }
639 }
640 } else if (hi == 0) { // hardware zero-extends to upper 32
641 //ori(d, R0, julong(value) >> 16);
642 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
643 count += 1;
644 //dsll(d, d, 16);
645 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
646 count += 1;
647 if (Assembler::split_low(value)) {
648 //ori(d, d, split_low(value));
649 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
650 count += 1;
651 }
652 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
653 //lui(d, value >> 32);
654 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
655 count += 1;
656 //ori(d, d, split_low(value >> 16));
657 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
658 count += 1;
659 //dsll(d, d, 16);
660 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
661 count += 1;
662 //ori(d, d, split_low(value));
663 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
664 count += 1;
665 } else {
666 tty->print_cr("dest = 0x%x", value);
667 guarantee(false, "Not supported yet !");
668 }
670 for (count; count < 4; count++) {
671 //nop();
672 set_int_at(count << 2, 0);
673 }
675 ICache::invalidate_range(addr_at(0), 16);
676 }
678 void NativeCall::patch_set32(address dest) {
679 patch_set32_gs(dest);
680 }
682 void NativeCall::set_destination(address dest) {
683 #ifndef _LP64
684 OrderAccess::fence();
685 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
686 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
687 ICache::invalidate_range(addr_at(0), 8);
688 #else
689 OrderAccess::fence();
691 // li64
692 if (is_special_op(int_at(16), Assembler::dsll_op)) {
693 int first_word = int_at(0);
694 set_int_at(0, 0x1000ffff); /* .1: b .1 */
695 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 32) & 0xffff));
696 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 16) & 0xffff));
697 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
698 set_int_at(0, (first_word & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 48) & 0xffff));
699 ICache::invalidate_range(addr_at(0), 24);
700 } else if (is_op(int_at(16), Assembler::jal_op)) {
701 if (UseLoongsonISA) {
702 patch_on_jal_gs(dest);
703 } else {
704 patch_on_jal(dest);
705 }
706 } else if (is_op(int_at(0), Assembler::jal_op)) {
707 patch_on_jal_only(dest);
708 } else if (is_special_op(int_at(16), Assembler::jalr_op)) {
709 if (UseLoongsonISA) {
710 patch_on_jalr(dest);
711 } else {
712 patch_on_jalr(dest);
713 }
714 } else if (is_special_op(int_at(8), Assembler::jalr_op)) {
715 guarantee(!os::is_MP() || (((long)addr_at(0) % 8) == 0), "destination must be aligned by 8");
716 if (UseLoongsonISA) {
717 patch_set32_gs(dest);
718 } else {
719 patch_set32(dest);
720 }
721 ICache::invalidate_range(addr_at(0), 8);
722 } else {
723 fatal("not a call");
724 }
725 #endif
726 }
728 void NativeCall::print() {
729 tty->print_cr(PTR_FORMAT ": call " PTR_FORMAT,
730 instruction_address(), destination());
731 }
733 // Inserts a native call instruction at a given pc
734 void NativeCall::insert(address code_pos, address entry) {
735 NativeCall *call = nativeCall_at(code_pos);
736 CodeBuffer cb(call->addr_at(0), instruction_size);
737 MacroAssembler masm(&cb);
738 #define __ masm.
739 #ifndef _LP64
740 __ lui(T9, Assembler::split_high((int)entry));
741 __ addiu(T9, T9, Assembler::split_low((int)entry));
742 #else
743 __ li48(T9, (long)entry);
744 #endif
745 __ jalr ();
746 __ delayed()->nop();
747 #undef __
749 ICache::invalidate_range(call->addr_at(0), instruction_size);
750 }
752 // MT-safe patching of a call instruction.
753 // First patches first word of instruction to two jmp's that jmps to them
754 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
755 // the jmp's with the first 4 byte of the new instruction.
756 void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
757 Unimplemented();
758 }
760 //-------------------------------------------------------------------
762 void NativeMovConstReg::verify() {
763 #ifndef _LP64
764 if ( !is_op(Assembler::lui_op) ||
765 !is_op(int_at(4), Assembler::addiu_op) )
766 fatal("not a mov reg, imm32")
767 #else
768 // li64
769 if ( is_op(Assembler::lui_op) &&
770 is_op(int_at(4), Assembler::ori_op) &&
771 is_special_op(int_at(8), Assembler::dsll_op) &&
772 is_op(int_at(12), Assembler::ori_op) &&
773 is_special_op(int_at(16), Assembler::dsll_op) &&
774 is_op(int_at(20), Assembler::ori_op) ) {
775 return;
776 }
778 //lui dst, imm16
779 //ori dst, dst, imm16
780 //dsll dst, dst, 16
781 //ori dst, dst, imm16
782 if ( is_op(Assembler::lui_op) &&
783 is_op (int_at(4), Assembler::ori_op) &&
784 is_special_op(int_at(8), Assembler::dsll_op) &&
785 is_op (int_at(12), Assembler::ori_op) ) {
786 return;
787 }
789 //ori dst, R0, imm16
790 //dsll dst, dst, 16
791 //ori dst, dst, imm16
792 //nop
793 if ( is_op(Assembler::ori_op) &&
794 is_special_op(int_at(4), Assembler::dsll_op) &&
795 is_op (int_at(8), Assembler::ori_op) &&
796 nativeInstruction_at(addr_at(12))->is_nop()) {
797 return;
798 }
800 //ori dst, R0, imm16
801 //dsll dst, dst, 16
802 //nop
803 //nop
804 if ( is_op(Assembler::ori_op) &&
805 is_special_op(int_at(4), Assembler::dsll_op) &&
806 nativeInstruction_at(addr_at(8))->is_nop() &&
807 nativeInstruction_at(addr_at(12))->is_nop()) {
808 return;
809 }
811 //daddiu dst, R0, imm16
812 //nop
813 //nop
814 //nop
815 if ( is_op(Assembler::daddiu_op) &&
816 nativeInstruction_at(addr_at(4))->is_nop() &&
817 nativeInstruction_at(addr_at(8))->is_nop() &&
818 nativeInstruction_at(addr_at(12))->is_nop() ) {
819 return;
820 }
822 //lui dst, imm16
823 //ori dst, dst, imm16
824 //nop
825 //nop
826 if ( is_op(Assembler::lui_op) &&
827 is_op (int_at(4), Assembler::ori_op) &&
828 nativeInstruction_at(addr_at(8))->is_nop() &&
829 nativeInstruction_at(addr_at(12))->is_nop() ) {
830 return;
831 }
833 //lui dst, imm16
834 //nop
835 //nop
836 //nop
837 if ( is_op(Assembler::lui_op) &&
838 nativeInstruction_at(addr_at(4))->is_nop() &&
839 nativeInstruction_at(addr_at(8))->is_nop() &&
840 nativeInstruction_at(addr_at(12))->is_nop() ) {
841 return;
842 }
844 fatal("not a mov reg, imm64/imm48");
845 #endif
846 }
848 void NativeMovConstReg::print() {
849 tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT,
850 instruction_address(), data());
851 }
853 intptr_t NativeMovConstReg::data() const {
854 #ifndef _LP64
855 return Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
856 #else
857 // li64
858 if ( is_op(Assembler::lui_op) &&
859 is_op(int_at(4), Assembler::ori_op) &&
860 is_special_op(int_at(8), Assembler::dsll_op) &&
861 is_op(int_at(12), Assembler::ori_op) &&
862 is_special_op(int_at(16), Assembler::dsll_op) &&
863 is_op(int_at(20), Assembler::ori_op) ) {
865 return Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
866 (intptr_t)(int_at(12) & 0xffff),
867 (intptr_t)(int_at(4) & 0xffff),
868 (intptr_t)(int_at(0) & 0xffff));
869 }
871 //lui dst, imm16
872 //ori dst, dst, imm16
873 //dsll dst, dst, 16
874 //ori dst, dst, imm16
875 if ( is_op(Assembler::lui_op) &&
876 is_op (int_at(4), Assembler::ori_op) &&
877 is_special_op(int_at(8), Assembler::dsll_op) &&
878 is_op (int_at(12), Assembler::ori_op) ) {
880 return Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
881 (intptr_t)(int_at(4) & 0xffff),
882 (intptr_t)(int_at(0) & 0xffff),
883 (intptr_t)0);
884 }
886 //ori dst, R0, imm16
887 //dsll dst, dst, 16
888 //ori dst, dst, imm16
889 //nop
890 if ( is_op(Assembler::ori_op) &&
891 is_special_op(int_at(4), Assembler::dsll_op) &&
892 is_op (int_at(8), Assembler::ori_op) &&
893 nativeInstruction_at(addr_at(12))->is_nop()) {
895 return Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
896 (intptr_t)(int_at(0) & 0xffff),
897 (intptr_t)0,
898 (intptr_t)0);
899 }
901 //ori dst, R0, imm16
902 //dsll dst, dst, 16
903 //nop
904 //nop
905 if ( is_op(Assembler::ori_op) &&
906 is_special_op(int_at(4), Assembler::dsll_op) &&
907 nativeInstruction_at(addr_at(8))->is_nop() &&
908 nativeInstruction_at(addr_at(12))->is_nop()) {
910 return Assembler::merge( (intptr_t)(0),
911 (intptr_t)(int_at(0) & 0xffff),
912 (intptr_t)0,
913 (intptr_t)0);
914 }
916 //daddiu dst, R0, imm16
917 //nop
918 //nop
919 //nop
920 if ( is_op(Assembler::daddiu_op) &&
921 nativeInstruction_at(addr_at(4))->is_nop() &&
922 nativeInstruction_at(addr_at(8))->is_nop() &&
923 nativeInstruction_at(addr_at(12))->is_nop() ) {
925 int sign = int_at(0) & 0x8000;
926 if (sign == 0) {
927 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
928 (intptr_t)0,
929 (intptr_t)0,
930 (intptr_t)0);
931 } else {
932 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
933 (intptr_t)(0xffff),
934 (intptr_t)(0xffff),
935 (intptr_t)(0xffff));
936 }
937 }
939 //lui dst, imm16
940 //ori dst, dst, imm16
941 //nop
942 //nop
943 if ( is_op(Assembler::lui_op) &&
944 is_op (int_at(4), Assembler::ori_op) &&
945 nativeInstruction_at(addr_at(8))->is_nop() &&
946 nativeInstruction_at(addr_at(12))->is_nop() ) {
948 int sign = int_at(0) & 0x8000;
949 if (sign == 0) {
950 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
951 (intptr_t)(int_at(0) & 0xffff),
952 (intptr_t)0,
953 (intptr_t)0);
954 } else {
955 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
956 (intptr_t)(int_at(0) & 0xffff),
957 (intptr_t)(0xffff),
958 (intptr_t)(0xffff));
959 }
960 }
962 //lui dst, imm16
963 //nop
964 //nop
965 //nop
966 if ( is_op(Assembler::lui_op) &&
967 nativeInstruction_at(addr_at(4))->is_nop() &&
968 nativeInstruction_at(addr_at(8))->is_nop() &&
969 nativeInstruction_at(addr_at(12))->is_nop() ) {
971 int sign = int_at(0) & 0x8000;
972 if (sign == 0) {
973 return Assembler::merge( (intptr_t)0,
974 (intptr_t)(int_at(0) & 0xffff),
975 (intptr_t)0,
976 (intptr_t)0);
977 } else {
978 return Assembler::merge( (intptr_t)0,
979 (intptr_t)(int_at(0) & 0xffff),
980 (intptr_t)(0xffff),
981 (intptr_t)(0xffff));
982 }
983 }
985 fatal("not a mov reg, imm64/imm48");
987 #endif
988 }
990 void NativeMovConstReg::patch_set48(intptr_t x) {
991 jlong value = (jlong) x;
992 int rt_reg = (int_at(0) & (0x1f << 16));
993 int rs_reg = rt_reg << 5;
994 int rd_reg = rt_reg >> 5;
996 int hi = (int)(value >> 32);
997 int lo = (int)(value & ~0);
999 int count = 0;
1001 if (value == lo) { // 32-bit integer
1002 if (Assembler::is_simm16(value)) {
1003 //daddiu(d, R0, value);
1004 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
1005 count += 1;
1006 } else {
1007 //lui(d, split_low(value >> 16));
1008 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
1009 count += 1;
1010 if (Assembler::split_low(value)) {
1011 //ori(d, d, split_low(value));
1012 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1013 count += 1;
1014 }
1015 }
1016 } else if (hi == 0) { // hardware zero-extends to upper 32
1017 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
1018 count += 1;
1019 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1020 count += 1;
1021 if (Assembler::split_low(value)) {
1022 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1023 count += 1;
1024 }
1025 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1026 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
1027 count += 1;
1028 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
1029 count += 1;
1030 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1031 count += 1;
1032 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1033 count += 1;
1034 } else {
1035 tty->print_cr("value = 0x%x", value);
1036 guarantee(false, "Not supported yet !");
1037 }
1039 for (count; count < 4; count++) {
1040 set_int_at(count << 2, 0);
1041 }
1042 }
1044 void NativeMovConstReg::set_data(intptr_t x) {
1045 #ifndef _LP64
1046 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
1047 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
1048 ICache::invalidate_range(addr_at(0), 8);
1049 #else
1050 /* li64 or li48 */
1051 if ((!nativeInstruction_at(addr_at(12))->is_nop()) && is_special_op(int_at(16), Assembler::dsll_op) && is_op(long_at(20), Assembler::ori_op)) {
1052 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 48) & 0xffff));
1053 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 32) & 0xffff));
1054 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 16) & 0xffff));
1055 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)x) & 0xffff));
1056 } else {
1057 patch_set48(x);
1058 }
1060 ICache::invalidate_range(addr_at(0), 24);
1061 #endif
1062 }
1064 //-------------------------------------------------------------------
1066 int NativeMovRegMem::offset() const{
1067 if (is_immediate())
1068 return (short)(int_at(instruction_offset)&0xffff);
1069 else
1070 return Assembler::merge(int_at(hiword_offset)&0xffff, long_at(instruction_offset)&0xffff);
1071 }
1073 void NativeMovRegMem::set_offset(int x) {
1074 if (is_immediate()) {
1075 assert(Assembler::is_simm16(x), "just check");
1076 set_int_at(0, (int_at(0)&0xffff0000) | (x&0xffff) );
1077 if (is_64ldst()) {
1078 assert(Assembler::is_simm16(x+4), "just check");
1079 set_int_at(4, (int_at(4)&0xffff0000) | ((x+4)&0xffff) );
1080 }
1081 } else {
1082 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
1083 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
1084 }
1085 ICache::invalidate_range(addr_at(0), 8);
1086 }
1088 void NativeMovRegMem::verify() {
1089 int offset = 0;
1091 if ( Assembler::opcode(int_at(0)) == Assembler::lui_op ) {
1092 #ifndef _LP64
1093 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op) ||
1094 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
1095 (Assembler::special(int_at(8)) != Assembler::add_op))
1096 #else
1097 /* Jin: fit MIPS64 */
1098 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op &&
1099 Assembler::opcode(int_at(4)) != Assembler::daddiu_op ) ||
1100 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
1101 (Assembler::special(int_at(8)) != Assembler::add_op
1102 && Assembler::special(int_at(8)) != Assembler::dadd_op))
1103 #endif
1104 fatal ("not a mov [reg+offs], reg instruction");
1105 offset += 12;
1106 }
1108 switch(Assembler::opcode(int_at(offset))) {
1109 case Assembler::lb_op:
1110 case Assembler::lbu_op:
1111 case Assembler::lh_op:
1112 case Assembler::lhu_op:
1113 case Assembler::lw_op:
1114 case Assembler::lwu_op:
1115 LP64_ONLY(case Assembler::ld_op:)
1116 case Assembler::lwc1_op:
1117 LP64_ONLY(case Assembler::ldc1_op:)
1118 case Assembler::sb_op:
1119 case Assembler::sh_op:
1120 case Assembler::sw_op:
1121 LP64_ONLY(case Assembler::sd_op:)
1122 case Assembler::swc1_op:
1123 LP64_ONLY(case Assembler::sdc1_op:)
1124 break;
1125 default:
1126 fatal ("not a mov [reg+offs], reg instruction");
1127 }
1128 }
1131 void NativeMovRegMem::print() {
1132 tty->print_cr("0x%x: mov reg, [reg + %x]", instruction_address(), offset());
1133 }
1135 void NativeIllegalInstruction::insert(address code_pos) {
1136 CodeBuffer cb(code_pos, instruction_size);
1137 MacroAssembler masm(&cb);
1138 #define __ masm.
1139 __ brk(11);
1140 #undef __
1142 ICache::invalidate_range(code_pos, instruction_size);
1143 }
1145 void NativeGeneralJump::verify() {
1146 assert(((NativeInstruction *)this)->is_jump() ||
1147 ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction");
1148 }
1150 void NativeGeneralJump::patch_set48_gs(address dest) {
1151 jlong value = (jlong) dest;
1152 int rt_reg = (int_at(0) & (0x1f << 16));
1154 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
1156 int rs_reg = rt_reg << 5;
1157 int rd_reg = rt_reg >> 5;
1159 int hi = (int)(value >> 32);
1160 int lo = (int)(value & ~0);
1162 int count = 0;
1164 int insts[4] = {0, 0, 0, 0};
1166 if (value == lo) { // 32-bit integer
1167 if (Assembler::is_simm16(value)) {
1168 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
1169 count += 1;
1170 } else {
1171 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
1172 count += 1;
1173 if (Assembler::split_low(value)) {
1174 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1175 count += 1;
1176 }
1177 }
1178 } else if (hi == 0) { // hardware zero-extends to upper 32
1179 insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
1180 count += 1;
1181 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
1182 count += 1;
1183 if (Assembler::split_low(value)) {
1184 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1185 count += 1;
1186 }
1187 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1188 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
1189 count += 1;
1190 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
1191 count += 1;
1192 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
1193 count += 1;
1194 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
1195 count += 1;
1196 } else {
1197 tty->print_cr("dest = 0x%x", value);
1198 guarantee(false, "Not supported yet !");
1199 }
1201 for (count; count < 4; count++) {
1202 insts[count] = 0;
1203 }
1205 atomic_store128_ptr func = get_atomic_store128_func();
1206 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
1208 ICache::invalidate_range(addr_at(0), 16);
1209 }
1211 void NativeGeneralJump::patch_set48(address dest) {
1212 jlong value = (jlong) dest;
1213 int rt_reg = (int_at(0) & (0x1f << 16));
1214 int rs_reg = rt_reg << 5;
1215 int rd_reg = rt_reg >> 5;
1217 int hi = (int)(value >> 32);
1218 int lo = (int)(value & ~0);
1220 int count = 0;
1222 if (value == lo) { // 32-bit integer
1223 if (Assembler::is_simm16(value)) {
1224 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
1225 count += 1;
1226 } else {
1227 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
1228 count += 1;
1229 if (Assembler::split_low(value)) {
1230 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1231 count += 1;
1232 }
1233 }
1234 } else if (hi == 0) { // hardware zero-extends to upper 32
1235 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
1236 count += 1;
1237 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1238 count += 1;
1239 if (Assembler::split_low(value)) {
1240 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1241 count += 1;
1242 }
1243 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
1244 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
1245 count += 1;
1246 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
1247 count += 1;
1248 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
1249 count += 1;
1250 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
1251 count += 1;
1252 } else {
1253 tty->print_cr("dest = 0x%x", value);
1254 guarantee(false, "Not supported yet !");
1255 }
1257 for (count; count < 4; count++) {
1258 set_int_at(count << 2, 0);
1259 }
1261 ICache::invalidate_range(addr_at(0), 16);
1262 }
1264 void NativeGeneralJump::patch_on_j_only(address dst) {
1265 #ifdef _LP64
1266 long dest = ((long)dst - (((long)addr_at(4)) & 0xfffffffff0000000))>>2;
1267 #else
1268 long dest = ((long)dst - (((long)addr_at(4)) & 0xf0000000))>>2;
1269 #endif
1270 if ((dest >= 0) && (dest < (1<<26))) {
1271 jint j_inst = (Assembler::j_op << 26) | dest;
1272 set_int_at(0, j_inst);
1273 ICache::invalidate_range(addr_at(0), 4);
1274 } else {
1275 ShouldNotReachHere();
1276 }
1277 }
1280 void NativeGeneralJump::patch_on_j_gs(address dst) {
1281 #ifdef _LP64
1282 long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
1283 #else
1284 long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
1285 #endif
1286 if ((dest >= 0) && (dest < (1<<26))) {
1287 jint j_inst = (Assembler::j_op << 26) | dest;
1288 set_int_at(16, j_inst);
1289 ICache::invalidate_range(addr_at(16), 4);
1290 } else {
1291 ShouldNotReachHere();
1292 }
1293 }
1295 void NativeGeneralJump::patch_on_j(address dst) {
1296 patch_on_j_gs(dst);
1297 }
1299 void NativeGeneralJump::patch_on_jr_gs(address dst) {
1300 patch_set48_gs(dst);
1301 ICache::invalidate_range(addr_at(0), 16);
1302 }
1304 void NativeGeneralJump::patch_on_jr(address dst) {
1305 patch_set48(dst);
1306 ICache::invalidate_range(addr_at(0), 16);
1307 }
1310 void NativeGeneralJump::set_jump_destination(address dest) {
1311 OrderAccess::fence();
1313 if (is_short()) {
1314 assert(Assembler::is_simm16(dest-addr_at(4)), "change this code");
1315 set_int_at(0, (int_at(0) & 0xffff0000) | (dest - addr_at(4)) & 0xffff );
1316 ICache::invalidate_range(addr_at(0), 4);
1317 #ifdef _LP64
1318 } else if (is_b_far()) {
1319 int offset = dest - addr_at(12);
1320 set_int_at(12, (int_at(12) & 0xffff0000) | (offset >> 16));
1321 set_int_at(16, (int_at(16) & 0xffff0000) | (offset & 0xffff));
1322 #endif
1323 } else {
1324 #ifndef _LP64
1325 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
1326 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
1327 ICache::invalidate_range(addr_at(0), 8);
1328 #else
1329 if (is_op(int_at(16), Assembler::j_op)) {
1330 if (UseLoongsonISA) {
1331 patch_on_j_gs(dest);
1332 } else {
1333 patch_on_j(dest);
1334 }
1335 } else if (is_op(int_at(0), Assembler::j_op)) {
1336 patch_on_j_only(dest);
1337 } else if (is_special_op(int_at(16), Assembler::jr_op)) {
1338 if (UseLoongsonISA) {
1339 //guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
1340 //patch_on_jr_gs(dest);
1341 patch_on_jr(dest);
1342 } else {
1343 patch_on_jr(dest);
1344 }
1345 } else {
1346 fatal("not a jump");
1347 }
1348 #endif
1349 }
1350 }
1352 // we now use b to do this. be careful when using this method
1353 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
1354 CodeBuffer cb(code_pos, instruction_size);
1355 MacroAssembler masm(&cb);
1356 #define __ masm.
1357 #ifdef _LP64
1358 if (Assembler::is_simm16((entry - code_pos - 4) / 4)) {
1359 __ b(entry);
1360 __ delayed()->nop();
1361 } else {
1362 /* a simplified b_far */
1363 int offset = entry - code_pos;
1365 // FIXME: need to preserve RA?
1366 __ emit_long(0x4110001); //__ emit_long(Assembler::insn_ORRI(Assembler::regimm_op, 0, Assembler::bgezal_op, 1));
1367 __ lui(T9, (offset - 8) >> 16); // delay slot
1368 __ ori(T9, T9, (offset - 8) & 0xffff);
1369 __ daddu(T9, T9, RA);
1370 __ jr(T9);
1371 __ nop();
1372 }
1373 #else
1374 __ b(entry);
1375 __ delayed()->nop();
1376 #endif
1377 #undef __
1379 ICache::invalidate_range(code_pos, instruction_size);
1380 }
1382 #ifdef _LP64
1383 bool NativeGeneralJump::is_b_far() {
1384 /*
1385 0x000000556809f198: dadd at, ra, zero
1386 0x000000556809f19c: [4110001]bgezal zero, 0x000000556809f1a4
1388 0x000000556809f1a0: nop
1389 0x000000556809f1a4: lui t9, 0xfffffffd
1390 0x000000556809f1a8: ori t9, t9, 0x14dc
1391 0x000000556809f1ac: daddu t9, t9, ra
1392 0x000000556809f1b0: dadd ra, at, zero
1393 0x000000556809f1b4: jr t9
1394 0x000000556809f1b8: nop
1395 ;; ImplicitNullCheckStub slow case
1396 0x000000556809f1bc: lui t9, 0x55
1397 */
1398 return is_op(int_at(12), Assembler::lui_op);
1399 }
1400 #endif
1402 address NativeGeneralJump::jump_destination() {
1403 if ( is_short() ) {
1404 return addr_at(4) + Assembler::imm_off(int_at(instruction_offset)) * 4;
1405 }
1406 #ifndef _LP64
1407 return (address)Assembler::merge(int_at(4)&0xffff, long_at(instruction_offset)&0xffff);
1408 #else
1409 /* 2012/4/19 Jin: Assembler::merge() is not correct in MIPS_64!
1411 Example:
1412 hi16 = 0xfffd,
1413 lo16 = f7a4,
1415 offset=0xfffdf7a4 (Right)
1416 Assembler::merge = 0xfffcf7a4 (Wrong)
1417 */
1418 if ( is_b_far() ) {
1419 int hi16 = int_at(12)&0xffff;
1420 int low16 = int_at(16)&0xffff;
1421 address target = addr_at(12) + (hi16 << 16) + low16;
1422 return target;
1423 }
1425 // nop
1426 // nop
1427 // nop
1428 // nop
1429 // j target
1430 // nop
1431 if ( nativeInstruction_at(addr_at(0))->is_nop() &&
1432 nativeInstruction_at(addr_at(4))->is_nop() &&
1433 nativeInstruction_at(addr_at(8))->is_nop() &&
1434 nativeInstruction_at(addr_at(12))->is_nop() &&
1435 is_op(int_at(16), Assembler::j_op) &&
1436 nativeInstruction_at(addr_at(20))->is_nop()) {
1437 int instr_index = int_at(16) & 0x3ffffff;
1438 intptr_t target_high = ((intptr_t)addr_at(20)) & 0xfffffffff0000000;
1439 intptr_t target = target_high | (instr_index << 2);
1440 return (address)target;
1441 }
1443 // j target
1444 // nop
1445 if ( is_op(int_at(0), Assembler::j_op) &&
1446 nativeInstruction_at(addr_at(4))->is_nop()) {
1447 int instr_index = int_at(0) & 0x3ffffff;
1448 intptr_t target_high = ((intptr_t)addr_at(4)) & 0xfffffffff0000000;
1449 intptr_t target = target_high | (instr_index << 2);
1450 return (address)target;
1451 }
1453 // li64
1454 if ( is_op(Assembler::lui_op) &&
1455 is_op(int_at(4), Assembler::ori_op) &&
1456 is_special_op(int_at(8), Assembler::dsll_op) &&
1457 is_op(int_at(12), Assembler::ori_op) &&
1458 is_special_op(int_at(16), Assembler::dsll_op) &&
1459 is_op(int_at(20), Assembler::ori_op) ) {
1461 return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
1462 (intptr_t)(int_at(12) & 0xffff),
1463 (intptr_t)(int_at(4) & 0xffff),
1464 (intptr_t)(int_at(0) & 0xffff));
1465 }
1467 //lui dst, imm16
1468 //ori dst, dst, imm16
1469 //dsll dst, dst, 16
1470 //ori dst, dst, imm16
1471 if ( is_op(Assembler::lui_op) &&
1472 is_op (int_at(4), Assembler::ori_op) &&
1473 is_special_op(int_at(8), Assembler::dsll_op) &&
1474 is_op (int_at(12), Assembler::ori_op) ) {
1476 return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
1477 (intptr_t)(int_at(4) & 0xffff),
1478 (intptr_t)(int_at(0) & 0xffff),
1479 (intptr_t)0);
1480 }
1482 //ori dst, R0, imm16
1483 //dsll dst, dst, 16
1484 //ori dst, dst, imm16
1485 //nop
1486 if ( is_op(Assembler::ori_op) &&
1487 is_special_op(int_at(4), Assembler::dsll_op) &&
1488 is_op (int_at(8), Assembler::ori_op) &&
1489 nativeInstruction_at(addr_at(12))->is_nop()) {
1491 return (address)Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
1492 (intptr_t)(int_at(0) & 0xffff),
1493 (intptr_t)0,
1494 (intptr_t)0);
1495 }
1497 //ori dst, R0, imm16
1498 //dsll dst, dst, 16
1499 //nop
1500 //nop
1501 if ( is_op(Assembler::ori_op) &&
1502 is_special_op(int_at(4), Assembler::dsll_op) &&
1503 nativeInstruction_at(addr_at(8))->is_nop() &&
1504 nativeInstruction_at(addr_at(12))->is_nop()) {
1506 return (address)Assembler::merge( (intptr_t)(0),
1507 (intptr_t)(int_at(0) & 0xffff),
1508 (intptr_t)0,
1509 (intptr_t)0);
1510 }
1512 //daddiu dst, R0, imm16
1513 //nop
1514 //nop
1515 //nop
1516 if ( is_op(Assembler::daddiu_op) &&
1517 nativeInstruction_at(addr_at(4))->is_nop() &&
1518 nativeInstruction_at(addr_at(8))->is_nop() &&
1519 nativeInstruction_at(addr_at(12))->is_nop() ) {
1521 int sign = int_at(0) & 0x8000;
1522 if (sign == 0) {
1523 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
1524 (intptr_t)0,
1525 (intptr_t)0,
1526 (intptr_t)0);
1527 } else {
1528 return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
1529 (intptr_t)(0xffff),
1530 (intptr_t)(0xffff),
1531 (intptr_t)(0xffff));
1532 }
1533 }
1535 //lui dst, imm16
1536 //ori dst, dst, imm16
1537 //nop
1538 //nop
1539 if ( is_op(Assembler::lui_op) &&
1540 is_op (int_at(4), Assembler::ori_op) &&
1541 nativeInstruction_at(addr_at(8))->is_nop() &&
1542 nativeInstruction_at(addr_at(12))->is_nop() ) {
1544 int sign = int_at(0) & 0x8000;
1545 if (sign == 0) {
1546 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
1547 (intptr_t)(int_at(0) & 0xffff),
1548 (intptr_t)0,
1549 (intptr_t)0);
1550 } else {
1551 return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
1552 (intptr_t)(int_at(0) & 0xffff),
1553 (intptr_t)(0xffff),
1554 (intptr_t)(0xffff));
1555 }
1556 }
1558 //lui dst, imm16
1559 //nop
1560 //nop
1561 //nop
1562 if ( is_op(Assembler::lui_op) &&
1563 nativeInstruction_at(addr_at(4))->is_nop() &&
1564 nativeInstruction_at(addr_at(8))->is_nop() &&
1565 nativeInstruction_at(addr_at(12))->is_nop() ) {
1567 int sign = int_at(0) & 0x8000;
1568 if (sign == 0) {
1569 return (address)Assembler::merge( (intptr_t)0,
1570 (intptr_t)(int_at(0) & 0xffff),
1571 (intptr_t)0,
1572 (intptr_t)0);
1573 } else {
1574 return (address)Assembler::merge( (intptr_t)0,
1575 (intptr_t)(int_at(0) & 0xffff),
1576 (intptr_t)(0xffff),
1577 (intptr_t)(0xffff));
1578 }
1579 }
1581 fatal("not a jump");
1582 #endif
1583 }
1585 // MT-safe patching of a long jump instruction.
1586 // First patches first word of instruction to two jmp's that jmps to them
1587 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
1588 // the jmp's with the first 4 byte of the new instruction.
1589 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
1590 NativeGeneralJump* h_jump = nativeGeneralJump_at (instr_addr);
1591 assert(NativeGeneralJump::instruction_size == NativeCall::instruction_size,
1592 "note::Runtime1::patch_code uses NativeCall::instruction_size");
1594 /* 2013/6/13 Jin: ensure 100% atomicity */
1595 //guarantee(!os::is_MP() || (((long)instr_addr % BytesPerWord) == 0), "destination must be aligned for SD");
1597 int *p = (int *)instr_addr;
1598 int jr_word = p[4];
1600 p[4] = 0x1000fffb; /* .1: --; --; --; --; b .1; nop */
1601 memcpy(instr_addr, code_buffer, NativeCall::instruction_size - 8);
1602 *(long *)(instr_addr + 16) = *(long *)(code_buffer + 16);
1603 }
1605 /* Must ensure atomicity */
1606 void NativeGeneralJump::patch_verified_entry(address entry, address verified_entry, address dest) {
1607 /* 2013/11/5 Jin: ensure 100% atomicity.
1608 * The destination is fixed and can be cached in JavaThread.
1609 */
1610 //guarantee(!os::is_MP() || (((long)verified_entry % BytesPerWord) == 0), "destination must be aligned for SD");
1612 int code_buffer[4];
1614 CodeBuffer cb((address)code_buffer, instruction_size);
1615 MacroAssembler masm(&cb);
1616 #define __ masm.
1617 __ ld(T9, TREG, in_bytes(JavaThread::handle_wrong_method_stub_offset()));
1618 __ jr(T9);
1619 __ delayed()->nop();
1620 __ nop();
1622 atomic_store128_ptr func = get_atomic_store128_func();
1623 (*func)((long *)verified_entry, 0, *(long *)&code_buffer[0], *(long *)&code_buffer[2]);
1625 ICache::invalidate_range(verified_entry, instruction_size);
1626 }
1628 bool NativeInstruction::is_jump()
1629 {
1630 #ifndef _LP64
1631 return ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode) ||
1632 (is_op(int_at(0), Assembler::lui_op) &&
1633 is_op(int_at(4), Assembler::addiu_op) &&
1634 is_special_op(int_at(8), Assembler::jr_op));
1635 #else
1636 // lui rd, imm(63...48);
1637 // ori rd, rd, imm(47...32);
1638 // dsll rd, rd, 16;
1639 // ori rd, rd, imm(31...16);
1640 // dsll rd, rd, 16;
1641 // ori rd, rd, imm(15...0);
1642 // jalr rd
1643 // nop
1644 //
1645 if ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode)
1646 return true;
1647 if (is_op(int_at(4), Assembler::lui_op)) /* simplified b_far */
1648 return true;
1649 if (is_op(int_at(12), Assembler::lui_op)) /* original b_far */
1650 return true;
1652 // nop
1653 // nop
1654 // nop
1655 // nop
1656 // j target
1657 // nop
1658 if ( is_nop() &&
1659 nativeInstruction_at(addr_at(4))->is_nop() &&
1660 nativeInstruction_at(addr_at(8))->is_nop() &&
1661 nativeInstruction_at(addr_at(12))->is_nop() &&
1662 nativeInstruction_at(addr_at(16))->is_op(Assembler::j_op) &&
1663 nativeInstruction_at(addr_at(20))->is_nop() ) {
1664 return true;
1665 }
1667 if ( nativeInstruction_at(addr_at(0))->is_op(Assembler::j_op) &&
1668 nativeInstruction_at(addr_at(4))->is_nop() ) {
1669 return true;
1670 }
1672 if (is_op(int_at(0), Assembler::lui_op) &&
1673 is_op(int_at(4), Assembler::ori_op) &&
1674 is_special_op(int_at(8), Assembler::dsll_op) &&
1675 is_op(int_at(12), Assembler::ori_op) &&
1676 is_special_op(int_at(16), Assembler::dsll_op) &&
1677 is_op(int_at(20), Assembler::ori_op))
1678 return true;
1679 if (is_op(int_at(0), Assembler::lui_op) &&
1680 is_op(int_at(4), Assembler::ori_op) &&
1681 is_special_op(int_at(8), Assembler::dsll_op) &&
1682 is_op(int_at(12), Assembler::ori_op))
1683 return true;
1685 //ori dst, R0, imm16
1686 //dsll dst, dst, 16
1687 //ori dst, dst, imm16
1688 //nop
1689 if ( is_op(Assembler::ori_op) &&
1690 is_special_op(int_at(4), Assembler::dsll_op) &&
1691 is_op (int_at(8), Assembler::ori_op) &&
1692 nativeInstruction_at(addr_at(12))->is_nop()) {
1693 return true;
1694 }
1696 //ori dst, R0, imm16
1697 //dsll dst, dst, 16
1698 //nop
1699 //nop
1700 if ( is_op(Assembler::ori_op) &&
1701 is_special_op(int_at(4), Assembler::dsll_op) &&
1702 nativeInstruction_at(addr_at(8))->is_nop() &&
1703 nativeInstruction_at(addr_at(12))->is_nop()) {
1704 return true;
1705 }
1707 //daddiu dst, R0, imm16
1708 //nop
1709 //nop
1710 //nop
1711 if ( is_op(Assembler::daddiu_op) &&
1712 nativeInstruction_at(addr_at(4))->is_nop() &&
1713 nativeInstruction_at(addr_at(8))->is_nop() &&
1714 nativeInstruction_at(addr_at(12))->is_nop() ) {
1715 return true;
1716 }
1718 //lui dst, imm16
1719 //ori dst, dst, imm16
1720 //nop
1721 //nop
1722 if ( is_op(Assembler::lui_op) &&
1723 is_op (int_at(4), Assembler::ori_op) &&
1724 nativeInstruction_at(addr_at(8))->is_nop() &&
1725 nativeInstruction_at(addr_at(12))->is_nop() ) {
1726 return true;
1727 }
1729 //lui dst, imm16
1730 //nop
1731 //nop
1732 //nop
1733 if ( is_op(Assembler::lui_op) &&
1734 nativeInstruction_at(addr_at(4))->is_nop() &&
1735 nativeInstruction_at(addr_at(8))->is_nop() &&
1736 nativeInstruction_at(addr_at(12))->is_nop() ) {
1737 return true;
1738 }
1740 return false;
1741 #endif
1742 }
1744 bool NativeInstruction::is_dtrace_trap() {
1745 //return (*(int32_t*)this & 0xff) == 0xcc;
1746 Unimplemented();
1747 return false;
1748 }
1750 bool NativeInstruction::is_safepoint_poll() {
1751 #ifdef _LP64
1752 /*
1753 390 li T2, 0x0000000000400000 #@loadConP
1754 394 sw [SP + #12], V1 # spill 9
1755 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
1757 0x000000ffe5815130: lui t2, 0x40
1758 0x000000ffe5815134: sw v1, 0xc(sp) ; OopMap{a6=Oop off=920}
1759 ;*goto
1760 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
1762 0x000000ffe5815138: lw at, 0x0(t2) ;*goto <--- PC
1763 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
1764 */
1766 // Since there may be some spill instructions between the safePoint_poll and loadConP,
1767 // we check the safepoint instruction like the this.
1768 return is_op(Assembler::lw_op) && is_rt(AT);
1769 #else
1770 return is_op(int_at(-4), Assembler::lui_op) &&
1771 is_op(Assembler::lw_op) &&
1772 is_rt(AT);
1773 #endif
1774 }