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