src/cpu/sparc/vm/sparc.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7063628_1 Sdiff src/cpu/sparc/vm

src/cpu/sparc/vm/sparc.ad

Print this page




2953     __ bpr(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
2954     __ delayed()->add(G0, 1, result_reg); // count == 0
2955 
2956     //rename registers
2957     Register limit_reg =    cnt_reg;
2958     Register  chr1_reg = result_reg;
2959     Register  chr2_reg =   tmp1_reg;
2960 
2961     //check for alignment and position the pointers to the ends
2962     __ or3(str1_reg, str2_reg, chr1_reg);
2963     __ andcc(chr1_reg, 0x3, chr1_reg);
2964     // notZero means at least one not 4-byte aligned.
2965     // We could optimize the case when both arrays are not aligned
2966     // but it is not frequent case and it requires additional checks.
2967     __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
2968     __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
2969 
2970     // Compare char[] arrays aligned to 4 bytes.
2971     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
2972                           chr1_reg, chr2_reg, Ldone);
2973     __ ba(Ldone, false);
2974     __ delayed()->add(G0, 1, result_reg);
2975 
2976     // char by char compare
2977     __ bind(Lchar);
2978     __ add(str1_reg, limit_reg, str1_reg);
2979     __ add(str2_reg, limit_reg, str2_reg);
2980     __ neg(limit_reg); //negate count
2981 
2982     __ lduh(str1_reg, limit_reg, chr1_reg);
2983     // Lchar_loop
2984     __ bind(Lchar_loop);
2985     __ lduh(str2_reg, limit_reg, chr2_reg);
2986     __ cmp(chr1_reg, chr2_reg);
2987     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
2988     __ delayed()->mov(G0, result_reg); //not equal
2989     __ inccc(limit_reg, sizeof(jchar));
2990     // annul LDUH if branch is not taken to prevent access past end of string
2991     __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
2992     __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2993 


9181 
9182     // Jump to base address + switch value
9183     __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
9184     __ jmp(label_reg, G0);
9185     __ delayed()->nop();
9186   %}
9187   ins_pc_relative(1);
9188   ins_pipe(ialu_reg_reg);
9189 %}
9190 
9191 // Direct Branch.  Use V8 version with longer range.
9192 instruct branch(label labl) %{
9193   match(Goto);
9194   effect(USE labl);
9195 
9196   size(8);
9197   ins_cost(BRANCH_COST);
9198   format %{ "BA     $labl" %}
9199   ins_encode %{
9200     Label* L = $labl$$label;
9201     assert(L != NULL, "need Label");
9202     __ ba(*L, false);
9203     __ delayed()->nop();
9204   %}
9205   ins_pc_relative(1);
9206   ins_pipe(br);
9207 %}
9208 
9209 // Conditional Direct Branch
9210 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
9211   match(If cmp icc);
9212   effect(USE labl);
9213 
9214   size(8);
9215   ins_cost(BRANCH_COST);
9216   format %{ "BP$cmp   $icc,$labl" %}
9217   // Prim = bits 24-22, Secnd = bits 31-30
9218   ins_encode( enc_bp( labl, cmp, icc ) );
9219   ins_pc_relative(1);
9220   ins_pipe(br_cc);
9221 %}
9222 


9266 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
9267   match(If cmp icc);
9268   effect(USE labl);
9269 
9270   format %{ "BP$cmp  $icc,$labl" %}
9271   // Prim = bits 24-22, Secnd = bits 31-30
9272   ins_encode( enc_bp( labl, cmp, icc ) );
9273   ins_pc_relative(1);
9274   ins_pipe(br_cc);
9275 %}
9276 
9277 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
9278   match(If cmp pcc);
9279   effect(USE labl);
9280 
9281   size(8);
9282   ins_cost(BRANCH_COST);
9283   format %{ "BP$cmp  $pcc,$labl" %}
9284   ins_encode %{
9285     Label* L = $labl$$label;
9286     assert(L != NULL, "need Label");
9287     Assembler::Predict predict_taken =
9288       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9289 
9290     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L);
9291     __ delayed()->nop();
9292   %}
9293   ins_pc_relative(1);
9294   ins_pipe(br_cc);
9295 %}
9296 
9297 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{
9298   match(If cmp fcc);
9299   effect(USE labl);
9300 
9301   size(8);
9302   ins_cost(BRANCH_COST);
9303   format %{ "FBP$cmp $fcc,$labl" %}
9304   ins_encode %{
9305     Label* L = $labl$$label;
9306     assert(L != NULL, "need Label");
9307     Assembler::Predict predict_taken =
9308       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9309 
9310     __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L);
9311     __ delayed()->nop();
9312   %}
9313   ins_pc_relative(1);
9314   ins_pipe(br_fcc);
9315 %}
9316 
9317 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
9318   match(CountedLoopEnd cmp icc);
9319   effect(USE labl);
9320 
9321   size(8);
9322   ins_cost(BRANCH_COST);
9323   format %{ "BP$cmp   $icc,$labl\t! Loop end" %}
9324   // Prim = bits 24-22, Secnd = bits 31-30
9325   ins_encode( enc_bp( labl, cmp, icc ) );
9326   ins_pc_relative(1);


9353 
9354 // Due to a shortcoming in the ADLC, it mixes up expressions like:
9355 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
9356 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
9357 // are collapsed internally in the ADLC's dfa-gen code.  The match for
9358 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
9359 // foo match ends up with the wrong leaf.  One fix is to not match both
9360 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
9361 // both forms beat the trinary form of long-compare and both are very useful
9362 // on Intel which has so few registers.
9363 
9364 instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
9365   match(If cmp xcc);
9366   effect(USE labl);
9367 
9368   size(8);
9369   ins_cost(BRANCH_COST);
9370   format %{ "BP$cmp   $xcc,$labl" %}
9371   ins_encode %{
9372     Label* L = $labl$$label;
9373     assert(L != NULL, "need Label");
9374     Assembler::Predict predict_taken =
9375       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9376 
9377     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
9378     __ delayed()->nop();
9379   %}
9380   ins_pc_relative(1);
9381   ins_pipe(br_cc);
9382 %}
9383 
9384 // Manifest a CmpL3 result in an integer register.  Very painful.
9385 // This is the test to avoid.
9386 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
9387   match(Set dst (CmpL3 src1 src2) );
9388   effect( KILL ccr );
9389   ins_cost(6*DEFAULT_COST);
9390   size(24);
9391   format %{ "CMP    $src1,$src2\t\t! long\n"
9392           "\tBLT,a,pn done\n"
9393           "\tMOV    -1,$dst\t! delay slot\n"




2953     __ bpr(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
2954     __ delayed()->add(G0, 1, result_reg); // count == 0
2955 
2956     //rename registers
2957     Register limit_reg =    cnt_reg;
2958     Register  chr1_reg = result_reg;
2959     Register  chr2_reg =   tmp1_reg;
2960 
2961     //check for alignment and position the pointers to the ends
2962     __ or3(str1_reg, str2_reg, chr1_reg);
2963     __ andcc(chr1_reg, 0x3, chr1_reg);
2964     // notZero means at least one not 4-byte aligned.
2965     // We could optimize the case when both arrays are not aligned
2966     // but it is not frequent case and it requires additional checks.
2967     __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
2968     __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
2969 
2970     // Compare char[] arrays aligned to 4 bytes.
2971     __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
2972                           chr1_reg, chr2_reg, Ldone);
2973     __ ba(Ldone);
2974     __ delayed()->add(G0, 1, result_reg);
2975 
2976     // char by char compare
2977     __ bind(Lchar);
2978     __ add(str1_reg, limit_reg, str1_reg);
2979     __ add(str2_reg, limit_reg, str2_reg);
2980     __ neg(limit_reg); //negate count
2981 
2982     __ lduh(str1_reg, limit_reg, chr1_reg);
2983     // Lchar_loop
2984     __ bind(Lchar_loop);
2985     __ lduh(str2_reg, limit_reg, chr2_reg);
2986     __ cmp(chr1_reg, chr2_reg);
2987     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
2988     __ delayed()->mov(G0, result_reg); //not equal
2989     __ inccc(limit_reg, sizeof(jchar));
2990     // annul LDUH if branch is not taken to prevent access past end of string
2991     __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
2992     __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
2993 


9181 
9182     // Jump to base address + switch value
9183     __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
9184     __ jmp(label_reg, G0);
9185     __ delayed()->nop();
9186   %}
9187   ins_pc_relative(1);
9188   ins_pipe(ialu_reg_reg);
9189 %}
9190 
9191 // Direct Branch.  Use V8 version with longer range.
9192 instruct branch(label labl) %{
9193   match(Goto);
9194   effect(USE labl);
9195 
9196   size(8);
9197   ins_cost(BRANCH_COST);
9198   format %{ "BA     $labl" %}
9199   ins_encode %{
9200     Label* L = $labl$$label;
9201     __ ba(*L);

9202     __ delayed()->nop();
9203   %}
9204   ins_pc_relative(1);
9205   ins_pipe(br);
9206 %}
9207 
9208 // Conditional Direct Branch
9209 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
9210   match(If cmp icc);
9211   effect(USE labl);
9212 
9213   size(8);
9214   ins_cost(BRANCH_COST);
9215   format %{ "BP$cmp   $icc,$labl" %}
9216   // Prim = bits 24-22, Secnd = bits 31-30
9217   ins_encode( enc_bp( labl, cmp, icc ) );
9218   ins_pc_relative(1);
9219   ins_pipe(br_cc);
9220 %}
9221 


9265 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
9266   match(If cmp icc);
9267   effect(USE labl);
9268 
9269   format %{ "BP$cmp  $icc,$labl" %}
9270   // Prim = bits 24-22, Secnd = bits 31-30
9271   ins_encode( enc_bp( labl, cmp, icc ) );
9272   ins_pc_relative(1);
9273   ins_pipe(br_cc);
9274 %}
9275 
9276 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
9277   match(If cmp pcc);
9278   effect(USE labl);
9279 
9280   size(8);
9281   ins_cost(BRANCH_COST);
9282   format %{ "BP$cmp  $pcc,$labl" %}
9283   ins_encode %{
9284     Label* L = $labl$$label;

9285     Assembler::Predict predict_taken =
9286       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9287 
9288     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L);
9289     __ delayed()->nop();
9290   %}
9291   ins_pc_relative(1);
9292   ins_pipe(br_cc);
9293 %}
9294 
9295 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{
9296   match(If cmp fcc);
9297   effect(USE labl);
9298 
9299   size(8);
9300   ins_cost(BRANCH_COST);
9301   format %{ "FBP$cmp $fcc,$labl" %}
9302   ins_encode %{
9303     Label* L = $labl$$label;

9304     Assembler::Predict predict_taken =
9305       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9306 
9307     __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L);
9308     __ delayed()->nop();
9309   %}
9310   ins_pc_relative(1);
9311   ins_pipe(br_fcc);
9312 %}
9313 
9314 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
9315   match(CountedLoopEnd cmp icc);
9316   effect(USE labl);
9317 
9318   size(8);
9319   ins_cost(BRANCH_COST);
9320   format %{ "BP$cmp   $icc,$labl\t! Loop end" %}
9321   // Prim = bits 24-22, Secnd = bits 31-30
9322   ins_encode( enc_bp( labl, cmp, icc ) );
9323   ins_pc_relative(1);


9350 
9351 // Due to a shortcoming in the ADLC, it mixes up expressions like:
9352 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)).  Note the
9353 // difference between 'Y' and '0L'.  The tree-matches for the CmpI sections
9354 // are collapsed internally in the ADLC's dfa-gen code.  The match for
9355 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
9356 // foo match ends up with the wrong leaf.  One fix is to not match both
9357 // reg-reg and reg-zero forms of long-compare.  This is unfortunate because
9358 // both forms beat the trinary form of long-compare and both are very useful
9359 // on Intel which has so few registers.
9360 
9361 instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
9362   match(If cmp xcc);
9363   effect(USE labl);
9364 
9365   size(8);
9366   ins_cost(BRANCH_COST);
9367   format %{ "BP$cmp   $xcc,$labl" %}
9368   ins_encode %{
9369     Label* L = $labl$$label;

9370     Assembler::Predict predict_taken =
9371       cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
9372 
9373     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
9374     __ delayed()->nop();
9375   %}
9376   ins_pc_relative(1);
9377   ins_pipe(br_cc);
9378 %}
9379 
9380 // Manifest a CmpL3 result in an integer register.  Very painful.
9381 // This is the test to avoid.
9382 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
9383   match(Set dst (CmpL3 src1 src2) );
9384   effect( KILL ccr );
9385   ins_cost(6*DEFAULT_COST);
9386   size(24);
9387   format %{ "CMP    $src1,$src2\t\t! long\n"
9388           "\tBLT,a,pn done\n"
9389           "\tMOV    -1,$dst\t! delay slot\n"


src/cpu/sparc/vm/sparc.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File