blob: 34a333d3a9cabb90339c813a4255dab5a80fc5e6 [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/*
18 * This file contains arm-specific codegen factory support.
19 * It is included by
20 *
21 * Codegen-$(TARGET_ARCH_VARIANT).c
22 *
23 */
24
buzbee5ade1d22011-09-09 14:44:52 -070025static ArmLIR* genUnconditionalBranch(CompilationUnit*, ArmLIR*);
26static ArmLIR* genConditionalBranch(CompilationUnit*, ArmConditionCode,
27 ArmLIR*);
28
buzbee67bf8852011-08-17 17:51:35 -070029/*
buzbeedfd3d702011-08-28 12:56:51 -070030 * Utiltiy to load the current Method*. Broken out
31 * to allow easy change between placing the current Method* in a
32 * dedicated register or its home location in the frame.
33 */
34static void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
35{
36#if defined(METHOD_IN_REG)
37 genRegCopy(cUnit, rTgt, rMETHOD);
38#else
39 loadWordDisp(cUnit, rSP, 0, rTgt);
40#endif
41}
42
buzbee1b4c8592011-08-31 10:43:51 -070043static int loadCurrMethod(CompilationUnit *cUnit)
44{
45#if defined(METHOD_IN_REG)
46 return rMETHOD;
47#else
48 int mReg = oatAllocTemp(cUnit);
49 loadCurrMethodDirect(cUnit, mReg);
50 return mReg;
51#endif
52}
53
buzbee5ade1d22011-09-09 14:44:52 -070054static ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
55 int reg, int immVal, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -070056{
buzbee5ade1d22011-09-09 14:44:52 -070057 ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
58 tgt->opcode = kArmPseudoThrowTarget;
59 tgt->operands[0] = kind;
60 tgt->operands[1] = mir->offset;
61 ArmLIR* branch;
62 if (cCode == kArmCondAl) {
63 branch = genUnconditionalBranch(cUnit, tgt);
buzbee67bf8852011-08-17 17:51:35 -070064 } else {
buzbeeec5adf32011-09-11 15:25:43 -070065 branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
buzbee5ade1d22011-09-09 14:44:52 -070066 branch->generic.target = (LIR*)tgt;
buzbee67bf8852011-08-17 17:51:35 -070067 }
buzbee5ade1d22011-09-09 14:44:52 -070068 // Remember branch target - will process later
69 oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
70 return branch;
buzbee67bf8852011-08-17 17:51:35 -070071}
72
73/*
74 * Perform null-check on a register. sReg is the ssa register being checked,
75 * and mReg is the machine register holding the actual value. If internal state
76 * indicates that sReg has been checked before the check request is ignored.
77 */
buzbee5ade1d22011-09-09 14:44:52 -070078static ArmLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
79 MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -070080{
buzbee67bf8852011-08-17 17:51:35 -070081 if (oatIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
buzbee5ade1d22011-09-09 14:44:52 -070082 /* This particular Dalvik register has been null-checked */
83 return NULL;
buzbee67bf8852011-08-17 17:51:35 -070084 }
85 oatSetBit(cUnit->regPool->nullCheckedRegs, sReg);
buzbee5ade1d22011-09-09 14:44:52 -070086 return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
buzbee67bf8852011-08-17 17:51:35 -070087}
88
buzbeeec5adf32011-09-11 15:25:43 -070089/* Perform check on two registers */
90static TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
91 int reg1, int reg2, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -070092{
buzbee5ade1d22011-09-09 14:44:52 -070093 ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
94 tgt->opcode = kArmPseudoThrowTarget;
95 tgt->operands[0] = kind;
buzbeeec5adf32011-09-11 15:25:43 -070096 tgt->operands[1] = mir ? mir->offset : 0;
97 tgt->operands[2] = reg1;
98 tgt->operands[3] = reg2;
99 opRegReg(cUnit, kOpCmp, reg1, reg2);
100 ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
buzbee5ade1d22011-09-09 14:44:52 -0700101 // Remember branch target - will process later
102 oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
103 return branch;
buzbee67bf8852011-08-17 17:51:35 -0700104}