utility_mips.cc revision dd7624d2b9e599d57762d12031b10b89defc9807
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "codegen_mips.h" 18#include "dex/quick/mir_to_lir-inl.h" 19#include "mips_lir.h" 20 21namespace art { 22 23/* This file contains codegen for the MIPS32 ISA. */ 24LIR* MipsMir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) { 25 int opcode; 26 /* must be both DOUBLE or both not DOUBLE */ 27 DCHECK_EQ(MIPS_DOUBLEREG(r_dest.GetReg()), MIPS_DOUBLEREG(r_src.GetReg())); 28 if (MIPS_DOUBLEREG(r_dest.GetReg())) { 29 opcode = kMipsFmovd; 30 } else { 31 if (MIPS_SINGLEREG(r_dest.GetReg())) { 32 if (MIPS_SINGLEREG(r_src.GetReg())) { 33 opcode = kMipsFmovs; 34 } else { 35 /* note the operands are swapped for the mtc1 instr */ 36 RegStorage t_opnd = r_src; 37 r_src = r_dest; 38 r_dest = t_opnd; 39 opcode = kMipsMtc1; 40 } 41 } else { 42 DCHECK(MIPS_SINGLEREG(r_src.GetReg())); 43 opcode = kMipsMfc1; 44 } 45 } 46 LIR* res = RawLIR(current_dalvik_offset_, opcode, r_src.GetReg(), r_dest.GetReg()); 47 if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) { 48 res->flags.is_nop = true; 49 } 50 return res; 51} 52 53bool MipsMir2Lir::InexpensiveConstantInt(int32_t value) { 54 return ((value == 0) || IsUint(16, value) || ((value < 0) && (value >= -32768))); 55} 56 57bool MipsMir2Lir::InexpensiveConstantFloat(int32_t value) { 58 return false; // TUNING 59} 60 61bool MipsMir2Lir::InexpensiveConstantLong(int64_t value) { 62 return false; // TUNING 63} 64 65bool MipsMir2Lir::InexpensiveConstantDouble(int64_t value) { 66 return false; // TUNING 67} 68 69/* 70 * Load a immediate using a shortcut if possible; otherwise 71 * grab from the per-translation literal pool. If target is 72 * a high register, build constant into a low register and copy. 73 * 74 * No additional register clobbering operation performed. Use this version when 75 * 1) r_dest is freshly returned from AllocTemp or 76 * 2) The codegen is under fixed register usage 77 */ 78LIR* MipsMir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) { 79 LIR *res; 80 81 RegStorage r_dest_save = r_dest; 82 int is_fp_reg = MIPS_FPREG(r_dest.GetReg()); 83 if (is_fp_reg) { 84 DCHECK(MIPS_SINGLEREG(r_dest.GetReg())); 85 r_dest = AllocTemp(); 86 } 87 88 /* See if the value can be constructed cheaply */ 89 if (value == 0) { 90 res = NewLIR2(kMipsMove, r_dest.GetReg(), rZERO); 91 } else if ((value > 0) && (value <= 65535)) { 92 res = NewLIR3(kMipsOri, r_dest.GetReg(), rZERO, value); 93 } else if ((value < 0) && (value >= -32768)) { 94 res = NewLIR3(kMipsAddiu, r_dest.GetReg(), rZERO, value); 95 } else { 96 res = NewLIR2(kMipsLui, r_dest.GetReg(), value >> 16); 97 if (value & 0xffff) 98 NewLIR3(kMipsOri, r_dest.GetReg(), r_dest.GetReg(), value); 99 } 100 101 if (is_fp_reg) { 102 NewLIR2(kMipsMtc1, r_dest.GetReg(), r_dest_save.GetReg()); 103 FreeTemp(r_dest); 104 } 105 106 return res; 107} 108 109LIR* MipsMir2Lir::OpUnconditionalBranch(LIR* target) { 110 LIR* res = NewLIR1(kMipsB, 0 /* offset to be patched during assembly*/); 111 res->target = target; 112 return res; 113} 114 115LIR* MipsMir2Lir::OpReg(OpKind op, RegStorage r_dest_src) { 116 MipsOpCode opcode = kMipsNop; 117 switch (op) { 118 case kOpBlx: 119 opcode = kMipsJalr; 120 break; 121 case kOpBx: 122 return NewLIR1(kMipsJr, r_dest_src.GetReg()); 123 break; 124 default: 125 LOG(FATAL) << "Bad case in OpReg"; 126 } 127 return NewLIR2(opcode, rRA, r_dest_src.GetReg()); 128} 129 130LIR* MipsMir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) { 131 LIR *res; 132 bool neg = (value < 0); 133 int abs_value = (neg) ? -value : value; 134 bool short_form = (abs_value & 0xff) == abs_value; 135 MipsOpCode opcode = kMipsNop; 136 switch (op) { 137 case kOpAdd: 138 return OpRegRegImm(op, r_dest_src1, r_dest_src1, value); 139 break; 140 case kOpSub: 141 return OpRegRegImm(op, r_dest_src1, r_dest_src1, value); 142 break; 143 default: 144 LOG(FATAL) << "Bad case in OpRegImm"; 145 break; 146 } 147 if (short_form) { 148 res = NewLIR2(opcode, r_dest_src1.GetReg(), abs_value); 149 } else { 150 RegStorage r_scratch = AllocTemp(); 151 res = LoadConstant(r_scratch, value); 152 if (op == kOpCmp) 153 NewLIR2(opcode, r_dest_src1.GetReg(), r_scratch.GetReg()); 154 else 155 NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_scratch.GetReg()); 156 } 157 return res; 158} 159 160LIR* MipsMir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2) { 161 MipsOpCode opcode = kMipsNop; 162 switch (op) { 163 case kOpAdd: 164 opcode = kMipsAddu; 165 break; 166 case kOpSub: 167 opcode = kMipsSubu; 168 break; 169 case kOpAnd: 170 opcode = kMipsAnd; 171 break; 172 case kOpMul: 173 opcode = kMipsMul; 174 break; 175 case kOpOr: 176 opcode = kMipsOr; 177 break; 178 case kOpXor: 179 opcode = kMipsXor; 180 break; 181 case kOpLsl: 182 opcode = kMipsSllv; 183 break; 184 case kOpLsr: 185 opcode = kMipsSrlv; 186 break; 187 case kOpAsr: 188 opcode = kMipsSrav; 189 break; 190 case kOpAdc: 191 case kOpSbc: 192 LOG(FATAL) << "No carry bit on MIPS"; 193 break; 194 default: 195 LOG(FATAL) << "bad case in OpRegRegReg"; 196 break; 197 } 198 return NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg()); 199} 200 201LIR* MipsMir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value) { 202 LIR *res; 203 MipsOpCode opcode = kMipsNop; 204 bool short_form = true; 205 206 switch (op) { 207 case kOpAdd: 208 if (IS_SIMM16(value)) { 209 opcode = kMipsAddiu; 210 } else { 211 short_form = false; 212 opcode = kMipsAddu; 213 } 214 break; 215 case kOpSub: 216 if (IS_SIMM16((-value))) { 217 value = -value; 218 opcode = kMipsAddiu; 219 } else { 220 short_form = false; 221 opcode = kMipsSubu; 222 } 223 break; 224 case kOpLsl: 225 DCHECK(value >= 0 && value <= 31); 226 opcode = kMipsSll; 227 break; 228 case kOpLsr: 229 DCHECK(value >= 0 && value <= 31); 230 opcode = kMipsSrl; 231 break; 232 case kOpAsr: 233 DCHECK(value >= 0 && value <= 31); 234 opcode = kMipsSra; 235 break; 236 case kOpAnd: 237 if (IS_UIMM16((value))) { 238 opcode = kMipsAndi; 239 } else { 240 short_form = false; 241 opcode = kMipsAnd; 242 } 243 break; 244 case kOpOr: 245 if (IS_UIMM16((value))) { 246 opcode = kMipsOri; 247 } else { 248 short_form = false; 249 opcode = kMipsOr; 250 } 251 break; 252 case kOpXor: 253 if (IS_UIMM16((value))) { 254 opcode = kMipsXori; 255 } else { 256 short_form = false; 257 opcode = kMipsXor; 258 } 259 break; 260 case kOpMul: 261 short_form = false; 262 opcode = kMipsMul; 263 break; 264 default: 265 LOG(FATAL) << "Bad case in OpRegRegImm"; 266 break; 267 } 268 269 if (short_form) { 270 res = NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), value); 271 } else { 272 if (r_dest != r_src1) { 273 res = LoadConstant(r_dest, value); 274 NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_dest.GetReg()); 275 } else { 276 RegStorage r_scratch = AllocTemp(); 277 res = LoadConstant(r_scratch, value); 278 NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_scratch.GetReg()); 279 } 280 } 281 return res; 282} 283 284LIR* MipsMir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) { 285 MipsOpCode opcode = kMipsNop; 286 LIR *res; 287 switch (op) { 288 case kOpMov: 289 opcode = kMipsMove; 290 break; 291 case kOpMvn: 292 return NewLIR3(kMipsNor, r_dest_src1.GetReg(), r_src2.GetReg(), rZERO); 293 case kOpNeg: 294 return NewLIR3(kMipsSubu, r_dest_src1.GetReg(), rZERO, r_src2.GetReg()); 295 case kOpAdd: 296 case kOpAnd: 297 case kOpMul: 298 case kOpOr: 299 case kOpSub: 300 case kOpXor: 301 return OpRegRegReg(op, r_dest_src1, r_dest_src1, r_src2); 302 case kOp2Byte: 303#if __mips_isa_rev >= 2 304 res = NewLIR2(kMipsSeb, r_dest_src1.GetReg(), r_src2.GetReg()); 305#else 306 res = OpRegRegImm(kOpLsl, r_dest_src1, r_src2, 24); 307 OpRegRegImm(kOpAsr, r_dest_src1, r_dest_src1, 24); 308#endif 309 return res; 310 case kOp2Short: 311#if __mips_isa_rev >= 2 312 res = NewLIR2(kMipsSeh, r_dest_src1.GetReg(), r_src2.GetReg()); 313#else 314 res = OpRegRegImm(kOpLsl, r_dest_src1, r_src2, 16); 315 OpRegRegImm(kOpAsr, r_dest_src1, r_dest_src1, 16); 316#endif 317 return res; 318 case kOp2Char: 319 return NewLIR3(kMipsAndi, r_dest_src1.GetReg(), r_src2.GetReg(), 0xFFFF); 320 default: 321 LOG(FATAL) << "Bad case in OpRegReg"; 322 break; 323 } 324 return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg()); 325} 326 327LIR* MipsMir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, 328 MoveType move_type) { 329 UNIMPLEMENTED(FATAL); 330 return nullptr; 331} 332 333LIR* MipsMir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) { 334 UNIMPLEMENTED(FATAL); 335 return nullptr; 336} 337 338LIR* MipsMir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) { 339 LOG(FATAL) << "Unexpected use of OpCondRegReg for MIPS"; 340 return NULL; 341} 342 343LIR* MipsMir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) { 344 LIR *res; 345 res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value)); 346 LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value)); 347 return res; 348} 349 350/* Load value from base + scaled index. */ 351LIR* MipsMir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, 352 int scale, OpSize size) { 353 LIR *first = NULL; 354 LIR *res; 355 MipsOpCode opcode = kMipsNop; 356 RegStorage t_reg = AllocTemp(); 357 358 if (MIPS_FPREG(r_dest.GetReg())) { 359 DCHECK(MIPS_SINGLEREG(r_dest.GetReg())); 360 DCHECK((size == kWord) || (size == kSingle)); 361 size = kSingle; 362 } else { 363 if (size == kSingle) 364 size = kWord; 365 } 366 367 if (!scale) { 368 first = NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), r_index.GetReg()); 369 } else { 370 first = OpRegRegImm(kOpLsl, t_reg, r_index, scale); 371 NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), t_reg.GetReg()); 372 } 373 374 switch (size) { 375 case kSingle: 376 opcode = kMipsFlwc1; 377 break; 378 case kWord: 379 opcode = kMipsLw; 380 break; 381 case kUnsignedHalf: 382 opcode = kMipsLhu; 383 break; 384 case kSignedHalf: 385 opcode = kMipsLh; 386 break; 387 case kUnsignedByte: 388 opcode = kMipsLbu; 389 break; 390 case kSignedByte: 391 opcode = kMipsLb; 392 break; 393 default: 394 LOG(FATAL) << "Bad case in LoadBaseIndexed"; 395 } 396 397 res = NewLIR3(opcode, r_dest.GetReg(), 0, t_reg.GetReg()); 398 FreeTemp(t_reg); 399 return (first) ? first : res; 400} 401 402/* store value base base + scaled index. */ 403LIR* MipsMir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, 404 int scale, OpSize size) { 405 LIR *first = NULL; 406 MipsOpCode opcode = kMipsNop; 407 RegStorage t_reg = AllocTemp(); 408 409 if (MIPS_FPREG(r_src.GetReg())) { 410 DCHECK(MIPS_SINGLEREG(r_src.GetReg())); 411 DCHECK((size == kWord) || (size == kSingle)); 412 size = kSingle; 413 } else { 414 if (size == kSingle) 415 size = kWord; 416 } 417 418 if (!scale) { 419 first = NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), r_index.GetReg()); 420 } else { 421 first = OpRegRegImm(kOpLsl, t_reg, r_index, scale); 422 NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), t_reg.GetReg()); 423 } 424 425 switch (size) { 426 case kSingle: 427 opcode = kMipsFswc1; 428 break; 429 case kWord: 430 opcode = kMipsSw; 431 break; 432 case kUnsignedHalf: 433 case kSignedHalf: 434 opcode = kMipsSh; 435 break; 436 case kUnsignedByte: 437 case kSignedByte: 438 opcode = kMipsSb; 439 break; 440 default: 441 LOG(FATAL) << "Bad case in StoreBaseIndexed"; 442 } 443 NewLIR3(opcode, r_src.GetReg(), 0, t_reg.GetReg()); 444 return first; 445} 446 447// FIXME: don't split r_dest into 2 containers. 448LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, 449 RegStorage r_dest_hi, OpSize size, int s_reg) { 450/* 451 * Load value from base + displacement. Optionally perform null check 452 * on base (which must have an associated s_reg and MIR). If not 453 * performing null check, incoming MIR can be null. IMPORTANT: this 454 * code must not allocate any new temps. If a new register is needed 455 * and base and dest are the same, spill some other register to 456 * rlp and then restore. 457 */ 458 LIR *res; 459 LIR *load = NULL; 460 LIR *load2 = NULL; 461 MipsOpCode opcode = kMipsNop; 462 bool short_form = IS_SIMM16(displacement); 463 bool pair = false; 464 465 switch (size) { 466 case kLong: 467 case kDouble: 468 pair = true; 469 opcode = kMipsLw; 470 if (MIPS_FPREG(r_dest.GetReg())) { 471 opcode = kMipsFlwc1; 472 if (MIPS_DOUBLEREG(r_dest.GetReg())) { 473 // TODO: rework to use k64BitSolo 474 r_dest.SetReg(r_dest.GetReg() - MIPS_FP_DOUBLE); 475 } else { 476 DCHECK(MIPS_FPREG(r_dest_hi.GetReg())); 477 DCHECK_EQ(r_dest.GetReg(), r_dest_hi.GetReg() - 1); 478 } 479 r_dest_hi.SetReg(r_dest.GetReg() + 1); 480 } 481 short_form = IS_SIMM16_2WORD(displacement); 482 DCHECK_EQ((displacement & 0x3), 0); 483 break; 484 case kWord: 485 case kSingle: 486 opcode = kMipsLw; 487 if (MIPS_FPREG(r_dest.GetReg())) { 488 opcode = kMipsFlwc1; 489 DCHECK(MIPS_SINGLEREG(r_dest.GetReg())); 490 } 491 DCHECK_EQ((displacement & 0x3), 0); 492 break; 493 case kUnsignedHalf: 494 opcode = kMipsLhu; 495 DCHECK_EQ((displacement & 0x1), 0); 496 break; 497 case kSignedHalf: 498 opcode = kMipsLh; 499 DCHECK_EQ((displacement & 0x1), 0); 500 break; 501 case kUnsignedByte: 502 opcode = kMipsLbu; 503 break; 504 case kSignedByte: 505 opcode = kMipsLb; 506 break; 507 default: 508 LOG(FATAL) << "Bad case in LoadBaseIndexedBody"; 509 } 510 511 if (short_form) { 512 if (!pair) { 513 load = res = NewLIR3(opcode, r_dest.GetReg(), displacement, r_base.GetReg()); 514 } else { 515 load = res = NewLIR3(opcode, r_dest.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); 516 load2 = NewLIR3(opcode, r_dest_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); 517 } 518 } else { 519 if (pair) { 520 RegStorage r_tmp = AllocTemp(); 521 res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement); 522 load = NewLIR3(opcode, r_dest.GetReg(), LOWORD_OFFSET, r_tmp.GetReg()); 523 load2 = NewLIR3(opcode, r_dest_hi.GetReg(), HIWORD_OFFSET, r_tmp.GetReg()); 524 FreeTemp(r_tmp); 525 } else { 526 RegStorage r_tmp = (r_base == r_dest) ? AllocTemp() : r_dest; 527 res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement); 528 load = NewLIR3(opcode, r_dest.GetReg(), 0, r_tmp.GetReg()); 529 if (r_tmp != r_dest) 530 FreeTemp(r_tmp); 531 } 532 } 533 534 if (r_base == rs_rMIPS_SP) { 535 AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 536 true /* is_load */, pair /* is64bit */); 537 if (pair) { 538 AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, 539 true /* is_load */, pair /* is64bit */); 540 } 541 } 542 return load; 543} 544 545LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, 546 OpSize size, int s_reg) { 547 return LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size, 548 s_reg); 549} 550 551LIR* MipsMir2Lir::LoadBaseDispWide(RegStorage r_base, int displacement, RegStorage r_dest, 552 int s_reg) { 553 return LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), kLong, s_reg); 554} 555 556LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, 557 RegStorage r_src, RegStorage r_src_hi, OpSize size) { 558 LIR *res; 559 LIR *store = NULL; 560 LIR *store2 = NULL; 561 MipsOpCode opcode = kMipsNop; 562 bool short_form = IS_SIMM16(displacement); 563 bool pair = false; 564 565 switch (size) { 566 case kLong: 567 case kDouble: 568 pair = true; 569 opcode = kMipsSw; 570 if (MIPS_FPREG(r_src.GetReg())) { 571 opcode = kMipsFswc1; 572 if (MIPS_DOUBLEREG(r_src.GetReg())) { 573 r_src.SetReg(r_src.GetReg() - MIPS_FP_DOUBLE); 574 } else { 575 DCHECK(MIPS_FPREG(r_src_hi.GetReg())); 576 DCHECK_EQ(r_src.GetReg(), (r_src_hi.GetReg() - 1)); 577 } 578 r_src_hi.SetReg(r_src.GetReg() + 1); 579 } 580 short_form = IS_SIMM16_2WORD(displacement); 581 DCHECK_EQ((displacement & 0x3), 0); 582 break; 583 case kWord: 584 case kSingle: 585 opcode = kMipsSw; 586 if (MIPS_FPREG(r_src.GetReg())) { 587 opcode = kMipsFswc1; 588 DCHECK(MIPS_SINGLEREG(r_src.GetReg())); 589 } 590 DCHECK_EQ((displacement & 0x3), 0); 591 break; 592 case kUnsignedHalf: 593 case kSignedHalf: 594 opcode = kMipsSh; 595 DCHECK_EQ((displacement & 0x1), 0); 596 break; 597 case kUnsignedByte: 598 case kSignedByte: 599 opcode = kMipsSb; 600 break; 601 default: 602 LOG(FATAL) << "Bad case in StoreBaseDispBody"; 603 } 604 605 if (short_form) { 606 if (!pair) { 607 store = res = NewLIR3(opcode, r_src.GetReg(), displacement, r_base.GetReg()); 608 } else { 609 store = res = NewLIR3(opcode, r_src.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); 610 store2 = NewLIR3(opcode, r_src_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); 611 } 612 } else { 613 RegStorage r_scratch = AllocTemp(); 614 res = OpRegRegImm(kOpAdd, r_scratch, r_base, displacement); 615 if (!pair) { 616 store = NewLIR3(opcode, r_src.GetReg(), 0, r_scratch.GetReg()); 617 } else { 618 store = NewLIR3(opcode, r_src.GetReg(), LOWORD_OFFSET, r_scratch.GetReg()); 619 store2 = NewLIR3(opcode, r_src_hi.GetReg(), HIWORD_OFFSET, r_scratch.GetReg()); 620 } 621 FreeTemp(r_scratch); 622 } 623 624 if (r_base == rs_rMIPS_SP) { 625 AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 626 false /* is_load */, pair /* is64bit */); 627 if (pair) { 628 AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, 629 false /* is_load */, pair /* is64bit */); 630 } 631 } 632 633 return res; 634} 635 636LIR* MipsMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, 637 OpSize size) { 638 return StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size); 639} 640 641LIR* MipsMir2Lir::StoreBaseDispWide(RegStorage r_base, int displacement, RegStorage r_src) { 642 return StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), kLong); 643} 644 645LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) { 646 LOG(FATAL) << "Unexpected use of OpThreadMem for MIPS"; 647 return NULL; 648} 649 650LIR* MipsMir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) { 651 LOG(FATAL) << "Unexpected use of OpMem for MIPS"; 652 return NULL; 653} 654 655LIR* MipsMir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 656 int displacement, RegStorage r_src, RegStorage r_src_hi, 657 OpSize size, int s_reg) { 658 LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for MIPS"; 659 return NULL; 660} 661 662LIR* MipsMir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) { 663 LOG(FATAL) << "Unexpected use of OpRegMem for MIPS"; 664 return NULL; 665} 666 667LIR* MipsMir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 668 int displacement, RegStorage r_dest, RegStorage r_dest_hi, 669 OpSize size, int s_reg) { 670 LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for MIPS"; 671 return NULL; 672} 673 674LIR* MipsMir2Lir::OpCondBranch(ConditionCode cc, LIR* target) { 675 LOG(FATAL) << "Unexpected use of OpCondBranch for MIPS"; 676 return NULL; 677} 678 679} // namespace art 680