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