blob: d700e4843fe70237892cfed9a0d83d66f4b0ab4b [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
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080025namespace art {
26
buzbeeed3e9302011-09-23 17:34:19 -070027STATIC ArmLIR* genUnconditionalBranch(CompilationUnit*, ArmLIR*);
28STATIC ArmLIR* genConditionalBranch(CompilationUnit*, ArmConditionCode,
buzbee5ade1d22011-09-09 14:44:52 -070029 ArmLIR*);
30
buzbee67bf8852011-08-17 17:51:35 -070031/*
buzbeedfd3d702011-08-28 12:56:51 -070032 * Utiltiy to load the current Method*. Broken out
33 * to allow easy change between placing the current Method* in a
34 * dedicated register or its home location in the frame.
35 */
buzbeeed3e9302011-09-23 17:34:19 -070036STATIC void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
buzbeedfd3d702011-08-28 12:56:51 -070037{
38#if defined(METHOD_IN_REG)
39 genRegCopy(cUnit, rTgt, rMETHOD);
40#else
41 loadWordDisp(cUnit, rSP, 0, rTgt);
42#endif
43}
44
buzbeeed3e9302011-09-23 17:34:19 -070045STATIC int loadCurrMethod(CompilationUnit *cUnit)
buzbee1b4c8592011-08-31 10:43:51 -070046{
47#if defined(METHOD_IN_REG)
48 return rMETHOD;
49#else
50 int mReg = oatAllocTemp(cUnit);
51 loadCurrMethodDirect(cUnit, mReg);
52 return mReg;
53#endif
54}
55
buzbee58f92742011-10-01 11:22:17 -070056STATIC ArmLIR* genCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
57 MIR* mir, ArmThrowKind kind)
58{
buzbeeba938cb2012-02-03 14:47:55 -080059 ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
buzbee58f92742011-10-01 11:22:17 -070060 tgt->opcode = kArmPseudoThrowTarget;
61 tgt->operands[0] = kind;
62 tgt->operands[1] = mir ? mir->offset : 0;
63 ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
64 // Remember branch target - will process later
buzbeeba938cb2012-02-03 14:47:55 -080065 oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
buzbee58f92742011-10-01 11:22:17 -070066 return branch;
67}
68
buzbeeed3e9302011-09-23 17:34:19 -070069STATIC ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
buzbee5ade1d22011-09-09 14:44:52 -070070 int reg, int immVal, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -070071{
buzbeeba938cb2012-02-03 14:47:55 -080072 ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
buzbee5ade1d22011-09-09 14:44:52 -070073 tgt->opcode = kArmPseudoThrowTarget;
74 tgt->operands[0] = kind;
75 tgt->operands[1] = mir->offset;
76 ArmLIR* branch;
77 if (cCode == kArmCondAl) {
78 branch = genUnconditionalBranch(cUnit, tgt);
buzbee67bf8852011-08-17 17:51:35 -070079 } else {
buzbeeec5adf32011-09-11 15:25:43 -070080 branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
buzbee5ade1d22011-09-09 14:44:52 -070081 branch->generic.target = (LIR*)tgt;
buzbee67bf8852011-08-17 17:51:35 -070082 }
buzbee5ade1d22011-09-09 14:44:52 -070083 // Remember branch target - will process later
buzbeeba938cb2012-02-03 14:47:55 -080084 oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
buzbee5ade1d22011-09-09 14:44:52 -070085 return branch;
buzbee67bf8852011-08-17 17:51:35 -070086}
87
buzbee43a36422011-09-14 14:00:13 -070088/* Perform null-check on a register. */
buzbeeed3e9302011-09-23 17:34:19 -070089STATIC ArmLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
buzbee5ade1d22011-09-09 14:44:52 -070090 MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -070091{
buzbee43a36422011-09-14 14:00:13 -070092 if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
93 mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
buzbee5ade1d22011-09-09 14:44:52 -070094 return NULL;
buzbee67bf8852011-08-17 17:51:35 -070095 }
buzbee5ade1d22011-09-09 14:44:52 -070096 return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
buzbee67bf8852011-08-17 17:51:35 -070097}
98
buzbeeec5adf32011-09-11 15:25:43 -070099/* Perform check on two registers */
buzbeeed3e9302011-09-23 17:34:19 -0700100STATIC TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
buzbeeec5adf32011-09-11 15:25:43 -0700101 int reg1, int reg2, MIR* mir, ArmThrowKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700102{
buzbeeba938cb2012-02-03 14:47:55 -0800103 ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
buzbee5ade1d22011-09-09 14:44:52 -0700104 tgt->opcode = kArmPseudoThrowTarget;
105 tgt->operands[0] = kind;
buzbeeec5adf32011-09-11 15:25:43 -0700106 tgt->operands[1] = mir ? mir->offset : 0;
107 tgt->operands[2] = reg1;
108 tgt->operands[3] = reg2;
109 opRegReg(cUnit, kOpCmp, reg1, reg2);
110 ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
buzbee5ade1d22011-09-09 14:44:52 -0700111 // Remember branch target - will process later
buzbeeba938cb2012-02-03 14:47:55 -0800112 oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
buzbee5ade1d22011-09-09 14:44:52 -0700113 return branch;
buzbee67bf8852011-08-17 17:51:35 -0700114}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800115
116} // namespace art