1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/mips/vm/c1_MacroAssembler_mips.cpp Fri Apr 29 00:06:10 2016 +0800 1.3 @@ -0,0 +1,516 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#include "precompiled.hpp" 1.30 +#include "c1/c1_MacroAssembler.hpp" 1.31 +#include "c1/c1_Runtime1.hpp" 1.32 +#include "classfile/systemDictionary.hpp" 1.33 +#include "gc_interface/collectedHeap.hpp" 1.34 +#include "interpreter/interpreter.hpp" 1.35 +#include "oops/arrayOop.hpp" 1.36 +#include "oops/markOop.hpp" 1.37 +#include "runtime/basicLock.hpp" 1.38 +#include "runtime/biasedLocking.hpp" 1.39 +#include "runtime/os.hpp" 1.40 +#include "runtime/stubRoutines.hpp" 1.41 + 1.42 +int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr,Register scratch, Label& slow_case) { 1.43 + const int aligned_mask = BytesPerWord -1; 1.44 + const int hdr_offset = oopDesc::mark_offset_in_bytes(); 1.45 + 1.46 + // hdr is just a temperary register, it cannot be AT, however 1.47 + if ( hdr == NOREG ) { 1.48 + hdr = T8; 1.49 + } 1.50 + 1.51 + assert_different_registers(hdr, obj, disp_hdr); 1.52 + Label done; 1.53 + // The following move must be the first instruction of emitted since debug 1.54 + // information may be generated for it. 1.55 + // Load object header 1.56 + int null_check_offset = -1; 1.57 + verify_oop(obj); 1.58 + 1.59 + // save object being locked into the BasicObjectLock 1.60 + st_ptr(obj, disp_hdr, BasicObjectLock::obj_offset_in_bytes()); 1.61 + if (UseBiasedLocking) { 1.62 + assert(scratch != noreg, "should have scratch register at this point"); 1.63 + null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, 1.64 + done, &slow_case); 1.65 + } else { 1.66 + null_check_offset = offset(); 1.67 + } 1.68 + 1.69 + // Load object header 1.70 + ld_ptr(hdr, obj, hdr_offset); 1.71 + // and mark it as unlocked 1.72 + ori(hdr, hdr, markOopDesc::unlocked_value); 1.73 + // save unlocked object header into the displaced header location on the stack 1.74 + sd(hdr, disp_hdr, 0); 1.75 + 1.76 + // test if object header is still the same (i.e. unlocked), and if so, store the 1.77 + // displaced header address in the object header - if it is not the same, get the 1.78 + // object header instead 1.79 + //if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! 1.80 + cmpxchg(disp_hdr, Address(obj, hdr_offset), hdr); 1.81 + // if the object header was the same, we're done 1.82 + if (PrintBiasedLockingStatistics) { 1.83 + //cond_incl(Assembler::equal, 1.84 + //Address((int) BiasedLocking::fast_path_entry_count_addr(), relocInfo::none)); 1.85 + // cond_incl(Assembler::equal, 1.86 + // Address((int) BiasedLocking::fast_path_entry_count_addr(), relocInfo::none)); 1.87 + 1.88 + } 1.89 + 1.90 + 1.91 + bne(AT, R0, done); 1.92 + delayed()->nop(); 1.93 + // if the object header was not the same, it is now in the hdr register 1.94 + // => test if it is a stack pointer into the same stack (recursive locking), i.e.: 1.95 + // 1.96 + // 1) (hdr & aligned_mask) == 0 1.97 + // 2) SP <= hdr 1.98 + // 3) hdr <= SP + page_size 1.99 + // 1.100 + // these 3 tests can be done by evaluating the following expression: 1.101 + // 1.102 + // (hdr - SP) & (aligned_mask - page_size) 1.103 + // 1.104 + // assuming both the stack pointer and page_size have their least 1.105 + // significant 2 bits cleared and page_size is a power of 2 1.106 + sub(hdr, hdr, SP); 1.107 + move(AT, aligned_mask - os::vm_page_size()); 1.108 + andr(hdr, hdr, AT); 1.109 + // for recursive locking, the result is zero => save it in the displaced header 1.110 + // location (NULL in the displaced hdr location indicates recursive locking) 1.111 + st_ptr(hdr, disp_hdr, 0); 1.112 + // otherwise we don't care about the result and handle locking via runtime call 1.113 + bne_far(hdr, R0, slow_case); 1.114 + delayed()->nop(); 1.115 + // done 1.116 + bind(done); 1.117 + return null_check_offset; 1.118 +} 1.119 + 1.120 + 1.121 +void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { 1.122 + const int aligned_mask = BytesPerWord -1; 1.123 + const int hdr_offset = oopDesc::mark_offset_in_bytes(); 1.124 + 1.125 + // hdr is just a temparay register, however, it cannot be AT 1.126 + if ( hdr == NOREG ) { 1.127 + hdr = T8; 1.128 + } 1.129 + 1.130 + assert_different_registers(hdr, obj, disp_hdr); 1.131 + assert(BytesPerWord == 8, "adjust aligned_mask and code"); 1.132 + Label done; 1.133 + if (UseBiasedLocking) { 1.134 + // load object 1.135 + ld_ptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); 1.136 + biased_locking_exit(obj, hdr, done); 1.137 + } 1.138 + 1.139 + 1.140 + 1.141 + // load displaced header 1.142 + ld_ptr(hdr, disp_hdr, 0); 1.143 + // if the loaded hdr is NULL we had recursive locking 1.144 + // if we had recursive locking, we are done 1.145 + beq(hdr, R0, done); 1.146 + delayed()->nop(); 1.147 + // load object 1.148 + if(!UseBiasedLocking){ 1.149 + ld_ptr(obj, disp_hdr, BasicObjectLock::obj_offset_in_bytes()); 1.150 + } 1.151 + 1.152 + verify_oop(obj); 1.153 + // test if object header is pointing to the displaced header, and if so, restore 1.154 + // the displaced header in the object - if the object header is not pointing to 1.155 + // the displaced header, get the object header instead 1.156 + //if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg! 1.157 + cmpxchg(hdr, Address(obj, hdr_offset), disp_hdr); 1.158 + // if the object header was not pointing to the displaced header, 1.159 + // we do unlocking via runtime call 1.160 + beq_far(AT, R0, slow_case); 1.161 + delayed()->nop(); 1.162 + // done 1.163 + bind(done); 1.164 +} 1.165 + 1.166 + 1.167 + 1.168 +// Defines obj, preserves var_size_in_bytes 1.169 +void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) { 1.170 + if (UseTLAB) { 1.171 + tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case); 1.172 + } else { 1.173 + eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case); 1.174 + } 1.175 +} 1.176 + 1.177 +void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1 , Register t2) { 1.178 + assert_different_registers(obj, klass, len, AT); 1.179 + 1.180 + if (UseBiasedLocking && !len->is_valid()) { 1.181 + assert_different_registers(obj, klass, len, t1, t2); 1.182 + ld_ptr(t1, klass, in_bytes(Klass::prototype_header_offset())); 1.183 + st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); 1.184 + } else { 1.185 + li(AT, (intptr_t)markOopDesc::prototype()); 1.186 + st_ptr(AT, obj, oopDesc::mark_offset_in_bytes()); 1.187 + } 1.188 + //st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); 1.189 +#ifdef _LP64 1.190 + if (UseCompressedOops) { 1.191 + move(AT, klass); 1.192 + store_klass(obj, AT); 1.193 + } else 1.194 +#endif 1.195 + { 1.196 + st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); 1.197 + } 1.198 + 1.199 + if (len->is_valid()) { 1.200 + sw(len, obj, arrayOopDesc::length_offset_in_bytes()); 1.201 + } 1.202 +#ifdef _LP64 1.203 + else if (UseCompressedOops) { 1.204 + store_klass_gap(obj, R0); 1.205 + } 1.206 + 1.207 +#endif 1.208 +} 1.209 + 1.210 +// preserves obj, destroys len_in_bytes 1.211 +void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) { 1.212 + Label done; 1.213 + Register ptr = t1; 1.214 + assert_different_registers(obj, ptr, len_in_bytes); 1.215 + assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, 1.216 + "header size is not a multiple of BytesPerWord"); 1.217 + Register index = len_in_bytes; 1.218 + 1.219 +//tty->print_cr("C1_MacroAssembler::initialize_body LEN=0x%x, hdr_size=0x%x", len_in_bytes, hdr_size_in_bytes); 1.220 + assert(is_simm16(hdr_size_in_bytes), "change this code"); 1.221 + addi(index, index, - hdr_size_in_bytes); 1.222 + beq(index, R0, done); 1.223 + delayed(); 1.224 + 1.225 + // initialize topmost word, divide index by 2, check if odd and test if zero 1.226 + // note: for the remaining code to work, index must be a multiple of BytesPerWord 1.227 +#ifdef ASSERT 1.228 + { 1.229 + Label L; 1.230 + andi(AT, index, BytesPerWord - 1); 1.231 + beq(AT, R0, L); 1.232 + delayed()->nop(); 1.233 + stop("index is not a multiple of BytesPerWord"); 1.234 + bind(L); 1.235 + } 1.236 +#endif 1.237 + // index could have been not a multiple of 8 (i.e., bit 2 was set) 1.238 + { 1.239 + Label even; 1.240 + // note: if index was a multiple of 8, than it cannot 1.241 + // be 0 now otherwise it must have been 0 before 1.242 + // => if it is even, we don't need to check for 0 again 1.243 +#ifdef _LP64 1.244 + andi(AT, index, 8); 1.245 + shr(index, 4); 1.246 + shl(index, 4); 1.247 +#else 1.248 + andi(AT, index, 4); 1.249 + shr(index, 3); 1.250 + shl(index, 3); 1.251 +#endif 1.252 + beq(AT, R0, even); 1.253 + delayed()->add(ptr, obj, index); 1.254 + // clear topmost word (no jump needed if conditional assignment would work here) 1.255 + st_ptr(R0, ptr, hdr_size_in_bytes); 1.256 + // index could be 0 now, need to check again 1.257 + beq(index, R0, done); 1.258 + delayed()->nop(); 1.259 + bind(even); 1.260 + } 1.261 + // initialize remaining object fields: edx is a multiple of 2 now 1.262 + { 1.263 + Label loop; 1.264 + bind(loop); 1.265 + st_ptr(R0, ptr, hdr_size_in_bytes - 1*BytesPerWord); 1.266 + st_ptr(R0, ptr, hdr_size_in_bytes - 2*BytesPerWord); 1.267 + 1.268 + addi(index, index, - 2 * wordSize); 1.269 + bne(index, R0, loop); 1.270 + delayed()->addi(ptr, ptr, - 2 * wordSize); 1.271 + } 1.272 + 1.273 + // done 1.274 + bind(done); 1.275 +} 1.276 + 1.277 +void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) { 1.278 + //assert(obj == rax, "obj must be in rax, for cmpxchg"); 1.279 + assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really? 1.280 + assert(header_size >= 0 && object_size >= header_size, "illegal sizes"); 1.281 + 1.282 + try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case); 1.283 + 1.284 + initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2); 1.285 +} 1.286 + 1.287 +void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) { 1.288 + assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, 1.289 + "con_size_in_bytes is not multiple of alignment"); 1.290 + //Merged from b25 1.291 + const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 1.292 + 1.293 + // initialize_header(obj, klass, NOREG); 1.294 + initialize_header(obj, klass, NOREG,t1,t2); 1.295 + 1.296 + // clear rest of allocated space 1.297 + const Register index = t2; 1.298 + //FIXME, x86 changed the value in jdk6 1.299 + // const int threshold = hdr_size_in_bytes + 36; 1.300 + // // approximate break even point for code size (see comments below) 1.301 + const int threshold = 6 * BytesPerWord; 1.302 + // approximate break even point for code size (see comments below) 1.303 + if (var_size_in_bytes != NOREG) { 1.304 + move(index, var_size_in_bytes); 1.305 + initialize_body(obj, index, hdr_size_in_bytes, t1); 1.306 + } else if (con_size_in_bytes <= threshold) { 1.307 + // use explicit null stores 1.308 + // code size = 4*n bytes (n = number of fields to clear) 1.309 + 1.310 + for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) { 1.311 + st_ptr(R0, obj, i); 1.312 + } 1.313 + 1.314 + 1.315 + 1.316 + } else if(con_size_in_bytes > hdr_size_in_bytes) { 1.317 + // use loop to null out the fields 1.318 + // code size = 32 bytes for even n (n = number of fields to clear) 1.319 + // initialize last object field first if odd number of fields 1.320 + assert( ((con_size_in_bytes - hdr_size_in_bytes) >> 3)!=0, "change code here"); 1.321 + 1.322 +#ifdef _LP64 1.323 + move(index, (con_size_in_bytes - hdr_size_in_bytes) >> 4); 1.324 + sll(t1, index, 4); 1.325 +#else 1.326 + move(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); 1.327 + sll(t1, index, 3); 1.328 +#endif 1.329 + add(t1, obj, t1); 1.330 + 1.331 + // initialize last object field if constant size is odd 1.332 +#ifdef _LP64 1.333 + if (! UseCompressedOops) 1.334 + { 1.335 + if (((con_size_in_bytes - hdr_size_in_bytes) & 8) != 0) { 1.336 + sd(R0, t1, hdr_size_in_bytes); 1.337 + } 1.338 + } else if (UseCompressedOops) { 1.339 + int extra = (con_size_in_bytes - hdr_size_in_bytes) % 16; 1.340 + while (extra != 0) { 1.341 + sw(R0, t1, hdr_size_in_bytes + extra - 4); 1.342 + extra -= 4; 1.343 + } 1.344 + } 1.345 +#else 1.346 + if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) { 1.347 + sw(R0, t1, hdr_size_in_bytes); 1.348 + } 1.349 +#endif 1.350 + // initialize remaining object fields: edx is a multiple of 2 1.351 + { 1.352 + Label loop; 1.353 + bind(loop); 1.354 + st_ptr(R0, t1, hdr_size_in_bytes - (1*BytesPerWord)); 1.355 + st_ptr(R0, t1, hdr_size_in_bytes - (2*BytesPerWord)); 1.356 + addi(index, index, -1); 1.357 + bne(index, R0, loop); 1.358 + delayed()->addi(t1, t1, - 2 * wordSize); 1.359 + } 1.360 + } 1.361 + 1.362 + if (DTraceAllocProbes) { 1.363 + //assert(obj == eax, "must be"); 1.364 + call(CAST_FROM_FN_PTR(address, 1.365 + Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), relocInfo::runtime_call_type); 1.366 + delayed()->nop(); 1.367 + } 1.368 + verify_oop(obj); 1.369 +} 1.370 + 1.371 +void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, Register t3,int header_size, 1.372 + int scale, Register klass, Label& slow_case) { 1.373 + assert(obj == V0, "obj must be in V0 for cmpxchg"); 1.374 + assert_different_registers(obj, len, t1, t2, t3,klass, AT); 1.375 + 1.376 + // determine alignment mask 1.377 + assert(BytesPerWord == 8, "must be a multiple of 2 for masking code to work"); 1.378 + 1.379 + // check for negative or excessive length 1.380 + //const int max_length = 0x00FFFFFF; 1.381 + // move(AT, max_length); 1.382 + move(AT, max_array_allocation_length); 1.383 + sltu(AT, AT, len); 1.384 + bne_far(AT, R0, slow_case); 1.385 + delayed()->nop(); 1.386 + 1.387 + const Register arr_size = t3; 1.388 + // align object end 1.389 + move(arr_size, header_size * BytesPerWord + MinObjAlignmentInBytesMask); 1.390 + sll(AT, len, scale); 1.391 + add(arr_size, arr_size, AT); 1.392 + move(AT, ~MinObjAlignmentInBytesMask); 1.393 + andr(arr_size, arr_size, AT); 1.394 + 1.395 + try_allocate(obj, arr_size, 0, t1, t2, slow_case); 1.396 + 1.397 + initialize_header(obj, klass, len,t1,t2); 1.398 + 1.399 + // clear rest of allocated space 1.400 + const Register len_zero = len; 1.401 + initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero); 1.402 + if (DTraceAllocProbes) { 1.403 + // assert(obj == eax, "must be"); 1.404 + call(CAST_FROM_FN_PTR(address, 1.405 + Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), 1.406 + relocInfo::runtime_call_type); 1.407 + delayed()->nop(); 1.408 + } 1.409 + 1.410 + verify_oop(obj); 1.411 +} 1.412 + 1.413 + 1.414 +void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { 1.415 + verify_oop(receiver); 1.416 + // explicit NULL check not needed since load from [klass_offset] causes a trap 1.417 + // check against inline cache 1.418 + assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); 1.419 + ///cmpl(iCache, Address(receiver, oopDesc::klass_offset_in_bytes())); 1.420 + // if icache check fails, then jump to runtime routine 1.421 + // Note: RECEIVER must still contain the receiver! 1.422 + Label L; 1.423 +#ifdef _LP64 1.424 + //ld_ptr(AT, receiver, oopDesc::klass_offset_in_bytes()); 1.425 + //add for compressedoops 1.426 + load_klass(AT, receiver); 1.427 +#else 1.428 + lw(AT, receiver, oopDesc::klass_offset_in_bytes()); 1.429 +#endif 1.430 + beq(AT, iCache, L); 1.431 + delayed()->nop(); 1.432 + // jmp(Runtime1::entry_for(Runtime1::handle_ic_miss_id), relocInfo::runtime_call_type); 1.433 + jmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); 1.434 + delayed()->nop(); 1.435 + bind(L); 1.436 + // assert(UseCompressedOops, "check alignment in emit_method_entry"); 1.437 +} 1.438 +/* 1.439 +void C1_MacroAssembler::method_exit(bool restore_frame) { 1.440 + if (restore_frame) { 1.441 + leave(); 1.442 + } 1.443 + jr(RA); 1.444 + delayed()->nop(); 1.445 +}*/ 1.446 + 1.447 + 1.448 +void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) { 1.449 + // Make sure there is enough stack space for this method's activation. 1.450 + // Note that we do this before doing an enter(). This matches the 1.451 + // ordering of C2's stack overflow check / esp decrement and allows 1.452 + // the SharedRuntime stack overflow handling to be consistent 1.453 + // between the two compilers. 1.454 + generate_stack_overflow_check(frame_size_in_bytes); 1.455 + 1.456 + enter(); 1.457 +//FIXME 1.458 +#ifdef TIERED 1.459 + // c2 leaves fpu stack dirty. Clean it on entry 1.460 + // if (UseSSE < 2 ) { 1.461 + empty_FPU_stack(); 1.462 + // } 1.463 +#endif // TIERED 1.464 + 1.465 + decrement(SP, frame_size_in_bytes); // does not emit code for frame_size == 0 1.466 +} 1.467 + 1.468 +void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) { 1.469 + if (C1Breakpoint) int3(); 1.470 + inline_cache_check(receiver, ic_klass); 1.471 +} 1.472 + 1.473 + 1.474 +void C1_MacroAssembler::verified_entry() { 1.475 + if (C1Breakpoint)int3(); 1.476 + // build frame 1.477 + verify_FPU(0, "method_entry"); 1.478 +} 1.479 + 1.480 + 1.481 +#ifndef PRODUCT 1.482 +void C1_MacroAssembler::verify_stack_oop(int stack_offset) { 1.483 + if (!VerifyOops) return; 1.484 + // verify_oop_addr(Address(esp, stack_offset)); 1.485 + verify_oop_addr(Address(SP, stack_offset)); 1.486 +} 1.487 + 1.488 +void C1_MacroAssembler::verify_not_null_oop(Register r) { 1.489 + if (!VerifyOops) return; 1.490 + Label not_null; 1.491 + // testl(r, r); 1.492 + //jcc(Assembler::notZero, not_null); 1.493 + bne(r,R0,not_null); 1.494 + delayed()->nop(); 1.495 + stop("non-null oop required"); 1.496 + bind(not_null); 1.497 + verify_oop(r); 1.498 +} 1.499 + 1.500 +void C1_MacroAssembler::invalidate_registers(bool inv_v0, bool inv_v1, bool inv_t3, bool inv_t7, bool inv_s0, bool inv_s7) { 1.501 +#ifdef ASSERT 1.502 + /* if (inv_eax) movl(eax, 0xDEAD); 1.503 + if (inv_ebx) movl(ebx, 0xDEAD); 1.504 + if (inv_ecx) movl(ecx, 0xDEAD); 1.505 + if (inv_edx) movl(edx, 0xDEAD); 1.506 + if (inv_esi) movl(esi, 0xDEAD); 1.507 + if (inv_edi) movl(edi, 0xDEAD); 1.508 + */ 1.509 + //if (inv_v0) move(V0, 0xDEAD); 1.510 + //if (inv_v1) move(V1, 0xDEAD); 1.511 + //if (inv_t3) move(T3, 0xDEAD); 1.512 + //if (inv_t7) move(T7, 0xDEAD); 1.513 + //if (inv_s0) move(S0, 0xDEAD); 1.514 + //if (inv_s7) move(S7, 0xDEAD); 1.515 +#endif 1.516 +} 1.517 +#endif // ifndef PRODUCT 1.518 + 1.519 +