blob: a68727fc34c9a8437e50b31099a5041af3aa5619 [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
buzbeeed3e9302011-09-23 17:34:19 -070025STATIC ArmLIR* genUnconditionalBranch(CompilationUnit*, ArmLIR*);
26STATIC ArmLIR* genConditionalBranch(CompilationUnit*, ArmConditionCode,
buzbee5ade1d22011-09-09 14:44:52 -070027 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 */
buzbeeed3e9302011-09-23 17:34:19 -070034STATIC void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
buzbeedfd3d702011-08-28 12:56:51 -070035{
36#if defined(METHOD_IN_REG)
37 genRegCopy(cUnit, rTgt, rMETHOD);
38#else
39 loadWordDisp(cUnit, rSP, 0, rTgt);
40#endif
41}
42
buzbeeed3e9302011-09-23 17:34:19 -070043STATIC int loadCurrMethod(CompilationUnit *cUnit)
buzbee1b4c8592011-08-31 10:43:51 -070044{
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
buzbee58f92742011-10-01 11:22:17 -070054STATIC ArmLIR* genCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
55 MIR* mir, ArmThrowKind kind)
56{
57 ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
58 tgt->opcode = kArmPseudoThrowTarget;
59 tgt->operands[0] = kind;
60 tgt->operands[1] = mir ? mir->offset : 0;
61 ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
62 // Remember branch target - will process later
63 oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
64 return branch;
65}
66
buzbeeed3e9302011-09-23 17:34:19 -070067STATIC ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
buzbee5ade1d22011-09-09 14:44:52 -070068 int reg, int immVal, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -070069{
buzbee5ade1d22011-09-09 14:44:52 -070070 ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
71 tgt->opcode = kArmPseudoThrowTarget;
72 tgt->operands[0] = kind;
73 tgt->operands[1] = mir->offset;
74 ArmLIR* branch;
75 if (cCode == kArmCondAl) {
76 branch = genUnconditionalBranch(cUnit, tgt);
buzbee67bf8852011-08-17 17:51:35 -070077 } else {
buzbeeec5adf32011-09-11 15:25:43 -070078 branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
buzbee5ade1d22011-09-09 14:44:52 -070079 branch->generic.target = (LIR*)tgt;
buzbee67bf8852011-08-17 17:51:35 -070080 }
buzbee5ade1d22011-09-09 14:44:52 -070081 // Remember branch target - will process later
82 oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
83 return branch;
buzbee67bf8852011-08-17 17:51:35 -070084}
85
buzbee43a36422011-09-14 14:00:13 -070086/* Perform null-check on a register. */
buzbeeed3e9302011-09-23 17:34:19 -070087STATIC ArmLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
buzbee5ade1d22011-09-09 14:44:52 -070088 MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -070089{
buzbee43a36422011-09-14 14:00:13 -070090 if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
91 mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
buzbee5ade1d22011-09-09 14:44:52 -070092 return NULL;
buzbee67bf8852011-08-17 17:51:35 -070093 }
buzbee5ade1d22011-09-09 14:44:52 -070094 return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
buzbee67bf8852011-08-17 17:51:35 -070095}
96
buzbeeec5adf32011-09-11 15:25:43 -070097/* Perform check on two registers */
buzbeeed3e9302011-09-23 17:34:19 -070098STATIC TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
buzbeeec5adf32011-09-11 15:25:43 -070099 int reg1, int reg2, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700100{
buzbee5ade1d22011-09-09 14:44:52 -0700101 ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
102 tgt->opcode = kArmPseudoThrowTarget;
103 tgt->operands[0] = kind;
buzbeeec5adf32011-09-11 15:25:43 -0700104 tgt->operands[1] = mir ? mir->offset : 0;
105 tgt->operands[2] = reg1;
106 tgt->operands[3] = reg2;
107 opRegReg(cUnit, kOpCmp, reg1, reg2);
108 ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
buzbee5ade1d22011-09-09 14:44:52 -0700109 // Remember branch target - will process later
110 oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
111 return branch;
buzbee67bf8852011-08-17 17:51:35 -0700112}