1.1 --- a/src/cpu/x86/vm/x86_32.ad Wed May 04 03:42:58 2011 -0700 1.2 +++ b/src/cpu/x86/vm/x86_32.ad Wed May 04 13:12:42 2011 -0700 1.3 @@ -12989,6 +12989,53 @@ 1.4 %} 1.5 1.6 // ============================================================================ 1.7 +// Counted Loop limit node which represents exact final iterator value. 1.8 +// Note: the resulting value should fit into integer range since 1.9 +// counted loops have limit check on overflow. 1.10 +instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{ 1.11 + match(Set limit (LoopLimit (Binary init limit) stride)); 1.12 + effect(TEMP limit_hi, TEMP tmp, KILL flags); 1.13 + ins_cost(300); 1.14 + 1.15 + format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %} 1.16 + ins_encode %{ 1.17 + int strd = (int)$stride$$constant; 1.18 + assert(strd != 1 && strd != -1, "sanity"); 1.19 + int m1 = (strd > 0) ? 1 : -1; 1.20 + // Convert limit to long (EAX:EDX) 1.21 + __ cdql(); 1.22 + // Convert init to long (init:tmp) 1.23 + __ movl($tmp$$Register, $init$$Register); 1.24 + __ sarl($tmp$$Register, 31); 1.25 + // $limit - $init 1.26 + __ subl($limit$$Register, $init$$Register); 1.27 + __ sbbl($limit_hi$$Register, $tmp$$Register); 1.28 + // + ($stride - 1) 1.29 + if (strd > 0) { 1.30 + __ addl($limit$$Register, (strd - 1)); 1.31 + __ adcl($limit_hi$$Register, 0); 1.32 + __ movl($tmp$$Register, strd); 1.33 + } else { 1.34 + __ addl($limit$$Register, (strd + 1)); 1.35 + __ adcl($limit_hi$$Register, -1); 1.36 + __ lneg($limit_hi$$Register, $limit$$Register); 1.37 + __ movl($tmp$$Register, -strd); 1.38 + } 1.39 + // signed devision: (EAX:EDX) / pos_stride 1.40 + __ idivl($tmp$$Register); 1.41 + if (strd < 0) { 1.42 + // restore sign 1.43 + __ negl($tmp$$Register); 1.44 + } 1.45 + // (EAX) * stride 1.46 + __ mull($tmp$$Register); 1.47 + // + init (ignore upper bits) 1.48 + __ addl($limit$$Register, $init$$Register); 1.49 + %} 1.50 + ins_pipe( pipe_slow ); 1.51 +%} 1.52 + 1.53 +// ============================================================================ 1.54 // Branch Instructions 1.55 // Jump Table 1.56 instruct jumpXtnd(eRegI switch_val) %{