src/cpu/mips/vm/nativeInst_mips.cpp

Tue, 12 Jun 2018 13:58:17 +0800

author
zhaixiang
date
Tue, 12 Jun 2018 13:58:17 +0800
changeset 9144
cecfc245b19a
parent 9128
1d748903b598
child 9146
4c971a763d55
permissions
-rw-r--r--

#7157 Fix all forgot saying delayed() when filling delay slot issues
Summary: enable check_delay and guarantee delay_state is at_delay_slot when filling delay slot
Reviewed-by: 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
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
aoqi@1 429 /* 2013/6/14 Jin: manual implementation of GSSQ
aoqi@1 430 *
aoqi@1 431 * 00000001200009c0 <atomic_store128>:
aoqi@1 432 * 1200009c0: 0085202d daddu a0, a0, a1
aoqi@1 433 * 1200009c4: e8860027 gssq a2, a3, 0(a0)
aoqi@1 434 * 1200009c8: 03e00008 jr ra
aoqi@1 435 * 1200009cc: 00000000 nop
aoqi@1 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@129 442 assert(UseLoongsonISA, "UseLoongsonISA 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@366 550 for (count; count < 4; count++) {
fujie@366 551 insts[count] = 0;
fujie@366 552 }
fujie@366 553
fujie@366 554 atomic_store128_ptr func = get_atomic_store128_func();
fujie@366 555 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
fujie@386 556
fujie@386 557 ICache::invalidate_range(addr_at(0), 16);
fujie@366 558 }
fujie@366 559
aoqi@6880 560 void NativeCall::patch_set32_gs(address dest) {
fujie@374 561 jlong value = (jlong) dest;
fujie@374 562 int rt_reg = (int_at(0) & (0x1f << 16));
fujie@379 563
aoqi@6880 564 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
fujie@379 565
fujie@374 566 int rs_reg = rt_reg << 5;
fujie@374 567 int rd_reg = rt_reg >> 5;
fujie@374 568
fujie@374 569 int hi = (int)(value >> 32);
fujie@374 570 int lo = (int)(value & ~0);
fujie@374 571
fujie@374 572 int count = 0;
fujie@374 573
fujie@374 574 int insts[2] = {0, 0};
fujie@374 575
fujie@374 576 if (value == lo) { // 32-bit integer
fujie@374 577 if (Assembler::is_simm16(value)) {
fujie@374 578 //daddiu(d, R0, value);
fujie@374 579 //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
fujie@374 580 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
fujie@374 581 count += 1;
fujie@374 582 } else {
fujie@374 583 //lui(d, split_low(value >> 16));
fujie@374 584 //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
fujie@374 585 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
fujie@374 586 count += 1;
fujie@374 587 if (Assembler::split_low(value)) {
fujie@374 588 //ori(d, d, split_low(value));
fujie@374 589 //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@374 590 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
fujie@374 591 count += 1;
fujie@374 592 }
fujie@374 593 }
fujie@374 594 } else {
fujie@374 595 tty->print_cr("dest = 0x%x", value);
fujie@374 596 guarantee(false, "Not supported yet !");
fujie@374 597 }
fujie@374 598
fujie@374 599 for (count; count < 2; count++) {
fujie@374 600 //nop();
fujie@374 601 //set_int_at(count << 2, 0);
fujie@374 602 insts[count] = 0;
fujie@374 603 }
fujie@374 604
fujie@374 605 long inst = insts[1];
fujie@374 606 inst = inst << 32;
fujie@374 607 inst = inst + insts[0];
fujie@374 608
fujie@374 609 set_long_at(0, inst);
fujie@374 610 }
fujie@374 611
aoqi@6880 612 void NativeCall::patch_set48(address dest) {
fujie@366 613 jlong value = (jlong) dest;
fujie@366 614 int rt_reg = (int_at(0) & (0x1f << 16));
fujie@379 615
aoqi@6880 616 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
fujie@379 617
fujie@366 618 int rs_reg = rt_reg << 5;
fujie@366 619 int rd_reg = rt_reg >> 5;
fujie@366 620
fujie@366 621 int hi = (int)(value >> 32);
fujie@366 622 int lo = (int)(value & ~0);
fujie@366 623
fujie@366 624 int count = 0;
fujie@366 625
fujie@366 626 if (value == lo) { // 32-bit integer
fujie@366 627 if (Assembler::is_simm16(value)) {
fujie@366 628 //daddiu(d, R0, value);
fujie@366 629 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
fujie@366 630 count += 1;
fujie@366 631 } else {
fujie@366 632 //lui(d, split_low(value >> 16));
fujie@366 633 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
fujie@366 634 count += 1;
fujie@366 635 if (Assembler::split_low(value)) {
fujie@366 636 //ori(d, d, split_low(value));
fujie@366 637 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@366 638 count += 1;
fujie@366 639 }
fujie@366 640 }
fujie@366 641 } else if (hi == 0) { // hardware zero-extends to upper 32
fujie@366 642 //ori(d, R0, julong(value) >> 16);
fujie@366 643 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
fujie@366 644 count += 1;
fujie@366 645 //dsll(d, d, 16);
fujie@366 646 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
fujie@366 647 count += 1;
fujie@366 648 if (Assembler::split_low(value)) {
fujie@366 649 //ori(d, d, split_low(value));
fujie@366 650 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@366 651 count += 1;
fujie@366 652 }
fujie@366 653 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
fujie@366 654 //lui(d, value >> 32);
fujie@366 655 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
fujie@366 656 count += 1;
fujie@366 657 //ori(d, d, split_low(value >> 16));
fujie@366 658 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
fujie@366 659 count += 1;
fujie@366 660 //dsll(d, d, 16);
fujie@366 661 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
fujie@366 662 count += 1;
fujie@366 663 //ori(d, d, split_low(value));
fujie@366 664 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@366 665 count += 1;
fujie@366 666 } else {
fujie@366 667 tty->print_cr("dest = 0x%x", value);
fujie@366 668 guarantee(false, "Not supported yet !");
fujie@366 669 }
fujie@366 670
fujie@366 671 for (count; count < 4; count++) {
fujie@366 672 //nop();
fujie@366 673 set_int_at(count << 2, 0);
fujie@366 674 }
fujie@386 675
fujie@386 676 ICache::invalidate_range(addr_at(0), 16);
fujie@366 677 }
fujie@366 678
fujie@374 679 void NativeCall::patch_set32(address dest) {
fujie@374 680 patch_set32_gs(dest);
fujie@374 681 }
fujie@374 682
aoqi@1 683 void NativeCall::set_destination(address dest) {
aoqi@1 684 #ifndef _LP64
aoqi@6880 685 OrderAccess::fence();
aoqi@6880 686 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
aoqi@6880 687 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
aoqi@6880 688 ICache::invalidate_range(addr_at(0), 8);
aoqi@1 689 #else
aoqi@6880 690 OrderAccess::fence();
aoqi@1 691
fujie@366 692 // li64
aoqi@1 693 if (is_special_op(int_at(16), Assembler::dsll_op)) {
aoqi@6880 694 int first_word = int_at(0);
aoqi@6880 695 set_int_at(0, 0x1000ffff); /* .1: b .1 */
aoqi@6880 696 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 32) & 0xffff));
aoqi@6880 697 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 16) & 0xffff));
aoqi@6880 698 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
aoqi@6880 699 set_int_at(0, (first_word & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 48) & 0xffff));
aoqi@6880 700 ICache::invalidate_range(addr_at(0), 24);
fujie@379 701 } else if (is_op(int_at(16), Assembler::jal_op)) {
aoqi@129 702 if (UseLoongsonISA) {
fujie@379 703 patch_on_jal_gs(dest);
aoqi@129 704 } else {
fujie@379 705 patch_on_jal(dest);
aoqi@129 706 }
fujie@397 707 } else if (is_op(int_at(0), Assembler::jal_op)) {
fujie@397 708 patch_on_jal_only(dest);
aoqi@6880 709 } else if (is_special_op(int_at(16), Assembler::jalr_op)) {
fujie@379 710 if (UseLoongsonISA) {
fujie@397 711 patch_on_jalr(dest);
fujie@379 712 } else {
fujie@379 713 patch_on_jalr(dest);
fujie@379 714 }
fujie@374 715 } else if (is_special_op(int_at(8), Assembler::jalr_op)) {
fujie@374 716 guarantee(!os::is_MP() || (((long)addr_at(0) % 8) == 0), "destination must be aligned by 8");
fujie@374 717 if (UseLoongsonISA) {
fujie@374 718 patch_set32_gs(dest);
fujie@374 719 } else {
fujie@374 720 patch_set32(dest);
fujie@374 721 }
fujie@374 722 ICache::invalidate_range(addr_at(0), 8);
aoqi@1 723 } else {
aoqi@1 724 fatal("not a call");
aoqi@1 725 }
aoqi@1 726 #endif
aoqi@1 727 }
aoqi@1 728
aoqi@1 729 void NativeCall::print() {
aoqi@1 730 tty->print_cr(PTR_FORMAT ": call " PTR_FORMAT,
aoqi@1 731 instruction_address(), destination());
aoqi@1 732 }
aoqi@1 733
aoqi@1 734 // Inserts a native call instruction at a given pc
aoqi@1 735 void NativeCall::insert(address code_pos, address entry) {
aoqi@1 736 NativeCall *call = nativeCall_at(code_pos);
aoqi@1 737 CodeBuffer cb(call->addr_at(0), instruction_size);
aoqi@1 738 MacroAssembler masm(&cb);
aoqi@1 739 #define __ masm.
aoqi@1 740 #ifndef _LP64
aoqi@1 741 __ lui(T9, Assembler::split_high((int)entry));
aoqi@1 742 __ addiu(T9, T9, Assembler::split_low((int)entry));
aoqi@1 743 #else
aoqi@8865 744 __ li48(T9, (long)entry);
aoqi@1 745 #endif
aoqi@1 746 __ jalr ();
aoqi@1 747 __ delayed()->nop();
aoqi@1 748 #undef __
aoqi@1 749
aoqi@1 750 ICache::invalidate_range(call->addr_at(0), instruction_size);
aoqi@1 751 }
aoqi@1 752
aoqi@1 753 // MT-safe patching of a call instruction.
aoqi@1 754 // First patches first word of instruction to two jmp's that jmps to them
aoqi@1 755 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
aoqi@1 756 // the jmp's with the first 4 byte of the new instruction.
aoqi@1 757 void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
aoqi@6880 758 Unimplemented();
aoqi@1 759 }
aoqi@1 760
aoqi@1 761 //-------------------------------------------------------------------
aoqi@1 762
aoqi@1 763 void NativeMovConstReg::verify() {
aoqi@1 764 #ifndef _LP64
aoqi@6880 765 if ( !is_op(Assembler::lui_op) ||
aoqi@6880 766 !is_op(int_at(4), Assembler::addiu_op) )
aoqi@1 767 fatal("not a mov reg, imm32")
aoqi@1 768 #else
fujie@347 769 // li64
aoqi@1 770 if ( is_op(Assembler::lui_op) &&
aoqi@6880 771 is_op(int_at(4), Assembler::ori_op) &&
aoqi@6880 772 is_special_op(int_at(8), Assembler::dsll_op) &&
aoqi@6880 773 is_op(int_at(12), Assembler::ori_op) &&
aoqi@6880 774 is_special_op(int_at(16), Assembler::dsll_op) &&
aoqi@6880 775 is_op(int_at(20), Assembler::ori_op) ) {
aoqi@6880 776 return;
aoqi@1 777 }
aoqi@1 778
fujie@347 779 //lui dst, imm16
fujie@347 780 //ori dst, dst, imm16
fujie@347 781 //dsll dst, dst, 16
fujie@347 782 //ori dst, dst, imm16
aoqi@1 783 if ( is_op(Assembler::lui_op) &&
aoqi@6880 784 is_op (int_at(4), Assembler::ori_op) &&
aoqi@6880 785 is_special_op(int_at(8), Assembler::dsll_op) &&
aoqi@6880 786 is_op (int_at(12), Assembler::ori_op) ) {
aoqi@6880 787 return;
aoqi@1 788 }
aoqi@1 789
fujie@347 790 //ori dst, R0, imm16
fujie@347 791 //dsll dst, dst, 16
fujie@347 792 //ori dst, dst, imm16
fujie@347 793 //nop
fujie@347 794 if ( is_op(Assembler::ori_op) &&
aoqi@6880 795 is_special_op(int_at(4), Assembler::dsll_op) &&
aoqi@6880 796 is_op (int_at(8), Assembler::ori_op) &&
aoqi@6880 797 nativeInstruction_at(addr_at(12))->is_nop()) {
aoqi@6880 798 return;
aoqi@1 799 }
fujie@347 800
fujie@347 801 //ori dst, R0, imm16
fujie@347 802 //dsll dst, dst, 16
fujie@347 803 //nop
fujie@347 804 //nop
fujie@347 805 if ( is_op(Assembler::ori_op) &&
aoqi@6880 806 is_special_op(int_at(4), Assembler::dsll_op) &&
aoqi@6880 807 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 808 nativeInstruction_at(addr_at(12))->is_nop()) {
aoqi@6880 809 return;
fujie@347 810 }
fujie@347 811
fujie@347 812 //daddiu dst, R0, imm16
fujie@347 813 //nop
fujie@347 814 //nop
fujie@347 815 //nop
fujie@347 816 if ( is_op(Assembler::daddiu_op) &&
aoqi@6880 817 nativeInstruction_at(addr_at(4))->is_nop() &&
aoqi@6880 818 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 819 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 820 return;
fujie@347 821 }
fujie@347 822
fujie@347 823 //lui dst, imm16
fujie@347 824 //ori dst, dst, imm16
fujie@347 825 //nop
fujie@347 826 //nop
fujie@347 827 if ( is_op(Assembler::lui_op) &&
aoqi@6880 828 is_op (int_at(4), Assembler::ori_op) &&
aoqi@6880 829 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 830 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 831 return;
fujie@347 832 }
fujie@347 833
fujie@347 834 //lui dst, imm16
fujie@347 835 //nop
fujie@347 836 //nop
fujie@347 837 //nop
fujie@347 838 if ( is_op(Assembler::lui_op) &&
aoqi@6880 839 nativeInstruction_at(addr_at(4))->is_nop() &&
aoqi@6880 840 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 841 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 842 return;
fujie@347 843 }
fujie@347 844
fujie@347 845 fatal("not a mov reg, imm64/imm48");
aoqi@1 846 #endif
aoqi@1 847 }
aoqi@1 848
aoqi@1 849 void NativeMovConstReg::print() {
aoqi@1 850 tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT,
aoqi@6880 851 instruction_address(), data());
aoqi@1 852 }
aoqi@1 853
aoqi@6880 854 intptr_t NativeMovConstReg::data() const {
aoqi@1 855 #ifndef _LP64
aoqi@6880 856 return Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
aoqi@1 857 #else
fujie@347 858 // li64
fujie@347 859 if ( is_op(Assembler::lui_op) &&
fujie@347 860 is_op(int_at(4), Assembler::ori_op) &&
fujie@347 861 is_special_op(int_at(8), Assembler::dsll_op) &&
fujie@347 862 is_op(int_at(12), Assembler::ori_op) &&
fujie@347 863 is_special_op(int_at(16), Assembler::dsll_op) &&
fujie@347 864 is_op(int_at(20), Assembler::ori_op) ) {
fujie@347 865
aoqi@6880 866 return Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
aoqi@6880 867 (intptr_t)(int_at(12) & 0xffff),
aoqi@6880 868 (intptr_t)(int_at(4) & 0xffff),
aoqi@6880 869 (intptr_t)(int_at(0) & 0xffff));
fujie@347 870 }
fujie@347 871
fujie@347 872 //lui dst, imm16
fujie@347 873 //ori dst, dst, imm16
fujie@347 874 //dsll dst, dst, 16
fujie@347 875 //ori dst, dst, imm16
fujie@347 876 if ( is_op(Assembler::lui_op) &&
fujie@347 877 is_op (int_at(4), Assembler::ori_op) &&
fujie@347 878 is_special_op(int_at(8), Assembler::dsll_op) &&
fujie@347 879 is_op (int_at(12), Assembler::ori_op) ) {
fujie@347 880
aoqi@6880 881 return Assembler::merge( (intptr_t)(int_at(12) & 0xffff),
aoqi@6880 882 (intptr_t)(int_at(4) & 0xffff),
aoqi@6880 883 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 884 (intptr_t)0);
fujie@347 885 }
fujie@347 886
fujie@347 887 //ori dst, R0, imm16
fujie@347 888 //dsll dst, dst, 16
fujie@347 889 //ori dst, dst, imm16
fujie@347 890 //nop
fujie@347 891 if ( is_op(Assembler::ori_op) &&
fujie@347 892 is_special_op(int_at(4), Assembler::dsll_op) &&
fujie@347 893 is_op (int_at(8), Assembler::ori_op) &&
fujie@347 894 nativeInstruction_at(addr_at(12))->is_nop()) {
fujie@347 895
aoqi@6880 896 return Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
aoqi@6880 897 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 898 (intptr_t)0,
aoqi@6880 899 (intptr_t)0);
fujie@347 900 }
fujie@347 901
fujie@347 902 //ori dst, R0, imm16
fujie@347 903 //dsll dst, dst, 16
fujie@347 904 //nop
fujie@347 905 //nop
fujie@347 906 if ( is_op(Assembler::ori_op) &&
fujie@347 907 is_special_op(int_at(4), Assembler::dsll_op) &&
fujie@347 908 nativeInstruction_at(addr_at(8))->is_nop() &&
fujie@347 909 nativeInstruction_at(addr_at(12))->is_nop()) {
fujie@347 910
aoqi@6880 911 return Assembler::merge( (intptr_t)(0),
aoqi@6880 912 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 913 (intptr_t)0,
aoqi@6880 914 (intptr_t)0);
fujie@347 915 }
fujie@347 916
fujie@347 917 //daddiu dst, R0, imm16
fujie@347 918 //nop
fujie@347 919 //nop
fujie@347 920 //nop
fujie@347 921 if ( is_op(Assembler::daddiu_op) &&
fujie@347 922 nativeInstruction_at(addr_at(4))->is_nop() &&
fujie@347 923 nativeInstruction_at(addr_at(8))->is_nop() &&
fujie@347 924 nativeInstruction_at(addr_at(12))->is_nop() ) {
fujie@347 925
aoqi@6880 926 int sign = int_at(0) & 0x8000;
aoqi@6880 927 if (sign == 0) {
aoqi@6880 928 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 929 (intptr_t)0,
aoqi@6880 930 (intptr_t)0,
aoqi@6880 931 (intptr_t)0);
aoqi@6880 932 } else {
aoqi@6880 933 return Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 934 (intptr_t)(0xffff),
aoqi@6880 935 (intptr_t)(0xffff),
aoqi@6880 936 (intptr_t)(0xffff));
aoqi@6880 937 }
fujie@347 938 }
fujie@347 939
fujie@347 940 //lui dst, imm16
fujie@347 941 //ori dst, dst, imm16
fujie@347 942 //nop
fujie@347 943 //nop
fujie@347 944 if ( is_op(Assembler::lui_op) &&
aoqi@6880 945 is_op (int_at(4), Assembler::ori_op) &&
aoqi@6880 946 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 947 nativeInstruction_at(addr_at(12))->is_nop() ) {
fujie@347 948
aoqi@6880 949 int sign = int_at(0) & 0x8000;
aoqi@6880 950 if (sign == 0) {
aoqi@6880 951 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
aoqi@6880 952 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 953 (intptr_t)0,
aoqi@6880 954 (intptr_t)0);
aoqi@6880 955 } else {
aoqi@6880 956 return Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
aoqi@6880 957 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 958 (intptr_t)(0xffff),
aoqi@6880 959 (intptr_t)(0xffff));
aoqi@6880 960 }
fujie@347 961 }
fujie@347 962
fujie@347 963 //lui dst, imm16
fujie@347 964 //nop
fujie@347 965 //nop
fujie@347 966 //nop
fujie@347 967 if ( is_op(Assembler::lui_op) &&
aoqi@6880 968 nativeInstruction_at(addr_at(4))->is_nop() &&
aoqi@6880 969 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 970 nativeInstruction_at(addr_at(12))->is_nop() ) {
fujie@347 971
aoqi@6880 972 int sign = int_at(0) & 0x8000;
aoqi@6880 973 if (sign == 0) {
aoqi@6880 974 return Assembler::merge( (intptr_t)0,
aoqi@6880 975 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 976 (intptr_t)0,
aoqi@6880 977 (intptr_t)0);
aoqi@6880 978 } else {
aoqi@6880 979 return Assembler::merge( (intptr_t)0,
aoqi@6880 980 (intptr_t)(int_at(0) & 0xffff),
aoqi@6880 981 (intptr_t)(0xffff),
aoqi@6880 982 (intptr_t)(0xffff));
aoqi@6880 983 }
fujie@347 984 }
fujie@347 985
fujie@347 986 fatal("not a mov reg, imm64/imm48");
fujie@347 987
fujie@347 988 #endif
fujie@347 989 }
fujie@347 990
fujie@347 991 void NativeMovConstReg::patch_set48(intptr_t x) {
fujie@347 992 jlong value = (jlong) x;
fujie@347 993 int rt_reg = (int_at(0) & (0x1f << 16));
fujie@347 994 int rs_reg = rt_reg << 5;
fujie@347 995 int rd_reg = rt_reg >> 5;
fujie@347 996
fujie@347 997 int hi = (int)(value >> 32);
fujie@347 998 int lo = (int)(value & ~0);
fujie@347 999
fujie@347 1000 int count = 0;
fujie@347 1001
fujie@347 1002 if (value == lo) { // 32-bit integer
fujie@347 1003 if (Assembler::is_simm16(value)) {
fujie@347 1004 //daddiu(d, R0, value);
fujie@347 1005 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
fujie@347 1006 count += 1;
fujie@347 1007 } else {
fujie@347 1008 //lui(d, split_low(value >> 16));
fujie@347 1009 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
fujie@347 1010 count += 1;
fujie@347 1011 if (Assembler::split_low(value)) {
fujie@347 1012 //ori(d, d, split_low(value));
fujie@347 1013 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@347 1014 count += 1;
fujie@347 1015 }
fujie@347 1016 }
fujie@347 1017 } else if (hi == 0) { // hardware zero-extends to upper 32
aoqi@6880 1018 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
aoqi@6880 1019 count += 1;
aoqi@6880 1020 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
aoqi@6880 1021 count += 1;
aoqi@6880 1022 if (Assembler::split_low(value)) {
aoqi@6880 1023 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@347 1024 count += 1;
aoqi@6880 1025 }
fujie@347 1026 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
fujie@347 1027 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
fujie@347 1028 count += 1;
fujie@347 1029 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
fujie@347 1030 count += 1;
fujie@347 1031 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
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));
fujie@347 1034 count += 1;
aoqi@1 1035 } else {
fujie@366 1036 tty->print_cr("value = 0x%x", value);
fujie@347 1037 guarantee(false, "Not supported yet !");
aoqi@1 1038 }
fujie@347 1039
fujie@347 1040 for (count; count < 4; count++) {
fujie@347 1041 set_int_at(count << 2, 0);
fujie@347 1042 }
aoqi@1 1043 }
aoqi@1 1044
aoqi@1 1045 void NativeMovConstReg::set_data(intptr_t x) {
aoqi@1 1046 #ifndef _LP64
aoqi@1 1047 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
aoqi@1 1048 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
aoqi@6880 1049 ICache::invalidate_range(addr_at(0), 8);
aoqi@1 1050 #else
aoqi@1 1051 /* li64 or li48 */
fujie@400 1052 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 1053 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 48) & 0xffff));
aoqi@1 1054 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 32) & 0xffff));
aoqi@1 1055 set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)x >> 16) & 0xffff));
aoqi@1 1056 set_int_at(20, (int_at(20) & 0xffff0000) | (Assembler::split_low((intptr_t)x) & 0xffff));
aoqi@1 1057 } else {
fujie@347 1058 patch_set48(x);
aoqi@1 1059 }
fujie@347 1060
aoqi@1 1061 ICache::invalidate_range(addr_at(0), 24);
aoqi@1 1062 #endif
aoqi@1 1063 }
aoqi@1 1064
aoqi@1 1065 //-------------------------------------------------------------------
aoqi@1 1066
aoqi@1 1067 int NativeMovRegMem::offset() const{
aoqi@6880 1068 if (is_immediate())
aoqi@1 1069 return (short)(int_at(instruction_offset)&0xffff);
aoqi@6880 1070 else
aoqi@1 1071 return Assembler::merge(int_at(hiword_offset)&0xffff, long_at(instruction_offset)&0xffff);
aoqi@1 1072 }
aoqi@1 1073
aoqi@1 1074 void NativeMovRegMem::set_offset(int x) {
aoqi@1 1075 if (is_immediate()) {
aoqi@1 1076 assert(Assembler::is_simm16(x), "just check");
aoqi@1 1077 set_int_at(0, (int_at(0)&0xffff0000) | (x&0xffff) );
aoqi@1 1078 if (is_64ldst()) {
aoqi@1 1079 assert(Assembler::is_simm16(x+4), "just check");
aoqi@6880 1080 set_int_at(4, (int_at(4)&0xffff0000) | ((x+4)&0xffff) );
aoqi@6880 1081 }
aoqi@1 1082 } else {
aoqi@1 1083 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high(x) & 0xffff));
aoqi@1 1084 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low(x) & 0xffff));
aoqi@1 1085 }
aoqi@1 1086 ICache::invalidate_range(addr_at(0), 8);
aoqi@1 1087 }
aoqi@1 1088
aoqi@1 1089 void NativeMovRegMem::verify() {
aoqi@1 1090 int offset = 0;
aoqi@1 1091
aoqi@1 1092 if ( Assembler::opcode(int_at(0)) == Assembler::lui_op ) {
aoqi@1 1093 #ifndef _LP64
aoqi@1 1094 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op) ||
aoqi@6880 1095 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
aoqi@6880 1096 (Assembler::special(int_at(8)) != Assembler::add_op))
aoqi@1 1097 #else
aoqi@1 1098 /* Jin: fit MIPS64 */
aoqi@6880 1099 if ( (Assembler::opcode(int_at(4)) != Assembler::addiu_op &&
aoqi@6880 1100 Assembler::opcode(int_at(4)) != Assembler::daddiu_op ) ||
aoqi@6880 1101 (Assembler::opcode(int_at(8)) != Assembler::special_op) ||
aoqi@6880 1102 (Assembler::special(int_at(8)) != Assembler::add_op
aoqi@6880 1103 && Assembler::special(int_at(8)) != Assembler::dadd_op))
aoqi@1 1104 #endif
aoqi@6880 1105 fatal ("not a mov [reg+offs], reg instruction");
aoqi@6880 1106 offset += 12;
aoqi@1 1107 }
aoqi@1 1108
aoqi@1 1109 switch(Assembler::opcode(int_at(offset))) {
aoqi@6880 1110 case Assembler::lb_op:
aoqi@6880 1111 case Assembler::lbu_op:
aoqi@6880 1112 case Assembler::lh_op:
aoqi@6880 1113 case Assembler::lhu_op:
aoqi@6880 1114 case Assembler::lw_op:
aoqi@8865 1115 case Assembler::lwu_op:
aoqi@6880 1116 LP64_ONLY(case Assembler::ld_op:)
aoqi@6880 1117 case Assembler::lwc1_op:
aoqi@6880 1118 LP64_ONLY(case Assembler::ldc1_op:)
aoqi@6880 1119 case Assembler::sb_op:
aoqi@6880 1120 case Assembler::sh_op:
aoqi@6880 1121 case Assembler::sw_op:
aoqi@6880 1122 LP64_ONLY(case Assembler::sd_op:)
aoqi@6880 1123 case Assembler::swc1_op:
aoqi@6880 1124 LP64_ONLY(case Assembler::sdc1_op:)
aoqi@6880 1125 break;
aoqi@6880 1126 default:
aoqi@6880 1127 fatal ("not a mov [reg+offs], reg instruction");
aoqi@6880 1128 }
aoqi@1 1129 }
aoqi@1 1130
aoqi@1 1131
aoqi@1 1132 void NativeMovRegMem::print() {
aoqi@1 1133 tty->print_cr("0x%x: mov reg, [reg + %x]", instruction_address(), offset());
aoqi@1 1134 }
aoqi@1 1135
aoqi@1 1136 void NativeIllegalInstruction::insert(address code_pos) {
aoqi@1 1137 CodeBuffer cb(code_pos, instruction_size);
aoqi@1 1138 MacroAssembler masm(&cb);
aoqi@1 1139 #define __ masm.
aoqi@1 1140 __ brk(11);
aoqi@1 1141 #undef __
aoqi@1 1142
aoqi@1 1143 ICache::invalidate_range(code_pos, instruction_size);
aoqi@1 1144 }
aoqi@1 1145
aoqi@1 1146 void NativeGeneralJump::verify() {
aoqi@1 1147 assert(((NativeInstruction *)this)->is_jump() ||
aoqi@1 1148 ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction");
aoqi@1 1149 }
aoqi@1 1150
fujie@386 1151 void NativeGeneralJump::patch_set48_gs(address dest) {
fujie@386 1152 jlong value = (jlong) dest;
fujie@386 1153 int rt_reg = (int_at(0) & (0x1f << 16));
fujie@386 1154
aoqi@6880 1155 if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9
fujie@386 1156
fujie@386 1157 int rs_reg = rt_reg << 5;
fujie@386 1158 int rd_reg = rt_reg >> 5;
fujie@386 1159
fujie@386 1160 int hi = (int)(value >> 32);
fujie@386 1161 int lo = (int)(value & ~0);
fujie@386 1162
fujie@386 1163 int count = 0;
fujie@386 1164
fujie@386 1165 int insts[4] = {0, 0, 0, 0};
fujie@386 1166
fujie@386 1167 if (value == lo) { // 32-bit integer
fujie@386 1168 if (Assembler::is_simm16(value)) {
fujie@386 1169 insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
fujie@386 1170 count += 1;
fujie@386 1171 } else {
fujie@386 1172 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
fujie@386 1173 count += 1;
fujie@386 1174 if (Assembler::split_low(value)) {
fujie@386 1175 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
fujie@386 1176 count += 1;
fujie@386 1177 }
fujie@386 1178 }
fujie@386 1179 } else if (hi == 0) { // hardware zero-extends to upper 32
fujie@386 1180 insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
fujie@386 1181 count += 1;
fujie@386 1182 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
fujie@386 1183 count += 1;
fujie@386 1184 if (Assembler::split_low(value)) {
fujie@386 1185 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
fujie@386 1186 count += 1;
fujie@386 1187 }
fujie@386 1188 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
fujie@386 1189 insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
fujie@386 1190 count += 1;
fujie@386 1191 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
fujie@386 1192 count += 1;
fujie@386 1193 insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
fujie@386 1194 count += 1;
fujie@386 1195 insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
fujie@386 1196 count += 1;
fujie@386 1197 } else {
fujie@386 1198 tty->print_cr("dest = 0x%x", value);
fujie@386 1199 guarantee(false, "Not supported yet !");
fujie@386 1200 }
fujie@386 1201
fujie@386 1202 for (count; count < 4; count++) {
fujie@386 1203 insts[count] = 0;
fujie@386 1204 }
fujie@386 1205
fujie@386 1206 atomic_store128_ptr func = get_atomic_store128_func();
fujie@386 1207 (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
fujie@386 1208
fujie@386 1209 ICache::invalidate_range(addr_at(0), 16);
fujie@386 1210 }
fujie@386 1211
fujie@367 1212 void NativeGeneralJump::patch_set48(address dest) {
fujie@367 1213 jlong value = (jlong) dest;
fujie@367 1214 int rt_reg = (int_at(0) & (0x1f << 16));
fujie@367 1215 int rs_reg = rt_reg << 5;
fujie@367 1216 int rd_reg = rt_reg >> 5;
fujie@367 1217
fujie@367 1218 int hi = (int)(value >> 32);
fujie@367 1219 int lo = (int)(value & ~0);
fujie@367 1220
fujie@367 1221 int count = 0;
fujie@367 1222
fujie@367 1223 if (value == lo) { // 32-bit integer
fujie@367 1224 if (Assembler::is_simm16(value)) {
fujie@367 1225 set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
fujie@367 1226 count += 1;
fujie@367 1227 } else {
fujie@367 1228 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
fujie@367 1229 count += 1;
fujie@367 1230 if (Assembler::split_low(value)) {
fujie@367 1231 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@367 1232 count += 1;
fujie@367 1233 }
fujie@367 1234 }
fujie@367 1235 } else if (hi == 0) { // hardware zero-extends to upper 32
fujie@367 1236 set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
fujie@367 1237 count += 1;
fujie@367 1238 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
fujie@367 1239 count += 1;
fujie@367 1240 if (Assembler::split_low(value)) {
fujie@367 1241 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@367 1242 count += 1;
fujie@367 1243 }
fujie@367 1244 } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
fujie@367 1245 set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
fujie@367 1246 count += 1;
fujie@367 1247 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
fujie@367 1248 count += 1;
fujie@367 1249 set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
fujie@367 1250 count += 1;
fujie@367 1251 set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
fujie@367 1252 count += 1;
fujie@367 1253 } else {
fujie@367 1254 tty->print_cr("dest = 0x%x", value);
fujie@367 1255 guarantee(false, "Not supported yet !");
fujie@367 1256 }
fujie@367 1257
fujie@367 1258 for (count; count < 4; count++) {
fujie@367 1259 set_int_at(count << 2, 0);
fujie@367 1260 }
fujie@386 1261
fujie@386 1262 ICache::invalidate_range(addr_at(0), 16);
fujie@386 1263 }
fujie@386 1264
fujie@397 1265 void NativeGeneralJump::patch_on_j_only(address dst) {
fujie@397 1266 #ifdef _LP64
aoqi@6880 1267 long dest = ((long)dst - (((long)addr_at(4)) & 0xfffffffff0000000))>>2;
fujie@397 1268 #else
aoqi@6880 1269 long dest = ((long)dst - (((long)addr_at(4)) & 0xf0000000))>>2;
fujie@397 1270 #endif
aoqi@6880 1271 if ((dest >= 0) && (dest < (1<<26))) {
aoqi@6880 1272 jint j_inst = (Assembler::j_op << 26) | dest;
aoqi@6880 1273 set_int_at(0, j_inst);
aoqi@6880 1274 ICache::invalidate_range(addr_at(0), 4);
aoqi@6880 1275 } else {
aoqi@6880 1276 ShouldNotReachHere();
aoqi@6880 1277 }
fujie@397 1278 }
fujie@397 1279
fujie@386 1280
fujie@386 1281 void NativeGeneralJump::patch_on_j_gs(address dst) {
fujie@386 1282 #ifdef _LP64
aoqi@6880 1283 long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
fujie@386 1284 #else
aoqi@6880 1285 long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
fujie@386 1286 #endif
aoqi@6880 1287 if ((dest >= 0) && (dest < (1<<26))) {
aoqi@6880 1288 jint j_inst = (Assembler::j_op << 26) | dest;
aoqi@6880 1289 set_int_at(16, j_inst);
aoqi@6880 1290 ICache::invalidate_range(addr_at(16), 4);
aoqi@6880 1291 } else {
aoqi@6880 1292 ShouldNotReachHere();
aoqi@6880 1293 }
fujie@386 1294 }
fujie@386 1295
fujie@386 1296 void NativeGeneralJump::patch_on_j(address dst) {
aoqi@6880 1297 patch_on_j_gs(dst);
fujie@386 1298 }
fujie@386 1299
fujie@386 1300 void NativeGeneralJump::patch_on_jr_gs(address dst) {
aoqi@6880 1301 patch_set48_gs(dst);
aoqi@6880 1302 ICache::invalidate_range(addr_at(0), 16);
fujie@386 1303 }
fujie@386 1304
fujie@386 1305 void NativeGeneralJump::patch_on_jr(address dst) {
aoqi@6880 1306 patch_set48(dst);
aoqi@6880 1307 ICache::invalidate_range(addr_at(0), 16);
fujie@367 1308 }
fujie@367 1309
aoqi@1 1310
aoqi@1 1311 void NativeGeneralJump::set_jump_destination(address dest) {
aoqi@1 1312 OrderAccess::fence();
aoqi@1 1313
aoqi@1 1314 if (is_short()) {
aoqi@1 1315 assert(Assembler::is_simm16(dest-addr_at(4)), "change this code");
aoqi@1 1316 set_int_at(0, (int_at(0) & 0xffff0000) | (dest - addr_at(4)) & 0xffff );
aoqi@1 1317 ICache::invalidate_range(addr_at(0), 4);
aoqi@1 1318 #ifdef _LP64
aoqi@1 1319 } else if (is_b_far()) {
aoqi@1 1320 int offset = dest - addr_at(12);
aoqi@1 1321 set_int_at(12, (int_at(12) & 0xffff0000) | (offset >> 16));
aoqi@1 1322 set_int_at(16, (int_at(16) & 0xffff0000) | (offset & 0xffff));
aoqi@1 1323 #endif
aoqi@1 1324 } else {
aoqi@1 1325 #ifndef _LP64
aoqi@1 1326 set_int_at(0, (int_at(0) & 0xffff0000) | (Assembler::split_high((intptr_t)dest) & 0xffff));
aoqi@1 1327 set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
aoqi@1 1328 ICache::invalidate_range(addr_at(0), 8);
aoqi@1 1329 #else
fujie@386 1330 if (is_op(int_at(16), Assembler::j_op)) {
fujie@386 1331 if (UseLoongsonISA) {
fujie@386 1332 patch_on_j_gs(dest);
fujie@386 1333 } else {
fujie@386 1334 patch_on_j(dest);
fujie@386 1335 }
fujie@397 1336 } else if (is_op(int_at(0), Assembler::j_op)) {
fujie@397 1337 patch_on_j_only(dest);
fujie@386 1338 } else if (is_special_op(int_at(16), Assembler::jr_op)) {
fujie@386 1339 if (UseLoongsonISA) {
fujie@397 1340 //guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
fujie@397 1341 //patch_on_jr_gs(dest);
fujie@397 1342 patch_on_jr(dest);
fujie@386 1343 } else {
fujie@386 1344 patch_on_jr(dest);
fujie@386 1345 }
fujie@397 1346 } else {
fujie@397 1347 fatal("not a jump");
fujie@386 1348 }
aoqi@1 1349 #endif
aoqi@1 1350 }
aoqi@1 1351 }
aoqi@1 1352
aoqi@1 1353 // we now use b to do this. be careful when using this method
aoqi@1 1354 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
aoqi@1 1355 CodeBuffer cb(code_pos, instruction_size);
aoqi@1 1356 MacroAssembler masm(&cb);
aoqi@6880 1357 #define __ masm.
aoqi@1 1358 #ifdef _LP64
aoqi@6880 1359 if (Assembler::is_simm16((entry - code_pos - 4) / 4)) {
aoqi@1 1360 __ b(entry);
aoqi@1 1361 __ delayed()->nop();
aoqi@6880 1362 } else {
aoqi@1 1363 /* a simplified b_far */
aoqi@1 1364 int offset = entry - code_pos;
aoqi@1 1365
aoqi@1 1366 // FIXME: need to preserve RA?
aoqi@1 1367 __ emit_long(0x4110001); //__ emit_long(Assembler::insn_ORRI(Assembler::regimm_op, 0, Assembler::bgezal_op, 1));
aoqi@6880 1368 __ lui(T9, (offset - 8) >> 16); // delay slot
aoqi@1 1369 __ ori(T9, T9, (offset - 8) & 0xffff);
aoqi@1 1370 __ daddu(T9, T9, RA);
aoqi@1 1371 __ jr(T9);
zhaixiang@9144 1372 __ delayed()->nop();
aoqi@1 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@1 1385 /*
aoqi@1 1386 0x000000556809f198: dadd at, ra, zero
aoqi@1 1387 0x000000556809f19c: [4110001]bgezal zero, 0x000000556809f1a4
aoqi@1 1388
aoqi@1 1389 0x000000556809f1a0: nop
aoqi@1 1390 0x000000556809f1a4: lui t9, 0xfffffffd
aoqi@6880 1391 0x000000556809f1a8: ori t9, t9, 0x14dc
aoqi@6880 1392 0x000000556809f1ac: daddu t9, t9, ra
aoqi@1 1393 0x000000556809f1b0: dadd ra, at, zero
aoqi@1 1394 0x000000556809f1b4: jr t9
aoqi@1 1395 0x000000556809f1b8: nop
aoqi@1 1396 ;; ImplicitNullCheckStub slow case
aoqi@1 1397 0x000000556809f1bc: lui t9, 0x55
aoqi@1 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
aoqi@1 1410 /* 2012/4/19 Jin: Assembler::merge() is not correct in MIPS_64!
aoqi@1 1411
aoqi@1 1412 Example:
aoqi@1 1413 hi16 = 0xfffd,
aoqi@1 1414 lo16 = f7a4,
aoqi@6880 1415
aoqi@1 1416 offset=0xfffdf7a4 (Right)
aoqi@1 1417 Assembler::merge = 0xfffcf7a4 (Wrong)
aoqi@1 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@397 1582 fatal("not a jump");
aoqi@1 1583 #endif
aoqi@1 1584 }
aoqi@1 1585
aoqi@1 1586 // MT-safe patching of a long jump instruction.
aoqi@1 1587 // First patches first word of instruction to two jmp's that jmps to them
aoqi@1 1588 // selfs (spinlock). Then patches the last byte, and then atomicly replaces
aoqi@1 1589 // the jmp's with the first 4 byte of the new instruction.
aoqi@1 1590 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
aoqi@6880 1591 NativeGeneralJump* h_jump = nativeGeneralJump_at (instr_addr);
aoqi@6880 1592 assert(NativeGeneralJump::instruction_size == NativeCall::instruction_size,
aoqi@1 1593 "note::Runtime1::patch_code uses NativeCall::instruction_size");
aoqi@1 1594
aoqi@1 1595 /* 2013/6/13 Jin: ensure 100% atomicity */
zhaixiang@9128 1596 guarantee(!os::is_MP() || (((long)instr_addr % BytesPerWord) == 0), "destination must be aligned for SD");
aoqi@1 1597
aoqi@1 1598 int *p = (int *)instr_addr;
aoqi@1 1599 int jr_word = p[4];
aoqi@1 1600
aoqi@1 1601 p[4] = 0x1000fffb; /* .1: --; --; --; --; b .1; nop */
aoqi@1 1602 memcpy(instr_addr, code_buffer, NativeCall::instruction_size - 8);
aoqi@1 1603 *(long *)(instr_addr + 16) = *(long *)(code_buffer + 16);
aoqi@1 1604 }
aoqi@1 1605
aoqi@1 1606 /* Must ensure atomicity */
aoqi@1 1607 void NativeGeneralJump::patch_verified_entry(address entry, address verified_entry, address dest) {
aoqi@6880 1608 /* 2013/11/5 Jin: ensure 100% atomicity.
aoqi@6880 1609 * The destination is fixed and can be cached in JavaThread.
aoqi@6880 1610 */
zhaixiang@9128 1611 guarantee(!os::is_MP() || (((long)verified_entry % BytesPerWord) == 0), "destination must be aligned for SD");
aoqi@1 1612
aoqi@6880 1613 int code_buffer[4];
aoqi@1 1614
aoqi@6880 1615 CodeBuffer cb((address)code_buffer, instruction_size);
aoqi@6880 1616 MacroAssembler masm(&cb);
aoqi@1 1617 #define __ masm.
aoqi@6880 1618 __ ld(T9, TREG, in_bytes(JavaThread::handle_wrong_method_stub_offset()));
aoqi@6880 1619 __ jr(T9);
aoqi@6880 1620 __ delayed()->nop();
aoqi@6880 1621 __ nop();
aoqi@1 1622
aoqi@6880 1623 atomic_store128_ptr func = get_atomic_store128_func();
aoqi@6880 1624 (*func)((long *)verified_entry, 0, *(long *)&code_buffer[0], *(long *)&code_buffer[2]);
aoqi@1 1625
aoqi@6880 1626 ICache::invalidate_range(verified_entry, instruction_size);
aoqi@1 1627 }
aoqi@1 1628
aoqi@1 1629 bool NativeInstruction::is_jump()
aoqi@6880 1630 {
aoqi@1 1631 #ifndef _LP64
aoqi@1 1632 return ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode) ||
aoqi@1 1633 (is_op(int_at(0), Assembler::lui_op) &&
aoqi@1 1634 is_op(int_at(4), Assembler::addiu_op) &&
aoqi@6880 1635 is_special_op(int_at(8), Assembler::jr_op));
aoqi@1 1636 #else
aoqi@6880 1637 // lui rd, imm(63...48);
aoqi@6880 1638 // ori rd, rd, imm(47...32);
aoqi@6880 1639 // dsll rd, rd, 16;
aoqi@6880 1640 // ori rd, rd, imm(31...16);
aoqi@6880 1641 // dsll rd, rd, 16;
aoqi@6880 1642 // ori rd, rd, imm(15...0);
aoqi@6880 1643 // jalr rd
aoqi@6880 1644 // nop
aoqi@6880 1645 //
aoqi@1 1646 if ((int_at(0) & NativeGeneralJump::b_mask) == NativeGeneralJump::beq_opcode)
aoqi@1 1647 return true;
aoqi@1 1648 if (is_op(int_at(4), Assembler::lui_op)) /* simplified b_far */
aoqi@1 1649 return true;
aoqi@1 1650 if (is_op(int_at(12), Assembler::lui_op)) /* original b_far */
aoqi@1 1651 return true;
fujie@386 1652
fujie@386 1653 // nop
fujie@386 1654 // nop
fujie@386 1655 // nop
fujie@386 1656 // nop
aoqi@6880 1657 // j target
fujie@386 1658 // nop
fujie@386 1659 if ( is_nop() &&
fujie@386 1660 nativeInstruction_at(addr_at(4))->is_nop() &&
fujie@386 1661 nativeInstruction_at(addr_at(8))->is_nop() &&
fujie@386 1662 nativeInstruction_at(addr_at(12))->is_nop() &&
fujie@386 1663 nativeInstruction_at(addr_at(16))->is_op(Assembler::j_op) &&
fujie@386 1664 nativeInstruction_at(addr_at(20))->is_nop() ) {
aoqi@6880 1665 return true;
fujie@386 1666 }
fujie@386 1667
fujie@397 1668 if ( nativeInstruction_at(addr_at(0))->is_op(Assembler::j_op) &&
fujie@397 1669 nativeInstruction_at(addr_at(4))->is_nop() ) {
aoqi@6880 1670 return true;
fujie@397 1671 }
fujie@397 1672
aoqi@1 1673 if (is_op(int_at(0), Assembler::lui_op) &&
aoqi@1 1674 is_op(int_at(4), Assembler::ori_op) &&
aoqi@1 1675 is_special_op(int_at(8), Assembler::dsll_op) &&
aoqi@1 1676 is_op(int_at(12), Assembler::ori_op) &&
aoqi@1 1677 is_special_op(int_at(16), Assembler::dsll_op) &&
aoqi@1 1678 is_op(int_at(20), Assembler::ori_op))
aoqi@1 1679 return true;
aoqi@1 1680 if (is_op(int_at(0), Assembler::lui_op) &&
aoqi@1 1681 is_op(int_at(4), Assembler::ori_op) &&
aoqi@1 1682 is_special_op(int_at(8), Assembler::dsll_op) &&
aoqi@6880 1683 is_op(int_at(12), Assembler::ori_op))
aoqi@1 1684 return true;
fujie@367 1685
fujie@367 1686 //ori dst, R0, imm16
fujie@367 1687 //dsll dst, dst, 16
fujie@367 1688 //ori dst, dst, imm16
fujie@367 1689 //nop
fujie@367 1690 if ( is_op(Assembler::ori_op) &&
aoqi@6880 1691 is_special_op(int_at(4), Assembler::dsll_op) &&
aoqi@6880 1692 is_op (int_at(8), Assembler::ori_op) &&
fujie@367 1693 nativeInstruction_at(addr_at(12))->is_nop()) {
aoqi@6880 1694 return true;
fujie@367 1695 }
fujie@367 1696
fujie@367 1697 //ori dst, R0, imm16
fujie@367 1698 //dsll dst, dst, 16
fujie@367 1699 //nop
fujie@367 1700 //nop
fujie@367 1701 if ( is_op(Assembler::ori_op) &&
aoqi@6880 1702 is_special_op(int_at(4), Assembler::dsll_op) &&
aoqi@6880 1703 nativeInstruction_at(addr_at(8))->is_nop() &&
fujie@367 1704 nativeInstruction_at(addr_at(12))->is_nop()) {
fujie@367 1705 return true;
fujie@367 1706 }
fujie@367 1707
fujie@367 1708 //daddiu dst, R0, imm16
fujie@367 1709 //nop
fujie@367 1710 //nop
fujie@367 1711 //nop
fujie@367 1712 if ( is_op(Assembler::daddiu_op) &&
aoqi@6880 1713 nativeInstruction_at(addr_at(4))->is_nop() &&
aoqi@6880 1714 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 1715 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 1716 return true;
fujie@367 1717 }
fujie@367 1718
fujie@367 1719 //lui dst, imm16
fujie@367 1720 //ori dst, dst, imm16
fujie@367 1721 //nop
fujie@367 1722 //nop
fujie@367 1723 if ( is_op(Assembler::lui_op) &&
aoqi@6880 1724 is_op (int_at(4), Assembler::ori_op) &&
aoqi@6880 1725 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 1726 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 1727 return true;
fujie@367 1728 }
fujie@367 1729
fujie@367 1730 //lui dst, imm16
fujie@367 1731 //nop
fujie@367 1732 //nop
fujie@367 1733 //nop
fujie@367 1734 if ( is_op(Assembler::lui_op) &&
aoqi@6880 1735 nativeInstruction_at(addr_at(4))->is_nop() &&
aoqi@6880 1736 nativeInstruction_at(addr_at(8))->is_nop() &&
aoqi@6880 1737 nativeInstruction_at(addr_at(12))->is_nop() ) {
aoqi@6880 1738 return true;
fujie@367 1739 }
fujie@367 1740
aoqi@1 1741 return false;
aoqi@1 1742 #endif
aoqi@1 1743 }
aoqi@1 1744
aoqi@1 1745 bool NativeInstruction::is_dtrace_trap() {
aoqi@1 1746 //return (*(int32_t*)this & 0xff) == 0xcc;
aoqi@6880 1747 Unimplemented();
aoqi@6880 1748 return false;
aoqi@1 1749 }
aoqi@1 1750
aoqi@1 1751 bool NativeInstruction::is_safepoint_poll() {
aoqi@1 1752 #ifdef _LP64
aoqi@1 1753 /*
fujie@166 1754 390 li T2, 0x0000000000400000 #@loadConP
fujie@166 1755 394 sw [SP + #12], V1 # spill 9
fujie@166 1756 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 1757
fujie@166 1758 0x000000ffe5815130: lui t2, 0x40
fujie@166 1759 0x000000ffe5815134: sw v1, 0xc(sp) ; OopMap{a6=Oop off=920}
fujie@166 1760 ;*goto
fujie@166 1761 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
fujie@166 1762
aoqi@6880 1763 0x000000ffe5815138: lw at, 0x0(t2) ;*goto <--- PC
fujie@166 1764 ; - spec.benchmarks.compress.Decompressor::decompress@224 (line 584)
aoqi@1 1765 */
fujie@166 1766
fujie@166 1767 // Since there may be some spill instructions between the safePoint_poll and loadConP,
fujie@166 1768 // we check the safepoint instruction like the this.
fujie@166 1769 return is_op(Assembler::lw_op) && is_rt(AT);
aoqi@1 1770 #else
aoqi@6880 1771 return is_op(int_at(-4), Assembler::lui_op) &&
aoqi@6880 1772 is_op(Assembler::lw_op) &&
aoqi@1 1773 is_rt(AT);
aoqi@1 1774 #endif
aoqi@1 1775 }

mercurial