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 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; 60b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 61a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 62b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 631fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 66fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest = rl_result.low_reg; 67fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src1 = rl_src1.low_reg; 68fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src2 = rl_src2.low_reg; 69fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src2) { 701fd3346740dfb7f47be9922312b68a4227fada96buzbee r_src2 = AllocTempFloat(); 711fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_src2, r_dest); 724abb1a9000b525a0636763a97528e24468f16d10jeffhao } 731fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 741fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, r_dest, r_src2); 751fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 76e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 77e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 781fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenArithOpDouble(Instruction::Code opcode, 7902031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { 80b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode op = kX86Nop; 81fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 82e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 83408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee switch (opcode) { 84b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_DOUBLE_2ADDR: 85b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::ADD_DOUBLE: 86b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86AddsdRR; 87b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 88b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_DOUBLE_2ADDR: 89b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::SUB_DOUBLE: 90b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86SubsdRR; 91b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 92b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_DOUBLE_2ADDR: 93b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DIV_DOUBLE: 94b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86DivsdRR; 95b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 96b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_DOUBLE_2ADDR: 97b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::MUL_DOUBLE: 98b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86MulsdRR; 99b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 100b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::REM_DOUBLE_2ADDR: 101babda950caf2d577aa57102c3281f0f3c36f3d6djeffhao case Instruction::REM_DOUBLE: 1021fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushAllRegs(); // Send everything to home location 1037655f29fabc0a12765de828914a18314382e5a35Ian Rogers CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(pFmod), rl_src1, rl_src2, 1047655f29fabc0a12765de828914a18314382e5a35Ian Rogers false); 1051fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = GetReturnWide(true); 1061fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 107a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 108a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee case Instruction::NEG_DOUBLE: 1091fd3346740dfb7f47be9922312b68a4227fada96buzbee GenNegDouble(rl_dest, rl_src1); 110a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 111b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 112a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(FATAL) << "Unexpected opcode: " << opcode; 113b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1141fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src1.wide); 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 117fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src2.wide); 1181fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 119fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 120fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_result.wide); 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest = S2d(rl_result.low_reg, rl_result.high_reg); 122fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src1 = S2d(rl_src1.low_reg, rl_src1.high_reg); 123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src2 = S2d(rl_src2.low_reg, rl_src2.high_reg); 124fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src2) { 1251fd3346740dfb7f47be9922312b68a4227fada96buzbee r_src2 = AllocTempDouble() | X86_FP_DOUBLE; 1261fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_src2, r_dest); 1274abb1a9000b525a0636763a97528e24468f16d10jeffhao } 1281fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 1291fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, r_dest, r_src2); 1301fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 131e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 132e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1331fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, 13402031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src) { 1355121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao RegisterClass rcSrc = kFPReg; 136b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode op = kX86Nop; 137fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg; 138fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 139b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (opcode) { 140b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::INT_TO_FLOAT: 1415121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kCoreReg; 142b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsi2ssRR; 143b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 144b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DOUBLE_TO_FLOAT: 1455121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kFPReg; 146b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsd2ssRR; 147b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 148b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::FLOAT_TO_DOUBLE: 1495121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kFPReg; 150b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtss2sdRR; 151b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 152b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::INT_TO_DOUBLE: 1535121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao rcSrc = kCoreReg; 154b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kX86Cvtsi2sdRR; 155b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 156292188d514c9826971308a18fcc5a66261729f3bjeffhao case Instruction::FLOAT_TO_INT: { 1571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kFPReg); 158fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 159078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 1601fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 1611fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 1621fd3346740dfb7f47be9922312b68a4227fada96buzbee int temp_reg = AllocTempFloat(); 16341005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 1641fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, 0x7fffffff); 1651fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Cvtsi2ssRR, temp_reg, rl_result.low_reg); 1661fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86ComissRR, src_reg, temp_reg); 1671fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 1681fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 1691fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Cvttss2siRR, rl_result.low_reg, src_reg); 1701fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 1711fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_na_n->target = NewLIR0(kPseudoTargetLabel); 1721fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Xor32RR, rl_result.low_reg, rl_result.low_reg); 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 1741fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_normal->target = NewLIR0(kPseudoTargetLabel); 1751fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 176a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 177292188d514c9826971308a18fcc5a66261729f3bjeffhao } 178292188d514c9826971308a18fcc5a66261729f3bjeffhao case Instruction::DOUBLE_TO_INT: { 1791fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kFPReg); 180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 181078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 1821fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 1831fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 1841fd3346740dfb7f47be9922312b68a4227fada96buzbee int temp_reg = AllocTempDouble() | X86_FP_DOUBLE; 18541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 1861fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(rl_result.low_reg, 0x7fffffff); 1871fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Cvtsi2sdRR, temp_reg, rl_result.low_reg); 1881fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86ComisdRR, src_reg, temp_reg); 1891fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA); 1901fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP); 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Cvttsd2siRR, rl_result.low_reg, src_reg); 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch_normal = NewLIR1(kX86Jmp8, 0); 1931fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_na_n->target = NewLIR0(kPseudoTargetLabel); 1941fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Xor32RR, rl_result.low_reg, rl_result.low_reg); 1951fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel); 1961fd3346740dfb7f47be9922312b68a4227fada96buzbee branch_normal->target = NewLIR0(kPseudoTargetLabel); 1971fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 198a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 199292188d514c9826971308a18fcc5a66261729f3bjeffhao } 200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::LONG_TO_DOUBLE: 2017655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pL2d), rl_dest, rl_src); 202a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 203b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::LONG_TO_FLOAT: 204babda950caf2d577aa57102c3281f0f3c36f3d6djeffhao // TODO: inline by using memory as a 64-bit source. Be careful about promoted registers. 2057655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pL2f), rl_dest, rl_src); 206a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 20741005ddb5576b8630a1084fbb3979ffa602c0599jeffhao case Instruction::FLOAT_TO_LONG: 2087655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pF2l), rl_dest, rl_src); 209a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 210b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case Instruction::DOUBLE_TO_LONG: 2117655f29fabc0a12765de828914a18314382e5a35Ian Rogers GenConversionCall(QUICK_ENTRYPOINT_OFFSET(pD2l), rl_dest, rl_src); 212a5954be0aac5edd892fb31a209960543d00e4500buzbee return; 213b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 214a5954be0aac5edd892fb31a209960543d00e4500buzbee LOG(INFO) << "Unexpected opcode: " << opcode; 215b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 216fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.wide) { 2171fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, rcSrc); 218fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = S2d(rl_src.low_reg, rl_src.high_reg); 219b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2201fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, rcSrc); 221fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg = rl_src.low_reg; 222b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 223fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_dest.wide) { 2241fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 2251fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg); 2261fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 227b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2281fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kFPReg, true); 2291fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(op, rl_result.low_reg, src_reg); 2301fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 231b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 232e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 233e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2341fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenCmpFP(Instruction::Code code, RegLocation rl_dest, 23502031b185b4653e6c72e21f7a51238b903f6d638buzbee RegLocation rl_src1, RegLocation rl_src2) { 236b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool single = (code == Instruction::CMPL_FLOAT) || (code == Instruction::CMPG_FLOAT); 237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool unordered_gt = (code == Instruction::CMPG_DOUBLE) || (code == Instruction::CMPG_FLOAT); 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg1; 239fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int src_reg2; 240b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (single) { 2411fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg1 = rl_src1.low_reg; 2431fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 244fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg2 = rl_src2.low_reg; 245b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2461fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg1 = S2d(rl_src1.low_reg, rl_src1.high_reg); 2481fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 249fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee src_reg2 = S2d(rl_src2.low_reg, rl_src2.high_reg); 250b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 251078fa459fee2d5f26a94fbbe5b8f4feeafb4afb2buzbee // In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc() 2521fd3346740dfb7f47be9922312b68a4227fada96buzbee ClobberSReg(rl_dest.s_reg_low); 2531fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); 2541fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstantNoClobber(rl_result.low_reg, unordered_gt ? 1 : 0); 255b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (single) { 2561fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86UcomissRR, src_reg1, src_reg2); 257b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2581fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86UcomisdRR, src_reg1, src_reg2); 259b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 260b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR* branch = NULL; 261fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 2621fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 263b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 264703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // If the result reg can't be byte accessed, use a jump and move instead of a set. 265fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_result.low_reg >= 4) { 266703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao LIR* branch2 = NULL; 267fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 2681fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2 = NewLIR2(kX86Jcc8, 0, kX86CondA); 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Mov32RI, rl_result.low_reg, 0x0); 270703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 2711fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2 = NewLIR2(kX86Jcc8, 0, kX86CondBe); 2721fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Mov32RI, rl_result.low_reg, 0x1); 273703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 2741fd3346740dfb7f47be9922312b68a4227fada96buzbee branch2->target = NewLIR0(kPseudoTargetLabel); 275703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 2761fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Set8R, rl_result.low_reg, kX86CondA /* above - unsigned > */); 277703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 2781fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Sbb32RI, rl_result.low_reg, 0); 279fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (unordered_gt) { 2801fd3346740dfb7f47be9922312b68a4227fada96buzbee branch->target = NewLIR0(kPseudoTargetLabel); 281b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 2821fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 283e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 284e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2851fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, 28602031b185b4653e6c72e21f7a51238b903f6d638buzbee bool is_double) { 2871fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* taken = &block_label_list_[bb->taken->id]; 2881fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* not_taken = &block_label_list_[bb->fall_through->id]; 2894b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao LIR* branch = NULL; 290fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src1; 291fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_src2; 292fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_double) { 2931fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrcWide(mir, 0); 2941fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrcWide(mir, 2); 2951fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValueWide(rl_src1, kFPReg); 2961fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValueWide(rl_src2, kFPReg); 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86UcomisdRR, S2d(rl_src1.low_reg, rl_src1.high_reg), 298fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee S2d(rl_src2.low_reg, rl_src2.high_reg)); 2994b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } else { 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = mir_graph_->GetSrc(mir, 0); 3011fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = mir_graph_->GetSrc(mir, 1); 3021fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src1 = LoadValue(rl_src1, kFPReg); 3031fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src2 = LoadValue(rl_src2, kFPReg); 3041fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86UcomissRR, rl_src1.low_reg, rl_src2.low_reg); 3054b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3064b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); 3074b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao switch (ccode) { 3084b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondEq: 309fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!gt_bias) { 3101fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 311fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 3124b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3134b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3144b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondNe: 315fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!gt_bias) { 3161fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 3174b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 3184b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3194b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3204b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondLt: 321fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 3221fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 323fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 3244b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3254b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondCs; 3264b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3274b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondLe: 328fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch->target = not_taken; 3314b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3324b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondLs; 3334b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3344b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondGt: 335fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 3361fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 3374b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 3384b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3394b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondHi; 3404b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3414b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao case kCondGe: 342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (gt_bias) { 3431fd3346740dfb7f47be9922312b68a4227fada96buzbee branch = NewLIR2(kX86Jcc8, 0, kX86CondPE); 3444b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao branch->target = taken; 3454b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3464b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao ccode = kCondCc; 3474b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao break; 3484b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao default: 349cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Unexpected ccode: " << ccode; 3504b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao } 3511fd3346740dfb7f47be9922312b68a4227fada96buzbee OpCondBranch(ccode, taken); 3524b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao} 3534b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao 3542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) { 355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 3561fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kCoreReg); 3571fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 3581fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegRegImm(kOpAdd, rl_result.low_reg, rl_src.low_reg, 0x80000000); 3591fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3622ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { 363fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegLocation rl_result; 3641fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValueWide(rl_src, kCoreReg); 3651fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_result = EvalLoc(rl_dest, kCoreReg, true); 3661fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegRegImm(kOpAdd, rl_result.high_reg, rl_src.high_reg, 0x80000000); 3671fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(rl_result.low_reg, rl_src.low_reg); 3681fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValueWide(rl_dest, rl_result); 369efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 370efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3711fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::GenInlinedSqrt(CallInfo* info) { 3721fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_NE(cu_->instruction_set, kThumb2); 373efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return false; 374efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 375efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 376efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 377efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 379