int_mips.cc revision 2bf31e67694da24a19fc1f328285cebb1a4b9964
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2012 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * See the License for the specific language governing permissions and
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * limitations under the License.
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This file contains codegen for the Mips ISA */
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "codegen_mips.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dex/quick/mir_to_lir-inl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "entrypoints/quick/quick_entrypoints.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "mips_lir.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "mirror/array.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace art {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compare two 64-bit values
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    x = y     return  0
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    x < y     return -1
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    x > y     return  1
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    bnez  res, finish
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    sltu  t0, x.lo, y.lo
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *    sgtu  r1, x.lo, y.lo
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *    subu  res, t0, t1
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * finish:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src2) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src1 = LoadValueWide(rl_src1, kCoreReg);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src2 = LoadValueWide(rl_src2, kCoreReg);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int t0 = AllocTemp();
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int t1 = AllocTemp();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewLIR3(kMipsSlt, t0, rl_src1.high_reg, rl_src2.high_reg);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSlt, t1, rl_src2.high_reg, rl_src1.high_reg);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LIR* branch = OpCmpImmBranch(kCondNe, rl_result.low_reg, 0, NULL);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSltu, t0, rl_src1.low_reg, rl_src2.low_reg);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSltu, t1, rl_src2.low_reg, rl_src1.low_reg);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeTemp(t0);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FreeTemp(t1);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LIR* target = NewLIR0(kPseudoTargetLabel);
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  branch->target = target;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StoreValue(rl_dest, rl_result);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpCmpBranch(ConditionCode cond, int src1, int src2,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LIR* target) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LIR* branch;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MipsOpCode slt_op;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MipsOpCode br_op;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool cmp_zero = false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool swapped = false;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cond) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondEq:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      br_op = kMipsBeq;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cmp_zero = true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondNe:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      br_op = kMipsBne;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cmp_zero = true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondUlt:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      slt_op = kMipsSltu;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      br_op = kMipsBnez;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondUge:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      slt_op = kMipsSltu;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      br_op = kMipsBeqz;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondGe:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      slt_op = kMipsSlt;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      br_op = kMipsBeqz;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondGt:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      slt_op = kMipsSlt;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      br_op = kMipsBnez;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      swapped = true;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kCondLe:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      slt_op = kMipsSlt;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      br_op = kMipsBeqz;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      swapped = true;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kCondLt:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      slt_op = kMipsSlt;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      br_op = kMipsBnez;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kCondHi:  // Gtu
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      slt_op = kMipsSltu;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      br_op = kMipsBnez;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      swapped = true;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(FATAL) << "No support for ConditionCode: " << cond;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (cmp_zero) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    branch = NewLIR2(br_op, src1, src2);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int t_reg = AllocTemp();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (swapped) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR3(slt_op, t_reg, src2, src1);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR3(slt_op, t_reg, src1, src2);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    branch = NewLIR1(br_op, t_reg);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTemp(t_reg);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  branch->target = target;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return branch;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LIR* MipsMir2Lir::OpCmpImmBranch(ConditionCode cond, int reg,
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 int check_value, LIR* target) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LIR* branch;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (check_value != 0) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TUNING: handle s16 & kCondLt/Mi case using slti
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int t_reg = AllocTemp();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadConstant(t_reg, check_value);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    branch = OpCmpBranch(cond, reg, t_reg, target);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTemp(t_reg);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return branch;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MipsOpCode opc;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cond) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondEq: opc = kMipsBeqz; break;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondGe: opc = kMipsBgez; break;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondGt: opc = kMipsBgtz; break;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondLe: opc = kMipsBlez; break;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // case KCondMi:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondLt: opc = kMipsBltz; break;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCondNe: opc = kMipsBnez; break;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Tuning: use slti when applicable
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int t_reg = AllocTemp();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadConstant(t_reg, check_value);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      branch = OpCmpBranch(cond, reg, t_reg, target);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(t_reg);
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return branch;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  branch = NewLIR1(opc, reg);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  branch->target = target;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return branch;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpRegCopyNoInsert(int r_dest, int r_src) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MIPS_FPREG(r_dest) || MIPS_FPREG(r_src))
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OpFpRegCopy(r_dest, r_src);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LIR* res = RawLIR(current_dalvik_offset_, kMipsMove,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            r_dest, r_src);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    res->flags.is_nop = true;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return res;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpRegCopy(int r_dest, int r_src) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LIR *res = OpRegCopyNoInsert(r_dest, r_src);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppendLIR(res);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return res;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::OpRegCopyWide(int dest_lo, int dest_hi, int src_lo,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int src_hi) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dest_fp = MIPS_FPREG(dest_lo) && MIPS_FPREG(dest_hi);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool src_fp = MIPS_FPREG(src_lo) && MIPS_FPREG(src_hi);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MIPS_FPREG(src_lo) == MIPS_FPREG(src_hi));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MIPS_FPREG(dest_lo) == MIPS_FPREG(dest_hi));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dest_fp) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (src_fp) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OpRegCopy(S2d(dest_lo, dest_hi), S2d(src_lo, src_hi));
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       /* note the operands are swapped for the mtc1 instr */
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR2(kMipsMtc1, src_lo, dest_lo);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR2(kMipsMtc1, src_hi, dest_hi);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (src_fp) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR2(kMipsMfc1, dest_lo, src_lo);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NewLIR2(kMipsMfc1, dest_hi, src_hi);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Handle overlap
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (src_hi == dest_lo) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OpRegCopy(dest_hi, src_hi);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OpRegCopy(dest_lo, src_lo);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OpRegCopy(dest_lo, src_lo);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OpRegCopy(dest_hi, src_hi);
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MipsMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UNIMPLEMENTED(FATAL) << "Need codegen for select";
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MipsMir2Lir::GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UNIMPLEMENTED(FATAL) << "Need codegen for fused long cmp branch";
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::GenRegMemCheck(ConditionCode c_code,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int reg1, int base, int offset, ThrowKind kind) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenRegMemCheck for Arm";
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, int reg1, int reg2,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    bool is_div) {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewLIR4(kMipsDiv, r_HI, r_LO, reg1, reg2);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_div) {
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return rl_result;
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, int reg1, int lit,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       bool is_div) {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int t_reg = AllocTemp();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewLIR3(kMipsAddiu, t_reg, r_ZERO, lit);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewLIR4(kMipsDiv, r_HI, r_LO, reg1, t_reg);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_div) {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FreeTemp(t_reg);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rl_result;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RegLocation rl_src2, bool is_div, bool check_zero) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenDivRem for Mips";
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rl_dest;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenDivRemLit for Mips";
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return rl_dest;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::OpLea(int rBase, int reg1, int reg2, int scale, int offset) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpLea for Arm";
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::OpTlsCmp(ThreadOffset offset, int val) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MipsMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(cu_->instruction_set, kThumb2);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MipsMir2Lir::GenInlinedSqrt(CallInfo* info) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(cu_->instruction_set, kThumb2);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MipsMir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size != kSignedByte) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // MIPS supports only aligned access. Defer unaligned access to JNI implementation.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_src_address = info->args[0];  // long address
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src_address.wide = 0;  // ignore high half in info->args[1]
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_dest = InlineTarget(info);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size == kSignedByte);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, size, INVALID_SREG);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreValue(rl_dest, rl_result);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MipsMir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size != kSignedByte) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // MIPS supports only aligned access. Defer unaligned access to JNI implementation.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_src_address = info->args[0];  // long address
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src_address.wide = 0;  // ignore high half in info->args[1]
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_src_value = info->args[2];  // [size] value
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size == kSignedByte);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, size);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpPcRelLoad(int reg, LIR* target) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpPcRelLoad for Mips";
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpVldm(int rBase, int count) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpVldm for Mips";
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpVstm(int rBase, int count) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpVstm for Mips";
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                RegLocation rl_result, int lit,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int first_bit, int second_bit) {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int t_reg = AllocTemp();
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpRegRegImm(kOpLsl, t_reg, rl_src.low_reg, second_bit - first_bit);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, t_reg);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FreeTemp(t_reg);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (first_bit != 0) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpRegRegImm(kOpLsl, rl_result.low_reg, rl_result.low_reg, first_bit);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenDivZeroCheck(int reg_lo, int reg_hi) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int t_reg = AllocTemp();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpOr, t_reg, reg_lo, reg_hi);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenImmedCheck(kCondEq, t_reg, 0, kThrowDivZero);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FreeTemp(t_reg);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test suspend flag, return target of taken suspend branch
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpTestSuspend(LIR* target) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegImm(kOpSub, rMIPS_SUSPEND, 1);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OpCmpImmBranch((target == NULL) ? kCondEq : kCondNe, rMIPS_SUSPEND, 0, target);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decrement register and branch on condition
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpDecAndBranch(ConditionCode c_code, int reg, LIR* target) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegImm(kOpSub, reg, 1);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OpCmpImmBranch(c_code, reg, 0, target);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MipsMir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     RegLocation rl_src, RegLocation rl_dest, int lit) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of smallLiteralDive in Mips";
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIR* MipsMir2Lir::OpIT(ConditionCode cond, const char* guide) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of OpIT in Mips";
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src1, RegLocation rl_src2) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenMulLong for Mips";
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenAddLong(Instruction::Code opcode, RegLocation rl_dest,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src1, RegLocation rl_src2) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src1 = LoadValueWide(rl_src1, kCoreReg);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rl_src2 = LoadValueWide(rl_src2, kCoreReg);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   *  [v1 v0] =  [a1 a0] + [a3 a2];
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   *  addu v0,a2,a0
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   *  addu t1,a3,a1
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   *  sltu v1,v0,a2
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   *  addu v1,v1,t1
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src2.low_reg, rl_src1.low_reg);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int t_reg = AllocTemp();
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpRegRegReg(kOpAdd, t_reg, rl_src2.high_reg, rl_src1.high_reg);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewLIR3(kMipsSltu, rl_result.high_reg, rl_result.low_reg, rl_src2.low_reg);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpAdd, rl_result.high_reg, rl_result.high_reg, t_reg);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeTemp(t_reg);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreValueWide(rl_dest, rl_result);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenSubLong(Instruction::Code opcode, RegLocation rl_dest,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src1, RegLocation rl_src2) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src1 = LoadValueWide(rl_src1, kCoreReg);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src2 = LoadValueWide(rl_src2, kCoreReg);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  [v1 v0] =  [a1 a0] - [a3 a2];
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  sltu  t1,a0,a2
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  subu  v0,a0,a2
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  subu  v1,a1,a3
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  subu  v1,v1,t1
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int t_reg = AllocTemp();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSltu, t_reg, rl_src1.low_reg, rl_src2.low_reg);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpSub, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpSub, rl_result.high_reg, rl_src1.high_reg, rl_src2.high_reg);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeTemp(t_reg);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoreValueWide(rl_dest, rl_result);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_src = LoadValueWide(rl_src, kCoreReg);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  [v1 v0] =  -[a1 a0]
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  negu  v0,a0
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  negu  v1,a1
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  sltu  t1,r_zero
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *  subu  v1,v1,t1
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegReg(kOpNeg, rl_result.low_reg, rl_src.low_reg);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegReg(kOpNeg, rl_result.high_reg, rl_src.high_reg);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int t_reg = AllocTemp();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NewLIR3(kMipsSltu, t_reg, r_ZERO, rl_result.low_reg);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeTemp(t_reg);
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StoreValueWide(rl_dest, rl_result);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenAndLong(Instruction::Code opcode, RegLocation rl_dest,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src1,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src2) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenAndLong for Mips";
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MipsMir2Lir::GenOrLong(Instruction::Code opcode, RegLocation rl_dest,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            RegLocation rl_src1, RegLocation rl_src2) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenOrLong for Mips";
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenXorLong(Instruction::Code opcode, RegLocation rl_dest,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RegLocation rl_src1, RegLocation rl_src2) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(FATAL) << "Unexpected use of GenXorLong for Mips";
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Generate array load
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          RegLocation rl_index, RegLocation rl_dest, int scale) {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegisterClass reg_class = oat_reg_class_by_size(size);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int len_offset = mirror::Array::LengthOffset().Int32Value();
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int data_offset;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegLocation rl_result;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_array = LoadValue(rl_array, kCoreReg);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rl_index = LoadValue(rl_index, kCoreReg);
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size == kLong || size == kDouble) {
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /* null object? */
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int reg_ptr = AllocTemp();
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int reg_len = INVALID_REG;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (needs_range_check) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reg_len = AllocTemp();
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* Get len */
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /* reg_ptr -> array data */
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpRegRegImm(kOpAdd, reg_ptr, rl_array.low_reg, data_offset);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FreeTemp(rl_array.low_reg);
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if ((size == kLong) || (size == kDouble)) {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (scale) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int r_new_index = AllocTemp();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegRegImm(kOpLsl, r_new_index, rl_index.low_reg, scale);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegReg(kOpAdd, reg_ptr, r_new_index);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(r_new_index);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTemp(rl_index.low_reg);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rl_result = EvalLoc(rl_dest, reg_class, true);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (needs_range_check) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(reg_len);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadBaseDispWide(reg_ptr, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FreeTemp(reg_ptr);
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StoreValueWide(rl_dest, rl_result);
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rl_result = EvalLoc(rl_dest, reg_class, true);
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (needs_range_check) {
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FreeTemp(reg_len);
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadBaseIndexed(reg_ptr, rl_index.low_reg, rl_result.low_reg, scale, size);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTemp(reg_ptr);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreValue(rl_dest, rl_result);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generate array store
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) {
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  RegisterClass reg_class = oat_reg_class_by_size(size);
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int len_offset = mirror::Array::LengthOffset().Int32Value();
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int data_offset;
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (size == kLong || size == kDouble) {
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_array = LoadValue(rl_array, kCoreReg);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rl_index = LoadValue(rl_index, kCoreReg);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int reg_ptr = INVALID_REG;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allocated_reg_ptr_temp = false;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsTemp(rl_array.low_reg) && !card_mark) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Clobber(rl_array.low_reg);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reg_ptr = rl_array.low_reg;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reg_ptr = AllocTemp();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpRegCopy(reg_ptr, rl_array.low_reg);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allocated_reg_ptr_temp = true;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* null object? */
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int reg_len = INVALID_REG;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_range_check) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reg_len = AllocTemp();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: max live temps(4) here.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get len */
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* reg_ptr -> array data */
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpRegImm(kOpAdd, reg_ptr, data_offset);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* at this point, reg_ptr points to array, 2 live temps */
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((size == kLong) || (size == kDouble)) {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TUNING: specific wide routine that can handle fp regs
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (scale) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int r_new_index = AllocTemp();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegRegImm(kOpLsl, r_new_index, rl_index.low_reg, scale);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegReg(kOpAdd, reg_ptr, r_new_index);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(r_new_index);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rl_src = LoadValueWide(rl_src, reg_class);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (needs_range_check) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(reg_len);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StoreBaseDispWide(reg_ptr, 0, rl_src.low_reg, rl_src.high_reg);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rl_src = LoadValue(rl_src, reg_class);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (needs_range_check) {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTemp(reg_len);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreBaseIndexed(reg_ptr, rl_index.low_reg, rl_src.low_reg,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     scale, size);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allocated_reg_ptr_temp) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTemp(reg_ptr);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (card_mark) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MarkGCCard(rl_src.low_reg, rl_array.low_reg);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    RegLocation rl_src1, RegLocation rl_shift) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default implementation is just to ignore the constant case.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenShiftOpLong(opcode, rl_dest, rl_src1, rl_shift);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default - bail to non-const handler.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace art
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)