src/cpu/mips/vm/nativeInst_mips.cpp

Thu, 24 May 2018 19:49:50 +0800

author
aoqi
date
Thu, 24 May 2018 19:49:50 +0800
changeset 8865
ffcdff41a92f
parent 8863
5376ce0dc552
child 9128
1d748903b598
permissions
-rw-r--r--

some C1 fix
Contributed-by: chenhaoxuan, zhaixiang, aoqi

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

mercurial