167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project 367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License. 667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at 767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * http://www.apache.org/licenses/LICENSE-2.0 967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software 1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS, 1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and 1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License. 1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_arm.h" 180b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe 190b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "arm_lir.h" 200b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h" 210b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "dex/mir_graph.h" 227940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 231bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 2411d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 2511d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 261fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, 272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_src1, RegLocation rl_src2) { 28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 3067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Don't attempt to optimize register usage since these opcodes call out to 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the handlers. 34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 35408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT_2ADDR: 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT: 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vadds; 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT_2ADDR: 41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT: 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubs; 43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT_2ADDR: 45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT: 46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivs; 47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT_2ADDR: 49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT: 50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuls; 51a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 52a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT_2ADDR: 53a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT: 541fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 55984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe CallRuntimeHelperRegLocationRegLocation(kQuickFmodf, rl_src1, rl_src2, false); 56a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee rl_result = GetReturn(kFPReg); 571fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 58a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 59a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_FLOAT: 601fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegFloat(rl_dest, rl_src1); 61a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 62a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 63a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 64a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 661fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 671fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 6800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 691fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 7067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 7167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 721fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenArithOpDouble(Instruction::Code opcode, 732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 74a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 7667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 77408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 78a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE_2ADDR: 79a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE: 80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vaddd; 81a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 82a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE_2ADDR: 83a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE: 84a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubd; 85a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE_2ADDR: 87a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE: 88a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivd; 89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE_2ADDR: 91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE: 92a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuld; 93a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 94a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE_2ADDR: 95a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE: 961fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 97984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe CallRuntimeHelperRegLocationRegLocation(kQuickFmod, rl_src1, rl_src2, false); 98a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee rl_result = GetReturnWide(kFPReg); 991fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 100a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 101a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 1021fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegDouble(rl_dest, rl_src1); 103a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 105a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 106a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1081fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 109fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src1.wide); 1101fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 111fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src2.wide); 1121fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 113fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_result.wide); 115091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 119675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jianvoid ArmMir2Lir::GenMultiplyByConstantFloat(RegLocation rl_dest, RegLocation rl_src1, 120675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian int32_t constant) { 121675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian RegLocation rl_result; 122675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian RegStorage r_tmp = AllocTempSingle(); 123675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian LoadConstantNoClobber(r_tmp, constant); 124675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian rl_src1 = LoadValue(rl_src1, kFPReg); 125675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian rl_result = EvalLoc(rl_dest, kFPReg, true); 126675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian NewLIR3(kThumb2Vmuls, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), r_tmp.GetReg()); 127675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian StoreValue(rl_dest, rl_result); 128675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian} 129675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian 130675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jianvoid ArmMir2Lir::GenMultiplyByConstantDouble(RegLocation rl_dest, RegLocation rl_src1, 131675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian int64_t constant) { 132675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian RegLocation rl_result; 133675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian RegStorage r_tmp = AllocTempDouble(); 134675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian DCHECK(r_tmp.IsDouble()); 135675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian LoadConstantWide(r_tmp, constant); 136675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian rl_src1 = LoadValueWide(rl_src1, kFPReg); 137675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian DCHECK(rl_src1.wide); 138675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian rl_result = EvalLocWide(rl_dest, kFPReg, true); 139675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian DCHECK(rl_dest.wide); 140675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian DCHECK(rl_result.wide); 141675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian NewLIR3(kThumb2Vmuld, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), r_tmp.GetReg()); 142675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian StoreValueWide(rl_dest, rl_result); 143675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian} 144675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian 145091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeevoid ArmMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src) { 146a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 147fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg; 148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 14967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 150a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (opcode) { 151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_FLOAT: 152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtIF; 153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_INT: 155a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFI; 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 157a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_FLOAT: 158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDF; 159a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_DOUBLE: 161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFd; 162a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 163a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_DOUBLE: 164e19649a91702234f9aa9941d76da447a1e0dcc2aZheng Xu op = kThumb2VcvtF64S32; 165a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 166a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_INT: 167a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDI; 168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 169ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers case Instruction::LONG_TO_DOUBLE: { 170ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers rl_src = LoadValueWide(rl_src, kFPReg); 17185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info = GetRegInfo(rl_src.reg); 17285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg(); 17385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(src_low.Valid()); 17485089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg(); 17585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(src_high.Valid()); 176ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers rl_result = EvalLoc(rl_dest, kFPReg, true); 1772700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage tmp1 = AllocTempDouble(); 1782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage tmp2 = AllocTempDouble(); 179ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers 180091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2VcvtF64S32, tmp1.GetReg(), src_high.GetReg()); 181091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2VcvtF64U32, rl_result.reg.GetReg(), src_low.GetReg()); 1822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstantWide(tmp2, 0x41f0000000000000LL); 183091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR3(kThumb2VmlaF64, rl_result.reg.GetReg(), tmp1.GetReg(), tmp2.GetReg()); 184ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers FreeTemp(tmp1); 185ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers FreeTemp(tmp2); 186ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers StoreValueWide(rl_dest, rl_result); 187a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 188ef6a776af2b4b8607d5f91add0ed0e8497100e31Ian Rogers } 189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_LONG: 190fac10700fd99516e8a14f751fe35553021ce6982Vladimir Marko CheckEntrypointTypes<kQuickF2l, int64_t, float>(); // int64_t -> kCoreReg 191fac10700fd99516e8a14f751fe35553021ce6982Vladimir Marko GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg); 192a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 193f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu case Instruction::LONG_TO_FLOAT: { 194f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu rl_src = LoadValueWide(rl_src, kFPReg); 19585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info = GetRegInfo(rl_src.reg); 19685089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg(); 19785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(src_low.Valid()); 19885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg(); 19985089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(src_high.Valid()); 200f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu rl_result = EvalLoc(rl_dest, kFPReg, true); 201f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu // Allocate temp registers. 2022700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage high_val = AllocTempDouble(); 2032700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage low_val = AllocTempDouble(); 2042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage const_val = AllocTempDouble(); 205f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu // Long to double. 206091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2VcvtF64S32, high_val.GetReg(), src_high.GetReg()); 207091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2VcvtF64U32, low_val.GetReg(), src_low.GetReg()); 2082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstantWide(const_val, INT64_C(0x41f0000000000000)); 209091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR3(kThumb2VmlaF64, low_val.GetReg(), high_val.GetReg(), const_val.GetReg()); 210f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu // Double to float. 211091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2VcvtDF, rl_result.reg.GetReg(), low_val.GetReg()); 212f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu // Free temp registers. 213f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu FreeTemp(high_val); 214f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu FreeTemp(low_val); 215f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu FreeTemp(const_val); 216f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu // Store result. 217f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu StoreValue(rl_dest, rl_result); 218a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 219f0e6c9c7b395f4fce4d00d31cabd362302e1d924Zheng Xu } 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_LONG: 221fac10700fd99516e8a14f751fe35553021ce6982Vladimir Marko CheckEntrypointTypes<kQuickD2l, int64_t, double>(); // int64_t -> kCoreReg 222fac10700fd99516e8a14f751fe35553021ce6982Vladimir Marko GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg); 223a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 225a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 227fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 2281fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 229091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee src_reg = rl_src.reg.GetReg(); 230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2311fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 23200e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee src_reg = rl_src.reg.GetReg(); 233a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 234fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 2351fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 236091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(op, rl_result.reg.GetReg(), src_reg); 2371fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2391fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 24000e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(op, rl_result.reg.GetReg(), src_reg); 2411fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 24367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 24467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2451fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, 2462ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is_double) { 2470d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LIR* target = &block_label_list_[bb->taken]; 248fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 249fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 250fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 2511fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrcWide(mir, 0); 2521fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrcWide(mir, 2); 2531fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 2541fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 255091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2Vcmpd, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 256a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrc(mir, 0); 2581fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrc(mir, 1); 2591fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 2601fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 26100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kThumb2Vcmps, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 264a894607bca7eb623bc957363e4b36f44cfeea1b6Vladimir Marko ConditionCode ccode = mir->meta.ccode; 265df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom switch (ccode) { 266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondEq: 267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondNe: 268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 269a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLt: 270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondMi; 272a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 274a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLe: 275fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondLs; 277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 278a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 279a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGt: 280fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 281a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondHi; 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 284a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGe: 285fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 28658af1f9385742f70aca4fcb5e13aba53b8be2ef4Vladimir Marko ccode = kCondUge; 287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 288a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 289a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 290cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2921fd3346740dfb7f47be9922312b68a4227fada96buzbee OpCondBranch(ccode, target); 29384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee} 29484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 29584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 2961fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, 2972ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_src1, RegLocation rl_src2) { 298a5954be0aac5edd892fb31a209960543d00e4500buzbee bool is_double = false; 299a5954be0aac5edd892fb31a209960543d00e4500buzbee int default_result = -1; 300fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 30167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 302408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 303a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_FLOAT: 304fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 307a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_FLOAT: 308fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 309fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 310a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 311a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_DOUBLE: 312fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 314a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 315a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_DOUBLE: 316fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 317fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 318a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 319a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 320a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 321a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 322fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 3231fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 3241fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 325078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a src vreg, break association to avoid useless copy by EvalLoc() 3261fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 3271fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 3282700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstant(rl_result.reg, default_result); 329091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2Vcmpd, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 330a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 3311fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 3321fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 333078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a srcvreg, break association to avoid useless copy by EvalLoc() 3341fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 3351fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 3362700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstant(rl_result.reg, default_result); 33700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kThumb2Vcmps, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 338a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 339091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!rl_result.reg.IsFloat()); 3401fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 34167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3423da67a558f1fd3d8a157d8044d521753f3f99ac8Dave Allison LIR* it = OpIT((default_result == -1) ? kCondGt : kCondMi, ""); 34300e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kThumb2MovI8M, rl_result.reg.GetReg(), 3447934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom ModifiedImmediate(-default_result)); // Must not alter ccodes 3453da67a558f1fd3d8a157d8044d521753f3f99ac8Dave Allison OpEndIT(it); 34667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3473da67a558f1fd3d8a157d8044d521753f3f99ac8Dave Allison it = OpIT(kCondEq, ""); 3482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstant(rl_result.reg, 0); 3493da67a558f1fd3d8a157d8044d521753f3f99ac8Dave Allison OpEndIT(it); 35067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3511fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 35267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 35311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 3542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) { 355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 3561fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 3571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 35800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kThumb2Vnegs, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 3591fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3622ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { 363fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 3641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 3651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 366091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2Vnegd, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 3671fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 368efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 369efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3705030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Markostatic RegisterClass RegClassForAbsFP(RegLocation rl_src, RegLocation rl_dest) { 3715030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // If src is in a core reg or, unlikely, dest has been promoted to a core reg, use core reg. 3725030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if ((rl_src.location == kLocPhysReg && !rl_src.reg.IsFloat()) || 3735030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko (rl_dest.location == kLocPhysReg && !rl_dest.reg.IsFloat())) { 3745030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return kCoreReg; 3755030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 3765030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // If src is in an fp reg or dest has been promoted to an fp reg, use fp reg. 3775030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if (rl_src.location == kLocPhysReg || rl_dest.location == kLocPhysReg) { 3785030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return kFPReg; 3795030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 3805030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // With both src and dest in the stack frame we have to perform load+abs+store. Whether this 3815030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // is faster using a core reg or fp reg depends on the particular CPU. Without further 3825030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // investigation and testing we prefer core register. (If the result is subsequently used in 3835030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // another fp operation, the dalvik reg will probably get promoted and that should be handled 3845030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko // by the cases above.) 3855030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return kCoreReg; 3865030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko} 3875030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko 3885030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Markobool ArmMir2Lir::GenInlinedAbsFloat(CallInfo* info) { 3895030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if (info->result.location == kLocInvalid) { 3905030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return true; // Result is unused: inlining successful, no code generated. 3915030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 3925030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_dest = info->result; 3935030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_src = UpdateLoc(info->args[0]); 3945030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegisterClass reg_class = RegClassForAbsFP(rl_src, rl_dest); 3955030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko rl_src = LoadValue(rl_src, reg_class); 3965030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_result = EvalLoc(rl_dest, reg_class, true); 3975030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if (reg_class == kFPReg) { 3985030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko NewLIR2(kThumb2Vabss, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 3995030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } else { 4005030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko OpRegRegImm(kOpAnd, rl_result.reg, rl_src.reg, 0x7fffffff); 4015030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 4025030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko StoreValue(rl_dest, rl_result); 4035030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return true; 4045030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko} 4055030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko 4065030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Markobool ArmMir2Lir::GenInlinedAbsDouble(CallInfo* info) { 4075030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if (info->result.location == kLocInvalid) { 4085030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return true; // Result is unused: inlining successful, no code generated. 4095030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 4105030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_dest = info->result; 4115030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_src = UpdateLocWide(info->args[0]); 4125030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegisterClass reg_class = RegClassForAbsFP(rl_src, rl_dest); 4135030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko rl_src = LoadValueWide(rl_src, reg_class); 4145030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko RegLocation rl_result = EvalLoc(rl_dest, reg_class, true); 4155030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko if (reg_class == kFPReg) { 4165030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko NewLIR2(kThumb2Vabsd, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 417a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko } else if (rl_result.reg.GetLow().GetReg() != rl_src.reg.GetHigh().GetReg()) { 418a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko // No inconvenient overlap. 419a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko OpRegCopy(rl_result.reg.GetLow(), rl_src.reg.GetLow()); 420a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko OpRegRegImm(kOpAnd, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), 0x7fffffff); 4215030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } else { 422a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko // Inconvenient overlap, use a temp register to preserve the high word of the source. 423a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko RegStorage rs_tmp = AllocTemp(); 424a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko OpRegCopy(rs_tmp, rl_src.reg.GetHigh()); 425a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko OpRegCopy(rl_result.reg.GetLow(), rl_src.reg.GetLow()); 426a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko OpRegRegImm(kOpAnd, rl_result.reg.GetHigh(), rs_tmp, 0x7fffffff); 427a5f90b6f0f5b33487e71eaeb05508555f17dcf30Vladimir Marko FreeTemp(rs_tmp); 4285030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko } 4295030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko StoreValueWide(rl_dest, rl_result); 4305030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko return true; 4315030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko} 4325030d3ee8c6fe10394912ede107cbc8df63b7b16Vladimir Marko 4331fd3346740dfb7f47be9922312b68a4227fada96buzbeebool ArmMir2Lir::GenInlinedSqrt(CallInfo* info) { 4341fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kThumb2); 435fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src = info->args[0]; 4361fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest = InlineTargetWide(info); // double place for result 4371fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 4381fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true); 439091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kThumb2Vsqrtd, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 4401fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 441efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return true; 442efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 44511d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 446