src/hotspot/cpu/s390/macroAssembler_s390.cpp
changeset 48331 a8e39cc7b88f
parent 48186 c722887b75a2
child 48332 651a95f30dfb
equal deleted inserted replaced
48330:e8230b52a8f4 48331:a8e39cc7b88f
  4912 //   cnt is signed int. Do not rely on high word!
  4912 //   cnt is signed int. Do not rely on high word!
  4913 //       counts # characters, not bytes.
  4913 //       counts # characters, not bytes.
  4914 // The result is the number of characters copied before the first incompatible character was found.
  4914 // The result is the number of characters copied before the first incompatible character was found.
  4915 // If precise is true, the processing stops exactly at this point. Otherwise, the result may be off
  4915 // If precise is true, the processing stops exactly at this point. Otherwise, the result may be off
  4916 // by a few bytes. The result always indicates the number of copied characters.
  4916 // by a few bytes. The result always indicates the number of copied characters.
       
  4917 // When used as a character index, the returned value points to the first incompatible character.
  4917 //
  4918 //
  4918 // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure:
  4919 // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure:
  4919 // - Different number of characters may have been written to dead array (if precise is false).
  4920 // - Different number of characters may have been written to dead array (if precise is false).
  4920 // - Returns a number <cnt instead of 0. (Result gets compared with cnt.)
  4921 // - Returns a number <cnt instead of 0. (Result gets compared with cnt.)
  4921 unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register cnt,
  4922 unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register cnt,
  4922                                              Register tmp,    bool precise) {
  4923                                              Register tmp,    bool precise) {
  4923   assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
  4924   assert_different_registers(Z_R0, Z_R1, result, src, dst, cnt, tmp);
  4924 
  4925 
  4925   if (precise) {
  4926   if (precise) {
  4926     BLOCK_COMMENT("encode_iso_array {");
  4927     BLOCK_COMMENT("encode_iso_array {");
  4927   } else {
  4928   } else {
  4928     BLOCK_COMMENT("string_compress {");
  4929     BLOCK_COMMENT("string_compress {");
  5025       z_vo(Vtmp1, Z_V20, Z_V21);
  5026       z_vo(Vtmp1, Z_V20, Z_V21);
  5026       z_vo(Vtmp2, Z_V22, Z_V23);
  5027       z_vo(Vtmp2, Z_V22, Z_V23);
  5027       z_vo(Vtmp1, Vtmp1, Vtmp2);
  5028       z_vo(Vtmp1, Vtmp1, Vtmp2);
  5028       z_vn(Vtmp1, Vtmp1, Vmask);
  5029       z_vn(Vtmp1, Vtmp1, Vmask);
  5029       z_vceqhs(Vtmp1, Vtmp1, Vzero);       // high half of all chars must be zero for successful compress.
  5030       z_vceqhs(Vtmp1, Vtmp1, Vzero);       // high half of all chars must be zero for successful compress.
  5030       z_brne(VectorBreak);                 // break vector loop, incompatible character found.
  5031       z_bvnt(VectorBreak);                 // break vector loop if not all vector elements compare eq -> incompatible character found.
  5031                                            // re-process data from current iteration in break handler.
  5032                                            // re-process data from current iteration in break handler.
  5032 
  5033 
  5033       //---<  pack & store characters  >---
  5034       //---<  pack & store characters  >---
  5034       z_vpkh(Vtmp1, Z_V20, Z_V21);         // pack (src1, src2) -> tmp1
  5035       z_vpkh(Vtmp1, Z_V20, Z_V21);         // pack (src1, src2) -> tmp1
  5035       z_vpkh(Vtmp2, Z_V22, Z_V23);         // pack (src3, src4) -> tmp2
  5036       z_vpkh(Vtmp2, Z_V22, Z_V23);         // pack (src3, src4) -> tmp2
  5092     z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop.
  5093     z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop.
  5093     z_nilf(Z_R0, ~(min_cnt-1));
  5094     z_nilf(Z_R0, ~(min_cnt-1));
  5094     z_tmll(Rcnt, min_cnt-1);
  5095     z_tmll(Rcnt, min_cnt-1);
  5095     z_brnaz(ScalarShortcut);               // if all bits zero, there is nothing left to do for scalar loop.
  5096     z_brnaz(ScalarShortcut);               // if all bits zero, there is nothing left to do for scalar loop.
  5096                                            // Rix == 0 in all cases.
  5097                                            // Rix == 0 in all cases.
       
  5098     z_sllg(Z_R1, Rcnt, 1);                 // # src bytes already processed. Only lower 32 bits are valid!
       
  5099                                            //   Z_R1 contents must be treated as unsigned operand! For huge strings,
       
  5100                                            //   (Rcnt >= 2**30), the value may spill into the sign bit by sllg.
  5097     z_lgfr(result, Rcnt);                  // all characters processed.
  5101     z_lgfr(result, Rcnt);                  // all characters processed.
  5098     z_sgfr(Rdst, Rcnt);                    // restore ptr
  5102     z_slgfr(Rdst, Rcnt);                   // restore ptr
  5099     z_sgfr(Rsrc, Rcnt);                    // restore ptr, double the element count for Rsrc restore
  5103     z_slgfr(Rsrc, Z_R1);                   // restore ptr, double the element count for Rsrc restore
  5100     z_sgfr(Rsrc, Rcnt);
       
  5101     z_bru(AllDone);
  5104     z_bru(AllDone);
  5102 
  5105 
  5103     bind(UnrolledBreak);
  5106     bind(UnrolledBreak);
  5104     z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop
  5107     z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop
  5105     z_nilf(Z_R0, ~(min_cnt-1));
  5108     z_nilf(Z_R0, ~(min_cnt-1));
  5106     z_sll(Rix, log_min_cnt);               // # chars processed so far in UnrolledLoop, excl. current iteration.
  5109     z_sll(Rix, log_min_cnt);               // # chars not yet processed in UnrolledLoop (due to break), broken iteration not included.
  5107     z_sr(Z_R0, Rix);                       // correct # chars processed in total.
  5110     z_sr(Z_R0, Rix);                       // fix # chars processed OK so far.
  5108     if (!precise) {
  5111     if (!precise) {
  5109       z_lgfr(result, Z_R0);
  5112       z_lgfr(result, Z_R0);
       
  5113       z_sllg(Z_R1, Z_R0, 1);               // # src bytes already processed. Only lower 32 bits are valid!
       
  5114                                            //   Z_R1 contents must be treated as unsigned operand! For huge strings,
       
  5115                                            //   (Rcnt >= 2**30), the value may spill into the sign bit by sllg.
  5110       z_aghi(result, min_cnt/2);           // min_cnt/2 characters have already been written
  5116       z_aghi(result, min_cnt/2);           // min_cnt/2 characters have already been written
  5111                                            // but ptrs were not updated yet.
  5117                                            // but ptrs were not updated yet.
  5112       z_sgfr(Rdst, Z_R0);                  // restore ptr
  5118       z_slgfr(Rdst, Z_R0);                 // restore ptr
  5113       z_sgfr(Rsrc, Z_R0);                  // restore ptr, double the element count for Rsrc restore
  5119       z_slgfr(Rsrc, Z_R1);                 // restore ptr, double the element count for Rsrc restore
  5114       z_sgfr(Rsrc, Z_R0);
       
  5115       z_bru(AllDone);
  5120       z_bru(AllDone);
  5116     }
  5121     }
  5117     bind(UnrolledDone);
  5122     bind(UnrolledDone);
  5118   }
  5123   }
  5119 
  5124 
  5163     } else {
  5168     } else {
  5164       z_lr(Rix, Rcnt);
  5169       z_lr(Rix, Rcnt);
  5165       z_sr(Rix, Z_R0);
  5170       z_sr(Rix, Z_R0);
  5166     }
  5171     }
  5167     z_lgfr(result, Rcnt);                  // # processed characters (if all runs ok).
  5172     z_lgfr(result, Rcnt);                  // # processed characters (if all runs ok).
  5168     z_brz(ScalarDone);
  5173     z_brz(ScalarDone);                     // uses CC from Rix calculation
  5169 
  5174 
  5170     bind(ScalarLoop);
  5175     bind(ScalarLoop);
  5171       z_llh(Z_R1, 0, Z_R0, Rsrc);
  5176       z_llh(Z_R1, 0, Z_R0, Rsrc);
  5172       z_tmll(Z_R1, 0xff00);
  5177       z_tmll(Z_R1, 0xff00);
  5173       z_brnaz(ScalarBreak);
  5178       z_brnaz(ScalarBreak);