fp_arm.cc revision a5954be0aac5edd892fb31a209960543d00e4500
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" 19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/codegen_util.h" 20641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/ralloc_util.h" 211bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 2211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 2311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 24a5954be0aac5edd892fb31a209960543d00e4500buzbeevoid ArmCodegen::GenArithOpFloat(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest, 2502031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src1, RegLocation rl_src2) 2667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 27a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 2967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 30a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Don't attempt to optimize register usage since these opcodes call out to 32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the handlers. 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 34408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT_2ADDR: 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::ADD_FLOAT: 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vadds; 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT_2ADDR: 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::SUB_FLOAT: 41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vsubs; 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT_2ADDR: 44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DIV_FLOAT: 45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vdivs; 46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT_2ADDR: 48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::MUL_FLOAT: 49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2Vmuls; 50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 51a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT_2ADDR: 52a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::REM_FLOAT: 53a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee FlushAllRegs(cu); // Send everything to home location 54a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee CallRuntimeHelperRegLocationRegLocation(cu, ENTRYPOINT_OFFSET(pFmodf), rl_src1, rl_src2, false); 55a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee rl_result = GetReturn(cu, true); 56a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee StoreValue(cu, rl_dest, rl_result); 57a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 58a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_FLOAT: 59a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee GenNegFloat(cu, rl_dest, rl_src1); 60a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 61a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 62a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 63a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 64fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValue(cu, rl_src1, kFPReg); 65fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValue(cu, rl_src2, kFPReg); 66fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 67fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR3(cu, op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg); 68fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValue(cu, rl_dest, rl_result); 6967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 7067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 71a5954be0aac5edd892fb31a209960543d00e4500buzbeevoid ArmCodegen::GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode, 7202031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) 7367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 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: 96a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee FlushAllRegs(cu); // Send everything to home location 97a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee CallRuntimeHelperRegLocationRegLocation(cu, ENTRYPOINT_OFFSET(pFmod), rl_src1, rl_src2, false); 98a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee rl_result = GetReturnWide(cu, true); 99a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee StoreValueWide(cu, rl_dest, rl_result); 100a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 101a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 102a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee GenNegDouble(cu, rl_dest, rl_src1); 103a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 105a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 106a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 108fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValueWide(cu, rl_src1, kFPReg); 109fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src1.wide); 110fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValueWide(cu, rl_src2, kFPReg); 111fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src2.wide); 112fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 113fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_result.wide); 115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR3(cu, op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg), 116fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 117fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValueWide(cu, rl_dest, rl_result); 11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 11967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 120a5954be0aac5edd892fb31a209960543d00e4500buzbeevoid ArmCodegen::GenConversion(CompilationUnit* cu, Instruction::Code opcode, 12102031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_dest, RegLocation rl_src) 12267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int op = kThumbBkpt; 124fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg; 125fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 12667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (opcode) { 128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_FLOAT: 129a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtIF; 130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_INT: 132a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFI; 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_FLOAT: 135a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDF; 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_DOUBLE: 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtFd; 139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 140a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::INT_TO_DOUBLE: 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtID; 142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_INT: 144a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = kThumb2VcvtDI; 145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 146a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_DOUBLE: 147a5954be0aac5edd892fb31a209960543d00e4500buzbee GenConversionCall(cu, ENTRYPOINT_OFFSET(pL2d), rl_dest, rl_src); 148a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 149a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::FLOAT_TO_LONG: 150a5954be0aac5edd892fb31a209960543d00e4500buzbee GenConversionCall(cu, ENTRYPOINT_OFFSET(pF2l), rl_dest, rl_src); 151a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::LONG_TO_FLOAT: 153a5954be0aac5edd892fb31a209960543d00e4500buzbee GenConversionCall(cu, ENTRYPOINT_OFFSET(pL2f), rl_dest, rl_src); 154a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 155a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::DOUBLE_TO_LONG: 156a5954be0aac5edd892fb31a209960543d00e4500buzbee GenConversionCall(cu, ENTRYPOINT_OFFSET(pD2l), rl_dest, rl_src); 157a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 159a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 161fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 162fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src = LoadValueWide(cu, rl_src, kFPReg); 163fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = S2d(rl_src.low_reg, rl_src.high_reg); 164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 165fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src = LoadValue(cu, rl_src, kFPReg); 166fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 167a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 168fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 169fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg); 171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValueWide(cu, rl_dest, rl_result); 172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 174fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, op, rl_result.low_reg, src_reg); 175fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValue(cu, rl_dest, rl_result); 176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 17767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 17867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 17902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid ArmCodegen::GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir, bool gt_bias, 18002031b185b4653e6c72e21f7a51238b903f6d638buzbee bool is_double) 18184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee{ 182fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* label_list = cu->block_label_list; 183fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* target = &label_list[bb->taken->id]; 184fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 185fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 187fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = GetSrcWide(cu, mir, 0); 188fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = GetSrcWide(cu, mir, 2); 189fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValueWide(cu, rl_src1, kFPReg); 190fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValueWide(cu, rl_src2, kFPReg); 191fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 192fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 194fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = GetSrc(cu, mir, 0); 195fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = GetSrc(cu, mir, 1); 196fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValue(cu, rl_src1, kFPReg); 197fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValue(cu, rl_src2, kFPReg); 198fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 200fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR0(cu, kThumb2Fmstat); 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch(ccode) { 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondEq: 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondNe: 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLt: 207fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 208a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondMi; 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 211a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondLe: 212fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondLs; 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGt: 217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondHi; 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kCondGe: 222fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ccode = kCondCs; 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 227cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 229fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpCondBranch(cu, ccode, target); 23084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee} 23184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 23284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee 233a5954be0aac5edd892fb31a209960543d00e4500buzbeevoid ArmCodegen::GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest, 23402031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src1, RegLocation rl_src2) 23567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 236a5954be0aac5edd892fb31a209960543d00e4500buzbee bool is_double = false; 237a5954be0aac5edd892fb31a209960543d00e4500buzbee int default_result = -1; 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 23967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 240408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 241a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_FLOAT: 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 243fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_FLOAT: 246fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = false; 247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPL_DOUBLE: 250fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 251fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = -1; 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 253a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case Instruction::CMPG_DOUBLE: 254fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee is_double = true; 255fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee default_result = 1; 256a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 257a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 258a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 260fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 261fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValueWide(cu, rl_src1, kFPReg); 262fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValueWide(cu, rl_src2, kFPReg); 263078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a src vreg, break association to avoid useless copy by EvalLoc() 264fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClobberSReg(cu, rl_dest.s_reg_low); 265fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kCoreReg, true); 266fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadConstant(cu, rl_result.low_reg, default_result); 267fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg), 268fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 269a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src1 = LoadValue(cu, rl_src1, kFPReg); 271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src2 = LoadValue(cu, rl_src2, kFPReg); 272078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also a srcvreg, break association to avoid useless copy by EvalLoc() 273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClobberSReg(cu, rl_dest.s_reg_low); 274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kCoreReg, true); 275fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadConstant(cu, rl_result.low_reg, default_result); 276fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg); 277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 278fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!ARM_FPREG(rl_result.low_reg)); 279fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR0(cu, kThumb2Fmstat); 28067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 28102031b185b4653e6c72e21f7a51238b903f6d638buzbee OpIT(cu, (default_result == -1) ? kCondGt : kCondMi, ""); 282fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2MovImmShift, rl_result.low_reg, 283fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ModifiedImmediate(-default_result)); // Must not alter ccodes 284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GenBarrier(cu); 28567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 28602031b185b4653e6c72e21f7a51238b903f6d638buzbee OpIT(cu, kCondEq, ""); 287fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadConstant(cu, rl_result.low_reg, 0); 288fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GenBarrier(cu); 28967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 290fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValue(cu, rl_dest, rl_result); 29167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 29211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 29302031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid ArmCodegen::GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src) 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 296fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src = LoadValue(cu, rl_src, kFPReg); 297fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 298fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vnegs, rl_result.low_reg, rl_src.low_reg); 299fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValue(cu, rl_dest, rl_result); 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 30202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid ArmCodegen::GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src) 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 304fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src = LoadValueWide(cu, rl_src, kFPReg); 306fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 307fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vnegd, S2d(rl_result.low_reg, rl_result.high_reg), 308fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 309fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValueWide(cu, rl_dest, rl_result); 310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 31202031b185b4653e6c72e21f7a51238b903f6d638buzbeebool ArmCodegen::GenInlinedSqrt(CompilationUnit* cu, CallInfo* info) { 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(cu->instruction_set, kThumb2); 314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LIR *branch; 315fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src = info->args[0]; 316fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_dest = InlineTargetWide(cu, info); // double place for result 317fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee rl_src = LoadValueWide(cu, rl_src, kFPReg); 318fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result = EvalLoc(cu, rl_dest, kFPReg, true); 319fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vsqrtd, S2d(rl_result.low_reg, rl_result.high_reg), 320fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src.low_reg, rl_src.high_reg)); 321fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kThumb2Vcmpd, S2d(rl_result.low_reg, rl_result.high_reg), 322fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_result.low_reg, rl_result.high_reg)); 323fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR0(cu, kThumb2Fmstat); 324fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch = NewLIR2(cu, kThumbBCond, 0, kArmCondEq); 325fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClobberCalleeSave(cu); 326fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LockCallTemps(cu); // Using fixed registers 327fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_tgt = LoadHelper(cu, ENTRYPOINT_OFFSET(pSqrt)); 328fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR3(cu, kThumb2Fmrrd, r0, r1, S2d(rl_src.low_reg, rl_src.high_reg)); 329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR1(cu, kThumbBlxR, r_tgt); 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR3(cu, kThumb2Fmdrr, S2d(rl_result.low_reg, rl_result.high_reg), r0, r1); 331fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = NewLIR0(cu, kPseudoTargetLabel); 332fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreValueWide(cu, rl_dest, rl_result); 333efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return true; 334efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 33711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 338