1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/*
2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2012 The Android Open Source Project
3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License.
6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at
7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software
11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and
14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License.
15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */
16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_mips.h"
18d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers
190b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h"
207940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h"
21166db04e259ca51838c311891598664deeed85adIan Rogers#include "entrypoints/quick/quick_entrypoints.h"
22641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h"
2357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
24e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art {
25e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
261095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevicvoid MipsMir2Lir::GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest,
271095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic                                  RegLocation rl_src1, RegLocation rl_src2) {
28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int op = kMipsNop;
29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegLocation rl_result;
30e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Don't attempt to optimize register usage since these opcodes call out to
33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * the handlers.
34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
35408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  switch (opcode) {
36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_FLOAT_2ADDR:
37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_FLOAT:
38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFadds;
39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_FLOAT_2ADDR:
41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_FLOAT:
42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFsubs;
43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_FLOAT_2ADDR:
45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_FLOAT:
46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFdivs;
47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_FLOAT_2ADDR:
49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_FLOAT:
50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFmuls;
51a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
52a6f3aaf8ca5385d870c35d1555b7787d56a70c95Ian Rogers    case Instruction::REM_FLOAT_2ADDR:
53a6f3aaf8ca5385d870c35d1555b7787d56a70c95Ian Rogers    case Instruction::REM_FLOAT:
541095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      FlushAllRegs();   // Send everything to home location.
55984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      CallRuntimeHelperRegLocationRegLocation(kQuickFmodf, rl_src1, rl_src2, false);
56a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee      rl_result = GetReturn(kFPReg);
571fd3346740dfb7f47be9922312b68a4227fada96buzbee      StoreValue(rl_dest, rl_result);
58a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
59a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee    case Instruction::NEG_FLOAT:
601fd3346740dfb7f47be9922312b68a4227fada96buzbee      GenNegFloat(rl_dest, rl_src1);
61a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
62a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
63a5954be0aac5edd892fb31a209960543d00e4500buzbee      LOG(FATAL) << "Unexpected opcode: " << opcode;
64a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
651fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src1 = LoadValue(rl_src1, kFPReg);
661fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src2 = LoadValue(rl_src2, kFPReg);
671fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_result = EvalLoc(rl_dest, kFPReg, true);
6800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee  NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
691fd3346740dfb7f47be9922312b68a4227fada96buzbee  StoreValue(rl_dest, rl_result);
70e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
71e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
721095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevicvoid MipsMir2Lir::GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest,
731095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic                                   RegLocation rl_src1, RegLocation rl_src2) {
74a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int op = kMipsNop;
75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegLocation rl_result;
76e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
77408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  switch (opcode) {
78a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_DOUBLE_2ADDR:
79a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_DOUBLE:
80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFaddd;
81a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
82a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_DOUBLE_2ADDR:
83a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_DOUBLE:
84a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFsubd;
85a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_DOUBLE_2ADDR:
87a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_DOUBLE:
88a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFdivd;
89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_DOUBLE_2ADDR:
91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_DOUBLE:
92a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFmuld;
93a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
94a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_DOUBLE_2ADDR:
95a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_DOUBLE:
961095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      FlushAllRegs();   // Send everything to home location.
97984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      CallRuntimeHelperRegLocationRegLocation(kQuickFmod, rl_src1, rl_src2, false);
98a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee      rl_result = GetReturnWide(kFPReg);
991fd3346740dfb7f47be9922312b68a4227fada96buzbee      StoreValueWide(rl_dest, rl_result);
100a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
101a3a82b219531effb53aef13f48e50db9bf0f9fb5buzbee    case Instruction::NEG_DOUBLE:
1021fd3346740dfb7f47be9922312b68a4227fada96buzbee      GenNegDouble(rl_dest, rl_src1);
103a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
105a5954be0aac5edd892fb31a209960543d00e4500buzbee      LOG(FATAL) << "Unpexpected opcode: " << opcode;
106a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1071fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src1 = LoadValueWide(rl_src1, kFPReg);
108fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src1.wide);
1091fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src2 = LoadValueWide(rl_src2, kFPReg);
110fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src2.wide);
1111fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_result = EvalLoc(rl_dest, kFPReg, true);
112fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_dest.wide);
113fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_result.wide);
114091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
1151fd3346740dfb7f47be9922312b68a4227fada96buzbee  StoreValueWide(rl_dest, rl_result);
116e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
117e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
118675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jianvoid MipsMir2Lir::GenMultiplyByConstantFloat(RegLocation rl_dest, RegLocation rl_src1,
119675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian                                             int32_t constant) {
120675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  // TODO: need mips implementation.
121675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  UNUSED(rl_dest, rl_src1, constant);
122675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  LOG(FATAL) << "Unimplemented GenMultiplyByConstantFloat in mips";
123675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian}
124675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian
125675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jianvoid MipsMir2Lir::GenMultiplyByConstantDouble(RegLocation rl_dest, RegLocation rl_src1,
126675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian                                              int64_t constant) {
127675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  // TODO: need mips implementation.
128675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  UNUSED(rl_dest, rl_src1, constant);
129675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian  LOG(FATAL) << "Unimplemented GenMultiplyByConstantDouble in mips";
130675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian}
131675e09b2753c2fcd521bd8f0230a0abf06e9b0e9Ningsheng Jian
1321fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
1332ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                                RegLocation rl_src) {
134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int op = kMipsNop;
135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegLocation rl_result;
136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch (opcode) {
137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_FLOAT:
138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFcvtsw;
139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
140a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_FLOAT:
141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFcvtsd;
142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_DOUBLE:
144a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFcvtds;
145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
146a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_DOUBLE:
147a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op = kMipsFcvtdw;
148a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
149a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_INT:
1501095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickF2iz, rl_dest, rl_src, kCoreReg);
151a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_INT:
1531095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickD2iz, rl_dest, rl_src, kCoreReg);
154a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
155a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::LONG_TO_DOUBLE:
1561095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickL2d, rl_dest, rl_src, kFPReg);
157a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_LONG:
1591095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg);
160a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::LONG_TO_FLOAT:
1621095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickL2f, rl_dest, rl_src, kFPReg);
163a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_LONG:
1651095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg);
166a5954be0aac5edd892fb31a209960543d00e4500buzbee      return;
167a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
168a5954be0aac5edd892fb31a209960543d00e4500buzbee      LOG(FATAL) << "Unexpected opcode: " << opcode;
169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.wide) {
1711fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_src = LoadValueWide(rl_src, kFPReg);
172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
1731fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_src = LoadValue(rl_src, kFPReg);
174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
175091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  rl_result = EvalLoc(rl_dest, kFPReg, true);
176091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  NewLIR2(op, rl_result.reg.GetReg(), rl_src.reg.GetReg());
177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_dest.wide) {
1781fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreValueWide(rl_dest, rl_result);
179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
1801fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreValue(rl_dest, rl_result);
181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
182e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
183e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
184027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung// Get the reg storage for a wide FP. Is either a solo or a pair. Base is Mips-counted, e.g., even
185027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung// values are valid (0, 2).
186027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leungstatic RegStorage GetWideArgFP(bool fpuIs32Bit, size_t base) {
187027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  // Think about how to make this be able to be computed. E.g., rMIPS_FARG0 + base. Right now
188027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  // inlining should optimize everything.
189027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  if (fpuIs32Bit) {
190027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung    switch (base) {
191027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung      case 0:
1921095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic        return RegStorage(RegStorage::k64BitPair, rFARG0, rFARG1);
193027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung      case 2:
1941095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic        return RegStorage(RegStorage::k64BitPair, rFARG2, rFARG3);
195027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung    }
196027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  } else {
197027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung    switch (base) {
198027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung      case 0:
1991095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic        return RegStorage(RegStorage::k64BitSolo, rFARG0);
200027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung      case 2:
2011095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic        return RegStorage(RegStorage::k64BitSolo, rFARG2);
202027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung    }
203027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  }
204027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  LOG(FATAL) << "Unsupported Mips.GetWideFP: " << fpuIs32Bit << " " << base;
205027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung  UNREACHABLE();
206027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung}
207027f0ff64c2512b9a5f1f54f3fea1bec481eb0f5Douglas Leung
2081095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevicvoid MipsMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
2091095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic                           RegLocation rl_src2) {
210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  bool wide = true;
211984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe  QuickEntrypointEnum target;
212e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
213408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  switch (opcode) {
214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPL_FLOAT:
215984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      target = kQuickCmplFloat;
216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      wide = false;
217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPG_FLOAT:
219984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      target = kQuickCmpgFloat;
220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      wide = false;
221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPL_DOUBLE:
223984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      target = kQuickCmplDouble;
224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPG_DOUBLE:
226984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      target = kQuickCmpgDouble;
227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
229a5954be0aac5edd892fb31a209960543d00e4500buzbee      LOG(FATAL) << "Unexpected opcode: " << opcode;
230984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe      target = kQuickCmplFloat;
231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2321fd3346740dfb7f47be9922312b68a4227fada96buzbee  FlushAllRegs();
2331fd3346740dfb7f47be9922312b68a4227fada96buzbee  LockCallTemps();
234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (wide) {
2351095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    RegStorage r_tmp1;
2361095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    RegStorage r_tmp2;
2371095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    if (cu_->target64) {
2381095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      r_tmp1 = RegStorage(RegStorage::k64BitSolo, rFARG0);
2391095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      r_tmp2 = RegStorage(RegStorage::k64BitSolo, rFARG1);
2401095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    } else {
2411095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      r_tmp1 = GetWideArgFP(fpuIs32Bit_, 0);
2421095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic      r_tmp2 = GetWideArgFP(fpuIs32Bit_, 2);
2431095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    }
2442700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirectWideFixed(rl_src1, r_tmp1);
2452700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirectWideFixed(rl_src2, r_tmp2);
246a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
2471095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    LoadValueDirectFixed(rl_src1, rs_rFARG0);
2481095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    LoadValueDirectFixed(rl_src2, cu_->target64 ? rs_rFARG1 : rs_rFARG2);
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
250984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe  RegStorage r_tgt = LoadHelper(target);
2511095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  // NOTE: not a safepoint.
2521fd3346740dfb7f47be9922312b68a4227fada96buzbee  OpReg(kOpBlx, r_tgt);
253a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee  RegLocation rl_result = GetReturn(kCoreReg);
2541fd3346740dfb7f47be9922312b68a4227fada96buzbee  StoreValue(rl_dest, rl_result);
255e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
256e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
2576a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersvoid MipsMir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double) {
2586a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(bb, mir, gt_bias, is_double);
2594b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao  UNIMPLEMENTED(FATAL) << "Need codegen for fused fp cmp branch";
2604b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao}
2614b771a09fe1d947dee7265e3c018d7f1dd89a5d3jeffhao
2622ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) {
263fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegLocation rl_result;
2641095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  if (cu_->target64) {
2651095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_src = LoadValue(rl_src, kFPReg);
2661095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_result = EvalLoc(rl_dest, kFPReg, true);
2671095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    NewLIR2(kMipsFnegs, rl_result.reg.GetReg(), rl_src.reg.GetReg());
2681095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  } else {
2691095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_src = LoadValue(rl_src, kCoreReg);
2701095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_result = EvalLoc(rl_dest, kCoreReg, true);
2711095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    OpRegRegImm(kOpAdd, rl_result.reg, rl_src.reg, 0x80000000);
2721095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  }
2731fd3346740dfb7f47be9922312b68a4227fada96buzbee  StoreValue(rl_dest, rl_result);
274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
2762ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) {
277fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegLocation rl_result;
2781095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  if (cu_->target64) {
2791095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_src = LoadValueWide(rl_src, kFPReg);
2801095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_result = EvalLocWide(rl_dest, kFPReg, true);
2811095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    NewLIR2(kMipsFnegd, rl_result.reg.GetReg(), rl_src.reg.GetReg());
2821095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  } else {
2831095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_src = LoadValueWide(rl_src, kCoreReg);
2841095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    rl_result = EvalLoc(rl_dest, kCoreReg, true);
2851095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    OpRegRegImm(kOpAdd, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), 0x80000000);
2861095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic    OpRegCopy(rl_result.reg, rl_src.reg);
2871095793154d2ff33323ba9edaa4f83373bdb6c8eGoran Jakovljevic  }
2881fd3346740dfb7f47be9922312b68a4227fada96buzbee  StoreValueWide(rl_dest, rl_result);
289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
29123abec955e2e733999a1e2c30e4e384e46e5dde4Serban Constantinescubool MipsMir2Lir::GenInlinedMinMax(CallInfo* info, bool is_min, bool is_long) {
2926a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  // TODO: need Mips implementation.
2936a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(info, is_min, is_long);
294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return false;
295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
2977934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
298