src/cpu/mips/vm/macroAssembler_mips.hpp

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

author
aoqi
date
Thu, 24 May 2018 19:49:50 +0800
changeset 8865
ffcdff41a92f
parent 8862
fd13a567f179
child 9043
7519f4bf92b5
permissions
-rw-r--r--

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

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@6880 26 #ifndef CPU_MIPS_VM_MACROASSEMBLER_MIPS_HPP
aoqi@6880 27 #define CPU_MIPS_VM_MACROASSEMBLER_MIPS_HPP
aoqi@1 28
aoqi@6880 29 #include "asm/assembler.hpp"
aoqi@6880 30 #include "utilities/macros.hpp"
aoqi@6880 31 #include "runtime/rtmLocking.hpp"
aoqi@1 32
aoqi@6880 33
aoqi@6880 34 // MacroAssembler extends Assembler by frequently used macros.
aoqi@6880 35 //
aoqi@6880 36 // Instructions for which a 'better' code sequence exists depending
aoqi@6880 37 // on arguments should also go in here.
aoqi@6880 38
aoqi@6880 39 class MacroAssembler: public Assembler {
aoqi@6880 40 friend class LIR_Assembler;
aoqi@6880 41 friend class Runtime1; // as_Address()
aoqi@6880 42
aoqi@6880 43 protected:
aoqi@6880 44
aoqi@6880 45 Address as_Address(AddressLiteral adr);
aoqi@6880 46 Address as_Address(ArrayAddress adr);
aoqi@6880 47
aoqi@6880 48 // Support for VM calls
aoqi@6880 49 //
aoqi@6880 50 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
aoqi@6880 51 // may customize this version by overriding it for its purposes (e.g., to save/restore
aoqi@6880 52 // additional registers when doing a VM call).
aoqi@6880 53 #ifdef CC_INTERP
aoqi@6880 54 // c++ interpreter never wants to use interp_masm version of call_VM
aoqi@6880 55 #define VIRTUAL
aoqi@6880 56 #else
aoqi@6880 57 #define VIRTUAL virtual
aoqi@6880 58 #endif
aoqi@6880 59
aoqi@6880 60 VIRTUAL void call_VM_leaf_base(
aoqi@6880 61 address entry_point, // the entry point
aoqi@6880 62 int number_of_arguments // the number of arguments to pop after the call
aoqi@6880 63 );
aoqi@6880 64
aoqi@6880 65 // This is the base routine called by the different versions of call_VM. The interpreter
aoqi@6880 66 // may customize this version by overriding it for its purposes (e.g., to save/restore
aoqi@6880 67 // additional registers when doing a VM call).
aoqi@6880 68 //
aoqi@6880 69 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base
aoqi@6880 70 // returns the register which contains the thread upon return. If a thread register has been
aoqi@6880 71 // specified, the return value will correspond to that register. If no last_java_sp is specified
aoqi@6880 72 // (noreg) than rsp will be used instead.
aoqi@6880 73 VIRTUAL void call_VM_base( // returns the register containing the thread upon return
aoqi@6880 74 Register oop_result, // where an oop-result ends up if any; use noreg otherwise
aoqi@6880 75 Register java_thread, // the thread if computed before ; use noreg otherwise
aoqi@6880 76 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise
aoqi@6880 77 address entry_point, // the entry point
aoqi@6880 78 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call
aoqi@6880 79 bool check_exceptions // whether to check for pending exceptions after return
aoqi@6880 80 );
aoqi@6880 81
aoqi@6880 82 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
aoqi@6880 83 // The implementation is only non-empty for the InterpreterMacroAssembler,
aoqi@6880 84 // as only the interpreter handles PopFrame and ForceEarlyReturn requests.
aoqi@6880 85 virtual void check_and_handle_popframe(Register java_thread);
aoqi@6880 86 virtual void check_and_handle_earlyret(Register java_thread);
aoqi@6880 87
aoqi@6880 88 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
aoqi@6880 89
aoqi@6880 90 // helpers for FPU flag access
aoqi@6880 91 // tmp is a temporary register, if none is available use noreg
aoqi@6880 92
aoqi@6880 93 public:
aoqi@6880 94 static intptr_t i[32];
aoqi@6880 95 static float f[32];
aoqi@6880 96 static void print(outputStream *s);
aoqi@6880 97
aoqi@6880 98 static int i_offset(unsigned int k);
aoqi@6880 99 static int f_offset(unsigned int k);
aoqi@6880 100
aoqi@6880 101 static void save_registers(MacroAssembler *masm);
aoqi@6880 102 static void restore_registers(MacroAssembler *masm);
aoqi@6880 103
aoqi@6880 104 MacroAssembler(CodeBuffer* code) : Assembler(code) {}
aoqi@6880 105
aoqi@6880 106 // Support for NULL-checks
aoqi@6880 107 //
aoqi@6880 108 // Generates code that causes a NULL OS exception if the content of reg is NULL.
aoqi@6880 109 // If the accessed location is M[reg + offset] and the offset is known, provide the
aoqi@6880 110 // offset. No explicit code generation is needed if the offset is within a certain
aoqi@6880 111 // range (0 <= offset <= page_size).
aoqi@6880 112
aoqi@6880 113 void null_check(Register reg, int offset = -1);
aoqi@6880 114 static bool needs_explicit_null_check(intptr_t offset);
aoqi@6880 115
aoqi@6880 116 // Required platform-specific helpers for Label::patch_instructions.
aoqi@6880 117 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
aoqi@6880 118 void pd_patch_instruction(address branch, address target);
aoqi@6880 119
aoqi@6880 120 // Support for inc/dec with optimal instruction selection depending on value
aoqi@6880 121 void incrementl(Register reg, int value = 1);
aoqi@6880 122 void decrementl(Register reg, int value = 1);
aoqi@6880 123
aoqi@6880 124
aoqi@6880 125 // Alignment
aoqi@6880 126 void align(int modulus);
aoqi@6880 127
aoqi@6880 128
aoqi@6880 129 // Stack frame creation/removal
aoqi@6880 130 void enter();
aoqi@6880 131 void leave();
aoqi@6880 132
aoqi@6880 133 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
aoqi@6880 134 // The pointer will be loaded into the thread register.
aoqi@6880 135 void get_thread(Register thread);
aoqi@6880 136
aoqi@6880 137
aoqi@6880 138 // Support for VM calls
aoqi@6880 139 //
aoqi@6880 140 // It is imperative that all calls into the VM are handled via the call_VM macros.
aoqi@6880 141 // They make sure that the stack linkage is setup correctly. call_VM's correspond
aoqi@6880 142 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
aoqi@6880 143
aoqi@6880 144
aoqi@6880 145 void call_VM(Register oop_result,
aoqi@6880 146 address entry_point,
aoqi@6880 147 bool check_exceptions = true);
aoqi@6880 148 void call_VM(Register oop_result,
aoqi@6880 149 address entry_point,
aoqi@6880 150 Register arg_1,
aoqi@6880 151 bool check_exceptions = true);
aoqi@6880 152 void call_VM(Register oop_result,
aoqi@6880 153 address entry_point,
aoqi@6880 154 Register arg_1, Register arg_2,
aoqi@6880 155 bool check_exceptions = true);
aoqi@6880 156 void call_VM(Register oop_result,
aoqi@6880 157 address entry_point,
aoqi@6880 158 Register arg_1, Register arg_2, Register arg_3,
aoqi@6880 159 bool check_exceptions = true);
aoqi@6880 160
aoqi@6880 161 // Overloadings with last_Java_sp
aoqi@6880 162 void call_VM(Register oop_result,
aoqi@6880 163 Register last_java_sp,
aoqi@6880 164 address entry_point,
aoqi@6880 165 int number_of_arguments = 0,
aoqi@6880 166 bool check_exceptions = true);
aoqi@6880 167 void call_VM(Register oop_result,
aoqi@6880 168 Register last_java_sp,
aoqi@6880 169 address entry_point,
aoqi@6880 170 Register arg_1, bool
aoqi@6880 171 check_exceptions = true);
aoqi@6880 172 void call_VM(Register oop_result,
aoqi@6880 173 Register last_java_sp,
aoqi@6880 174 address entry_point,
aoqi@6880 175 Register arg_1, Register arg_2,
aoqi@6880 176 bool check_exceptions = true);
aoqi@6880 177 void call_VM(Register oop_result,
aoqi@6880 178 Register last_java_sp,
aoqi@6880 179 address entry_point,
aoqi@6880 180 Register arg_1, Register arg_2, Register arg_3,
aoqi@6880 181 bool check_exceptions = true);
aoqi@6880 182
aoqi@6880 183 void get_vm_result (Register oop_result, Register thread);
aoqi@6880 184 void get_vm_result_2(Register metadata_result, Register thread);
aoqi@6880 185 void call_VM_leaf(address entry_point,
aoqi@6880 186 int number_of_arguments = 0);
aoqi@6880 187 void call_VM_leaf(address entry_point,
aoqi@6880 188 Register arg_1);
aoqi@6880 189 void call_VM_leaf(address entry_point,
aoqi@6880 190 Register arg_1, Register arg_2);
aoqi@6880 191 void call_VM_leaf(address entry_point,
aoqi@6880 192 Register arg_1, Register arg_2, Register arg_3);
aoqi@6880 193
aoqi@6880 194 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
aoqi@6880 195 void super_call_VM_leaf(address entry_point);
aoqi@6880 196 void super_call_VM_leaf(address entry_point, Register arg_1);
aoqi@6880 197 void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2);
aoqi@6880 198 void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3);
aoqi@6880 199 // last Java Frame (fills frame anchor)
aoqi@6880 200 void set_last_Java_frame(Register thread,
aoqi@6880 201 Register last_java_sp,
aoqi@6880 202 Register last_java_fp,
aoqi@6880 203 address last_java_pc);
aoqi@6880 204
aoqi@6880 205 // thread in the default location (r15_thread on 64bit)
aoqi@6880 206 void set_last_Java_frame(Register last_java_sp,
aoqi@6880 207 Register last_java_fp,
aoqi@6880 208 address last_java_pc);
aoqi@6880 209
aoqi@6880 210 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
aoqi@6880 211
aoqi@6880 212 // thread in the default location (r15_thread on 64bit)
aoqi@6880 213 void reset_last_Java_frame(bool clear_fp, bool clear_pc);
aoqi@6880 214
aoqi@6880 215 // Stores
aoqi@6880 216 void store_check(Register obj); // store check for obj - register is destroyed afterwards
aoqi@6880 217 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
aoqi@6880 218
aoqi@6880 219 #if INCLUDE_ALL_GCS
aoqi@6880 220
aoqi@6880 221 void g1_write_barrier_pre(Register obj,
fujie@8000 222 Register pre_val,
aoqi@6880 223 Register thread,
aoqi@6880 224 Register tmp,
fujie@8000 225 bool tosca_live,
fujie@8000 226 bool expand_call);
aoqi@6880 227
aoqi@6880 228 void g1_write_barrier_post(Register store_addr,
aoqi@6880 229 Register new_val,
aoqi@6880 230 Register thread,
aoqi@6880 231 Register tmp,
aoqi@6880 232 Register tmp2);
aoqi@6880 233
aoqi@6880 234 #endif // INCLUDE_ALL_GCS
aoqi@6880 235
aoqi@6880 236 // split store_check(Register obj) to enhance instruction interleaving
aoqi@6880 237 void store_check_part_1(Register obj);
aoqi@6880 238 void store_check_part_2(Register obj);
aoqi@6880 239
aoqi@6880 240 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
aoqi@6880 241 void c2bool(Register x);
aoqi@6880 242 //add for compressedoops
aoqi@6880 243 void load_klass(Register dst, Register src);
aoqi@6880 244 void store_klass(Register dst, Register src);
aoqi@6880 245 void load_prototype_header(Register dst, Register src);
aoqi@6880 246
aoqi@6880 247 #ifdef _LP64
aoqi@6880 248 void store_klass_gap(Register dst, Register src);
aoqi@6880 249
aoqi@6880 250 void load_heap_oop(Register dst, Address src);
aoqi@6880 251 void store_heap_oop(Address dst, Register src);
fujie@8001 252 void store_heap_oop_null(Address dst);
aoqi@6880 253 void encode_heap_oop(Register r);
aoqi@6880 254 void encode_heap_oop(Register dst, Register src);
aoqi@6880 255 void decode_heap_oop(Register r);
aoqi@6880 256 void decode_heap_oop(Register dst, Register src);
aoqi@6880 257 void encode_heap_oop_not_null(Register r);
aoqi@6880 258 void decode_heap_oop_not_null(Register r);
aoqi@6880 259 void encode_heap_oop_not_null(Register dst, Register src);
aoqi@6880 260 void decode_heap_oop_not_null(Register dst, Register src);
aoqi@6880 261
aoqi@6880 262 void encode_klass_not_null(Register r);
aoqi@6880 263 void decode_klass_not_null(Register r);
aoqi@6880 264 void encode_klass_not_null(Register dst, Register src);
aoqi@6880 265 void decode_klass_not_null(Register dst, Register src);
aoqi@6880 266
aoqi@6880 267 // Returns the byte size of the instructions generated by decode_klass_not_null()
aoqi@6880 268 // when compressed klass pointers are being used.
aoqi@6880 269 static int instr_size_for_decode_klass_not_null();
aoqi@6880 270
aoqi@6880 271 // if heap base register is used - reinit it with the correct value
aoqi@6880 272 void reinit_heapbase();
aoqi@6880 273
aoqi@6880 274 DEBUG_ONLY(void verify_heapbase(const char* msg);)
aoqi@6880 275
aoqi@6880 276 void set_narrow_klass(Register dst, Klass* k);
aoqi@6880 277 void set_narrow_oop(Register dst, jobject obj);
aoqi@6880 278
aoqi@6880 279 #endif // _LP64
aoqi@6880 280
aoqi@6880 281
aoqi@6880 282
aoqi@6880 283 void int3();
aoqi@6880 284 // Sign extension
aoqi@6880 285 #ifdef _LP64
aoqi@6880 286 void sign_extend_short(Register reg) { /*dsll32(reg, reg, 16); dsra32(reg, reg, 16);*/ seh(reg, reg); }
aoqi@6880 287 void sign_extend_byte(Register reg) { /*dsll32(reg, reg, 24); dsra32(reg, reg, 24);*/ seb(reg, reg); }
aoqi@6880 288 #else
aoqi@6880 289 void sign_extend_short(Register reg) { /*sll(reg, reg, 16); sra(reg, reg, 16);*/ seh(reg, reg); }
aoqi@6880 290 void sign_extend_byte(Register reg) { /*sll(reg, reg, 24); sra(reg, reg, 24);*/ seb(reg, reg);}
aoqi@6880 291 #endif
aoqi@6880 292 void rem_s(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
aoqi@6880 293 void rem_d(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
aoqi@6880 294
aoqi@6880 295 // Inlined sin/cos generator for Java; must not use CPU instruction
aoqi@6880 296 // directly on Intel as it does not have high enough precision
aoqi@6880 297 // outside of the range [-pi/4, pi/4]. Extra argument indicate the
aoqi@6880 298 // number of FPU stack slots in use; all but the topmost will
aoqi@6880 299 // require saving if a slow case is necessary. Assumes argument is
aoqi@6880 300 // on FP TOS; result is on FP TOS. No cpu registers are changed by
aoqi@6880 301 // this code.
aoqi@6880 302 void trigfunc(char trig, int num_fpu_regs_in_use = 1);
aoqi@6880 303 // allocation
aoqi@6880 304 void eden_allocate(
aoqi@6880 305 Register obj, // result: pointer to object after successful allocation
aoqi@6880 306 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
aoqi@6880 307 int con_size_in_bytes, // object size in bytes if known at compile time
aoqi@6880 308 Register t1, // temp register
aoqi@6880 309 Register t2,
aoqi@6880 310 Label& slow_case // continuation point if fast allocation fails
aoqi@6880 311 );
aoqi@6880 312 void tlab_allocate(
aoqi@6880 313 Register obj, // result: pointer to object after successful allocation
aoqi@6880 314 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
aoqi@6880 315 int con_size_in_bytes, // object size in bytes if known at compile time
aoqi@6880 316 Register t1, // temp register
aoqi@6880 317 Register t2, // temp register
aoqi@6880 318 Label& slow_case // continuation point if fast allocation fails
aoqi@6880 319 );
aoqi@6880 320 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
aoqi@6880 321 // interface method calling
aoqi@6880 322 void lookup_interface_method(Register recv_klass,
aoqi@6880 323 Register intf_klass,
aoqi@6880 324 RegisterOrConstant itable_index,
aoqi@6880 325 Register method_result,
aoqi@6880 326 Register scan_temp,
aoqi@6880 327 Label& no_such_interface);
aoqi@6880 328
aoqi@6880 329 // virtual method calling
aoqi@6880 330 void lookup_virtual_method(Register recv_klass,
aoqi@6880 331 RegisterOrConstant vtable_index,
aoqi@6880 332 Register method_result);
aoqi@6880 333
aoqi@6880 334 // Test sub_klass against super_klass, with fast and slow paths.
aoqi@6880 335
aoqi@6880 336 // The fast path produces a tri-state answer: yes / no / maybe-slow.
aoqi@6880 337 // One of the three labels can be NULL, meaning take the fall-through.
aoqi@6880 338 // If super_check_offset is -1, the value is loaded up from super_klass.
aoqi@6880 339 // No registers are killed, except temp_reg.
aoqi@6880 340 void check_klass_subtype_fast_path(Register sub_klass,
aoqi@6880 341 Register super_klass,
aoqi@6880 342 Register temp_reg,
aoqi@6880 343 Label* L_success,
aoqi@6880 344 Label* L_failure,
aoqi@6880 345 Label* L_slow_path,
aoqi@6880 346 RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
aoqi@6880 347
aoqi@6880 348 // The rest of the type check; must be wired to a corresponding fast path.
aoqi@6880 349 // It does not repeat the fast path logic, so don't use it standalone.
aoqi@6880 350 // The temp_reg and temp2_reg can be noreg, if no temps are available.
aoqi@6880 351 // Updates the sub's secondary super cache as necessary.
aoqi@6880 352 // If set_cond_codes, condition codes will be Z on success, NZ on failure.
aoqi@6880 353 void check_klass_subtype_slow_path(Register sub_klass,
aoqi@6880 354 Register super_klass,
aoqi@6880 355 Register temp_reg,
aoqi@6880 356 Register temp2_reg,
aoqi@6880 357 Label* L_success,
aoqi@6880 358 Label* L_failure,
aoqi@6880 359 bool set_cond_codes = false);
aoqi@6880 360
aoqi@6880 361 // Simplified, combined version, good for typical uses.
aoqi@6880 362 // Falls through on failure.
aoqi@6880 363 void check_klass_subtype(Register sub_klass,
aoqi@6880 364 Register super_klass,
aoqi@6880 365 Register temp_reg,
aoqi@6880 366 Label& L_success);
aoqi@6880 367
aoqi@6880 368
aoqi@6880 369 // Debugging
aoqi@6880 370
aoqi@6880 371 // only if +VerifyOops
aoqi@6880 372 void verify_oop(Register reg, const char* s = "broken oop");
aoqi@6880 373 void verify_oop_addr(Address addr, const char * s = "broken oop addr");
aoqi@6880 374 void verify_oop_subroutine();
aoqi@6880 375 // TODO: verify method and klass metadata (compare against vptr?)
aoqi@6880 376 void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {}
aoqi@6880 377 void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line){}
aoqi@6880 378
aoqi@6880 379 #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
aoqi@6880 380 #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
aoqi@6880 381
aoqi@6880 382 // only if +VerifyFPU
aoqi@6880 383 void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
aoqi@6880 384
aoqi@6880 385 // prints msg, dumps registers and stops execution
aoqi@6880 386 void stop(const char* msg);
aoqi@6880 387
aoqi@6880 388 // prints msg and continues
aoqi@6880 389 void warn(const char* msg);
aoqi@6880 390
aoqi@6880 391 static void debug(char* msg/*, RegistersForDebugging* regs*/);
aoqi@6880 392 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
aoqi@6880 393 static void debug64(char* msg, int64_t pc, int64_t regs[]);
aoqi@6880 394
aoqi@6880 395 void print_reg(Register reg);
aoqi@6880 396 void print_reg(FloatRegister reg);
aoqi@6880 397 //void os_breakpoint();
aoqi@6880 398
aoqi@6880 399 void untested() { stop("untested"); }
aoqi@6880 400
aoqi@6880 401 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); }
aoqi@6880 402
aoqi@6880 403 void should_not_reach_here() { stop("should not reach here"); }
aoqi@6880 404
aoqi@6880 405 void print_CPU_state();
aoqi@6880 406
aoqi@6880 407 // Stack overflow checking
aoqi@6880 408 void bang_stack_with_offset(int offset) {
aoqi@6880 409 // stack grows down, caller passes positive offset
aoqi@6880 410 assert(offset > 0, "must bang with negative offset");
aoqi@6880 411 if (offset <= 32768) {
aoqi@6880 412 sw(A0, SP, -offset);
aoqi@6880 413 } else {
aoqi@6880 414 #ifdef _LP64
aoqi@6880 415 li(AT, offset);
aoqi@6880 416 dsub(AT, SP, AT);
aoqi@6880 417 #else
aoqi@6880 418 move(AT, offset);
aoqi@6880 419 sub(AT, SP, AT);
aoqi@6880 420 #endif
aoqi@6880 421 sw(A0, AT, 0);
aoqi@6880 422 }
aoqi@6880 423 }
aoqi@6880 424
aoqi@6880 425 // Writes to stack successive pages until offset reached to check for
aoqi@6880 426 // stack overflow + shadow pages. Also, clobbers tmp
aoqi@6880 427 void bang_stack_size(Register size, Register tmp);
aoqi@6880 428
aoqi@6880 429 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
aoqi@6880 430 Register tmp,
aoqi@6880 431 int offset);
aoqi@6880 432
aoqi@6880 433 // Support for serializing memory accesses between threads
aoqi@6880 434 void serialize_memory(Register thread, Register tmp);
aoqi@6880 435
aoqi@6880 436 //void verify_tlab();
aoqi@6880 437 void verify_tlab(Register t1, Register t2);
aoqi@6880 438
aoqi@6880 439 // Biased locking support
aoqi@6880 440 // lock_reg and obj_reg must be loaded up with the appropriate values.
aoqi@6880 441 // swap_reg must be rax, and is killed.
aoqi@6880 442 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will
aoqi@6880 443 // be killed; if not supplied, push/pop will be used internally to
aoqi@6880 444 // allocate a temporary (inefficient, avoid if possible).
aoqi@6880 445 // Optional slow case is for implementations (interpreter and C1) which branch to
aoqi@6880 446 // slow case directly. Leaves condition codes set for C2's Fast_Lock node.
aoqi@6880 447 // Returns offset of first potentially-faulting instruction for null
aoqi@6880 448 // check info (currently consumed only by C1). If
aoqi@6880 449 // swap_reg_contains_mark is true then returns -1 as it is assumed
aoqi@6880 450 // the calling code has already passed any potential faults.
aoqi@6880 451 int biased_locking_enter(Register lock_reg, Register obj_reg,
aoqi@6880 452 Register swap_reg, Register tmp_reg,
aoqi@6880 453 bool swap_reg_contains_mark,
aoqi@6880 454 Label& done, Label* slow_case = NULL,
aoqi@6880 455 BiasedLockingCounters* counters = NULL);
aoqi@6880 456 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
aoqi@6880 457 #ifdef COMPILER2
aoqi@6880 458 void fast_lock(Register obj, Register box, Register tmp, Register scr);
aoqi@6880 459 void fast_unlock(Register obj, Register box, Register tmp);
aoqi@6880 460 #endif
aoqi@6880 461
aoqi@6880 462
aoqi@6880 463 // Arithmetics
aoqi@6880 464 // Regular vs. d* versions
aoqi@6880 465 inline void addu_long(Register rd, Register rs, Register rt) {
aoqi@6880 466 #ifdef _LP64
aoqi@6880 467 daddu(rd, rs, rt);
aoqi@6880 468 #else
aoqi@6880 469 addu(rd, rs, rt);
aoqi@6880 470 #endif
aoqi@6880 471 }
aoqi@6880 472 inline void addu_long(Register rd, Register rs, long imm32_64) {
aoqi@6880 473 #ifdef _LP64
aoqi@6880 474 daddiu(rd, rs, imm32_64);
aoqi@6880 475 #else
aoqi@6880 476 addiu(rd, rs, imm32_64);
aoqi@6880 477 #endif
aoqi@6880 478
aoqi@6880 479 }
aoqi@6880 480
aoqi@6880 481 void round_to(Register reg, int modulus) {
aoqi@6880 482 assert_different_registers(reg, AT);
aoqi@6880 483 increment(reg, modulus - 1);
aoqi@6880 484 move(AT, - modulus);
aoqi@6880 485 andr(reg, reg, AT);
aoqi@6880 486 }
aoqi@6880 487
aoqi@6880 488 // the follow two might use AT register, be sure you have no meanful data in AT before you call them
aoqi@6880 489 void increment(Register reg, int imm);
aoqi@6880 490 void decrement(Register reg, int imm);
aoqi@6880 491
aoqi@6880 492 #ifdef _LP64
aoqi@6880 493 void shl(Register reg, int sa) { dsll(reg, reg, sa); }
aoqi@6880 494 void shr(Register reg, int sa) { dsrl(reg, reg, sa); }
aoqi@6880 495 void sar(Register reg, int sa) { dsra(reg, reg, sa); }
aoqi@6880 496 #else
aoqi@6880 497 void shl(Register reg, int sa) { sll(reg, reg, sa); }
aoqi@6880 498 void shr(Register reg, int sa) { srl(reg, reg, sa); }
aoqi@6880 499 void sar(Register reg, int sa) { sra(reg, reg, sa); }
aoqi@6880 500 #endif
aoqi@6880 501 // Helper functions for statistics gathering.
aoqi@6880 502 void atomic_inc32(address counter_addr, int inc, Register tmp_reg1, Register tmp_reg2);
aoqi@6880 503
aoqi@6880 504 // Calls
aoqi@6880 505 void call(address entry);
aoqi@6880 506 void call(address entry, relocInfo::relocType rtype);
aoqi@6880 507 void call(address entry, RelocationHolder& rh);
aoqi@6880 508 // Emit the CompiledIC call idiom
aoqi@6880 509 void ic_call(address entry);
aoqi@6880 510
aoqi@6880 511 // Jumps
aoqi@6880 512 void jmp(address entry);
aoqi@6880 513 void jmp(address entry, relocInfo::relocType rtype);
aoqi@8862 514 void jmp_far(Label& L); // always long jumps
aoqi@6880 515
aoqi@6880 516 /* branches may exceed 16-bit offset */
aoqi@6880 517 void b_far(address entry);
aoqi@6880 518 void b_far(Label& L);
aoqi@6880 519
aoqi@6880 520 void bne_far (Register rs, Register rt, address entry);
aoqi@6880 521 void bne_far (Register rs, Register rt, Label& L);
aoqi@6880 522
aoqi@6880 523 void beq_far (Register rs, Register rt, address entry);
aoqi@6880 524 void beq_far (Register rs, Register rt, Label& L);
aoqi@6880 525
aoqi@8862 526 // For C2 to support long branches
aoqi@8862 527 void beq_long (Register rs, Register rt, Label& L);
aoqi@8862 528 void bne_long (Register rs, Register rt, Label& L);
aoqi@8862 529 void bc1t_long (Label& L);
aoqi@8862 530 void bc1f_long (Label& L);
aoqi@8862 531
aoqi@6880 532 void patchable_call(address target);
aoqi@6880 533 void general_call(address target);
aoqi@6880 534
aoqi@6880 535 void patchable_jump(address target);
aoqi@6880 536 void general_jump(address target);
aoqi@6880 537
aoqi@6880 538 static int insts_for_patchable_call(address target);
aoqi@6880 539 static int insts_for_general_call(address target);
aoqi@6880 540
aoqi@6880 541 static int insts_for_patchable_jump(address target);
aoqi@6880 542 static int insts_for_general_jump(address target);
aoqi@6880 543
aoqi@6880 544 // Floating
aoqi@6880 545 // Data
aoqi@6880 546
aoqi@6880 547 // Argument ops
aoqi@6880 548 inline void store_int_argument(Register s, Argument &a) {
aoqi@6880 549 if(a.is_Register()) {
aoqi@6880 550 move(a.as_Register(), s);
aoqi@6880 551 } else {
aoqi@6880 552 sw(s, a.as_caller_address());
aoqi@6880 553 }
aoqi@6880 554 }
aoqi@6880 555
aoqi@6880 556 inline void store_long_argument(Register s, Argument &a) {
aoqi@6880 557 Argument a1 = a.successor();
aoqi@6880 558 if(a.is_Register() && a1.is_Register()) {
aoqi@6880 559 move(a.as_Register(), s);
aoqi@6880 560 move(a.as_Register(), s);
aoqi@6880 561 } else {
aoqi@6880 562 sd(s, a.as_caller_address());
aoqi@6880 563 }
aoqi@6880 564 }
aoqi@6880 565
aoqi@6880 566 inline void store_float_argument(FloatRegister s, Argument &a) {
aoqi@6880 567 if(a.is_Register()) {
aoqi@6880 568 mov_s(a.as_FloatRegister(), s);
aoqi@6880 569 } else {
aoqi@6880 570 swc1(s, a.as_caller_address());
aoqi@6880 571 }
aoqi@6880 572 }
aoqi@6880 573 inline void store_double_argument(FloatRegister s, Argument &a) {
aoqi@6880 574 if(a.is_Register()) {
aoqi@6880 575 mov_d(a.as_FloatRegister(), s);
aoqi@6880 576 } else {
aoqi@6880 577 sdc1(s, a.as_caller_address());
aoqi@6880 578 }
aoqi@6880 579 }
aoqi@6880 580
aoqi@6880 581 inline void store_ptr_argument(Register s, Argument &a) {
aoqi@6880 582 if(a.is_Register()) {
aoqi@6880 583 move(a.as_Register(), s);
aoqi@6880 584 } else {
aoqi@6880 585 st_ptr(s, a.as_caller_address());
aoqi@6880 586 }
aoqi@6880 587 }
aoqi@6880 588
aoqi@6880 589 // Load and store values by size and signed-ness
aoqi@6880 590 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
aoqi@6880 591 void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
aoqi@6880 592
aoqi@6880 593 // ld_ptr will perform lw for 32 bit VMs and ld for 64 bit VMs
aoqi@6880 594 // st_ptr will perform sw for 32 bit VMs and sd for 64 bit VMs
aoqi@6880 595 inline void ld_ptr(Register rt, Address a){
aoqi@6880 596 #ifdef _LP64
aoqi@6880 597 ld(rt, a.base(), a.disp());
aoqi@6880 598 #else
aoqi@6880 599 lw(rt, a.base(), a.disp());
aoqi@6880 600 #endif
aoqi@6880 601 }
aoqi@6880 602 inline void ld_ptr(Register rt, Register base, int offset16){
aoqi@6880 603 #ifdef _LP64
aoqi@6880 604 ld(rt, base, offset16);
aoqi@6880 605 #else
aoqi@6880 606 lw(rt, base, offset16);
aoqi@6880 607 #endif
aoqi@6880 608
aoqi@6880 609 }
aoqi@6880 610 inline void st_ptr(Register rt, Address a){
aoqi@6880 611 #ifdef _LP64
aoqi@6880 612 sd(rt, a.base(), a.disp());
aoqi@6880 613 #else
aoqi@6880 614 sw(rt, a.base(), a.disp());
aoqi@6880 615 #endif
aoqi@6880 616 }
aoqi@6880 617 inline void st_ptr(Register rt, Register base, int offset16) {
aoqi@6880 618 #ifdef _LP64
aoqi@6880 619 sd(rt, base, offset16);
aoqi@6880 620 #else
aoqi@6880 621 sw(rt, base, offset16);
aoqi@6880 622 #endif
aoqi@6880 623 }
aoqi@6880 624
aoqi@6880 625 void ld_ptr(Register rt, Register offset, Register base);
aoqi@6880 626 void st_ptr(Register rt, Register offset, Register base);
aoqi@6880 627
aoqi@6880 628 // ld_long will perform lw for 32 bit VMs and ld for 64 bit VMs
aoqi@6880 629 // st_long will perform sw for 32 bit VMs and sd for 64 bit VMs
aoqi@6880 630 inline void ld_long(Register rt, Register base, int offset16);
aoqi@6880 631 inline void st_long(Register rt, Register base, int offset16);
aoqi@6880 632 inline void ld_long(Register rt, Address a);
aoqi@6880 633 inline void st_long(Register rt, Address a);
aoqi@6880 634 void ld_long(Register rt, Register offset, Register base);
aoqi@6880 635 void st_long(Register rt, Register offset, Register base);
aoqi@6880 636
aoqi@6880 637 // swap the two byte of the low 16-bit halfword
aoqi@6880 638 // this directive will use AT, be sure the high 16-bit of reg is zero
aoqi@6880 639 void hswap(Register reg);
aoqi@6880 640 void huswap(Register reg);
aoqi@6880 641
aoqi@6880 642 // convert big endian integer to little endian integer
aoqi@6880 643 void swap(Register reg);
aoqi@6880 644
aoqi@6880 645 // implement the x86 instruction semantic
aoqi@6880 646 // if c_reg == *dest then *dest <= x_reg
aoqi@6880 647 // else c_reg <= *dest
aoqi@6880 648 // the AT indicate if xchg occurred, 1 for xchged, else 0
aoqi@6880 649 void cmpxchg(Register x_reg, Address dest, Register c_reg);
aoqi@6880 650 #ifdef _LP64
aoqi@6880 651 void cmpxchg32(Register x_reg, Address dest, Register c_reg);
aoqi@6880 652 #endif
aoqi@6880 653 void cmpxchg8(Register x_regLo, Register x_regHi, Address dest, Register c_regLo, Register c_regHi);
aoqi@6880 654
aoqi@6880 655 //pop & push, added by aoqi
aoqi@6880 656 #ifdef _LP64
aoqi@6880 657 void extend_sign(Register rh, Register rl) { stop("extend_sign"); }
aoqi@6880 658 void neg(Register reg) { dsubu(reg, R0, reg); }
aoqi@6880 659 void push (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
aoqi@6880 660 void push (FloatRegister reg) { sdc1(reg, SP, -8); daddi(SP, SP, -8); }
aoqi@6880 661 void pop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
aoqi@6880 662 void pop (FloatRegister reg) { ldc1(reg, SP, 0); daddi(SP, SP, 8); }
aoqi@6880 663 void pop () { daddi(SP, SP, 8); }
aoqi@6880 664 void pop2 () { daddi(SP, SP, 16); }
aoqi@6880 665 #else
aoqi@6880 666 void extend_sign(Register rh, Register rl) { sra(rh, rl, 31); }
aoqi@6880 667 void neg(Register reg) { subu(reg, R0, reg); }
aoqi@6880 668 void push (Register reg) { sw (reg, SP, -4); addi(SP, SP, -4); }
aoqi@6880 669 void push (FloatRegister reg) { swc1(reg, SP, -4); addi(SP, SP, -4); }
aoqi@6880 670 void pop (Register reg) { lw (reg, SP, 0); addi(SP, SP, 4); }
aoqi@6880 671 void pop (FloatRegister reg) { lwc1(reg, SP, 0); addi(SP, SP, 4); }
aoqi@6880 672 void pop () { addi(SP, SP, 4); }
aoqi@6880 673 void pop2 () { addi(SP, SP, 8); }
aoqi@6880 674 #endif
aoqi@6880 675 void push2(Register reg1, Register reg2);
aoqi@6880 676 void pop2 (Register reg1, Register reg2);
aoqi@6880 677 void dpush (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
aoqi@6880 678 void dpop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
aoqi@6880 679 //we need 2 fun to save and resotre general register
aoqi@6880 680 void pushad();
aoqi@6880 681 void popad();
aoqi@6880 682
aoqi@6880 683 //move an 32-bit immediate to Register
aoqi@6880 684 void move(Register reg, int imm32) { li32(reg, imm32); }
aoqi@6880 685 void li (Register rd, long imm);
aoqi@6880 686 void li (Register rd, address addr) { li(rd, (long)addr); }
aoqi@6880 687 //replace move(Register reg, int imm)
aoqi@6880 688 void li32(Register rd, int imm32); // sign-extends to 64 bits on mips64
aoqi@6880 689 #ifdef _LP64
aoqi@6880 690 void set64(Register d, jlong value);
aoqi@6880 691 static int insts_for_set64(jlong value);
aoqi@6880 692
aoqi@6880 693 void patchable_set48(Register d, jlong value);
aoqi@6880 694 void patchable_set32(Register d, jlong value);
aoqi@6880 695
aoqi@6880 696 void patchable_call32(Register d, jlong value);
aoqi@6880 697
aoqi@6880 698 static int call_size(address target, bool far, bool patchable);
aoqi@6880 699
aoqi@6880 700 static bool reachable_from_cache(address target);
aoqi@6880 701
aoqi@6880 702
aoqi@6880 703 void dli(Register rd, long imm) { li(rd, imm); }
aoqi@6880 704 void li64(Register rd, long imm);
aoqi@6880 705 void li48(Register rd, long imm);
aoqi@6880 706 #endif
aoqi@6880 707
aoqi@6880 708 #ifdef _LP64
aoqi@6880 709 void move(Register rd, Register rs) { dadd(rd, rs, R0); }
aoqi@6880 710 void move_u32(Register rd, Register rs) { addu32(rd, rs, R0); }
aoqi@6880 711 #else
aoqi@6880 712 void move(Register rd, Register rs) { add(rd, rs, R0); }
aoqi@6880 713 #endif
aoqi@6880 714 void dmove(Register rd, Register rs) { dadd(rd, rs, R0); }
aoqi@8865 715 void mov_metadata(Register dst, Metadata* obj);
aoqi@8865 716 void mov_metadata(Address dst, Metadata* obj);
aoqi@6880 717
aoqi@6880 718
aoqi@6880 719 #ifndef PRODUCT
aoqi@6880 720 static void pd_print_patched_instruction(address branch) {
aoqi@6880 721 jint stub_inst = *(jint*) branch;
aoqi@6880 722 print_instruction(stub_inst);
aoqi@6880 723 ::tty->print("%s", " (unresolved)");
aoqi@6880 724
aoqi@6880 725 }
aoqi@6880 726 #endif
aoqi@6880 727
aoqi@6880 728 //FIXME
aoqi@6880 729 void empty_FPU_stack(){/*need implemented*/};
aoqi@6880 730
aoqi@6880 731
aoqi@6880 732 // method handles (JSR 292)
aoqi@6880 733 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
aoqi@6880 734
aoqi@6880 735 #undef VIRTUAL
aoqi@6880 736
aoqi@6880 737 };
aoqi@6880 738
aoqi@6880 739 /**
aoqi@6880 740 * class SkipIfEqual:
aoqi@6880 741 *
aoqi@6880 742 * Instantiating this class will result in assembly code being output that will
aoqi@6880 743 * jump around any code emitted between the creation of the instance and it's
aoqi@6880 744 * automatic destruction at the end of a scope block, depending on the value of
aoqi@6880 745 * the flag passed to the constructor, which will be checked at run-time.
aoqi@6880 746 */
aoqi@6880 747 class SkipIfEqual {
aoqi@6880 748 private:
aoqi@6880 749 MacroAssembler* _masm;
aoqi@6880 750 Label _label;
aoqi@6880 751
aoqi@6880 752 public:
aoqi@6880 753 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value);
aoqi@6880 754 ~SkipIfEqual();
aoqi@6880 755 };
aoqi@6880 756
aoqi@6880 757 #ifdef ASSERT
aoqi@6880 758 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; }
aoqi@6880 759 #endif
aoqi@6880 760
aoqi@6880 761
aoqi@6880 762 #endif // CPU_MIPS_VM_MACROASSEMBLER_MIPS_HPP

mercurial