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 527655f29fabc0a12765de828914a18314382e5a35Ian Rogers CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(pFmodf), rl_src1, rl_src2, 537655f29fabc0a12765de828914a18314382e5a35Ian Rogers false); 541fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = GetReturn(true); 551fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 56a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 57a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_FLOAT: 581fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegFloat(rl_dest, rl_src1); 59a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 60a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 61a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 62a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 631fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 661fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg); 671fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 6867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 6967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 701fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenArithOpDouble(Instruction::Code opcode, 712ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 72a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 73fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 7467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 75408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 76a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE_2ADDR: 77a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_DOUBLE: 78a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vaddd; 79a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE_2ADDR: 81a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_DOUBLE: 82a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubd; 83a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 84a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE_2ADDR: 85a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_DOUBLE: 86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivd; 87a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 88a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE_2ADDR: 89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_DOUBLE: 90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuld; 91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 92a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE_2ADDR: 93a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_DOUBLE: 941fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 957655f29fabc0a12765de828914a18314382e5a35Ian Rogers CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(pFmod), rl_src1, rl_src2, 967655f29fabc0a12765de828914a18314382e5a35Ian Rogers false); 971fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = GetReturnWide(true); 981fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 99a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 100a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 1011fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegDouble(rl_dest, rl_src1); 102a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 103a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 104a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 105a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1071fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 108fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src1.wide); 1091fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 110fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src2.wide); 1111fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 112fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 113fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_result.wide); 1141fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg), 115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1191fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenConversion(Instruction::Code opcode, 1202ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_dest, RegLocation rl_src) { 121a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 122fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg; 123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 12467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (opcode) { 126a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_FLOAT: 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtIF; 128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 129a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_INT: 130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFI; 131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 132a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_FLOAT: 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDF; 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 135a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_DOUBLE: 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFd; 137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_DOUBLE: 139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtID; 140a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_INT: 142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDI; 143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 144a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_DOUBLE: 1457655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pL2d), rl_dest, rl_src); 146a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 147a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_LONG: 1487655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pF2l), rl_dest, rl_src); 149a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 150a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_FLOAT: 1517655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pL2f), rl_dest, rl_src); 152a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_LONG: 1547655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pD2l), rl_dest, rl_src); 155a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 157a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 159fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 1601fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 161fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = S2d(rl_src.low_reg, rl_src.high_reg); 162a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1631fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 164fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 165a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 166fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 1671fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 1681fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg); 1691fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 170a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1711fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 1721fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, rl_result.low_reg, src_reg); 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 17567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 17667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1771fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, 1782ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is_double) { 1791fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* target = &block_label_list_[bb->taken->id]; 180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 181fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 182fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 1831fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrcWide(mir, 0); 1841fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrcWide(mir, 2); 1851fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 1861fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 1871fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 188fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1901fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrc(mir, 0); 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrc(mir, 1); 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 1931fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 1941fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1961fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); 198df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom switch (ccode) { 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondEq: 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondNe: 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLt: 203fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondMi; 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLe: 208fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondLs; 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 211a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGt: 213fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondHi; 215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGe: 218fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondCs; 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 223cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2251fd3346740dfb7f47be9922312b68a4227fada96buzbee OpCondBranch(ccode, target); 22684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee} 22784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 22884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 2291fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid ArmMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, 2302ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom RegLocation rl_src1, RegLocation rl_src2) { 231a5954be0aac5edd892fb31a209960543d00e4500buzbee bool is_double = false; 232a5954be0aac5edd892fb31a209960543d00e4500buzbee int default_result = -1; 233fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 23467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 235408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 236a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_FLOAT: 237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 239a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_FLOAT: 241fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 243a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_DOUBLE: 245fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 246fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 247a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_DOUBLE: 249fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 250fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 251a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 253a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 254a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 255fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 2561fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 2571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 258078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a src vreg, break association to avoid useless copy by EvalLoc() 2591fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2601fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 2611fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, default_result); 2621fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 263fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 2661fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 267078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a srcvreg, break association to avoid useless copy by EvalLoc() 2681fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 2701fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, default_result); 2711fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 272a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!ARM_FPREG(rl_result.low_reg)); 2741fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 27567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2761fd3346740dfb7f47be9922312b68a4227fada96buzbee OpIT((default_result == -1) ? kCondGt : kCondMi, ""); 2771fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2MovImmShift, rl_result.low_reg, 2787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom ModifiedImmediate(-default_result)); // Must not alter ccodes 2791fd3346740dfb7f47be9922312b68a4227fada96buzbee GenBarrier(); 28067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2811fd3346740dfb7f47be9922312b68a4227fada96buzbee OpIT(kCondEq, ""); 2821fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, 0); 2831fd3346740dfb7f47be9922312b68a4227fada96buzbee GenBarrier(); 28467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2851fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 28667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 28711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 2882ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) { 289fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2901fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 2911fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 2921fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vnegs, rl_result.low_reg, rl_src.low_reg); 2931fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2962ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid ArmMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { 297fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2981fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 2991fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vnegd, S2d(rl_result.low_reg, rl_result.high_reg), 301fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 3021fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3051fd3346740dfb7f47be9922312b68a4227fada96buzbeebool ArmMir2Lir::GenInlinedSqrt(CallInfo* info) { 3061fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kThumb2); 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LIR *branch; 308fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src = info->args[0]; 3091fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest = InlineTargetWide(info); // double place for result 3101fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 3111fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true); 3121fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vsqrtd, S2d(rl_result.low_reg, rl_result.high_reg), 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 3141fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vcmpd, S2d(rl_result.low_reg, rl_result.high_reg), 315fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_result.low_reg, rl_result.high_reg)); 3161fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kThumb2Fmstat); 3171fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kThumbBCond, 0, kArmCondEq); 3181fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberCalleeSave(); 3191fd3346740dfb7f47be9922312b68a4227fada96buzbee LockCallTemps(); // Using fixed registers 3207655f29fabc0a12765de828914a18314382e5a35Ian Rogers int r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(pSqrt)); 3211fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(kThumb2Fmrrd, r0, r1, S2d(rl_src.low_reg, rl_src.high_reg)); 3221fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kThumbBlxR, r_tgt); 3231fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR3(kThumb2Fmdrr, S2d(rl_result.low_reg, rl_result.high_reg), r0, r1); 3241fd3346740dfb7f47be9922312b68a4227fada96buzbee branch->target = NewLIR0(kPseudoTargetLabel); 3251fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return true; 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 329efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 33011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 331