< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page
rev 11248 : 8156943: aarch64: string compare does not support CompactStrings
Summary: Implement LL, UL and LU encodings for StrComp
Reviewed-by: aph


3313     ciEnv::current()->record_failure("CodeCache is full");
3314     return 0;  // CodeBuffer::expand failed
3315   }
3316   int offset = __ offset();
3317 
3318   __ adr(lr, __ pc());
3319   __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
3320 
3321   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
3322   __ end_a_stub();
3323   return offset;
3324 }
3325 
3326 // REQUIRED MATCHER CODE
3327 
3328 //=============================================================================
3329 
3330 const bool Matcher::match_rule_supported(int opcode) {
3331 
3332   switch (opcode) {
3333   case Op_StrComp:
3334   case Op_StrIndexOf:
3335     if (CompactStrings)  return false;
3336     break;
3337   default:
3338     break;
3339   }
3340 
3341   if (!has_match_rule(opcode)) {
3342     return false;
3343   }
3344 
3345   return true;  // Per default match rules are supported.
3346 }
3347 
3348 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
3349 
3350   // TODO
3351   // identify extra cases that we might want to provide match rules for
3352   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
3353   bool ret_value = match_rule_supported(opcode);


14927   ins_cost(1100);  // slightly larger than the next version
14928   format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
14929 
14930   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14931 
14932   opcode(0x0); // Don't zero result reg on hit
14933 
14934   ins_pipe(pipe_class_memory);
14935 %}
14936 
14937 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14938                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14939 %{
14940   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
14941   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14942   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14943 
14944   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14945   ins_encode %{
14946     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
14947     __ asrw($cnt1$$Register, $cnt1$$Register, 1);
14948     __ asrw($cnt2$$Register, $cnt2$$Register, 1);
14949     __ string_compare($str1$$Register, $str2$$Register,
14950                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14951                       $tmp1$$Register);




















































14952   %}
14953   ins_pipe(pipe_class_memory);
14954 %}
14955 
14956 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
14957        iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
14958 %{
14959   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
14960   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
14961   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
14962          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
14963   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %}
14964 
14965   ins_encode %{
14966     __ string_indexof($str1$$Register, $str2$$Register,
14967                       $cnt1$$Register, $cnt2$$Register,
14968                       $tmp1$$Register, $tmp2$$Register,
14969                       $tmp3$$Register, $tmp4$$Register,
14970                       -1, $result$$Register);
14971   %}




3313     ciEnv::current()->record_failure("CodeCache is full");
3314     return 0;  // CodeBuffer::expand failed
3315   }
3316   int offset = __ offset();
3317 
3318   __ adr(lr, __ pc());
3319   __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
3320 
3321   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
3322   __ end_a_stub();
3323   return offset;
3324 }
3325 
3326 // REQUIRED MATCHER CODE
3327 
3328 //=============================================================================
3329 
3330 const bool Matcher::match_rule_supported(int opcode) {
3331 
3332   switch (opcode) {

3333   case Op_StrIndexOf:
3334     if (CompactStrings)  return false;
3335     break;
3336   default:
3337     break;
3338   }
3339 
3340   if (!has_match_rule(opcode)) {
3341     return false;
3342   }
3343 
3344   return true;  // Per default match rules are supported.
3345 }
3346 
3347 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
3348 
3349   // TODO
3350   // identify extra cases that we might want to provide match rules for
3351   // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
3352   bool ret_value = match_rule_supported(opcode);


14926   ins_cost(1100);  // slightly larger than the next version
14927   format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
14928 
14929   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14930 
14931   opcode(0x0); // Don't zero result reg on hit
14932 
14933   ins_pipe(pipe_class_memory);
14934 %}
14935 
14936 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14937                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14938 %{
14939   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
14940   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14941   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14942 
14943   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14944   ins_encode %{
14945     // Count is in 8-bit bytes; non-Compact chars are 16 bits.


14946     __ string_compare($str1$$Register, $str2$$Register,
14947                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14948                       $tmp1$$Register,
14949                       fnoreg, fnoreg, StrIntrinsicNode::UU);
14950   %}
14951   ins_pipe(pipe_class_memory);
14952 %}
14953 
14954 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14955                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14956 %{
14957   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
14958   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14959   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14960 
14961   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14962   ins_encode %{
14963     __ string_compare($str1$$Register, $str2$$Register,
14964                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14965                       $tmp1$$Register,
14966                       fnoreg, fnoreg, StrIntrinsicNode::LL);
14967   %}
14968   ins_pipe(pipe_class_memory);
14969 %}
14970 
14971 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14972                         iRegI_R0 result, vRegD vtmp1, vRegD vtmp2, iRegP_R10 tmp1, rFlagsReg cr)
14973 %{
14974   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
14975   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14976   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP vtmp1, TEMP vtmp2, KILL cr);
14977 
14978   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14979   ins_encode %{
14980     __ string_compare($str1$$Register, $str2$$Register,
14981                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14982                       $tmp1$$Register,
14983                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, StrIntrinsicNode::UL);
14984   %}
14985   ins_pipe(pipe_class_memory);
14986 %}
14987 
14988 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14989                         iRegI_R0 result, vRegD vtmp1, vRegD vtmp2, iRegP_R10 tmp1, rFlagsReg cr)
14990 %{
14991   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
14992   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14993   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP vtmp1, TEMP vtmp2, KILL cr);
14994 
14995   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14996   ins_encode %{
14997     __ string_compare($str1$$Register, $str2$$Register,
14998                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14999                       $tmp1$$Register,
15000                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, StrIntrinsicNode::LU);
15001   %}
15002   ins_pipe(pipe_class_memory);
15003 %}
15004 
15005 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15006        iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
15007 %{
15008   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
15009   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15010   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15011          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15012   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %}
15013 
15014   ins_encode %{
15015     __ string_indexof($str1$$Register, $str2$$Register,
15016                       $cnt1$$Register, $cnt2$$Register,
15017                       $tmp1$$Register, $tmp2$$Register,
15018                       $tmp3$$Register, $tmp4$$Register,
15019                       -1, $result$$Register);
15020   %}


< prev index next >