src/cpu/sparc/vm/assembler_sparc.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
hotspot-dvm Cdiff src/cpu/sparc/vm/assembler_sparc.hpp
src/cpu/sparc/vm/assembler_sparc.hpp
Print this page
rev 522 : [mq]: meth.patch
*** 82,101 ****
// These globals are used as short-lived scratch registers in the compiler:
REGISTER_DECLARATION(Register, Gtemp , G5);
// The compiler requires that G5_megamorphic_method is G5_inline_cache_klass,
// because a single patchable "set" instruction (NativeMovConstReg,
// or NativeMovConstPatching for compiler1) instruction
// serves to set up either quantity, depending on whether the compiled
// call site is an inline cache or is megamorphic. See the function
// CompiledIC::set_to_megamorphic.
//
! // On the other hand, G5_inline_cache_klass must differ from G5_method,
! // because both registers are needed for an inline cache that calls
! // an interpreted method.
//
// Note that G5_method is only the method-self for the interpreter,
// and is logically unrelated to G5_megamorphic_method.
//
// Invariants on G2_thread (the JavaThread pointer):
--- 82,109 ----
// These globals are used as short-lived scratch registers in the compiler:
REGISTER_DECLARATION(Register, Gtemp , G5);
+ // JSR 292 fixed register usages:
+ REGISTER_DECLARATION(Register, G5_method_type , G5);
+ REGISTER_DECLARATION(Register, G3_method_handle , G3);
+
// The compiler requires that G5_megamorphic_method is G5_inline_cache_klass,
// because a single patchable "set" instruction (NativeMovConstReg,
// or NativeMovConstPatching for compiler1) instruction
// serves to set up either quantity, depending on whether the compiled
// call site is an inline cache or is megamorphic. See the function
// CompiledIC::set_to_megamorphic.
//
! // If a inline cache targets an interpreted method, then the
! // G5 register will be used twice during the call. First,
! // the call site will be patched to load a compiledICHolder
! // into G5. (This is an ordered pair of ic_klass, method.)
! // The c2i adapter will first check the ic_klass, then load
! // G5_method with the method part of the pair just before
! // jumping into the interpreter.
//
// Note that G5_method is only the method-self for the interpreter,
// and is logically unrelated to G5_megamorphic_method.
//
// Invariants on G2_thread (the JavaThread pointer):
*** 257,266 ****
--- 265,295 ----
#define Oissuing_pc AS_REGISTER(Register, Oissuing_pc)
#endif
+ // A union type for code which has to assemble both constant and non-constant operands.
+ class RegisterConstant VALUE_OBJ_CLASS_SPEC {
+ private:
+ Register _r;
+ intptr_t _c;
+
+ public:
+ RegisterConstant(): _r(noreg), _c(0) {}
+ RegisterConstant(Register r): _r(r), _c(0) {}
+ RegisterConstant(intptr_t c): _r(noreg), _c(c) {}
+
+ Register as_register() const { assert(is_register(),""); return _r; }
+ intptr_t as_constant() const { assert(is_constant(),""); return _c; }
+
+ Register register_or_noreg() const { return _r; }
+ intptr_t constant_or_zero() const { return _c; }
+
+ bool is_register() const { return _r != noreg; }
+ bool is_constant() const { return _r == noreg; }
+ };
+
// Address is an abstraction used to represent a memory location.
//
// Note: A register location is represented via a Register, not
// via an address for efficiency & simplicity reasons.
*** 1080,1091 ****
--- 1109,1122 ----
// pp 135 (addc was addx in v8)
inline void add( Register s1, Register s2, Register d );
inline void add( Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none);
inline void add( Register s1, int simm13a, Register d, RelocationHolder const& rspec);
+ inline void add( Register s1, RegisterConstant s2, Register d, int offset = 0);
inline void add( const Address& a, Register d, int offset = 0);
+
void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); }
void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
*** 1296,1305 ****
--- 1327,1341 ----
inline void lduw( const Address& a, Register d, int offset = 0 );
inline void ldx( const Address& a, Register d, int offset = 0 );
inline void ld( const Address& a, Register d, int offset = 0 );
inline void ldd( const Address& a, Register d, int offset = 0 );
+ inline void ld( Register s1, RegisterConstant s2, Register d );
+ inline void lduw( Register s1, RegisterConstant s2, Register d );
+ inline void ldsw( Register s1, RegisterConstant s2, Register d );
+ inline void ldx( Register s1, RegisterConstant s2, Register d );
+
// pp 177
void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
void ldsba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
void ldsha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
*** 1516,1525 ****
--- 1552,1564 ----
inline void stw( Register d, const Address& a, int offset = 0 );
inline void stx( Register d, const Address& a, int offset = 0 );
inline void st( Register d, const Address& a, int offset = 0 );
inline void std( Register d, const Address& a, int offset = 0 );
+ inline void st( Register d, Register s1, RegisterConstant s2 );
+ inline void stx( Register d, Register s1, RegisterConstant s2 );
+
// pp 177
void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
void stba( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
void stha( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
*** 1904,1913 ****
--- 1943,1953 ----
inline void load_ptr_contents( Address& a, Register d, int offset = 0 );
inline void store_contents( Register s, Address& a, int offset = 0 );
inline void store_ptr_contents( Register s, Address& a, int offset = 0 );
inline void jumpl_to( Address& a, Register d, int offset = 0 );
inline void jump_to( Address& a, int offset = 0 );
+ inline void jump_indirect_to( Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0 );
// ring buffer traceable jumps
void jmp2( Register r1, Register r2, const char* file, int line );
void jmp ( Register r1, int offset, const char* file, int line );
*** 1938,1950 ****
--- 1978,1992 ----
// Functions for isolating 64 bit loads for LP64
// ld_ptr will perform ld for 32 bit VM's and ldx for 64 bit VM's
// st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's
inline void ld_ptr( Register s1, Register s2, Register d );
inline void ld_ptr( Register s1, int simm13a, Register d);
+ inline void ld_ptr( Register s1, RegisterConstant s2, Register d );
inline void ld_ptr( const Address& a, Register d, int offset = 0 );
inline void st_ptr( Register d, Register s1, Register s2 );
inline void st_ptr( Register d, Register s1, int simm13a);
+ inline void st_ptr( Register d, Register s1, RegisterConstant s2 );
inline void st_ptr( Register d, const Address& a, int offset = 0 );
// ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's
// st_long will perform st for 32 bit VM's and stx for 64 bit VM's
inline void ld_long( Register s1, Register s2, Register d );
*** 2265,2274 ****
--- 2307,2353 ----
Register t1, // temp register
Label& slow_case // continuation point if fast allocation fails
);
void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
+ // small bootstrap problems
+ RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp,
+ int offset = 0);
+ RegisterConstant delayed_value(int(*value_fn)(), Register tmp,
+ int offset = 0) {
+ return delayed_value(delayed_value_addr(value_fn), tmp, offset);
+ }
+ RegisterConstant delayed_value(address(*value_fn)(), Register tmp,
+ int offset = 0) {
+ return delayed_value((intptr_t*) delayed_value_addr(value_fn), tmp, offset);
+ }
+
+ // interface method calling
+ void lookup_interface_method(Register recv_klass,
+ Register intf_klass,
+ RegisterConstant itable_index,
+ Register method_result,
+ Register scan_temp,
+ Label& no_such_interface);
+
+ // method handles (JSR 292)
+ void check_method_handle_type(Register mtype_reg, Register mh_reg,
+ Register temp_reg,
+ Label& wrong_method_type);
+ void jump_to_method_handle_entry(Register mh_reg, Register temp_reg);
+ // offset relative to Gargs of argument at tos[arg_slot].
+ // (arg_slot == 0 means the last argument, not the first).
+ RegisterConstant argument_offset(RegisterConstant arg_slot,
+ int extra_slot_offset = 0);
+
+ // klass type checking (falls through on failure)
+ void check_klass_subtype(Register sub_klass,
+ Register super_klass,
+ Register temp_reg,
+ Label& L_success);
+
+
// Stack overflow checking
// Note: this clobbers G3_scratch
void bang_stack_with_offset(int offset) {
// stack grows down, caller passes positive offset
src/cpu/sparc/vm/assembler_sparc.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File