diff options
author | Michelle McDaniel <adiaaida@gmail.com> | 2016-08-31 08:14:57 -0700 |
---|---|---|
committer | Michelle McDaniel <adiaaida@gmail.com> | 2016-09-07 08:02:15 -0700 |
commit | ef8acec1b92b4fc119b39fd15f7ac5d7df725f0f (patch) | |
tree | 52e5feadcfab83552c6cf9b5607c9d8073756f49 /src/jit/gtlist.h | |
parent | 365fab07c3e49c9b3ca824aad822a17e3e8061c9 (diff) | |
download | coreclr-ef8acec1b92b4fc119b39fd15f7ac5d7df725f0f.tar.gz coreclr-ef8acec1b92b4fc119b39fd15f7ac5d7df725f0f.tar.bz2 coreclr-ef8acec1b92b4fc119b39fd15f7ac5d7df725f0f.zip |
Enable long multiply
Most long multiplies are converted in morph to helper calls. However,
GT_MULs of the form long = (long)int * (long)int are passed through to be
handled in codegen. In decompose, we convert these multiplies to
GT_MUL_HIs to be handled in a similar manner at GT_MULHI. Since mul and
imul take two ints and return a long in edx:eax, we can handle them
similarly to GT_CALLs, where we save them to lclvars if they aren't
already saved. In codegen, we generate a mul (or imul for signed
multiply), which produces the output in edx:eax, and then we store those
locations when we handle the storelclvar.
Diffstat (limited to 'src/jit/gtlist.h')
-rw-r--r-- | src/jit/gtlist.h | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/jit/gtlist.h b/src/jit/gtlist.h index a03bcfe4b0..4c69022ecf 100644 --- a/src/jit/gtlist.h +++ b/src/jit/gtlist.h @@ -116,6 +116,9 @@ GTNODE(RSZ , ">>>" ,0,GTK_BINOP) GTNODE(ROL , "rol" ,0,GTK_BINOP) GTNODE(ROR , "ror" ,0,GTK_BINOP) GTNODE(MULHI , "mulhi" ,1,GTK_BINOP) // returns high bits (top N bits of the 2N bit result of an NxN multiply) + // GT_MULHI is used in division by a constant (fgMorphDivByConst). We turn + // the div into a MULHI + some adjustments. In codegen, we only use the + // results of the high register, and we drop the low results. GTNODE(ASG , "=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR) GTNODE(ASG_ADD , "+=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR) @@ -159,16 +162,23 @@ GTNODE(LEA , "lea" ,0,GTK_BINOP|GTK_EXOP) // nodes such as calls, returns and stores of long lclVars. GTNODE(LONG , "gt_long" ,0,GTK_BINOP) -// The following are nodes representing the upper half of a 64-bit operation -// that requires a carry/borrow. However, they are all named GT_XXX_HI for -// consistency. +// The following are nodes representing x86 specific long operators, including +// high operators of a 64-bit operations that requires a carry/borrow, which are +// named GT_XXX_HI for consistency, low operators of 64-bit operations that need +// to not be modified in phases post-decompose, and operators that return 64-bit +// results in one instruction. GTNODE(ADD_LO , "+Lo" ,1,GTK_BINOP) GTNODE(ADD_HI , "+Hi" ,1,GTK_BINOP) GTNODE(SUB_LO , "-Lo" ,0,GTK_BINOP) GTNODE(SUB_HI , "-Hi" ,0,GTK_BINOP) -GTNODE(MUL_HI , "*Hi" ,1,GTK_BINOP) GTNODE(DIV_HI , "/Hi" ,0,GTK_BINOP) GTNODE(MOD_HI , "%Hi" ,0,GTK_BINOP) +GTNODE(MUL_LONG , "*long" ,1,GTK_BINOP) // A mul that returns the 2N bit result of an NxN multiply. This op + // is used for x86 multiplies that take two ints and return a long + // result. All other multiplies with long results are morphed into + // helper calls. It is similar to GT_MULHI, the difference being that + // GT_MULHI drops the lo part of the result, whereas GT_MUL_LONG keeps + // both parts of the result. #endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_) #ifdef FEATURE_SIMD |