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.rop.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Plain instruction, which has no embedded data and which cannot possibly
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception.
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class PlainInsn
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        extends Insn {
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param opcode {@code non-null;} the opcode
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param position {@code non-null;} source position
3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param result {@code null-ok;} spec for the result, if any
3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param sources {@code non-null;} specs for all the sources
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public PlainInsn(Rop opcode, SourcePosition position,
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     RegisterSpec result, RegisterSpecList sources) {
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(opcode, position, result, sources);
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (opcode.getBranchingness()) {
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Rop.BRANCH_SWITCH:
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case Rop.BRANCH_THROW: {
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("bogus branchingness");
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (result != null && opcode.getBranchingness() != Rop.BRANCH_NONE) {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // move-result-pseudo is required here
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ("can't mix branchingness with result");
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a single-source instance.
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param opcode {@code non-null;} the opcode
6199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param position {@code non-null;} source position
6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param result {@code null-ok;} spec for the result, if any
6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param source {@code non-null;} spec for the source
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public PlainInsn(Rop opcode, SourcePosition position, RegisterSpec result,
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     RegisterSpec source) {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(opcode, position, result, RegisterSpecList.make(source));
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList getCatches() {
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return StdTypeList.EMPTY;
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void accept(Visitor visitor) {
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        visitor.visitPlainInsn(this);
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn withAddedCatch(Type type) {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new UnsupportedOperationException("unsupported");
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn withRegisterOffset(int delta) {
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new PlainInsn(getOpcode(), getPosition(),
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             getResult().withOffset(delta),
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             getSources().withOffset(delta));
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn withLastSourceLiteral() {
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList sources = getSources();
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int szSources = sources.size();
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (szSources == 0) {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return this;
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!lastType.isConstant()) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return this;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Constant cst = (Constant) lastType;
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList newSources = sources.withoutLast();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Rop newRop;
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            newRop = Rops.ropFor(getOpcode().getOpcode(),
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    getResult(), newSources, (Constant)lastType);
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IllegalArgumentException ex) {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // There's no rop for this case
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return this;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new PlainCstInsn(newRop, getPosition(),
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                getResult(), newSources, cst);
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn withNewRegisters(RegisterSpec result,
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpecList sources) {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new PlainInsn(getOpcode(), getPosition(),
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             result,
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             sources);
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
141