fp_arm.cc revision 7934ac288acfb2552bb0b06ec1f61e5820d924a4
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 171bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee#include "arm_lir.h" 1802031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_arm.h" 197940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 201bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 2111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 2211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 231fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, 242ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_src1, RegLocation rl_src2) { 25a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 26fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 29a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Don't attempt to optimize register usage since these opcodes call out to 30a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the handlers. 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 32408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT_2ADDR: 34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT: 35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vadds; 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT_2ADDR: 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT: 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubs; 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT_2ADDR: 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT: 43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivs; 44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT_2ADDR: 46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT: 47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuls; 48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT_2ADDR: 50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT: 511fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 521fd3346740dfb7f47be9922312b68a4227fada96buzbee CallRuntimeHelperRegLocationRegLocation(ENTRYPOINT_OFFSET(pFmodf), rl_src1, rl_src2, false); 531fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = GetReturn(true); 541fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 55a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 56a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_FLOAT: 571fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegFloat(rl_dest, rl_src1); 58a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 59a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 60a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 61a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 621fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 631fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 651fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg); 661fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 6767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 6867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 691fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenArithOpDouble(Instruction::Code opcode, 702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 71a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 72fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 7367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 74408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 75a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE_2ADDR: 76a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE: 77a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vaddd; 78a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 79a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE_2ADDR: 80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE: 81a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubd; 82a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 83a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE_2ADDR: 84a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE: 85a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivd; 86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 87a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE_2ADDR: 88a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE: 89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuld; 90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE_2ADDR: 92a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE: 931fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 941fd3346740dfb7f47be9922312b68a4227fada96buzbee CallRuntimeHelperRegLocationRegLocation(ENTRYPOINT_OFFSET(pFmod), rl_src1, rl_src2, false); 951fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = GetReturnWide(true); 961fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 97a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 98a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 991fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegDouble(rl_dest, rl_src1); 100a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 101a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 102a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 103a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1051fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 106fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src1.wide); 1071fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 108fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src2.wide); 1091fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 110fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 111fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_result.wide); 1121fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg), 113fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 1141fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1171fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenConversion(Instruction::Code opcode, 1182ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_dest, RegLocation rl_src) { 119a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 120fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg; 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 12267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (opcode) { 124a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_FLOAT: 125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtIF; 126a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_INT: 128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFI; 129a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_FLOAT: 131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDF; 132a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_DOUBLE: 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFd; 135a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_DOUBLE: 137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtID; 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_INT: 140a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDI; 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_DOUBLE: 1431fd3346740dfb7f47be9922312b68a4227fada96buzbee GenConversionCall(ENTRYPOINT_OFFSET(pL2d), rl_dest, rl_src); 144a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_LONG: 1461fd3346740dfb7f47be9922312b68a4227fada96buzbee GenConversionCall(ENTRYPOINT_OFFSET(pF2l), rl_dest, rl_src); 147a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 148a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_FLOAT: 1491fd3346740dfb7f47be9922312b68a4227fada96buzbee GenConversionCall(ENTRYPOINT_OFFSET(pL2f), rl_dest, rl_src); 150a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_LONG: 1521fd3346740dfb7f47be9922312b68a4227fada96buzbee GenConversionCall(ENTRYPOINT_OFFSET(pD2l), rl_dest, rl_src); 153a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 155a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 157fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 1581fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 159fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = S2d(rl_src.low_reg, rl_src.high_reg); 160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1611fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 162fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 163a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 164fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 1651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 1661fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg); 1671fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1691fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 1701fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, rl_result.low_reg, src_reg); 1711fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 17367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 17467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1751fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, 1762ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is_double) { 1771fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* target = &block_label_list_[bb->taken->id]; 178fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 179fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 1811fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrcWide(mir, 0); 1821fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrcWide(mir, 2); 1831fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 1841fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 1851fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 187a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1881fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrc(mir, 0); 1891fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrc(mir, 1); 1901fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1941fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); 196df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom switch (ccode) { 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondEq: 198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondNe: 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLt: 201fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondMi; 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLe: 206fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondLs; 208a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGt: 211fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondHi; 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGe: 216fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondCs; 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 221cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2231fd3346740dfb7f47be9922312b68a4227fada96buzbee OpCondBranch(ccode, target); 22484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee} 22584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 22684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 2271fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, 2282ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_src1, RegLocation rl_src2) { 229a5954be0aac5edd892fb31a209960543d00e4500buzbee bool is_double = false; 230a5954be0aac5edd892fb31a209960543d00e4500buzbee int default_result = -1; 231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 23267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 233408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_FLOAT: 235fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 236fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 237a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_FLOAT: 239fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 240fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 241a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_DOUBLE: 243fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 244fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 246a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_DOUBLE: 247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 248fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 251a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 253fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 2541fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 2551fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 256078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a src vreg, break association to avoid useless copy by EvalLoc() 2571fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2581fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 2591fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, default_result); 2601fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 261fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 2641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 265078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a srcvreg, break association to avoid useless copy by EvalLoc() 2661fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2671fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 2681fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, default_result); 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 270a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!ARM_FPREG(rl_result.low_reg)); 2721fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 27367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2741fd3346740dfb7f47be9922312b68a4227fada96buzbee OpIT((default_result == -1) ? kCondGt : kCondMi, ""); 2751fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2MovImmShift, rl_result.low_reg, 2767934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom ModifiedImmediate(-default_result)); // Must not alter ccodes 2771fd3346740dfb7f47be9922312b68a4227fada96buzbee GenBarrier(); 27867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2791fd3346740dfb7f47be9922312b68a4227fada96buzbee OpIT(kCondEq, ""); 2801fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, 0); 2811fd3346740dfb7f47be9922312b68a4227fada96buzbee GenBarrier(); 28267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2831fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 28467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 28511d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 2862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) { 287fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2881fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 2891fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 2901fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vnegs, rl_result.low_reg, rl_src.low_reg); 2911fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2942ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { 295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2961fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 2981fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vnegd, S2d(rl_result.low_reg, rl_result.high_reg), 299fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3031fd3346740dfb7f47be9922312b68a4227fada96buzbeebool ArmMir2Lir::GenInlinedSqrt(CallInfo* info) { 3041fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kThumb2); 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LIR *branch; 306fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src = info->args[0]; 3071fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest = InlineTargetWide(info); // double place for result 3081fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 3091fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true); 3101fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vsqrtd, S2d(rl_result.low_reg, rl_result.high_reg), 311fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 3121fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_result.low_reg, rl_result.high_reg), 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_result.low_reg, rl_result.high_reg)); 3141fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 3151fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kThumbBCond, 0, kArmCondEq); 3161fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberCalleeSave(); 3171fd3346740dfb7f47be9922312b68a4227fada96buzbee LockCallTemps(); // Using fixed registers 3181fd3346740dfb7f47be9922312b68a4227fada96buzbee int r_tgt = LoadHelper(ENTRYPOINT_OFFSET(pSqrt)); 3191fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(kThumb2Fmrrd, r0, r1, S2d(rl_src.low_reg, rl_src.high_reg)); 3201fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kThumbBlxR, r_tgt); 3211fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(kThumb2Fmdrr, S2d(rl_result.low_reg, rl_result.high_reg), r0, r1); 3221fd3346740dfb7f47be9922312b68a4227fada96buzbee branch->target = NewLIR0(kPseudoTargetLabel); 3231fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return true; 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 32811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 329