comparison src/cpu/x86/vm/x86_32.ad @ 3345:bad7ecd0b6ed

5091921: Sign flip issues in loop optimizer Summary: Fix integer overflow problem in the code generated by loop optimizer. Reviewed-by: never
author kvn
date Wed, 04 May 2011 13:12:42 -0700
parents 15c9a0e16269
children 3d42f82cd811
comparison
equal deleted inserted replaced
3344:0139aac70fb5 3345:bad7ecd0b6ed
12983 ins_cost(300); 12983 ins_cost(300);
12984 12984
12985 format %{ "MAX $dst,$src" %} 12985 format %{ "MAX $dst,$src" %}
12986 opcode(0xCC); 12986 opcode(0xCC);
12987 ins_encode( max_enc(dst,src) ); 12987 ins_encode( max_enc(dst,src) );
12988 ins_pipe( pipe_slow );
12989 %}
12990
12991 // ============================================================================
12992 // Counted Loop limit node which represents exact final iterator value.
12993 // Note: the resulting value should fit into integer range since
12994 // counted loops have limit check on overflow.
12995 instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{
12996 match(Set limit (LoopLimit (Binary init limit) stride));
12997 effect(TEMP limit_hi, TEMP tmp, KILL flags);
12998 ins_cost(300);
12999
13000 format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %}
13001 ins_encode %{
13002 int strd = (int)$stride$$constant;
13003 assert(strd != 1 && strd != -1, "sanity");
13004 int m1 = (strd > 0) ? 1 : -1;
13005 // Convert limit to long (EAX:EDX)
13006 __ cdql();
13007 // Convert init to long (init:tmp)
13008 __ movl($tmp$$Register, $init$$Register);
13009 __ sarl($tmp$$Register, 31);
13010 // $limit - $init
13011 __ subl($limit$$Register, $init$$Register);
13012 __ sbbl($limit_hi$$Register, $tmp$$Register);
13013 // + ($stride - 1)
13014 if (strd > 0) {
13015 __ addl($limit$$Register, (strd - 1));
13016 __ adcl($limit_hi$$Register, 0);
13017 __ movl($tmp$$Register, strd);
13018 } else {
13019 __ addl($limit$$Register, (strd + 1));
13020 __ adcl($limit_hi$$Register, -1);
13021 __ lneg($limit_hi$$Register, $limit$$Register);
13022 __ movl($tmp$$Register, -strd);
13023 }
13024 // signed devision: (EAX:EDX) / pos_stride
13025 __ idivl($tmp$$Register);
13026 if (strd < 0) {
13027 // restore sign
13028 __ negl($tmp$$Register);
13029 }
13030 // (EAX) * stride
13031 __ mull($tmp$$Register);
13032 // + init (ignore upper bits)
13033 __ addl($limit$$Register, $init$$Register);
13034 %}
12988 ins_pipe( pipe_slow ); 13035 ins_pipe( pipe_slow );
12989 %} 13036 %}
12990 13037
12991 // ============================================================================ 13038 // ============================================================================
12992 // Branch Instructions 13039 // Branch Instructions