diff options
Diffstat (limited to 'src/compiler/codegen/arm/codegen.h')
| -rw-r--r-- | src/compiler/codegen/arm/codegen.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/compiler/codegen/arm/codegen.h b/src/compiler/codegen/arm/codegen.h new file mode 100644 index 0000000000..47f45c6c20 --- /dev/null +++ b/src/compiler/codegen/arm/codegen.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file contains register alloction support. */ + +#include "../../compiler_ir.h" + +namespace art { + +#if defined(_CODEGEN_C) +LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value); +LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2); +LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, + int checkValue, LIR* target); +bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc); + +/* Forward declaraton the portable versions due to circular dependency */ +bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc1, + RegLocation rlSrc2); + +bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc1, + RegLocation rlSrc2); + +bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc); + +ArmConditionCode oatArmConditionEncoding(ConditionCode code); + +int loadHelper(CompilationUnit* cUnit, int offset); +LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal); +void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, + int srcLo, int srcHi); +LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); +void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, + RegLocation rlFree); + + +/* + * Return most flexible allowed register class based on size. + * Bug: 2813841 + * Must use a core register for data types narrower than word (due + * to possible unaligned load/store. + */ +inline RegisterClass oatRegClassBySize(OpSize size) +{ + return (size == kUnsignedHalf || + size == kSignedHalf || + size == kUnsignedByte || + size == kSignedByte ) ? kCoreReg : kAnyReg; +} + +/* + * Construct an s4 from two consecutive half-words of switch data. + * This needs to check endianness because the DEX optimizer only swaps + * half-words in instruction stream. + * + * "switchData" must be 32-bit aligned. + */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +inline s4 s4FromSwitchData(const void* switchData) { + return *(s4*) switchData; +} +#else +inline s4 s4FromSwitchData(const void* switchData) { + u2* data = switchData; + return data[0] | (((s4) data[1]) << 16); +} +#endif + +#endif + +extern void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); + +extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); + +bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); + +} // namespace art |