36 // - - NativeCall
37 // - - NativeFarCall
38 // - - NativeMovConstReg
39 // - - NativeMovConstRegPatching
40 // - - NativeMovRegMem
41 // - - NativeJump
42 // - - NativeGeneralJump
43 // - - NativeIllegalInstruction
44 // The base class for different kinds of native instruction abstractions.
45 // Provides the primitive operations to manipulate code relative to this.
46 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
47 friend class Relocation;
48
49 public:
50 enum Sparc_specific_constants {
51 nop_instruction_size = 4
52 };
53
54 bool is_nop() { return long_at(0) == nop_instruction(); }
55 bool is_call() { return is_op(long_at(0), Assembler::call_op); }
56 bool is_sethi() { return (is_op2(long_at(0), Assembler::sethi_op2)
57 && inv_rd(long_at(0)) != G0); }
58
59 bool sets_cc() {
60 // conservative (returns true for some instructions that do not set the
61 // the condition code, such as, "save".
62 // Does not return true for the deprecated tagged instructions, such as, TADDcc
63 int x = long_at(0);
64 return (is_op(x, Assembler::arith_op) &&
65 (inv_op3(x) & Assembler::cc_bit_op3) == Assembler::cc_bit_op3);
66 }
67 bool is_illegal();
68 bool is_zombie() {
69 int x = long_at(0);
70 return is_op3(x,
71 Assembler::ldsw_op3,
72 Assembler::ldst_op)
73 && Assembler::inv_rs1(x) == G0
74 && Assembler::inv_rd(x) == O7;
75 }
398 static bool is_call_to(address instr, address target) {
399 return nativeInstruction_at(instr)->is_call() &&
400 nativeCall_at(instr)->destination() == target;
401 }
402
403 // MT-safe patching of a call instruction.
404 static void insert(address code_pos, address entry) {
405 (void)nativeCall_overwriting_at(code_pos, entry);
406 }
407
408 static void replace_mt_safe(address instr_addr, address code_buffer);
409 };
410 inline NativeCall* nativeCall_at(address instr) {
411 NativeCall* call = (NativeCall*)instr;
412 #ifdef ASSERT
413 call->verify();
414 #endif
415 return call;
416 }
417
418 // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere
419 // instructions in the sparcv9 vm. Used to call native methods which may be loaded
420 // anywhere in the address space, possibly out of reach of a call instruction.
421
422 #ifndef _LP64
423
424 // On 32-bit systems, a far call is the same as a near one.
425 class NativeFarCall;
426 inline NativeFarCall* nativeFarCall_at(address instr);
427 class NativeFarCall : public NativeCall {
428 public:
429 friend inline NativeFarCall* nativeFarCall_at(address instr) { return (NativeFarCall*)nativeCall_at(instr); }
430 friend NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination = NULL)
431 { return (NativeFarCall*)nativeCall_overwriting_at(instr, destination); }
432 friend NativeFarCall* nativeFarCall_before(address return_address)
433 { return (NativeFarCall*)nativeCall_before(return_address); }
434 };
435
436 #else
437
|
36 // - - NativeCall
37 // - - NativeFarCall
38 // - - NativeMovConstReg
39 // - - NativeMovConstRegPatching
40 // - - NativeMovRegMem
41 // - - NativeJump
42 // - - NativeGeneralJump
43 // - - NativeIllegalInstruction
44 // The base class for different kinds of native instruction abstractions.
45 // Provides the primitive operations to manipulate code relative to this.
46 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
47 friend class Relocation;
48
49 public:
50 enum Sparc_specific_constants {
51 nop_instruction_size = 4
52 };
53
54 bool is_nop() { return long_at(0) == nop_instruction(); }
55 bool is_call() { return is_op(long_at(0), Assembler::call_op); }
56 bool is_call_reg() { return is_op(long_at(0), Assembler::arith_op); }
57 bool is_sethi() { return (is_op2(long_at(0), Assembler::sethi_op2)
58 && inv_rd(long_at(0)) != G0); }
59
60 bool sets_cc() {
61 // conservative (returns true for some instructions that do not set the
62 // the condition code, such as, "save".
63 // Does not return true for the deprecated tagged instructions, such as, TADDcc
64 int x = long_at(0);
65 return (is_op(x, Assembler::arith_op) &&
66 (inv_op3(x) & Assembler::cc_bit_op3) == Assembler::cc_bit_op3);
67 }
68 bool is_illegal();
69 bool is_zombie() {
70 int x = long_at(0);
71 return is_op3(x,
72 Assembler::ldsw_op3,
73 Assembler::ldst_op)
74 && Assembler::inv_rs1(x) == G0
75 && Assembler::inv_rd(x) == O7;
76 }
399 static bool is_call_to(address instr, address target) {
400 return nativeInstruction_at(instr)->is_call() &&
401 nativeCall_at(instr)->destination() == target;
402 }
403
404 // MT-safe patching of a call instruction.
405 static void insert(address code_pos, address entry) {
406 (void)nativeCall_overwriting_at(code_pos, entry);
407 }
408
409 static void replace_mt_safe(address instr_addr, address code_buffer);
410 };
411 inline NativeCall* nativeCall_at(address instr) {
412 NativeCall* call = (NativeCall*)instr;
413 #ifdef ASSERT
414 call->verify();
415 #endif
416 return call;
417 }
418
419 class NativeCallReg: public NativeInstruction {
420 public:
421 enum Sparc_specific_constants {
422 instruction_size = 8,
423 return_address_offset = 8,
424 instruction_offset = 0
425 };
426
427 address next_instruction_address() const {
428 return addr_at(instruction_size);
429 }
430 };
431
432 // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere
433 // instructions in the sparcv9 vm. Used to call native methods which may be loaded
434 // anywhere in the address space, possibly out of reach of a call instruction.
435
436 #ifndef _LP64
437
438 // On 32-bit systems, a far call is the same as a near one.
439 class NativeFarCall;
440 inline NativeFarCall* nativeFarCall_at(address instr);
441 class NativeFarCall : public NativeCall {
442 public:
443 friend inline NativeFarCall* nativeFarCall_at(address instr) { return (NativeFarCall*)nativeCall_at(instr); }
444 friend NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination = NULL)
445 { return (NativeFarCall*)nativeCall_overwriting_at(instr, destination); }
446 friend NativeFarCall* nativeFarCall_before(address return_address)
447 { return (NativeFarCall*)nativeCall_before(return_address); }
448 };
449
450 #else
451
|