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 Cheng/*
185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * This file is included by Codegen-armv5te-vfp.c, and implements architecture
195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * variant-specific code.
205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */
215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
2210a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee/*
2310a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee * Take the address of a Dalvik register and store it into rDest.
2410a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee * Clobber any live values associated either with the Dalvik value
2510a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee * or the target register and lock the target fixed register.
2610a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee */
2710a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbeestatic void loadValueAddressDirect(CompilationUnit *cUnit, RegLocation rlSrc,
2810a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee                                   int rDest)
295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
30c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee     rlSrc = rlSrc.wide ? dvmCompilerUpdateLocWide(cUnit, rlSrc) :
31c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                          dvmCompilerUpdateLoc(cUnit, rlSrc);
325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     if (rlSrc.location == kLocPhysReg) {
335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         if (rlSrc.wide) {
34f6789277a9d25379bf43ffc39ef091db722dd5afbuzbee             dvmCompilerFlushRegWide(cUnit, rlSrc.lowReg, rlSrc.highReg);
355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         } else {
36f6789277a9d25379bf43ffc39ef091db722dd5afbuzbee             dvmCompilerFlushReg(cUnit, rlSrc.lowReg);
375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         }
385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     }
3910a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee     dvmCompilerClobber(cUnit, rDest);
4010a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee     dvmCompilerLockTemp(cUnit, rDest);
4120d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng     opRegRegImm(cUnit, kOpAdd, rDest, r5FP,
42c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                 dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2);
435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir)
465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
47c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    RegLocation rlResult = LOC_C_RETURN_WIDE;
495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    RegLocation rlDest = LOC_DALVIK_RETURN_VAL_WIDE;
5010a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc, r2);
515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    genDispatchToHandler(cUnit, TEMPLATE_SQRT_DOUBLE_VFP);
525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    storeValueWide(cUnit, rlDest, rlResult);
535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return false;
545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/*
575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * TUNING: On some implementations, it is quicker to pass addresses
585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * to the handlers rather than load the operands into core registers
595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * and then move the values to FP regs in the handlers.  Other implementations
605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * may prefer passing data in registers (and the latter approach would
617e914f110323165e7f683eece444ef83a499596dElliott Hughes * yield cleaner register handling - avoiding the requirement that operands
625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * be flushed to memory prior to the call).
635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */
645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                            RegLocation rlDest, RegLocation rlSrc1,
665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                            RegLocation rlSrc2)
675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
689a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    TemplateOpcode opcode;
695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /*
715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     * Don't attempt to optimize register usage since these opcodes call out to
725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     * the handlers.
735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     */
749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    switch (mir->dalvikInsn.opcode) {
755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_ADD_FLOAT_2ADDR:
765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_ADD_FLOAT:
779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_ADD_FLOAT_VFP;
785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_SUB_FLOAT_2ADDR:
805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_SUB_FLOAT:
819a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_SUB_FLOAT_VFP;
825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DIV_FLOAT_2ADDR:
845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DIV_FLOAT:
859a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_DIV_FLOAT_VFP;
865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_MUL_FLOAT_2ADDR:
885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_MUL_FLOAT:
899a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_MUL_FLOAT_VFP;
905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_REM_FLOAT_2ADDR:
925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_REM_FLOAT:
935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_NEG_FLOAT: {
945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        }
965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        default:
975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return true;
985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
9910a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlDest, r0);
10010a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc1, r1);
10110a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc2, r2);
1029a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    genDispatchToHandler(cUnit, opcode);
103c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    rlDest = dvmCompilerUpdateLoc(cUnit, rlDest);
1045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (rlDest.location == kLocPhysReg) {
105c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerClobber(cUnit, rlDest.lowReg);
1065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
1075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return false;
1085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
1095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
1105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
1115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                             RegLocation rlDest, RegLocation rlSrc1,
1125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                             RegLocation rlSrc2)
1135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
1149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    TemplateOpcode opcode;
1155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
1169a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    switch (mir->dalvikInsn.opcode) {
1175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_ADD_DOUBLE_2ADDR:
1185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_ADD_DOUBLE:
1199a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_ADD_DOUBLE_VFP;
1205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_SUB_DOUBLE_2ADDR:
1225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_SUB_DOUBLE:
1239a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_SUB_DOUBLE_VFP;
1245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DIV_DOUBLE_2ADDR:
1265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DIV_DOUBLE:
1279a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_DIV_DOUBLE_VFP;
1285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_MUL_DOUBLE_2ADDR:
1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_MUL_DOUBLE:
1319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein            opcode = TEMPLATE_MUL_DOUBLE_VFP;
1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_REM_DOUBLE_2ADDR:
1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_REM_DOUBLE:
1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_NEG_DOUBLE: {
1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1,
1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                               rlSrc2);
1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        }
1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        default:
1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return true;
1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
14210a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlDest, r0);
14310a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc1, r1);
14410a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc2, r2);
1459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    genDispatchToHandler(cUnit, opcode);
146c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    rlDest = dvmCompilerUpdateLocWide(cUnit, rlDest);
1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (rlDest.location == kLocPhysReg) {
148c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerClobber(cUnit, rlDest.lowReg);
149c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerClobber(cUnit, rlDest.highReg);
1505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return false;
1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genConversion(CompilationUnit *cUnit, MIR *mir)
1555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
1569a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    Opcode opcode = mir->dalvikInsn.opcode;
1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    bool longSrc = false;
1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    bool longDest = false;
1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    RegLocation rlSrc;
1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    RegLocation rlDest;
1616958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng    TemplateOpcode templateOpcode;
1629a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    switch (opcode) {
1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_INT_TO_FLOAT:
1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = false;
1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = false;
1666958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_INT_TO_FLOAT_VFP;
1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_FLOAT_TO_INT:
1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = false;
1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = false;
1716958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_FLOAT_TO_INT_VFP;
1725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DOUBLE_TO_FLOAT:
1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = true;
1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = false;
1766958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_DOUBLE_TO_FLOAT_VFP;
1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_FLOAT_TO_DOUBLE:
1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = false;
1805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = true;
1816958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_FLOAT_TO_DOUBLE_VFP;
1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_INT_TO_DOUBLE:
1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = false;
1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = true;
1866958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_INT_TO_DOUBLE_VFP;
1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DOUBLE_TO_INT:
1895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longSrc = true;
1905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            longDest = false;
1916958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_DOUBLE_TO_INT_VFP;
1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_LONG_TO_DOUBLE:
1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_FLOAT_TO_LONG:
1955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_LONG_TO_FLOAT:
1965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_DOUBLE_TO_LONG:
1975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return genConversionPortable(cUnit, mir);
1985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        default:
1995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return true;
2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
2015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
2025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (longSrc) {
203c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
2045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
205c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
2085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (longDest) {
209c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
2105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
211c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
21310a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlDest, r0);
21410a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc, r1);
2156958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng    genDispatchToHandler(cUnit, templateOpcode);
2165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (rlDest.wide) {
217c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlDest = dvmCompilerUpdateLocWide(cUnit, rlDest);
218c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerClobber(cUnit, rlDest.highReg);
2195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
220c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        rlDest = dvmCompilerUpdateLoc(cUnit, rlDest);
2215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
222c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    dvmCompilerClobber(cUnit, rlDest.lowReg);
2235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return false;
2245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
2255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
2265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
227c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                     RegLocation rlSrc1, RegLocation rlSrc2)
2285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
2296958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng    TemplateOpcode templateOpcode;
230c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    RegLocation rlResult = dvmCompilerGetReturn(cUnit);
2315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    bool wide = true;
2325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
2339a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein    switch(mir->dalvikInsn.opcode) {
2345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_CMPL_FLOAT:
2356958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_CMPL_FLOAT_VFP;
2365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            wide = false;
2375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
2385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_CMPG_FLOAT:
2396958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_CMPG_FLOAT_VFP;
2405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            wide = false;
2415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
2425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_CMPL_DOUBLE:
2436958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_CMPL_DOUBLE_VFP;
2445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
2455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        case OP_CMPG_DOUBLE:
2466958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng            templateOpcode = TEMPLATE_CMPG_DOUBLE_VFP;
2475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            break;
2485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        default:
2495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return true;
2505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
25110a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc1, r0);
25210a548d86ad1ef83fa6fc69c71ea20e06ba45184buzbee    loadValueAddressDirect(cUnit, rlSrc2, r1);
2536958e9edbf0cbc04c7c2aab7ccd63516b794a92dBen Cheng    genDispatchToHandler(cUnit, templateOpcode);
2545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    storeValue(cUnit, rlDest, rlResult);
2555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return false;
2565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
257