OSDN Git Service

JIT: Use rsb and shift in easy multiply.
authorAnders O Nilsson <anders.o.nilsson@stericsson.com>
Wed, 10 Oct 2012 13:26:32 +0000 (15:26 +0200)
committerPatrik Ryd <patrik.ryd@stericsson.com>
Fri, 14 Jun 2013 13:25:48 +0000 (15:25 +0200)
For easy multiplication using reverse subtract (when
lit is 2^n-1) use the barrel shifter for rsb.

This improves arithmetic performance for code executing
in Dalvik. E.g String.hashCode.

Change-Id: Ifb086dcec344b30fd3e392ac21d508b43e820cdc
Signed-off-by: Patrik Ryd <patrik.ryd@stericsson.com>
vm/compiler/codegen/arm/ArmLIR.h
vm/compiler/codegen/arm/Assemble.cpp
vm/compiler/codegen/arm/CodegenDriver.cpp
vm/compiler/codegen/arm/Thumb/Gen.cpp
vm/compiler/codegen/arm/Thumb2/Gen.cpp

index cbd4c70..e159aec 100644 (file)
@@ -627,6 +627,8 @@ typedef enum ArmOpcode {
     kThumb2Dmb,          /* dmb [1111001110111111100011110101] option[3-0] */
     kThumb2LdrPcReln12,  /* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
                                   imm12[11-0] */
+    kThumb2RsbRRR,       /* rsb [111010111101] rn[19..16] [0000] rd[11..8]
+                                  [0000] rm[3..0] */
     kThumbUndefined,     /* undefined [11011110xxxxxxxx] */
     kArmLast,
 } ArmOpcode;
index 7406d3e..a729dc5 100644 (file)
@@ -881,6 +881,11 @@ ArmEncodingMap EncodingMap[kArmLast] = {
                  kFmtUnused, -1, -1,
                  IS_BINARY_OP | REG_DEF0 | REG_USE_PC | IS_LOAD,
                  "ldr", "r!0d, [r15pc, -#!1d]", 2),
+    ENCODING_MAP(kThumb2RsbRRR,  0xebd00000, /* setflags encoding */
+                 kFmtBitBlt, 11, 8, kFmtBitBlt, 19, 16, kFmtBitBlt, 3, 0,
+                 kFmtShift, -1, -1,
+                 IS_QUAD_OP | REG_DEF0_USE12 | SETS_CCODES,
+                 "rsb", "r!0d, r!1d, r!2d!3H", 2),
     ENCODING_MAP(kThumbUndefined,       0xde00,
                  kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
                  kFmtUnused, -1, -1, NO_OPERAND,
index f8570c4..44a48f7 100644 (file)
@@ -2257,10 +2257,7 @@ static bool handleEasyMultiply(CompilationUnit *cUnit,
     } else {
         // Reverse subtract: (src << (shift + 1)) - src.
         assert(powerOfTwoMinusOne);
-        // TODO: rsb dst, src, src lsl#lowestSetBit(lit + 1)
-        int tReg = dvmCompilerAllocTemp(cUnit);
-        opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lowestSetBit(lit + 1));
-        opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg);
+        genMultiplyByShiftAndReverseSubtract(cUnit, rlSrc, rlResult, lowestSetBit(lit + 1));
     }
     storeValue(cUnit, rlDest, rlResult);
     return true;
index abc4420..622f47e 100644 (file)
@@ -274,3 +274,11 @@ static void genMultiplyByTwoBitMultiplier(CompilationUnit *cUnit,
     // to do a regular multiply.
     opRegRegImm(cUnit, kOpMul, rlResult.lowReg, rlSrc.lowReg, lit);
 }
+
+static void genMultiplyByShiftAndReverseSubtract(CompilationUnit *cUnit,
+        RegLocation rlSrc, RegLocation rlResult, int lit)
+{
+    int tReg = dvmCompilerAllocTemp(cUnit);
+    opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lit);
+    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg);
+}
index ea64547..950da90 100644 (file)
@@ -453,3 +453,10 @@ static void genMultiplyByTwoBitMultiplier(CompilationUnit *cUnit,
         opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
     }
 }
+
+static void genMultiplyByShiftAndReverseSubtract(CompilationUnit *cUnit,
+        RegLocation rlSrc, RegLocation rlResult, int lit)
+{
+    newLIR4(cUnit, kThumb2RsbRRR, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
+            encodeShift(kArmLsl, lit));
+}