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