src/cpu/mips/vm/nativeInst_mips.cpp

Wed, 29 Mar 2017 09:41:51 +0800

author
aoqi
date
Wed, 29 Mar 2017 09:41:51 +0800
changeset 392
4bfb40d1e17a
parent 386
f50649f9eda6
child 397
1e8b8bc62356
permissions
-rw-r--r--

#4662 TieredCompilation is turned off.
TieredCompilation is not supported yet.

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

mercurial