• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dexgen.rop.code;
18 
19 import com.android.dexgen.rop.cst.CstInteger;
20 import com.android.dexgen.rop.type.Type;
21 
22 /**
23  * Implementation of {@link TranslationAdvice} which represents what
24  * the dex format will be able to represent.
25  */
26 public final class DexTranslationAdvice
27         implements TranslationAdvice {
28     /** {@code non-null;} standard instance of this class */
29     public static final DexTranslationAdvice THE_ONE =
30         new DexTranslationAdvice();
31 
32     /** debug advice for disabling invoke-range optimization */
33     public static final DexTranslationAdvice NO_SOURCES_IN_ORDER =
34         new DexTranslationAdvice(true);
35 
36     /**
37      * The minimum source width, in register units, for an invoke
38      * instruction that requires its sources to be in order and contiguous.
39      */
40     private static final int MIN_INVOKE_IN_ORDER = 6;
41 
42     /** when true: always returns false for requiresSourcesInOrder */
43     private final boolean disableSourcesInOrder;
44 
45     /**
46      * This class is not publicly instantiable. Use {@link #THE_ONE}.
47      */
DexTranslationAdvice()48     private DexTranslationAdvice() {
49         disableSourcesInOrder = false;
50     }
51 
DexTranslationAdvice(boolean disableInvokeRange)52     private DexTranslationAdvice(boolean disableInvokeRange) {
53         this.disableSourcesInOrder = disableInvokeRange;
54     }
55 
56     /** {@inheritDoc} */
hasConstantOperation(Rop opcode, RegisterSpec sourceA, RegisterSpec sourceB)57     public boolean hasConstantOperation(Rop opcode,
58             RegisterSpec sourceA, RegisterSpec sourceB) {
59         if (sourceA.getType() != Type.INT) {
60             return false;
61         }
62 
63         if (! (sourceB.getTypeBearer() instanceof CstInteger)) {
64             return false;
65         }
66 
67         CstInteger cst = (CstInteger) sourceB.getTypeBearer();
68 
69         // TODO handle rsub
70         switch (opcode.getOpcode()) {
71             // These have 8 and 16 bit cst representations
72             case RegOps.REM:
73             case RegOps.ADD:
74             case RegOps.MUL:
75             case RegOps.DIV:
76             case RegOps.AND:
77             case RegOps.OR:
78             case RegOps.XOR:
79                 return cst.fitsIn16Bits();
80             // These only have 8 bit cst reps
81             case RegOps.SHL:
82             case RegOps.SHR:
83             case RegOps.USHR:
84                 return cst.fitsIn8Bits();
85             default:
86                 return false;
87         }
88     }
89 
90     /** {@inheritDoc} */
requiresSourcesInOrder(Rop opcode, RegisterSpecList sources)91     public boolean requiresSourcesInOrder(Rop opcode,
92             RegisterSpecList sources) {
93 
94         return !disableSourcesInOrder && opcode.isCallLike()
95                 && totalRopWidth(sources) >= MIN_INVOKE_IN_ORDER;
96     }
97 
98     /**
99      * Calculates the total rop width of the list of SSA registers
100      *
101      * @param sources {@code non-null;} list of SSA registers
102      * @return {@code >= 0;} rop-form width in register units
103      */
totalRopWidth(RegisterSpecList sources)104     private int totalRopWidth(RegisterSpecList sources) {
105         int sz = sources.size();
106         int total = 0;
107 
108         for (int i = 0; i < sz; i++) {
109             total += sources.get(i).getCategory();
110         }
111 
112         return total;
113     }
114 
115     /** {@inheritDoc} */
getMaxOptimalRegisterCount()116     public int getMaxOptimalRegisterCount() {
117         return 16;
118     }
119 }
120