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"
|