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)