Mercurial > hg > graal-jvmci-8
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 |