src/cpu/mips/vm/nativeInst_mips.cpp

Wed, 04 Dec 2019 18:01:06 +0800

author
jiefu
date
Wed, 04 Dec 2019 18:01:06 +0800
changeset 9761
17884ee5d053
parent 9645
ac996ba07f9d
child 9932
86ea9a02a717
permissions
-rw-r--r--

#10637: java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java fails with -XX:ReservedCodeCacheSize=256m
Reviewed-by: aoqi

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

mercurial