< prev index next >

src/hotspot/cpu/s390/macroAssembler_s390.cpp

Print this page

        

*** 1169,1179 **** } // Load narrow klass constant, compression required. void MacroAssembler::load_narrow_klass(Register t, Klass* k) { assert(UseCompressedClassPointers, "must be on to call this method"); ! narrowKlass encoded_k = CompressedKlassPointers::encode(k); load_const_32to64(t, encoded_k, false /*sign_extend*/); } //------------------------------------------------------ // Compare (patchable) constant with register. --- 1169,1179 ---- } // Load narrow klass constant, compression required. void MacroAssembler::load_narrow_klass(Register t, Klass* k) { assert(UseCompressedClassPointers, "must be on to call this method"); ! narrowKlass encoded_k = Klass::encode_klass(k); load_const_32to64(t, encoded_k, false /*sign_extend*/); } //------------------------------------------------------ // Compare (patchable) constant with register.
*** 1187,1197 **** } // Compare narrow oop in reg with narrow oop constant, no decompression. void MacroAssembler::compare_immediate_narrow_klass(Register klass1, Klass* klass2) { assert(UseCompressedClassPointers, "must be on to call this method"); ! narrowKlass encoded_k = CompressedKlassPointers::encode(klass2); Assembler::z_clfi(klass1, encoded_k); } //---------------------------------------------------------- --- 1187,1197 ---- } // Compare narrow oop in reg with narrow oop constant, no decompression. void MacroAssembler::compare_immediate_narrow_klass(Register klass1, Klass* klass2) { assert(UseCompressedClassPointers, "must be on to call this method"); ! narrowKlass encoded_k = Klass::encode_klass(klass2); Assembler::z_clfi(klass1, encoded_k); } //----------------------------------------------------------
*** 1283,1293 **** // Patching the immediate value of CPU version dependent load_narrow_klass sequence. // The passed ptr must NOT be in compressed format! int MacroAssembler::patch_load_narrow_klass(address pos, Klass* k) { assert(UseCompressedClassPointers, "Can only patch compressed klass pointers"); ! narrowKlass nk = CompressedKlassPointers::encode(k); return patch_load_const_32to64(pos, nk); } // Patching the immediate value of CPU version dependent compare_immediate_narrow_oop sequence. // The passed ptr must NOT be in compressed format! --- 1283,1293 ---- // Patching the immediate value of CPU version dependent load_narrow_klass sequence. // The passed ptr must NOT be in compressed format! int MacroAssembler::patch_load_narrow_klass(address pos, Klass* k) { assert(UseCompressedClassPointers, "Can only patch compressed klass pointers"); ! narrowKlass nk = Klass::encode_klass(k); return patch_load_const_32to64(pos, nk); } // Patching the immediate value of CPU version dependent compare_immediate_narrow_oop sequence. // The passed ptr must NOT be in compressed format!
*** 1301,1311 **** // Patching the immediate value of CPU version dependent compare_immediate_narrow_klass sequence. // The passed ptr must NOT be in compressed format! int MacroAssembler::patch_compare_immediate_narrow_klass(address pos, Klass* k) { assert(UseCompressedClassPointers, "Can only patch compressed klass pointers"); ! narrowKlass nk = CompressedKlassPointers::encode(k); return patch_compare_immediate_32(pos, nk); } //------------------------------------------------------------------------ // Extract the constant from a load_constant instruction stream. --- 1301,1311 ---- // Patching the immediate value of CPU version dependent compare_immediate_narrow_klass sequence. // The passed ptr must NOT be in compressed format! int MacroAssembler::patch_compare_immediate_narrow_klass(address pos, Klass* k) { assert(UseCompressedClassPointers, "Can only patch compressed klass pointers"); ! narrowKlass nk = Klass::encode_klass(k); return patch_compare_immediate_32(pos, nk); } //------------------------------------------------------------------------ // Extract the constant from a load_constant instruction stream.
*** 3604,3615 **** //------------------------------------- // Klass oop manipulations if compressed. void MacroAssembler::encode_klass_not_null(Register dst, Register src) { Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. (dst == src) also possible. ! address base = CompressedKlassPointers::base(); ! int shift = CompressedKlassPointers::shift(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass encoder {"); #ifdef ASSERT --- 3604,3615 ---- //------------------------------------- // Klass oop manipulations if compressed. void MacroAssembler::encode_klass_not_null(Register dst, Register src) { Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. (dst == src) also possible. ! address base = Universe::narrow_klass_base(); ! int shift = Universe::narrow_klass_shift(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass encoder {"); #ifdef ASSERT
*** 3653,3664 **** // This function calculates the size of the code generated by // decode_klass_not_null(register dst, Register src) // when (Universe::heap() != NULL). Hence, if the instructions // it generates change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { ! address base = CompressedKlassPointers::base(); ! int shift_size = CompressedKlassPointers::shift() == 0 ? 0 : 6; /* sllg */ int addbase_size = 0; assert(UseCompressedClassPointers, "only for compressed klass ptrs"); if (base != NULL) { unsigned int base_h = ((unsigned long)base)>>32; --- 3653,3664 ---- // This function calculates the size of the code generated by // decode_klass_not_null(register dst, Register src) // when (Universe::heap() != NULL). Hence, if the instructions // it generates change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { ! address base = Universe::narrow_klass_base(); ! int shift_size = Universe::narrow_klass_shift() == 0 ? 0 : 6; /* sllg */ int addbase_size = 0; assert(UseCompressedClassPointers, "only for compressed klass ptrs"); if (base != NULL) { unsigned int base_h = ((unsigned long)base)>>32;
*** 3683,3694 **** // then function instr_size_for_decode_klass_not_null() // needs to get updated. // This variant of decode_klass_not_null() must generate predictable code! // The code must only depend on globally known parameters. void MacroAssembler::decode_klass_not_null(Register dst) { ! address base = CompressedKlassPointers::base(); ! int shift = CompressedKlassPointers::shift(); int beg_off = offset(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass decoder (const size) {"); --- 3683,3694 ---- // then function instr_size_for_decode_klass_not_null() // needs to get updated. // This variant of decode_klass_not_null() must generate predictable code! // The code must only depend on globally known parameters. void MacroAssembler::decode_klass_not_null(Register dst) { ! address base = Universe::narrow_klass_base(); ! int shift = Universe::narrow_klass_shift(); int beg_off = offset(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass decoder (const size) {");
*** 3726,3737 **** // This variant of decode_klass_not_null() is for cases where // 1) the size of the generated instructions may vary // 2) the result is (potentially) stored in a register different from the source. void MacroAssembler::decode_klass_not_null(Register dst, Register src) { ! address base = CompressedKlassPointers::base(); ! int shift = CompressedKlassPointers::shift(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass decoder {"); if (src == noreg) src = dst; --- 3726,3737 ---- // This variant of decode_klass_not_null() is for cases where // 1) the size of the generated instructions may vary // 2) the result is (potentially) stored in a register different from the source. void MacroAssembler::decode_klass_not_null(Register dst, Register src) { ! address base = Universe::narrow_klass_base(); ! int shift = Universe::narrow_klass_shift(); assert(UseCompressedClassPointers, "only for compressed klass ptrs"); BLOCK_COMMENT("cKlass decoder {"); if (src == noreg) src = dst;
*** 3827,3838 **** void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybeNULL) { BLOCK_COMMENT("compare klass ptr {"); if (UseCompressedClassPointers) { ! const int shift = CompressedKlassPointers::shift(); ! address base = CompressedKlassPointers::base(); assert((shift == 0) || (shift == LogKlassAlignmentInBytes), "cKlass encoder detected bad shift"); assert_different_registers(Rop1, Z_R0); assert_different_registers(Rop1, Rbase, Z_R1); --- 3827,3838 ---- void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybeNULL) { BLOCK_COMMENT("compare klass ptr {"); if (UseCompressedClassPointers) { ! const int shift = Universe::narrow_klass_shift(); ! address base = Universe::narrow_klass_base(); assert((shift == 0) || (shift == LogKlassAlignmentInBytes), "cKlass encoder detected bad shift"); assert_different_registers(Rop1, Z_R0); assert_different_registers(Rop1, Rbase, Z_R1);
*** 3961,3972 **** void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL) { Register Rbase = mem.baseOrR0(); Register Rindex = mem.indexOrR0(); int64_t disp = mem.disp(); ! const int shift = CompressedOops::shift(); ! address base = CompressedOops::base(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this method"); assert((shift == 0) || (shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); assert_different_registers(Rop1, Z_R0); --- 3961,3972 ---- void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL) { Register Rbase = mem.baseOrR0(); Register Rindex = mem.indexOrR0(); int64_t disp = mem.disp(); ! const int shift = Universe::narrow_oop_shift(); ! address base = Universe::narrow_oop_base(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this method"); assert((shift == 0) || (shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); assert_different_registers(Rop1, Z_R0);
*** 4073,4085 **** // only32bitValid is set, if later code only uses the lower 32 bits. In this // case we must not fix the upper 32 bits. void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, Register Rbase, int pow2_offset, bool only32bitValid) { ! const address oop_base = CompressedOops::base(); ! const int oop_shift = CompressedOops::shift(); ! const bool disjoint = CompressedOops::base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this encoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); --- 4073,4085 ---- // only32bitValid is set, if later code only uses the lower 32 bits. In this // case we must not fix the upper 32 bits. void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, Register Rbase, int pow2_offset, bool only32bitValid) { ! const address oop_base = Universe::narrow_oop_base(); ! const int oop_shift = Universe::narrow_oop_shift(); ! const bool disjoint = Universe::narrow_oop_base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this encoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift");
*** 4208,4220 **** // - avoid Z_R0 for any of the argument registers. // - keep Rdst and Rsrc distinct from Rbase. Rdst == Rsrc is ok for performance. // - avoid Z_R1 for Rdst if Rdst == Rbase. void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, Register Rbase, int pow2_offset) { ! const address oop_base = CompressedOops::base(); ! const int oop_shift = CompressedOops::shift(); ! const bool disjoint = CompressedOops::base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this decoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); --- 4208,4220 ---- // - avoid Z_R0 for any of the argument registers. // - keep Rdst and Rsrc distinct from Rbase. Rdst == Rsrc is ok for performance. // - avoid Z_R1 for Rdst if Rdst == Rbase. void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, Register Rbase, int pow2_offset) { ! const address oop_base = Universe::narrow_oop_base(); ! const int oop_shift = Universe::narrow_oop_shift(); ! const bool disjoint = Universe::narrow_oop_base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); assert(Universe::heap() != NULL, "java heap must be initialized to call this decoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift");
*** 4353,4407 **** // Compiler ensures base is doubleword aligned and cnt is #doublewords. // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. // Actually, only r0, r1, and r5 are killed. ! unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg) { int block_start = offset(); Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE. Label doXC, doMVCLE, done; BLOCK_COMMENT("Clear_Array {"); // Check for zero len and convert to long. ! z_ltgfr(odd_tmp_reg, cnt_arg); z_bre(done); // Nothing to do if len == 0. // Prefetch data to be cleared. if (VM_Version::has_Prefetch()) { z_pfd(0x02, 0, Z_R0, base_pointer_arg); z_pfd(0x02, 256, Z_R0, base_pointer_arg); } ! z_sllg(dst_len, odd_tmp_reg, 3); // #bytes to clear. ! z_cghi(odd_tmp_reg, 32); // Check for len <= 256 bytes (<=32 DW). ! z_brnh(doXC); // If so, use executed XC to clear. // MVCLE: initialize long arrays (general case). bind(doMVCLE); z_lgr(dst_addr, base_pointer_arg); ! // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0. ! // The even register of the register pair is not killed. ! clear_reg(odd_tmp_reg, true, false); ! MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding()-1), 0); z_bru(done); // XC: initialize short arrays. Label XC_template; // Instr template, never exec directly! bind(XC_template); z_xc(0,0,base_pointer_arg,0,base_pointer_arg); bind(doXC); ! add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE. if (VM_Version::has_ExecuteExtensions()) { ! z_exrl(dst_len, XC_template); // Execute XC with var. len. } else { ! z_larl(odd_tmp_reg, XC_template); ! z_ex(dst_len,0,Z_R0,odd_tmp_reg); // Execute XC with var. len. } // z_bru(done); // fallthru bind(done); --- 4353,4409 ---- // Compiler ensures base is doubleword aligned and cnt is #doublewords. // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. // Actually, only r0, r1, and r5 are killed. ! unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len) { ! // Src_addr is evenReg. ! // Src_len is odd_Reg. int block_start = offset(); + Register tmp_reg = src_len; // Holds target instr addr for EX. Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE. Label doXC, doMVCLE, done; BLOCK_COMMENT("Clear_Array {"); // Check for zero len and convert to long. ! z_ltgfr(src_len, cnt_arg); // Remember casted value for doSTG case. z_bre(done); // Nothing to do if len == 0. // Prefetch data to be cleared. if (VM_Version::has_Prefetch()) { z_pfd(0x02, 0, Z_R0, base_pointer_arg); z_pfd(0x02, 256, Z_R0, base_pointer_arg); } ! z_sllg(dst_len, src_len, 3); // #bytes to clear. ! z_cghi(src_len, 32); // Check for len <= 256 bytes (<=32 DW). ! z_brnh(doXC); // If so, use executed XC to clear. // MVCLE: initialize long arrays (general case). bind(doMVCLE); z_lgr(dst_addr, base_pointer_arg); ! clear_reg(src_len, true, false); // Src len of MVCLE is zero. ! ! MacroAssembler::move_long_ext(dst_addr, src_addr, 0); z_bru(done); // XC: initialize short arrays. Label XC_template; // Instr template, never exec directly! bind(XC_template); z_xc(0,0,base_pointer_arg,0,base_pointer_arg); bind(doXC); ! add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE. if (VM_Version::has_ExecuteExtensions()) { ! z_exrl(dst_len, XC_template); // Execute XC with var. len. } else { ! z_larl(tmp_reg, XC_template); ! z_ex(dst_len,0,Z_R0,tmp_reg); // Execute XC with var. len. } // z_bru(done); // fallthru bind(done);
*** 4459,4477 **** } // Compiler ensures base is doubleword aligned and cnt is #doublewords. // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. ! // Actually, only r0, r1, (which are work registers) and odd_tmp_reg are killed. // // For very large arrays, exploit MVCLE H/W support. // MVCLE instruction automatically exploits H/W-optimized page mover. // - Bytes up to next page boundary are cleared with a series of XC to self. // - All full pages are cleared with the page mover H/W assist. // - Remaining bytes are again cleared by a series of XC to self. // ! unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg) { int block_start = offset(); Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE. --- 4461,4481 ---- } // Compiler ensures base is doubleword aligned and cnt is #doublewords. // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. ! // Actually, only r0, r1, r4, and r5 (which are work registers) are killed. // // For very large arrays, exploit MVCLE H/W support. // MVCLE instruction automatically exploits H/W-optimized page mover. // - Bytes up to next page boundary are cleared with a series of XC to self. // - All full pages are cleared with the page mover H/W assist. // - Remaining bytes are again cleared by a series of XC to self. // ! unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register src_addr, Register src_len) { ! // Src_addr is evenReg. ! // Src_len is odd_Reg. int block_start = offset(); Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE.
*** 4480,4493 **** // Get len to clear. load_const_optimized(dst_len, (long)cnt*8L); // in Bytes = #DW*8 // Prepare other args to MVCLE. z_lgr(dst_addr, base_pointer_arg); ! // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0. ! // The even register of the register pair is not killed. ! (void) clear_reg(odd_tmp_reg, true, false); // Src len of MVCLE is zero. ! MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding() - 1), 0); BLOCK_COMMENT("} Clear_Array_Const_Big"); int block_end = offset(); return block_end - block_start; } --- 4484,4498 ---- // Get len to clear. load_const_optimized(dst_len, (long)cnt*8L); // in Bytes = #DW*8 // Prepare other args to MVCLE. z_lgr(dst_addr, base_pointer_arg); ! // Indicate unused result. ! (void) clear_reg(src_len, true, false); // Src len of MVCLE is zero. ! ! // Clear. ! MacroAssembler::move_long_ext(dst_addr, src_addr, 0); BLOCK_COMMENT("} Clear_Array_Const_Big"); int block_end = offset(); return block_end - block_start; }
< prev index next >