fp_arm.cc revision 84fd693103dddd50b6a18522bfb5eaab0e51b6ec
167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project
367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License");
567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License.
667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at
767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *      http://www.apache.org/licenses/LICENSE-2.0
967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software
1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS,
1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and
1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License.
1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art {
1811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
1931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool genArithOpFloat(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
2031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee                     RegLocation rlSrc1, RegLocation rlSrc2)
2167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{
2267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    int op = kThumbBkpt;
2367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlResult;
2467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    /*
2667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee     * Don't attempt to optimize register usage since these opcodes call out to
2767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee     * the handlers.
2867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee     */
2967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    switch (mir->dalvikInsn.opcode) {
30adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::ADD_FLOAT_2ADDR:
31adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::ADD_FLOAT:
3267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vadds;
3367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
34adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::SUB_FLOAT_2ADDR:
35adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::SUB_FLOAT:
3667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vsubs;
3767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
38adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DIV_FLOAT_2ADDR:
39adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DIV_FLOAT:
4067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vdivs;
4167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
42adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::MUL_FLOAT_2ADDR:
43adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::MUL_FLOAT:
4467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vmuls;
4567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
46adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::REM_FLOAT_2ADDR:
47adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::REM_FLOAT:
48adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::NEG_FLOAT: {
4967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1,
5067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee                                              rlSrc2);
5167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        }
5267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        default:
5367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return true;
5467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
5567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
5667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
5767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
5867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    newLIR3(cUnit, (ArmOpcode)op, rlResult.lowReg, rlSrc1.lowReg,
5967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            rlSrc2.lowReg);
6067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    storeValue(cUnit, rlDest, rlResult);
6167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    return false;
6267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
6367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
6431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool genArithOpDouble(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
6531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee                      RegLocation rlSrc1, RegLocation rlSrc2)
6667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{
6767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    int op = kThumbBkpt;
6867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlResult;
6967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
7067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    switch (mir->dalvikInsn.opcode) {
71adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::ADD_DOUBLE_2ADDR:
72adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::ADD_DOUBLE:
7367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vaddd;
7467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
75adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::SUB_DOUBLE_2ADDR:
76adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::SUB_DOUBLE:
7767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vsubd;
7867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
79adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DIV_DOUBLE_2ADDR:
80adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DIV_DOUBLE:
8167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vdivd;
8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
83adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::MUL_DOUBLE_2ADDR:
84adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::MUL_DOUBLE:
8567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2Vmuld;
8667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
87adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::REM_DOUBLE_2ADDR:
88adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::REM_DOUBLE:
89adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::NEG_DOUBLE: {
9067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1,
9167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee                                               rlSrc2);
9267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        }
9367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        default:
9467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return true;
9567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
9667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
9767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
98ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee    DCHECK(rlSrc1.wide);
9967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
100ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee    DCHECK(rlSrc2.wide);
10167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
102ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee    DCHECK(rlDest.wide);
103ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee    DCHECK(rlResult.wide);
10467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    newLIR3(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg),
10567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            S2D(rlSrc1.lowReg, rlSrc1.highReg),
10667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            S2D(rlSrc2.lowReg, rlSrc2.highReg));
10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    storeValueWide(cUnit, rlDest, rlResult);
10867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    return false;
10967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
11067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
11131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool genConversion(CompilationUnit* cUnit, MIR* mir)
11267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{
113adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    Instruction::Code opcode = mir->dalvikInsn.opcode;
11467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    int op = kThumbBkpt;
11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    bool longSrc = false;
11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    bool longDest = false;
11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    int srcReg;
11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlSrc;
11967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlDest;
12067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlResult;
12167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
12267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    switch (opcode) {
123adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::INT_TO_FLOAT:
12467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = false;
12567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = false;
12667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtIF;
12767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
128adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::FLOAT_TO_INT:
12967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = false;
13067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = false;
13167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtFI;
13267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
133adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DOUBLE_TO_FLOAT:
13467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = true;
13567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = false;
13667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtDF;
13767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
138adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::FLOAT_TO_DOUBLE:
13967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = false;
14067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = true;
14167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtFd;
14267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
143adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::INT_TO_DOUBLE:
14467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = false;
14567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = true;
14667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtID;
14767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
148adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DOUBLE_TO_INT:
14967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longSrc = true;
15067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            longDest = false;
15167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            op = kThumb2VcvtDI;
15267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
153adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::LONG_TO_DOUBLE:
154adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::FLOAT_TO_LONG:
155adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::LONG_TO_FLOAT:
156adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::DOUBLE_TO_LONG:
15767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return genConversionPortable(cUnit, mir);
15867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        default:
15967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return true;
16067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
16167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    if (longSrc) {
16267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
16367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
16467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
16567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
16667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc = oatGetSrc(cUnit, mir, 0);
16767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc = loadValue(cUnit, rlSrc, kFPReg);
16867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        srcReg = rlSrc.lowReg;
16967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
17067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    if (longDest) {
17167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlDest = oatGetDestWide(cUnit, mir, 0, 1);
17267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
17367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        newLIR2(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg),
17467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee                srcReg);
17567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        storeValueWide(cUnit, rlDest, rlResult);
17667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
17767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlDest = oatGetDest(cUnit, mir, 0);
17867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
17967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        newLIR2(cUnit, (ArmOpcode)op, rlResult.lowReg, srcReg);
18067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        storeValue(cUnit, rlDest, rlResult);
18167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
18267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    return false;
18367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
18467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
18584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbeevoid genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
18684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                         bool gtBias, bool isDouble)
18784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee{
18884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    LIR* labelList = (LIR*)cUnit->blockLabelList;
18984fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    LIR* target = &labelList[bb->taken->id];
19084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    RegLocation rlSrc1;
19184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    RegLocation rlSrc2;
19284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    if (isDouble) {
19384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
19484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
19584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
19684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
19784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
19884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                S2D(rlSrc2.lowReg, rlSrc2.highReg));
19984fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    } else {
20084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc1 = oatGetSrc(cUnit, mir, 0);
20184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc2 = oatGetSrc(cUnit, mir, 1);
20284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
20384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
20484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg);
20584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    }
20684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    newLIR0(cUnit, kThumb2Fmstat);
20784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
20884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    switch(ccode) {
20984fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondEq:
21084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondNe:
21184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            break;
21284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondLt:
21384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            if (gtBias) {
21484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                ccode = kCondMi;
21584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            }
21684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            break;
21784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondLe:
21884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            if (gtBias) {
21984fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                ccode = kCondLs;
22084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            }
22184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            break;
22284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondGt:
22384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            if (gtBias) {
22484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                ccode = kCondHi;
22584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            }
22684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            break;
22784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        case kCondGe:
22884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            if (gtBias) {
22984fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee                ccode = kCondCs;
23084fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            }
23184fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            break;
23284fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee        default:
23384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee            LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
23484fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    }
23584fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee    opCondBranch(cUnit, ccode, target);
23684fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee}
23784fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee
23884fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbee
23931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool genCmpFP(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
24031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee              RegLocation rlSrc1, RegLocation rlSrc2)
24167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{
24267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    bool isDouble;
24367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    int defaultResult;
24467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    RegLocation rlResult;
24567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
246b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes    switch (mir->dalvikInsn.opcode) {
247adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::CMPL_FLOAT:
24867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            isDouble = false;
24967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            defaultResult = -1;
25067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
251adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::CMPG_FLOAT:
25267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            isDouble = false;
25367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            defaultResult = 1;
25467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
255adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::CMPL_DOUBLE:
25667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            isDouble = true;
25767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            defaultResult = -1;
25867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
259adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        case Instruction::CMPG_DOUBLE:
26067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            isDouble = true;
26167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            defaultResult = 1;
26267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            break;
26367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        default:
26467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            return true;
26567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
26667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    if (isDouble) {
26767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
26867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
26967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        oatClobberSReg(cUnit, rlDest.sRegLow);
27067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
27167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        loadConstant(cUnit, rlResult.lowReg, defaultResult);
27267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
27367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee                S2D(rlSrc2.lowReg, rlSrc2.highReg));
27467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
27567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
27667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
27767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        oatClobberSReg(cUnit, rlDest.sRegLow);
27867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
27967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        loadConstant(cUnit, rlResult.lowReg, defaultResult);
28067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee        newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg);
28167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
282ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee    DCHECK(!FPREG(rlResult.lowReg));
28367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    newLIR0(cUnit, kThumb2Fmstat);
28467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
28582488f563e7f72f8c626052893c1792d76ab3fafbuzbee    opIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, "");
28667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg,
28767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee            modifiedImmediate(-defaultResult)); // Must not alter ccodes
28867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    genBarrier(cUnit);
28967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
29082488f563e7f72f8c626052893c1792d76ab3fafbuzbee    opIT(cUnit, kArmCondEq, "");
29167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    loadConstant(cUnit, rlResult.lowReg, 0);
29267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    genBarrier(cUnit);
29367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
29467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    storeValue(cUnit, rlDest, rlResult);
29567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    return false;
29667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
29711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
29811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes}  // namespace art
299