fp_x86.cc revision a014776f4474579d4dfc72e3374ba45c6f6e5f35
1e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 2e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Copyright (C) 2012 The Android Open Source Project 3e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 4e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * you may not use this file except in compliance with the License. 6e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * You may obtain a copy of the License at 7e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 8e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * http://www.apache.org/licenses/LICENSE-2.0 9e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 10e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Unless required by applicable law or agreed to in writing, software 11e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * See the License for the specific language governing permissions and 14e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * limitations under the License. 15e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 16e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h" 187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h" 201bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 21e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 22e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 231fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenArithOpFloat(Instruction::Code opcode, 2402031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 25b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode op = kX86Nop; 26fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 27e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 28b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers /* 29b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Don't attempt to optimize register usage since these opcodes call out to 30b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * the handlers. 31b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers */ 32408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 33b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_FLOAT_2ADDR: 34b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_FLOAT: 35b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86AddssRR; 36b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 37b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_FLOAT_2ADDR: 38b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_FLOAT: 39b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86SubssRR; 40b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 41b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_FLOAT_2ADDR: 42b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_FLOAT: 43b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86DivssRR; 44b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 45b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_FLOAT_2ADDR: 46b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_FLOAT: 47b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86MulssRR; 48b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 49b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::REM_FLOAT_2ADDR: 50babda950caf2d577aa57102c3281f0f3c36f3d6djeffhao case Instruction::REM_FLOAT: 511fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 529ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (Is64BitInstructionSet(cu_->instruction_set)) { 539ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pFmodf), rl_src1, rl_src2, 549ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko false); 559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmodf), rl_src1, rl_src2, 579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko false); 589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 59a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee rl_result = GetReturn(kFPReg); 601fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 61a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 62a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_FLOAT: 631fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegFloat(rl_dest, rl_src1); 64a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 65b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 66a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 67b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 681fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 691fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 701fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 712700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_dest = rl_result.reg; 722700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_src1 = rl_src1.reg; 732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_src2 = rl_src2.reg; 74fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src2) { 75091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee r_src2 = AllocTempSingle(); 761fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_src2, r_dest); 774abb1a9000b525a0636763a97528e24468f16d10jeffhao } 781fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee NewLIR2(op, r_dest.GetReg(), r_src2.GetReg()); 801fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 81e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 82e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 831fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenArithOpDouble(Instruction::Code opcode, 8402031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 85091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_dest.wide); 86091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_dest.fp); 87091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_src1.wide); 88091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_src1.fp); 89091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_src2.wide); 90091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_src2.fp); 91b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode op = kX86Nop; 92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 93e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 94408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 95b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_DOUBLE_2ADDR: 96b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_DOUBLE: 97b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86AddsdRR; 98b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 99b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_DOUBLE_2ADDR: 100b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_DOUBLE: 101b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86SubsdRR; 102b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 103b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_DOUBLE_2ADDR: 104b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_DOUBLE: 105b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86DivsdRR; 106b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 107b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_DOUBLE_2ADDR: 108b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_DOUBLE: 109b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86MulsdRR; 110b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 111b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::REM_DOUBLE_2ADDR: 112babda950caf2d577aa57102c3281f0f3c36f3d6djeffhao case Instruction::REM_DOUBLE: 1131fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 1149ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (Is64BitInstructionSet(cu_->instruction_set)) { 1159ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pFmod), rl_src1, rl_src2, 1169ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko false); 1179ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 1189ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmod), rl_src1, rl_src2, 1199ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko false); 1209ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 121a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee rl_result = GetReturnWide(kFPReg); 1221fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 123a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 124a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 1251fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegDouble(rl_dest, rl_src1); 126a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 128a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1301fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 1311fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 1321fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 133091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (rl_result.reg == rl_src2.reg) { 134091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rl_src2.reg = AllocTempDouble(); 135091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(rl_src2.reg, rl_result.reg); 1364abb1a9000b525a0636763a97528e24468f16d10jeffhao } 137091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(rl_result.reg, rl_src1.reg); 138091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(op, rl_result.reg.GetReg(), rl_src2.reg.GetReg()); 1391fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 140e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 141e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 142614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoruvoid X86Mir2Lir::GenLongToFP(RegLocation rl_dest, RegLocation rl_src, bool is_double) { 143614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // Compute offsets to the source and destination VRs on stack 144614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru int src_v_reg_offset = SRegOffset(rl_src.s_reg_low); 145614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru int dest_v_reg_offset = SRegOffset(rl_dest.s_reg_low); 146614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 147614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // Update the in-register state of source. 148614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru rl_src = UpdateLocWide(rl_src); 149614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 150614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // If the source is in physical register, then put it in its location on stack. 151614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru if (rl_src.location == kLocPhysReg) { 152091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegisterInfo* reg_info = GetRegInfo(rl_src.reg); 153614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 154091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (reg_info != nullptr && reg_info->IsTemp()) { 155614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // Calling FlushSpecificReg because it will only write back VR if it is dirty. 156091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FlushSpecificReg(reg_info); 157091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // ResetDef to prevent NullifyRange from removing stores. 158091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee ResetDef(rl_src.reg); 159614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } else { 160614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // It must have been register promoted if it is not a temp but is still in physical 161614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // register. Since we need it to be in memory to convert, we place it there now. 162455759b5702b9435b91d1b4dada22c4cce7cae3cVladimir Marko StoreBaseDisp(TargetReg(kSp), src_v_reg_offset, rl_src.reg, k64); 163614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } 164614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } 165614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 166614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // Push the source virtual register onto the x87 stack. 167091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LIR *fild64 = NewLIR2NoDest(kX86Fild64M, TargetReg(kSp).GetReg(), 168091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee src_v_reg_offset + LOWORD_OFFSET); 169614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru AnnotateDalvikRegAccess(fild64, (src_v_reg_offset + LOWORD_OFFSET) >> 2, 170091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee true /* is_load */, true /* is64bit */); 171614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 172614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru // Now pop off x87 stack and store it in the destination VR's stack location. 173614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru int opcode = is_double ? kX86Fstp64M : kX86Fstp32M; 174614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru int displacement = is_double ? dest_v_reg_offset + LOWORD_OFFSET : dest_v_reg_offset; 1752700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LIR *fstp = NewLIR2NoDest(opcode, TargetReg(kSp).GetReg(), displacement); 176614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru AnnotateDalvikRegAccess(fstp, displacement >> 2, false /* is_load */, is_double); 177614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 178614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru /* 179614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * The result is in a physical register if it was in a temp or was register 180614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * promoted. For that reason it is enough to check if it is in physical 181614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * register. If it is, then we must do all of the bookkeeping necessary to 182614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * invalidate temp (if needed) and load in promoted register (if needed). 183614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * If the result's location is in memory, then we do not need to do anything 184614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * more since the fstp has already placed the correct value in memory. 185614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru */ 18630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee RegLocation rl_result = is_double ? UpdateLocWideTyped(rl_dest, kFPReg) : 18730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee UpdateLocTyped(rl_dest, kFPReg); 188614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru if (rl_result.location == kLocPhysReg) { 189614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru /* 190614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * We already know that the result is in a physical register but do not know if it is the 191614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * right class. So we call EvalLoc(Wide) first which will ensure that it will get moved to the 192614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru * correct register class. 193614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru */ 194614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru if (is_double) { 195614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru rl_result = EvalLocWide(rl_dest, kFPReg, true); 196614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 1973bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko LoadBaseDisp(TargetReg(kSp), dest_v_reg_offset, rl_result.reg, k64); 198614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 19951a80d72dc436a4a89c636987b9cedabe774fdd6Maxim Kazantsev StoreFinalValueWide(rl_dest, rl_result); 200614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } else { 201614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru rl_result = EvalLoc(rl_dest, kFPReg, true); 202614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 203695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Load32Disp(TargetReg(kSp), dest_v_reg_offset, rl_result.reg); 204614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 20551a80d72dc436a4a89c636987b9cedabe774fdd6Maxim Kazantsev StoreFinalValue(rl_dest, rl_result); 206614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } 207614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru } 208614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru} 209614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 2101fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, 21102031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src) { 2125121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao RegisterClass rcSrc = kFPReg; 213b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode op = kX86Nop; 214fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 215b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (opcode) { 216b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::INT_TO_FLOAT: 2175121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kCoreReg; 218b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsi2ssRR; 219b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 220b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DOUBLE_TO_FLOAT: 2215121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kFPReg; 222b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsd2ssRR; 223b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 224b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::FLOAT_TO_DOUBLE: 2255121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kFPReg; 226b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtss2sdRR; 227b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 228b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::INT_TO_DOUBLE: 2295121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kCoreReg; 230b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsi2sdRR; 231b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 232292188d514c9826971308a18fcc5a66261729f3bjeffhao case Instruction::FLOAT_TO_INT: { 2331fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 234078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 2351fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2361fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 237091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage temp_reg = AllocTempSingle(); 23841005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 2392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstant(rl_result.reg, 0x7fffffff); 240091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86Cvtsi2ssRR, temp_reg.GetReg(), rl_result.reg.GetReg()); 241091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86ComissRR, rl_src.reg.GetReg(), temp_reg.GetReg()); 2421fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 2431fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 244091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86Cvttss2siRR, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 2451fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 2461fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_na_n->target = NewLIR0(kPseudoTargetLabel); 24700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Xor32RR, rl_result.reg.GetReg(), rl_result.reg.GetReg()); 2481fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 2491fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_normal->target = NewLIR0(kPseudoTargetLabel); 2501fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 251a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 252292188d514c9826971308a18fcc5a66261729f3bjeffhao } 253292188d514c9826971308a18fcc5a66261729f3bjeffhao case Instruction::DOUBLE_TO_INT: { 2541fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 255078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 2561fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 258091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage temp_reg = AllocTempDouble(); 25941005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 2602700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstant(rl_result.reg, 0x7fffffff); 261091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86Cvtsi2sdRR, temp_reg.GetReg(), rl_result.reg.GetReg()); 262091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86ComisdRR, rl_src.reg.GetReg(), temp_reg.GetReg()); 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 2641fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 265091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86Cvttsd2siRR, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 2661fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 2671fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_na_n->target = NewLIR0(kPseudoTargetLabel); 26800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Xor32RR, rl_result.reg.GetReg(), rl_result.reg.GetReg()); 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 2701fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_normal->target = NewLIR0(kPseudoTargetLabel); 2711fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 272a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 273292188d514c9826971308a18fcc5a66261729f3bjeffhao } 274b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::LONG_TO_DOUBLE: 275a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu if (Gen64Bit()) { 276a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rcSrc = kCoreReg; 277a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu op = kX86Cvtsqi2sdRR; 278a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu break; 279a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu } 280614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru GenLongToFP(rl_dest, rl_src, true /* is_double */); 281a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 282b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::LONG_TO_FLOAT: 283a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu if (Gen64Bit()) { 284a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rcSrc = kCoreReg; 285a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu op = kX86Cvtsqi2ssRR; 286a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu break; 287a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu } 288614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru GenLongToFP(rl_dest, rl_src, false /* is_double */); 289a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 29041005ddb5576b8630a1084fbb3979ffa602c0599jeffhao case Instruction::FLOAT_TO_LONG: 291a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu if (Gen64Bit()) { 292a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rl_src = LoadValue(rl_src, kFPReg); 293a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu // If result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 294a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu ClobberSReg(rl_dest.s_reg_low); 295a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rl_result = EvalLoc(rl_dest, kCoreReg, true); 296a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu RegStorage temp_reg = AllocTempSingle(); 297a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu 298a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu // Set 0x7fffffffffffffff to rl_result 299a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LoadConstantWide(rl_result.reg, 0x7fffffffffffffff); 300a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Cvtsqi2ssRR, temp_reg.GetReg(), rl_result.reg.GetReg()); 301a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86ComissRR, rl_src.reg.GetReg(), temp_reg.GetReg()); 302a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 303a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 304a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Cvttss2sqiRR, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 305a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 306a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_na_n->target = NewLIR0(kPseudoTargetLabel); 307a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Xor64RR, rl_result.reg.GetReg(), rl_result.reg.GetReg()); 308a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 309a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_normal->target = NewLIR0(kPseudoTargetLabel); 310a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu StoreValueWide(rl_dest, rl_result); 3119ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 3129ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pF2l), rl_dest, rl_src); 3139ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 314a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 315b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DOUBLE_TO_LONG: 316a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu if (Gen64Bit()) { 317a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rl_src = LoadValueWide(rl_src, kFPReg); 318a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu // If result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 319a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu ClobberSReg(rl_dest.s_reg_low); 320a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rl_result = EvalLoc(rl_dest, kCoreReg, true); 321a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu RegStorage temp_reg = AllocTempDouble(); 322a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu 323a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu // Set 0x7fffffffffffffff to rl_result 324a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LoadConstantWide(rl_result.reg, 0x7fffffffffffffff); 325a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Cvtsqi2sdRR, temp_reg.GetReg(), rl_result.reg.GetReg()); 326a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86ComisdRR, rl_src.reg.GetReg(), temp_reg.GetReg()); 327a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 328a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 329a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Cvttsd2sqiRR, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 330a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 331a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_na_n->target = NewLIR0(kPseudoTargetLabel); 332a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu NewLIR2(kX86Xor64RR, rl_result.reg.GetReg(), rl_result.reg.GetReg()); 333a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 334a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu branch_normal->target = NewLIR0(kPseudoTargetLabel); 335a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu StoreValueWide(rl_dest, rl_result); 3369ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 3379ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pD2l), rl_dest, rl_src); 3389ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 339a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 340b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 341a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(INFO) << "Unexpected opcode: " << opcode; 342b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 343091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // At this point, target will be either float or double. 344091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(rl_dest.fp); 345fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 3461fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, rcSrc); 347b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 3481fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, rcSrc); 349b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 350091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 351091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(op, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 352fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 3531fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 354b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 3551fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 356b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 357e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 358e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 3591fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenCmpFP(Instruction::Code code, RegLocation rl_dest, 36002031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src1, RegLocation rl_src2) { 361b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool single = (code == Instruction::CMPL_FLOAT) || (code == Instruction::CMPG_FLOAT); 362fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool unordered_gt = (code == Instruction::CMPG_DOUBLE) || (code == Instruction::CMPG_FLOAT); 363b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (single) { 3641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 3651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 366b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 3671fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 3681fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 369b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 370078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 3711fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 3721fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); 3732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstantNoClobber(rl_result.reg, unordered_gt ? 1 : 0); 374b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (single) { 375091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86UcomissRR, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 376b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 377091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86UcomisdRR, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 378b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 379b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR* branch = NULL; 380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 3811fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 382b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 383703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // If the result reg can't be byte accessed, use a jump and move instead of a set. 384091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (rl_result.reg.GetReg() >= rs_rX86_SP.GetReg()) { 385703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao LIR* branch2 = NULL; 386fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 3871fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2 = NewLIR2(kX86Jcc8, 0, kX86CondA); 38800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Mov32RI, rl_result.reg.GetReg(), 0x0); 389703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 3901fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2 = NewLIR2(kX86Jcc8, 0, kX86CondBe); 39100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Mov32RI, rl_result.reg.GetReg(), 0x1); 392703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 3931fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2->target = NewLIR0(kPseudoTargetLabel); 394703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 39500e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondA /* above - unsigned > */); 396703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 39700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86Sbb32RI, rl_result.reg.GetReg(), 0); 398fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 3991fd3346740dfb7f47be9922312b68a4227fada96buzbee branch->target = NewLIR0(kPseudoTargetLabel); 400b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 4011fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 402e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 403e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4041fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, 40502031b185b4653e6c72e21f7a51238b903f6d638buzbee bool is_double) { 4060d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LIR* taken = &block_label_list_[bb->taken]; 4070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LIR* not_taken = &block_label_list_[bb->fall_through]; 4084b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao LIR* branch = NULL; 409fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 410fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 411fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 4121fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrcWide(mir, 0); 4131fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrcWide(mir, 2); 4141fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 4151fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 416091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86UcomisdRR, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 4174b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } else { 4181fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrc(mir, 0); 4191fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrc(mir, 1); 4201fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 4211fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 42200e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee NewLIR2(kX86UcomissRR, rl_src1.reg.GetReg(), rl_src2.reg.GetReg()); 4234b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 424a894607bca7eb623bc957363e4b36f44cfeea1b6Vladimir Marko ConditionCode ccode = mir->meta.ccode; 4254b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao switch (ccode) { 4264b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondEq: 427fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!gt_bias) { 4281fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 429fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 4304b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 4314b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4324b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondNe: 433fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!gt_bias) { 4341fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 4354b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 4364b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 4374b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4384b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondLt: 439fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 4401fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 441fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 4424b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 44358af1f9385742f70aca4fcb5e13aba53b8be2ef4Vladimir Marko ccode = kCondUlt; 4444b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4454b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondLe: 446fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 4471fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 448fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 4494b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 4504b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondLs; 4514b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4524b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondGt: 453fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 4541fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 4554b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 4564b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 4574b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondHi; 4584b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4594b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondGe: 460fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 4611fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 4624b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 4634b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 46458af1f9385742f70aca4fcb5e13aba53b8be2ef4Vladimir Marko ccode = kCondUge; 4654b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 4664b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao default: 467cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 4684b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 4691fd3346740dfb7f47be9922312b68a4227fada96buzbee OpCondBranch(ccode, taken); 4704b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao} 4714b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao 4722ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) { 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 4741fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kCoreReg); 4751fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 4762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegRegImm(kOpAdd, rl_result.reg, rl_src.reg, 0x80000000); 4771fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 479efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4802ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { 481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 4821fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kCoreReg); 483a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu rl_result = EvalLocWide(rl_dest, kCoreReg, true); 484a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu if (Gen64Bit()) { 485a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu LoadConstantWide(rl_result.reg, 0x8000000000000000); 486a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu OpRegReg(kOpAdd, rl_result.reg, rl_src.reg); 487a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu } else { 488a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu OpRegRegImm(kOpAdd, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), 0x80000000); 489a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu OpRegCopy(rl_result.reg, rl_src.reg); 490a014776f4474579d4dfc72e3374ba45c6f6e5f35Chao-ying Fu } 4911fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 492efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 493efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4941fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::GenInlinedSqrt(CallInfo* info) { 495bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell RegLocation rl_src = info->args[0]; 496bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell RegLocation rl_dest = InlineTargetWide(info); // double place for result 497bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell rl_src = LoadValueWide(rl_src, kFPReg); 498bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true); 499091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86SqrtsdRR, rl_result.reg.GetReg(), rl_src.reg.GetReg()); 500bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell StoreValueWide(rl_dest, rl_result); 501bff1ef0746048978b877c0664f758d2d6006f27dMark Mendell return true; 502efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5067934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 507