Thumb2VFP.cpp revision 7e914f110323165e7f683eece444ef83a499596d
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); 575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, op, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); 585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, 635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest, RegLocation rlSrc1, 645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc2) 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int op = kThumbBkpt; 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch (mir->dalvikInsn.opcode) { 705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_DOUBLE_2ADDR: 715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_ADD_DOUBLE: 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vaddd; 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_DOUBLE_2ADDR: 755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_SUB_DOUBLE: 765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vsubd; 775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_DOUBLE_2ADDR: 795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DIV_DOUBLE: 805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vdivd; 815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_DOUBLE_2ADDR: 835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_MUL_DOUBLE: 845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2Vmuld; 855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_DOUBLE_2ADDR: 875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_REM_DOUBLE: 885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_NEG_DOUBLE: { 895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, 905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2); 915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); 975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc1.wide); 985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); 995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc2.wide); 100c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlDest.wide); 1025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlResult.wide); 1035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, op, S2D(rlResult.lowReg, rlResult.highReg), 1045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc1.lowReg, rlSrc1.highReg), 1055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc2.lowReg, rlSrc2.highReg)); 1065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 1085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genConversion(CompilationUnit *cUnit, MIR *mir) 1115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1129a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein Opcode opcode = mir->dalvikInsn.opcode; 1135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int op = kThumbBkpt; 1145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool longSrc = false; 1155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool longDest = false; 1165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcReg; 1175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc; 1185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest; 1195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 1205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch (opcode) { 1225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_INT_TO_FLOAT: 1235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtIF; 1265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_INT: 1285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtFI; 1315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_FLOAT: 1335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = true; 1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtDF; 1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_DOUBLE: 1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = true; 1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtFd; 1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_INT_TO_DOUBLE: 1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = false; 1445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = true; 1455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtID; 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_INT: 1485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longSrc = true; 1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng longDest = false; 1505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng op = kThumb2VcvtDI; 1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_LONG_TO_DOUBLE: 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_FLOAT_TO_LONG: 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_LONG_TO_FLOAT: 1555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_DOUBLE_TO_LONG: 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return genConversionPortable(cUnit, mir); 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (longSrc) { 161c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); 1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng srcReg = S2D(rlSrc.lowReg, rlSrc.highReg); 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 165c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerGetSrc(cUnit, mir, 0); 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValue(cUnit, rlSrc, kFPReg); 1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng srcReg = rlSrc.lowReg; 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (longDest) { 170c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1); 171c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, op, S2D(rlResult.lowReg, rlResult.highReg), srcReg); 1735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 175c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerGetDest(cUnit, mir, 0); 176c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, op, rlResult.lowReg, srcReg); 1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir) 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *branch; 186c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); 1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlDest = inlinedTargetWide(cUnit, mir, true); 1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); 189c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); 1905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg), 1915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc.lowReg, rlSrc.highReg)); 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg), 1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlResult.lowReg, rlResult.highReg)); 1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR0(cUnit, kThumb2Fmstat); 1955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); 1966a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerClobberCallRegs(cUnit); 197bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng LOAD_FUNC_ADDR(cUnit, r2, (int)sqrt); 1985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg)); 1995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR1(cUnit, kThumbBlxR, r2); 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg), 2015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng r0, r1); 2025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *label = newLIR0(cUnit, kArmPseudoTargetLabel); 2035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng label->defMask = ENCODE_ALL; 2045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng branch->generic.target = (LIR *)label; 2055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 2067e914f110323165e7f683eece444ef83a499596dElliott Hughes return false; 2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, 2105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc1, RegLocation rlSrc2) 2115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 2125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool isDouble; 2135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int defaultResult; 2145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 2155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2169a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch(mir->dalvikInsn.opcode) { 2175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPL_FLOAT: 2185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = false; 2195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = -1; 2205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPG_FLOAT: 2225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = false; 2235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = 1; 2245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPL_DOUBLE: 2265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = true; 2275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = -1; 2285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng case OP_CMPG_DOUBLE: 2305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isDouble = true; 2315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defaultResult = 1; 2325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng break; 2335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng default: 2345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return true; 2355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (isDouble) { 2375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); 2385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); 239c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); 240c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 2415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, defaultResult); 2425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg), 2435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng S2D(rlSrc2.lowReg, rlSrc2.highReg)); 2445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 2455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); 2465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); 247c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobberSReg(cUnit, rlDest.sRegLow); 248c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 2495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, defaultResult); 2505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); 2515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(!FPREG(rlResult.lowReg)); 2535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR0(cUnit, kThumb2Fmstat); 2545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, ""); 2555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg, 2565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modifiedImmediate(-defaultResult)); // Must not alter ccodes 2575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genIT(cUnit, kArmCondEq, ""); 2585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, rlResult.lowReg, 0); 2595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 2605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 2615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 262