buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 1 | /* |
| 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 | #ifndef ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_ |
| 18 | #define ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_ |
| 19 | |
Brian Carlstrom | 641ce03 | 2013-01-31 15:21:37 -0800 | [diff] [blame] | 20 | #include "compiler/compiler_internals.h" |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 21 | |
| 22 | namespace art { |
| 23 | |
| 24 | class ArmCodegen : public Codegen { |
| 25 | public: |
| 26 | // Required for target - codegen helpers. |
| 27 | virtual bool SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode, |
| 28 | RegLocation rl_src, RegLocation rl_dest, int lit); |
| 29 | virtual int LoadHelper(CompilationUnit* cu, int offset); |
| 30 | virtual LIR* LoadBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_dest, |
| 31 | OpSize size, int s_reg); |
| 32 | virtual LIR* LoadBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_dest_lo, |
| 33 | int r_dest_hi, int s_reg); |
| 34 | virtual LIR* LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest, int scale, |
| 35 | OpSize size); |
| 36 | virtual LIR* LoadBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale, |
| 37 | int displacement, int r_dest, int r_dest_hi, OpSize size, |
| 38 | int s_reg); |
| 39 | virtual LIR* LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value); |
| 40 | virtual LIR* LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi, |
| 41 | int val_lo, int val_hi); |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 42 | virtual LIR* StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_src, |
| 43 | OpSize size); |
| 44 | virtual LIR* StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_src_lo, |
| 45 | int r_src_hi); |
| 46 | virtual LIR* StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src, int scale, |
| 47 | OpSize size); |
| 48 | virtual LIR* StoreBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale, |
| 49 | int displacement, int r_src, int r_src_hi, OpSize size, |
| 50 | int s_reg); |
| 51 | virtual void MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg); |
| 52 | |
| 53 | // Required for target - register utilities. |
| 54 | virtual bool IsFpReg(int reg); |
| 55 | virtual bool SameRegType(int reg1, int reg2); |
| 56 | virtual int AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class); |
| 57 | virtual int AllocTypedTempPair(CompilationUnit* cu, bool fp_hint, int reg_class); |
| 58 | virtual int S2d(int low_reg, int high_reg); |
| 59 | virtual int TargetReg(SpecialTargetRegister reg); |
| 60 | virtual RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg); |
| 61 | virtual RegLocation GetReturnAlt(CompilationUnit* cu); |
| 62 | virtual RegLocation GetReturnWideAlt(CompilationUnit* cu); |
| 63 | virtual RegLocation LocCReturn(); |
| 64 | virtual RegLocation LocCReturnDouble(); |
| 65 | virtual RegLocation LocCReturnFloat(); |
| 66 | virtual RegLocation LocCReturnWide(); |
| 67 | virtual uint32_t FpRegMask(); |
| 68 | virtual uint64_t GetRegMaskCommon(CompilationUnit* cu, int reg); |
| 69 | virtual void AdjustSpillMask(CompilationUnit* cu); |
| 70 | virtual void ClobberCalleeSave(CompilationUnit *cu); |
| 71 | virtual void FlushReg(CompilationUnit* cu, int reg); |
| 72 | virtual void FlushRegWide(CompilationUnit* cu, int reg1, int reg2); |
| 73 | virtual void FreeCallTemps(CompilationUnit* cu); |
| 74 | virtual void FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free); |
| 75 | virtual void LockCallTemps(CompilationUnit* cu); |
| 76 | virtual void MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg); |
| 77 | virtual void CompilerInitializeRegAlloc(CompilationUnit* cu); |
| 78 | |
| 79 | // Required for target - miscellaneous. |
| 80 | virtual AssemblerStatus AssembleInstructions(CompilationUnit* cu, uintptr_t start_addr); |
| 81 | virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); |
| 82 | virtual void SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir); |
| 83 | virtual const char* GetTargetInstFmt(int opcode); |
| 84 | virtual const char* GetTargetInstName(int opcode); |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 85 | virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr); |
| 86 | virtual uint64_t GetPCUseDefEncoding(); |
| 87 | virtual uint64_t GetTargetInstFlags(int opcode); |
| 88 | virtual int GetInsnSize(LIR* lir); |
| 89 | virtual bool IsUnconditionalBranch(LIR* lir); |
| 90 | |
| 91 | // Required for target - Dalvik-level generators. |
buzbee | e6285f9 | 2012-12-06 15:57:46 -0800 | [diff] [blame] | 92 | virtual void GenArrayObjPut(CompilationUnit* cu, int opt_flags, RegLocation rl_array, |
| 93 | RegLocation rl_index, RegLocation rl_src, int scale); |
| 94 | virtual void GenArrayGet(CompilationUnit* cu, int opt_flags, OpSize size, RegLocation rl_array, |
| 95 | RegLocation rl_index, RegLocation rl_dest, int scale); |
| 96 | virtual void GenArrayPut(CompilationUnit* cu, int opt_flags, OpSize size, RegLocation rl_array, |
| 97 | RegLocation rl_index, RegLocation rl_src, int scale); |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 98 | virtual bool GenAddLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 99 | RegLocation rl_src2); |
| 100 | virtual bool GenAndLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 101 | RegLocation rl_src2); |
| 102 | virtual bool GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode, |
| 103 | RegLocation rl_dest, RegLocation rl_src1, |
| 104 | RegLocation rl_src2); |
| 105 | virtual bool GenArithOpFloat(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest, |
| 106 | RegLocation rl_src1, RegLocation rl_src2); |
| 107 | virtual bool GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest, |
| 108 | RegLocation rl_src1, RegLocation rl_src2); |
| 109 | virtual bool GenConversion(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest, |
| 110 | RegLocation rl_src); |
| 111 | virtual bool GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier); |
| 112 | virtual bool GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min); |
| 113 | virtual bool GenInlinedSqrt(CompilationUnit* cu, CallInfo* info); |
| 114 | virtual bool GenNegLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src); |
| 115 | virtual bool GenOrLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 116 | RegLocation rl_src2); |
| 117 | virtual bool GenSubLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 118 | RegLocation rl_src2); |
| 119 | virtual bool GenXorLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 120 | RegLocation rl_src2); |
| 121 | virtual LIR* GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code, int reg1, int base, |
| 122 | int offset, ThrowKind kind); |
| 123 | virtual RegLocation GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int reg_hi, |
| 124 | bool is_div); |
| 125 | virtual RegLocation GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int lit, |
| 126 | bool is_div); |
| 127 | virtual void GenCmpLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1, |
| 128 | RegLocation rl_src2); |
| 129 | virtual void GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi); |
| 130 | virtual void GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs, |
| 131 | RegLocation rl_method); |
| 132 | virtual void GenExitSequence(CompilationUnit* cu); |
| 133 | virtual void GenFillArrayData(CompilationUnit* cu, uint32_t table_offset, |
| 134 | RegLocation rl_src); |
| 135 | virtual void GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir, bool gt_bias, |
| 136 | bool is_double); |
| 137 | virtual void GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir); |
| 138 | virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind); |
| 139 | virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src); |
| 140 | virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src); |
jeffhao | 1eab958 | 2013-01-22 13:33:52 -0800 | [diff] [blame] | 141 | virtual void GenMoveException(CompilationUnit* cu, RegLocation rl_dest); |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 142 | virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src, |
| 143 | RegLocation rl_result, int lit, int first_bit, |
| 144 | int second_bit); |
| 145 | virtual void GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src); |
| 146 | virtual void GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src); |
| 147 | virtual void GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset, |
| 148 | RegLocation rl_src); |
| 149 | virtual void GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset, |
| 150 | RegLocation rl_src); |
| 151 | virtual void GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir, |
| 152 | SpecialCaseHandler special_case); |
| 153 | |
| 154 | // Required for target - single operation generators. |
| 155 | virtual LIR* OpUnconditionalBranch(CompilationUnit* cu, LIR* target); |
| 156 | virtual LIR* OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1, int src2, |
| 157 | LIR* target); |
| 158 | virtual LIR* OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg, int check_value, |
| 159 | LIR* target); |
| 160 | virtual LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target); |
| 161 | virtual LIR* OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg, |
| 162 | LIR* target); |
| 163 | virtual LIR* OpFpRegCopy(CompilationUnit* cu, int r_dest, int r_src); |
| 164 | virtual LIR* OpIT(CompilationUnit* cu, ConditionCode cond, const char* guide); |
| 165 | virtual LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp); |
| 166 | virtual LIR* OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target); |
| 167 | virtual LIR* OpReg(CompilationUnit* cu, OpKind op, int r_dest_src); |
| 168 | virtual LIR* OpRegCopy(CompilationUnit* cu, int r_dest, int r_src); |
| 169 | virtual LIR* OpRegCopyNoInsert(CompilationUnit* cu, int r_dest, int r_src); |
| 170 | virtual LIR* OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value); |
| 171 | virtual LIR* OpRegMem(CompilationUnit* cu, OpKind op, int r_dest, int rBase, int offset); |
| 172 | virtual LIR* OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2); |
| 173 | virtual LIR* OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, int value); |
| 174 | virtual LIR* OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, |
| 175 | int r_src2); |
| 176 | virtual LIR* OpTestSuspend(CompilationUnit* cu, LIR* target); |
| 177 | virtual LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset); |
| 178 | virtual LIR* OpVldm(CompilationUnit* cu, int rBase, int count); |
| 179 | virtual LIR* OpVstm(CompilationUnit* cu, int rBase, int count); |
| 180 | virtual void OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale, |
| 181 | int offset); |
| 182 | virtual void OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi, int src_lo, |
| 183 | int src_hi); |
| 184 | virtual void OpTlsCmp(CompilationUnit* cu, int offset, int val); |
| 185 | |
| 186 | static RegLocation ArgLoc(CompilationUnit* cu, RegLocation loc); |
| 187 | LIR* LoadBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_dest, |
| 188 | int r_dest_hi, OpSize size, int s_reg); |
| 189 | LIR* StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_src, |
| 190 | int r_src_hi, OpSize size); |
| 191 | static void GenPrintLabel(CompilationUnit *cu, MIR* mir); |
| 192 | static LIR* OpRegRegRegShift(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, |
| 193 | int r_src2, int shift); |
| 194 | static LIR* OpRegRegShift(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2, |
| 195 | int shift); |
| 196 | static const ArmEncodingMap EncodingMap[kArmLast]; |
| 197 | static int EncodeShift(int code, int amount); |
| 198 | static int ModifiedImmediate(uint32_t value); |
| 199 | static ArmConditionCode ArmConditionEncoding(ConditionCode code); |
buzbee | e6285f9 | 2012-12-06 15:57:46 -0800 | [diff] [blame] | 200 | bool InexpensiveConstant(int reg, int value); |
buzbee | 02031b1 | 2012-11-23 09:41:35 -0800 | [diff] [blame] | 201 | }; |
| 202 | |
| 203 | } // namespace art |
| 204 | |
| 205 | #endif // ART_SRC_COMPILER_CODEGEN_ARM_CODEGENARM_H_ |