blob: 237f5e0469f48e98e0bacb15f877f249e32e7846 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Dalvik.h"
18#include "CompilerInternals.h"
19
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
Ian Rogers680b1bd2012-03-07 20:18:49 -080022static const char* gOpKindNames[kOpInvalid + 1] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070023 "OpMov",
24 "OpMvn",
25 "OpCmp",
26 "OpLsl",
27 "OpLsr",
28 "OpAsr",
29 "OpRor",
30 "OpNot",
31 "OpAnd",
32 "OpOr",
33 "OpXor",
34 "OpNeg",
35 "OpAdd",
36 "OpAdc",
37 "OpSub",
38 "OpSbc",
39 "OpRsub",
40 "OpMul",
41 "OpDiv",
42 "OpRem",
43 "OpBic",
44 "OpCmn",
45 "OpTst",
46 "OpBkpt",
47 "OpBlx",
48 "OpPush",
49 "OpPop",
50 "Op2Char",
51 "Op2Short",
52 "Op2Byte",
53 "OpCondBr",
54 "OpUncondBr",
55 "OpBx",
56 "OpInvalid",
Ian Rogers680b1bd2012-03-07 20:18:49 -080057};
58
59std::ostream& operator<<(std::ostream& os, const OpKind& kind) {
60 if (kind >= kOpMov && kind <= kOpInvalid) {
61 os << gOpKindNames[kind];
62 } else {
63 os << "Unknown Op " << static_cast<int>(kind);
64 }
65 return os;
66}
67
buzbee67bf8852011-08-17 17:51:35 -070068/* Allocate a new basic block */
buzbee5abfa3e2012-01-31 17:01:43 -080069BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId)
buzbee67bf8852011-08-17 17:51:35 -070070{
Bill Buzbeea114add2012-05-03 15:00:40 -070071 BasicBlock* bb = (BasicBlock* )oatNew(cUnit, sizeof(BasicBlock), true,
72 kAllocBB);
73 bb->blockType = blockType;
74 bb->id = blockId;
75 bb->predecessors = (GrowableList*) oatNew(cUnit, sizeof(GrowableList),
76 false, kAllocPredecessors);
77 oatInitGrowableList(cUnit, bb->predecessors,
78 (blockType == kExitBlock) ? 2048 : 2,
79 kListPredecessors);
80 return bb;
buzbee67bf8852011-08-17 17:51:35 -070081}
82
83/* Insert an MIR instruction to the end of a basic block */
84void oatAppendMIR(BasicBlock* bb, MIR* mir)
85{
Bill Buzbeea114add2012-05-03 15:00:40 -070086 if (bb->firstMIRInsn == NULL) {
87 DCHECK(bb->lastMIRInsn == NULL);
88 bb->lastMIRInsn = bb->firstMIRInsn = mir;
89 mir->prev = mir->next = NULL;
90 } else {
91 bb->lastMIRInsn->next = mir;
92 mir->prev = bb->lastMIRInsn;
93 mir->next = NULL;
94 bb->lastMIRInsn = mir;
95 }
buzbee67bf8852011-08-17 17:51:35 -070096}
97
98/* Insert an MIR instruction to the head of a basic block */
99void oatPrependMIR(BasicBlock* bb, MIR* mir)
100{
Bill Buzbeea114add2012-05-03 15:00:40 -0700101 if (bb->firstMIRInsn == NULL) {
102 DCHECK(bb->lastMIRInsn == NULL);
103 bb->lastMIRInsn = bb->firstMIRInsn = mir;
104 mir->prev = mir->next = NULL;
105 } else {
106 bb->firstMIRInsn->prev = mir;
107 mir->next = bb->firstMIRInsn;
108 mir->prev = NULL;
109 bb->firstMIRInsn = mir;
110 }
buzbee67bf8852011-08-17 17:51:35 -0700111}
112
buzbeee1965672012-03-11 18:39:19 -0700113/* Insert a MIR instruction after the specified MIR */
buzbee67bf8852011-08-17 17:51:35 -0700114void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR)
115{
Bill Buzbeea114add2012-05-03 15:00:40 -0700116 newMIR->prev = currentMIR;
117 newMIR->next = currentMIR->next;
118 currentMIR->next = newMIR;
buzbee67bf8852011-08-17 17:51:35 -0700119
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 if (newMIR->next) {
121 /* Is not the last MIR in the block */
122 newMIR->next->prev = newMIR;
123 } else {
124 /* Is the last MIR in the block */
125 bb->lastMIRInsn = newMIR;
126 }
buzbee67bf8852011-08-17 17:51:35 -0700127}
128
129/*
130 * Append an LIR instruction to the LIR list maintained by a compilation
131 * unit
132 */
133void oatAppendLIR(CompilationUnit *cUnit, LIR* lir)
134{
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 if (cUnit->firstLIRInsn == NULL) {
136 DCHECK(cUnit->lastLIRInsn == NULL);
137 cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir;
138 lir->prev = lir->next = NULL;
139 } else {
140 cUnit->lastLIRInsn->next = lir;
141 lir->prev = cUnit->lastLIRInsn;
142 lir->next = NULL;
143 cUnit->lastLIRInsn = lir;
144 }
buzbee67bf8852011-08-17 17:51:35 -0700145}
146
147/*
148 * Insert an LIR instruction before the current instruction, which cannot be the
149 * first instruction.
150 *
151 * prevLIR <-> newLIR <-> currentLIR
152 */
153void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR)
154{
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 DCHECK(currentLIR->prev != NULL);
156 LIR *prevLIR = currentLIR->prev;
buzbee67bf8852011-08-17 17:51:35 -0700157
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 prevLIR->next = newLIR;
159 newLIR->prev = prevLIR;
160 newLIR->next = currentLIR;
161 currentLIR->prev = newLIR;
buzbee67bf8852011-08-17 17:51:35 -0700162}
163
164/*
165 * Insert an LIR instruction after the current instruction, which cannot be the
166 * first instruction.
167 *
168 * currentLIR -> newLIR -> oldNext
169 */
170void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR)
171{
Bill Buzbeea114add2012-05-03 15:00:40 -0700172 newLIR->prev = currentLIR;
173 newLIR->next = currentLIR->next;
174 currentLIR->next = newLIR;
175 newLIR->next->prev = newLIR;
buzbee67bf8852011-08-17 17:51:35 -0700176}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800177
178} // namespace art