< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page
rev 11557 : 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     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);
3353   // Add rules here.
3354 
3355   return ret_value;  // Per default match rules are supported.


14971   ins_cost(1100);  // slightly larger than the next version
14972   format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
14973 
14974   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14975 
14976   opcode(0x0); // Don't zero result reg on hit
14977 
14978   ins_pipe(pipe_class_memory);
14979 %}
14980 
14981 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14982                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14983 %{
14984   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
14985   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14986   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14987 
14988   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14989   ins_encode %{
14990     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
14991     __ asrw($cnt1$$Register, $cnt1$$Register, 1);
14992     __ asrw($cnt2$$Register, $cnt2$$Register, 1);
14993     __ string_compare($str1$$Register, $str2$$Register,
14994                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14995                       $tmp1$$Register);




















































14996   %}
14997   ins_pipe(pipe_class_memory);
14998 %}
14999 
15000 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15001        iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
15002 %{
15003   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
15004   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15005   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15006          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15007   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
15008 
15009   ins_encode %{
15010     __ string_indexof($str1$$Register, $str2$$Register,
15011                       $cnt1$$Register, $cnt2$$Register,
15012                       $tmp1$$Register, $tmp2$$Register,
15013                       $tmp3$$Register, $tmp4$$Register,
15014                       -1, $result$$Register, StrIntrinsicNode::UU);
15015   %}




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


14968   ins_cost(1100);  // slightly larger than the next version
14969   format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
14970 
14971   ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
14972 
14973   opcode(0x0); // Don't zero result reg on hit
14974 
14975   ins_pipe(pipe_class_memory);
14976 %}
14977 
14978 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14979                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14980 %{
14981   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
14982   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
14983   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
14984 
14985   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
14986   ins_encode %{
14987     // Count is in 8-bit bytes; non-Compact chars are 16 bits.


14988     __ string_compare($str1$$Register, $str2$$Register,
14989                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
14990                       $tmp1$$Register,
14991                       fnoreg, fnoreg, StrIntrinsicNode::UU);
14992   %}
14993   ins_pipe(pipe_class_memory);
14994 %}
14995 
14996 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
14997                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
14998 %{
14999   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
15000   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15001   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
15002 
15003   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
15004   ins_encode %{
15005     __ string_compare($str1$$Register, $str2$$Register,
15006                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
15007                       $tmp1$$Register,
15008                       fnoreg, fnoreg, StrIntrinsicNode::LL);
15009   %}
15010   ins_pipe(pipe_class_memory);
15011 %}
15012 
15013 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15014                         iRegI_R0 result, vRegD vtmp1, vRegD vtmp2, iRegP_R10 tmp1, rFlagsReg cr)
15015 %{
15016   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
15017   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15018   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP vtmp1, TEMP vtmp2, KILL cr);
15019 
15020   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
15021   ins_encode %{
15022     __ string_compare($str1$$Register, $str2$$Register,
15023                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
15024                       $tmp1$$Register,
15025                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, StrIntrinsicNode::UL);
15026   %}
15027   ins_pipe(pipe_class_memory);
15028 %}
15029 
15030 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
15031                         iRegI_R0 result, vRegD vtmp1, vRegD vtmp2, iRegP_R10 tmp1, rFlagsReg cr)
15032 %{
15033   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
15034   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
15035   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP vtmp1, TEMP vtmp2, KILL cr);
15036 
15037   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
15038   ins_encode %{
15039     __ string_compare($str1$$Register, $str2$$Register,
15040                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
15041                       $tmp1$$Register,
15042                       $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, StrIntrinsicNode::LU);
15043   %}
15044   ins_pipe(pipe_class_memory);
15045 %}
15046 
15047 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
15048        iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
15049 %{
15050   predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
15051   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
15052   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
15053          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
15054   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
15055 
15056   ins_encode %{
15057     __ string_indexof($str1$$Register, $str2$$Register,
15058                       $cnt1$$Register, $cnt2$$Register,
15059                       $tmp1$$Register, $tmp2$$Register,
15060                       $tmp3$$Register, $tmp4$$Register,
15061                       -1, $result$$Register, StrIntrinsicNode::UU);
15062   %}


< prev index next >