1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.FillArrayDataInsn;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Insn;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.PlainCstInsn;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.PlainInsn;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegOps;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpec;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpecList;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Rop;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Rops;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.SourcePosition;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.SwitchInsn;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.ThrowingCstInsn;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.ThrowingInsn;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.TranslationAdvice;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstFieldRef;
354596322b12a72cdeea8deba1242d9b74da5ba12ajeffhaoimport com.android.dx.rop.cst.CstInteger;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstNat;
38333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Machine implementation for use by {@link Ropper}.
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*package*/ final class RopperMachine extends ValueAwareMachine {
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} array reflection class */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final CstType ARRAY_REFLECT_TYPE =
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        new CstType(Type.internClassName("java/lang/reflect/Array"));
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} method constant for use in converting
56de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * {@code multianewarray} instructions
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final CstMethodRef MULTIANEWARRAY_METHOD =
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        new CstMethodRef(ARRAY_REFLECT_TYPE,
60333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson                         new CstNat(new CstString("newInstance"),
61333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson                                    new CstString("(Ljava/lang/Class;[I)" +
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                "Ljava/lang/Object;")));
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} {@link Ropper} controlling this instance */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final Ropper ropper;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} method being converted */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ConcreteMethod method;
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} translation advice */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final TranslationAdvice advice;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** max locals of the method */
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int maxLocals;
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} instructions for the rop basic block in-progress */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<Insn> insns;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} catches for the block currently being processed */
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeList catches;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** whether the catches have been used in an instruction */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean catchesUsed;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** whether the block contains a {@code return} */
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean returns;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** primary successor index */
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int primarySuccessorIndex;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= 0;} number of extra basic blocks required */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int extraBlockCount;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** true if last processed block ends with a jsr or jsr_W*/
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean hasJsr;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** true if an exception can be thrown by the last block processed */
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean blockCanThrow;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If non-null, the ReturnAddress that was used by the terminating ret
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instruction. If null, there was no ret instruction encountered.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ReturnAddress returnAddress;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the appropriate {@code return} op or {@code null}
109de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * if it is not yet known
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Rop returnOp;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the source position for the return block or {@code null}
115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * if it is not yet known
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private SourcePosition returnPosition;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
121de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param ropper {@code non-null;} ropper controlling this instance
12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} method being converted
12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param advice {@code non-null;} translation advice to use
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RopperMachine(Ropper ropper, ConcreteMethod method,
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            TranslationAdvice advice) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(method.getEffectiveDescriptor());
129de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ropper == null) {
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("ropper == null");
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (advice == null) {
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("advice == null");
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.ropper = ropper;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.method = method;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.advice = advice;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.maxLocals = method.getMaxLocals();
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.insns = new ArrayList<Insn>(25);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catches = null;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catchesUsed = false;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returns = false;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.primarySuccessorIndex = -1;
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.extraBlockCount = 0;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.blockCanThrow = false;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returnOp = null;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returnPosition = null;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the instructions array. It is shared and gets modified by
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subsequent calls to this instance.
156de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the instructions array
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ArrayList<Insn> getInsns() {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insns;
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the return opcode encountered, if any.
165de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the return opcode
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Rop getReturnOp() {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnOp;
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the return position, if known.
174de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
17599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the return position
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public SourcePosition getReturnPosition() {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnPosition;
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets ready to start working on a new block. This will clear the
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link #insns} list, set {@link #catches}, reset whether it has
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * been used, reset whether the block contains a
18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code return}, and reset {@link #primarySuccessorIndex}.
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void startBlock(TypeList catches) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catches = catches;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insns.clear();
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchesUsed = false;
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        returns = false;
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        primarySuccessorIndex = 0;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        extraBlockCount = 0;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        blockCanThrow = false;
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hasJsr = false;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        returnAddress = null;
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets whether {@link #catches} was used. This indicates that the
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * last instruction in the block is one of the ones that can throw.
203de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return whether {@code catches} has been used
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean wereCatchesUsed() {
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return catchesUsed;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets whether the block just processed ended with a
21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code return}.
213de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return whether the block returns
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean returns() {
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returns;
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the primary successor index. This is the index into the
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successors list where the primary may be found or
22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code -1} if there are successors but no primary
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successor. This may return something other than
22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code -1} in the case of an instruction with no
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successors at all (primary or otherwise).
227de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= -1;} the primary successor index
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getPrimarySuccessorIndex() {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return primarySuccessorIndex;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets how many extra blocks will be needed to represent the
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * block currently being translated. Each extra block should consist
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of one instruction from the end of the original block.
238de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
23999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the number of extra blocks needed
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getExtraBlockCount() {
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return extraBlockCount;
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if at least one of the insn processed since the last
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call to startBlock() can throw.
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean canThrow() {
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return blockCanThrow;
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if a JSR has ben encountered since the last call to
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * startBlock()
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean hasJsr() {
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return hasJsr;
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
262d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * @return {@code true} if a {@code ret} has ben encountered since
263d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * the last call to {@code startBlock()}
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean hasRet() {
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnAddress != null;
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
270d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * @return {@code null-ok;} return address of a {@code ret}
271d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * instruction if encountered since last call to startBlock().
272d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * {@code null} if no ret instruction encountered.
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ReturnAddress getReturnAddress() {
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnAddress;
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void run(Frame frame, int offset, int opcode) {
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * This is the stack pointer after the opcode's arguments have been
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * popped.
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackPointer = maxLocals + frame.getStack().size();
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The sources have to be retrieved before super.run() gets called.
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList sources = getSources(opcode, stackPointer);
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sourceCount = sources.size();
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.run(frame, offset, opcode);
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SourcePosition pos = method.makeSourcePosistion(offset);
2943d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein        RegisterSpec localTarget = getLocalTarget(opcode == ByteOps.ISTORE);
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int destCount = resultCount();
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpec dest;
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (destCount == 0) {
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (opcode) {
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.POP:
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.POP2: {
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // These simply don't appear in the rop form.
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return;
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (localTarget != null) {
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = localTarget;
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (destCount == 1) {
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = RegisterSpec.make(stackPointer, result(0));
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * This clause only ever applies to the stack manipulation
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * ops that have results (that is, dup* and swap but not
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * pop*).
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * What we do is first move all the source registers into
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * the "temporary stack" area defined for the method, and
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * then move stuff back down onto the main "stack" in the
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * arrangement specified by the stack op pattern.
321de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro             *
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Note: This code ends up emitting a lot of what will
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * turn out to be superfluous moves (e.g., moving back and
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * forth to the same local when doing a dup); however,
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * that makes this code a bit easier (and goodness knows
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it doesn't need any extra complexity), and all the SSA
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * stuff is going to want to deal with this sort of
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * superfluous assignment anyway, so it should be a wash
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * in the end.
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int scratchAt = ropper.getFirstTempStackReg();
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount];
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < sourceCount; i++) {
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec src = sources.get(i);
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = src.getTypeBearer();
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec scratch = src.withReg(scratchAt);
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insns.add(new PlainInsn(Rops.opMove(type), pos, scratch, src));
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                scratchRegs[i] = scratch;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                scratchAt += src.getCategory();
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int which = (pattern & 0x0f) - 1;
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec scratch = scratchRegs[which];
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = scratch.getTypeBearer();
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insns.add(new PlainInsn(Rops.opMove(type), pos,
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        scratch.withReg(stackPointer),
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        scratch));
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                stackPointer += type.getType().getCategory();
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
353de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        }
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TypeBearer destType = (dest != null) ? dest : Type.VOID;
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Constant cst = getAuxCst();
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int ropOpcode;
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Rop rop;
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Insn insn;
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opcode == ByteOps.MULTIANEWARRAY) {
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            blockCanThrow = true;
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add the extra instructions for handling multianewarray.
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount = 6;
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add an array constructor for the int[] containing all the
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * dimensions.
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
372de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro            RegisterSpec dimsReg =
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY);
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount);
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingCstInsn(rop, pos, sources, catches,
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    CstType.INT_ARRAY);
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add a move-result for the new-filled-array
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResult(Type.INT_ARRAY);
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY);
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add a const-class instruction for the specified array
386de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro             * class.
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Remove as many dimensions from the originally specified
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * class as are given in the explicit list of dimensions,
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * so as to pass the right component class to the standard
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Java library array constructor.
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Type componentType = ((CstType) cst).getClassType();
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < sourceCount; i++) {
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                componentType = componentType.getComponentType();
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec classReg =
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getReg(), Type.CLASS);
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (componentType.isPrimitive()) {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The component type is primitive (e.g., int as opposed
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * to Integer), so we have to fetch the corresponding
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * TYPE class.
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstFieldRef typeField =
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    CstFieldRef.forPrimitiveType(componentType);
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos,
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           RegisterSpecList.EMPTY,
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           catches, typeField);
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The component type is an object type, so just make a
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * normal class reference.
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos,
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           RegisterSpecList.EMPTY, catches,
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           new CstType(componentType));
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add a move-result-pseudo for the get-static or const
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResultPseudo(classReg.getType());
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY);
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add a call to the "multianewarray method," that is,
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Array.newInstance(class, dims). Note: The result type
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * of newInstance() is Object, which is why the last
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * instruction in this sequence is a cast to the right
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * type for the original instruction.
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec objectReg =
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getReg(), Type.OBJECT);
441de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingCstInsn(
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()),
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pos, RegisterSpecList.make(classReg, dimsReg),
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    catches, MULTIANEWARRAY_METHOD);
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
448d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein            // Add a move-result.
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype()
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .getReturnType());
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY);
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * And finally, set up for the remainder of this method to
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * add an appropriate cast.
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            opcode = ByteOps.CHECKCAST;
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = RegisterSpecList.make(objectReg);
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (opcode == ByteOps.JSR) {
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // JSR has no Rop instruction
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hasJsr = true;
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (opcode == ByteOps.RET) {
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                returnAddress = (ReturnAddress)arg(0);
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch (ClassCastException ex) {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new RuntimeException(
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "Argument to RET was not a ReturnAddress", ex);
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // RET has no Rop instruction.
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ropOpcode = jopToRopOpcode(opcode, cst);
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        rop = Rops.ropFor(ropOpcode, destType, sources, cst);
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Insn moveResult = null;
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dest != null && rop.isCallLike()) {
481d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein            /*
482d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             * We're going to want to have a move-result in the next
483d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             * basic block.
484d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             */
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            moveResult = new PlainInsn(
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opMoveResult(((CstMethodRef) cst).getPrototype()
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .getReturnType()), pos, dest, RegisterSpecList.EMPTY);
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (dest != null && rop.canThrow()) {
493d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein            /*
494d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             * We're going to want to have a move-result-pseudo in the
495d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             * next basic block.
496d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein             */
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            moveResult = new PlainInsn(
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opMoveResultPseudo(dest.getTypeBearer()),
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pos, dest, RegisterSpecList.EMPTY);
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ropOpcode == RegOps.NEW_ARRAY) {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * In the original bytecode, this was either a primitive
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * array constructor "newarray" or an object array
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * constructor "anewarray". In the former case, there is
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * no explicit constant, and in the latter, the constant
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * is for the element type and not the array type. The rop
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * instruction form for both of these is supposed to be
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * the resulting array type, so we initialize / alter
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * "cst" here, accordingly. Conveniently enough, the rop
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * opcode already gets constructed with the proper array
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * type.
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cst = CstType.intern(rop.getResult());
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if ((cst == null) && (sourceCount == 2)) {
5204596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao            TypeBearer firstType = sources.get(0).getTypeBearer();
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            TypeBearer lastType = sources.get(1).getTypeBearer();
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5234596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao            if ((lastType.isConstant() || firstType.isConstant()) &&
5244596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                 advice.hasConstantOperation(rop, sources.get(0),
5254596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                                             sources.get(1))) {
5264596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao
5274596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                if (lastType.isConstant()) {
5284596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    /*
5294596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * The target architecture has an instruction that can
5304596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * build in the constant found in the second argument,
5314596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * so pull it out of the sources and just use it as a
5324596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * constant here.
5334596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     */
5344596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    cst = (Constant) lastType;
5354596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    sources = sources.withoutLast();
5364596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao
5374596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    // For subtraction, change to addition and invert constant
5384596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    if (rop.getOpcode() == RegOps.SUB) {
5394596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                        ropOpcode = RegOps.ADD;
5404596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                        CstInteger cstInt = (CstInteger) lastType;
5414596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                        cst = CstInteger.make(-cstInt.getValue());
5424596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    }
5434596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                } else {
5444596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    /*
5454596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * The target architecture has an instruction that can
5464596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * build in the constant found in the first argument,
5474596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * so pull it out of the sources and just use it as a
5484596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     * constant here.
5494596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                     */
5504596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    cst = (Constant) firstType;
5514596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                    sources = sources.withoutFirst();
5524596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao                }
5534596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rop = Rops.ropFor(ropOpcode, destType, sources, cst);
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SwitchList cases = getAuxCases();
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayList<Constant> initValues = getInitValues();
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean canThrow = rop.canThrow();
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        blockCanThrow |= canThrow;
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cases != null) {
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cases.size() == 0) {
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // It's a default-only switch statement. It can happen!
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new PlainInsn(Rops.GOTO, pos, null,
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     RegisterSpecList.EMPTY);
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = 0;
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                IntList values = cases.getValues();
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new SwitchInsn(rop, pos, dest, sources, values);
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = values.size();
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (ropOpcode == RegOps.RETURN) {
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Returns get turned into the combination of a move (if
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * non-void and if the return doesn't already mention
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * register 0) and a goto (to the return block).
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (sources.size() != 0) {
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec source = sources.get(0);
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = source.getTypeBearer();
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (source.getReg() != 0) {
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    insns.add(new PlainInsn(Rops.opMove(type), pos,
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            RegisterSpec.make(0, type),
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            source));
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY);
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            primarySuccessorIndex = 0;
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            updateReturnOp(rop, pos);
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returns = true;
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (cst != null) {
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (canThrow) {
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn =
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    new ThrowingCstInsn(rop, pos, sources, catches, cst);
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                catchesUsed = true;
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = catches.size();
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new PlainCstInsn(rop, pos, dest, sources, cst);
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (canThrow) {
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingInsn(rop, pos, sources, catches);
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchesUsed = true;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (opcode == ByteOps.ATHROW) {
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The op athrow is the only one where it's possible
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * to have non-empty successors and yet not have a
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * primary successor.
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = -1;
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = catches.size();
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, dest, sources);
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insns.add(insn);
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (moveResult != null) {
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(moveResult);
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
627d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * If initValues is non-null, it means that the parser has
628d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * seen a group of compatible constant initialization
629d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * bytecodes that are applied to the current newarray. The
630d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * action we take here is to convert these initialization
631d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * bytecodes into a single fill-array-data ROP which lays out
632d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein         * all the constant values in a table.
633de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         */
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (initValues != null) {
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new FillArrayDataInsn(Rops.FILL_ARRAY_DATA, pos,
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpecList.make(moveResult.getResult()), initValues,
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    cst);
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper for {@link #run}, which gets the list of sources for the.
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instruction.
646de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opcode the opcode being translated
648d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * @param stackPointer {@code >= 0;} the stack pointer after the
649d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein     * instruction's arguments have been popped
65099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the sources
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private RegisterSpecList getSources(int opcode, int stackPointer) {
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = argCount();
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (count == 0) {
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // We get an easy out if there aren't any sources.
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return RegisterSpecList.EMPTY;
658de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        }
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int localIndex = getLocalIndex();
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList sources;
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (localIndex >= 0) {
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // The instruction is operating on a local variable.
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = new RegisterSpecList(1);
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources.set(0, RegisterSpec.make(localIndex, arg(0)));
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = new RegisterSpecList(count);
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int regAt = stackPointer;
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < count; i++) {
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec spec = RegisterSpec.make(regAt, arg(i));
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sources.set(i, spec);
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                regAt += spec.getCategory();
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (opcode) {
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.IASTORE: {
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * The Java argument order for array stores is
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * (array, index, value), but the rop argument
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * order is (value, array, index). The following
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * code gets the right arguments in the right
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * places.
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (count != 3) {
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new RuntimeException("shouldn't happen");
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec array = sources.get(0);
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec index = sources.get(1);
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec value = sources.get(2);
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(0, value);
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(1, array);
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(2, index);
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.PUTFIELD: {
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * Similar to above: The Java argument order for
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * putfield is (object, value), but the rop
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * argument order is (value, object).
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (count != 2) {
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new RuntimeException("shouldn't happen");
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec obj = sources.get(0);
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec value = sources.get(1);
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(0, value);
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(1, obj);
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources.setImmutable();
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sources;
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets or updates the information about the return block.
720de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
72199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param op {@code non-null;} the opcode to use
72299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param pos {@code non-null;} the position to use
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void updateReturnOp(Rop op, SourcePosition pos) {
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (op == null) {
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("op == null");
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pos == null) {
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("pos == null");
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (returnOp == null) {
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returnOp = op;
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returnPosition = pos;
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (returnOp != op) {
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new SimException("return op mismatch: " + op + ", " +
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                       returnOp);
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (pos.getLine() > returnPosition.getLine()) {
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Pick the largest line number to be the "canonical" return.
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                returnPosition = pos;
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register opcode for the given Java opcode.
751de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
75299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param jop {@code >= 0;} the Java opcode
75399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param cst {@code null-ok;} the constant argument, if any
75499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the corresponding register opcode
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int jopToRopOpcode(int jop, Constant cst) {
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (jop) {
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.POP:
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.POP2:
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP:
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP_X1:
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP_X2:
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2:
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2_X1:
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2_X2:
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.SWAP:
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.JSR:
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.RET:
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MULTIANEWARRAY: {
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // These need to be taken care of specially.
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NOP: {
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NOP;
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LDC:
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LDC2_W: {
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CONST;
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
780de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro            case ByteOps.ILOAD:
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISTORE: {
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MOVE;
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IALOAD: {
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.AGET;
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IASTORE: {
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.APUT;
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IADD:
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IINC: {
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.ADD;
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISUB: {
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SUB;
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IMUL: {
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MUL;
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IDIV: {
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.DIV;
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IREM: {
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.REM;
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INEG: {
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEG;
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISHL: {
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SHL;
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISHR: {
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SHR;
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IUSHR: {
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.USHR;
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IAND: {
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.AND;
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IOR: {
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.OR;
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IXOR: {
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.XOR;
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2L:
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2F:
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2D:
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2I:
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2F:
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2D:
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2I:
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2L:
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2D:
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2I:
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2L:
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2F: {
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CONV;
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2B: {
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_BYTE;
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2C: {
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_CHAR;
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2S: {
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_SHORT;
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LCMP:
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.FCMPL:
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DCMPL: {
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CMPL;
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.FCMPG:
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DCMPG: {
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CMPG;
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFEQ:
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPEQ:
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ACMPEQ:
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNULL: {
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_EQ;
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNE:
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPNE:
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ACMPNE:
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNONNULL: {
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_NE;
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFLT:
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPLT: {
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_LT;
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFGE:
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPGE: {
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_GE;
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFGT:
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPGT: {
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_GT;
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFLE:
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPLE: {
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_LE;
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GOTO: {
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GOTO;
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LOOKUPSWITCH: {
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SWITCH;
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IRETURN:
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.RETURN: {
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.RETURN;
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GETSTATIC: {
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GET_STATIC;
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.PUTSTATIC: {
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.PUT_STATIC;
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GETFIELD: {
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GET_FIELD;
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.PUTFIELD: {
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.PUT_FIELD;
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKEVIRTUAL: {
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_VIRTUAL;
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKESPECIAL: {
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Determine whether the opcode should be
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * INVOKE_DIRECT or INVOKE_SUPER. See vmspec-2 section 6
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * on "invokespecial" as well as section 4.8.2 (7th
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * bullet point) for the gory details.
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstMethodRef ref = (CstMethodRef) cst;
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ref.isInstanceInit() ||
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    (ref.getDefiningClass() == method.getDefiningClass()) ||
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    !method.getAccSuper()) {
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return RegOps.INVOKE_DIRECT;
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_SUPER;
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKESTATIC: {
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_STATIC;
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKEINTERFACE: {
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_INTERFACE;
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NEW: {
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEW_INSTANCE;
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NEWARRAY:
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ANEWARRAY: {
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEW_ARRAY;
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ARRAYLENGTH: {
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.ARRAY_LENGTH;
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ATHROW: {
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.THROW;
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.CHECKCAST: {
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CHECK_CAST;
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INSTANCEOF: {
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INSTANCE_OF;
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MONITORENTER: {
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MONITOR_ENTER;
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MONITOREXIT: {
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MONITOR_EXIT;
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new RuntimeException("shouldn't happen");
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
963