/* * 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 and is intended to be * included by: * * Codegen-$(TARGET_ARCH_VARIANT).c * */ #include "../../CompilerIR.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(LIR* lir); extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); } // namespace art