15d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 25d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Copyright (C) 2009 The Android Open Source Project 35d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 45d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 55d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * you may not use this file except in compliance with the License. 65d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * You may obtain a copy of the License at 75d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 85d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * http://www.apache.org/licenses/LICENSE-2.0 95d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Unless required by applicable law or agreed to in writing, software 115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * distributed under the License is distributed on an "AS IS" BASIS, 125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * See the License for the specific language governing permissions and 145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * limitations under the License. 155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, 185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest, RegLocation rlSrc1, 195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc2) 205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int op = kThumbBkpt; 225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Don't attempt to optimize register usage since these opcodes call out to 265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * the handlers. 275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 289a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch (mir->dalvikInsn.opcode) { 295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_FLOAT_2ADDR: 305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_FLOAT: 315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vadds; 325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_FLOAT_2ADDR: 345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_FLOAT: 355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vsubs; 365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_FLOAT_2ADDR: 385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_FLOAT: 395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vdivs; 405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_FLOAT_2ADDR: 425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_FLOAT: 435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vmuls; 445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_FLOAT_2ADDR: 465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_FLOAT: 475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_NEG_FLOAT: { 485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, 495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2); 505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); 555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); 56c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 575d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro newLIR3(cUnit, (ArmOpcode)op, rlResult.lowReg, rlSrc1.lowReg, 585d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro rlSrc2.lowReg); 595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, 645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest, RegLocation rlSrc1, 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc2) 665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int op = kThumbBkpt; 685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 709a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch (mir->dalvikInsn.opcode) { 715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_DOUBLE_2ADDR: 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_DOUBLE: 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vaddd; 745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_DOUBLE_2ADDR: 765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_DOUBLE: 775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vsubd; 785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_DOUBLE_2ADDR: 805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_DOUBLE: 815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vdivd; 825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_DOUBLE_2ADDR: 845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_DOUBLE: 855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vmuld; 865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_DOUBLE_2ADDR: 885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_DOUBLE: 895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_NEG_DOUBLE: { 905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, 915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2); 925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); 985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc1.wide); 995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); 1005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc2.wide); 101c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlDest.wide); 1035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlResult.wide); 1045d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro newLIR3(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg), 1055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc1.lowReg, rlSrc1.highReg), 1065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc2.lowReg, rlSrc2.highReg)); 1075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 1095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genConversion(CompilationUnit *cUnit, MIR *mir) 1125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1139a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein Opcode opcode = mir->dalvikInsn.opcode; 1145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int op = kThumbBkpt; 1155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool longSrc = false; 1165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool longDest = false; 1175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcReg; 1185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc; 1195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest; 1205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 1215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1229a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch (opcode) { 1235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_INT_TO_FLOAT: 1245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtIF; 1275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_INT: 1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtFI; 1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_FLOAT: 1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = true; 1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtDF; 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_DOUBLE: 1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = true; 1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtFd; 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_INT_TO_DOUBLE: 1445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = true; 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtID; 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_INT: 1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = true; 1505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtDI; 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_LONG_TO_DOUBLE: 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_LONG: 1555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_LONG_TO_FLOAT: 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_LONG: 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return genConversionPortable(cUnit, mir); 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (longSrc) { 162c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng srcReg = S2D(rlSrc.lowReg, rlSrc.highReg); 1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 166c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerGetSrc(cUnit, mir, 0); 1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValue(cUnit, rlSrc, kFPReg); 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng srcReg = rlSrc.lowReg; 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (longDest) { 171c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1); 172c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1735d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro newLIR2(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg), 1745d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro srcReg); 1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 177c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerGetDest(cUnit, mir, 0); 178c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1795d5b94c8d14b166af580d5dd5906db4f9527d6caCarl Shapiro newLIR2(cUnit, (ArmOpcode)op, rlResult.lowReg, srcReg); 1805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir) 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *branch; 188c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); 1895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest = inlinedTargetWide(cUnit, mir, true); 1905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); 191c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg), 1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc.lowReg, rlSrc.highReg)); 1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg), 1955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlResult.lowReg, rlResult.highReg)); 1965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR0(cUnit, kThumb2Fmstat); 1975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); 1986a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerClobberCallRegs(cUnit); 1990fbb7030fff58e25718291811394487d95d95a3eElliott Hughes LOAD_FUNC_ADDR(cUnit, r2, (int) (double (*)(double)) sqrt); 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg)); 2015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR1(cUnit, kThumbBlxR, r2); 2025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg), 2035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng r0, r1); 2045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *label = newLIR0(cUnit, kArmPseudoTargetLabel); 2055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng label->defMask = ENCODE_ALL; 2065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng branch->generic.target = (LIR *)label; 2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 2087e914f110323165e7f683eece444ef83a499596dElliott Hughes return false; 2095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, 2125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc1, RegLocation rlSrc2) 2135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 2145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool isDouble; 2155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int defaultResult; 2165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 2175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2189a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch(mir->dalvikInsn.opcode) { 2195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPL_FLOAT: 2205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = false; 2215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = -1; 2225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPG_FLOAT: 2245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = false; 2255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = 1; 2265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPL_DOUBLE: 2285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = true; 2295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = -1; 2305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPG_DOUBLE: 2325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = true; 2335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = 1; 2345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 2365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 2375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (isDouble) { 2395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); 2405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); 241c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); 242c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 2435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, defaultResult); 2445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg), 2455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc2.lowReg, rlSrc2.highReg)); 2465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 2475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); 2485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); 249c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); 250c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 2515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, defaultResult); 2525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); 2535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(!FPREG(rlResult.lowReg)); 2555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR0(cUnit, kThumb2Fmstat); 256ef32e1c4c7bac1ee15035e359330d84c0cea1770Ben Cheng 2575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, ""); 2585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg, 2595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modifiedImmediate(-defaultResult)); // Must not alter ccodes 260ef32e1c4c7bac1ee15035e359330d84c0cea1770Ben Cheng genBarrier(cUnit); 261ef32e1c4c7bac1ee15035e359330d84c0cea1770Ben Cheng 2625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genIT(cUnit, kArmCondEq, ""); 2635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, 0); 264ef32e1c4c7bac1ee15035e359330d84c0cea1770Ben Cheng genBarrier(cUnit); 265ef32e1c4c7bac1ee15035e359330d84c0cea1770Ben Cheng 2665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 2675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 2685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 269