LLVM  4.0.0
MipsMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the MipsMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13 //
14 
15 #include "MipsMCCodeEmitter.h"
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixup.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
29 
30 #define DEBUG_TYPE "mccodeemitter"
31 
32 #define GET_INSTRMAP_INFO
33 #include "MipsGenInstrInfo.inc"
34 #undef GET_INSTRMAP_INFO
35 
36 namespace llvm {
38  const MCRegisterInfo &MRI,
39  MCContext &Ctx) {
40  return new MipsMCCodeEmitter(MCII, Ctx, false);
41 }
42 
44  const MCRegisterInfo &MRI,
45  MCContext &Ctx) {
46  return new MipsMCCodeEmitter(MCII, Ctx, true);
47 }
48 } // End of namespace llvm.
49 
50 // If the D<shift> instruction has a shift amount that is greater
51 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
52 static void LowerLargeShift(MCInst& Inst) {
53 
54  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
55  assert(Inst.getOperand(2).isImm());
56 
57  int64_t Shift = Inst.getOperand(2).getImm();
58  if (Shift <= 31)
59  return; // Do nothing
60  Shift -= 32;
61 
62  // saminus32
63  Inst.getOperand(2).setImm(Shift);
64 
65  switch (Inst.getOpcode()) {
66  default:
67  // Calling function is not synchronized
68  llvm_unreachable("Unexpected shift instruction");
69  case Mips::DSLL:
70  Inst.setOpcode(Mips::DSLL32);
71  return;
72  case Mips::DSRL:
73  Inst.setOpcode(Mips::DSRL32);
74  return;
75  case Mips::DSRA:
76  Inst.setOpcode(Mips::DSRA32);
77  return;
78  case Mips::DROTR:
79  Inst.setOpcode(Mips::DROTR32);
80  return;
81  case Mips::DSLL_MM64R6:
82  Inst.setOpcode(Mips::DSLL32_MM64R6);
83  return;
84  case Mips::DSRL_MM64R6:
85  Inst.setOpcode(Mips::DSRL32_MM64R6);
86  return;
87  case Mips::DSRA_MM64R6:
88  Inst.setOpcode(Mips::DSRA32_MM64R6);
89  return;
90  case Mips::DROTR_MM64R6:
91  Inst.setOpcode(Mips::DROTR32_MM64R6);
92  return;
93  }
94 }
95 
96 // Pick a DINS instruction variant based on the pos and size operands
97 static void LowerDins(MCInst& InstIn) {
98  assert(InstIn.getNumOperands() == 5 &&
99  "Invalid no. of machine operands for DINS!");
100 
101  assert(InstIn.getOperand(2).isImm());
102  int64_t pos = InstIn.getOperand(2).getImm();
103  assert(InstIn.getOperand(3).isImm());
104  int64_t size = InstIn.getOperand(3).getImm();
105 
106  if (size <= 32) {
107  if (pos < 32) // DINS, do nothing
108  return;
109  // DINSU
110  InstIn.getOperand(2).setImm(pos - 32);
111  InstIn.setOpcode(Mips::DINSU);
112  return;
113  }
114  // DINSM
115  assert(pos < 32 && "DINS cannot have both size and pos > 32");
116  InstIn.getOperand(3).setImm(size - 32);
117  InstIn.setOpcode(Mips::DINSM);
118  return;
119 }
120 
121 // Fix a bad compact branch encoding for beqc/bnec.
122 void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
123 
124  // Encoding may be illegal !(rs < rt), but this situation is
125  // easily fixed.
126  unsigned RegOp0 = Inst.getOperand(0).getReg();
127  unsigned RegOp1 = Inst.getOperand(1).getReg();
128 
129  unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
130  unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
131 
132  if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC ||
133  Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) {
134  assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
135  if (Reg0 < Reg1)
136  return;
137  } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) {
138  if (Reg0 >= Reg1)
139  return;
140  } else if (Inst.getOpcode() == Mips::BNVC_MMR6 ||
141  Inst.getOpcode() == Mips::BOVC_MMR6) {
142  if (Reg1 >= Reg0)
143  return;
144  } else
145  llvm_unreachable("Cannot rewrite unknown branch!");
146 
147  Inst.getOperand(0).setReg(RegOp1);
148  Inst.getOperand(1).setReg(RegOp0);
149 
150 }
151 
152 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
153  return STI.getFeatureBits()[Mips::FeatureMicroMips];
154 }
155 
156 bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
157  return STI.getFeatureBits()[Mips::FeatureMips32r6];
158 }
159 
160 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
161  OS << (char)C;
162 }
163 
164 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
165  const MCSubtargetInfo &STI,
166  raw_ostream &OS) const {
167  // Output the instruction encoding in little endian byte order.
168  // Little-endian byte ordering:
169  // mips32r2: 4 | 3 | 2 | 1
170  // microMIPS: 2 | 1 | 4 | 3
171  if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
172  EmitInstruction(Val >> 16, 2, STI, OS);
173  EmitInstruction(Val, 2, STI, OS);
174  } else {
175  for (unsigned i = 0; i < Size; ++i) {
176  unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
177  EmitByte((Val >> Shift) & 0xff, OS);
178  }
179  }
180 }
181 
182 /// encodeInstruction - Emit the instruction.
183 /// Size the instruction with Desc.getSize().
184 void MipsMCCodeEmitter::
185 encodeInstruction(const MCInst &MI, raw_ostream &OS,
186  SmallVectorImpl<MCFixup> &Fixups,
187  const MCSubtargetInfo &STI) const
188 {
189 
190  // Non-pseudo instructions that get changed for direct object
191  // only based on operand values.
192  // If this list of instructions get much longer we will move
193  // the check to a function call. Until then, this is more efficient.
194  MCInst TmpInst = MI;
195  switch (MI.getOpcode()) {
196  // If shift amount is >= 32 it the inst needs to be lowered further
197  case Mips::DSLL:
198  case Mips::DSRL:
199  case Mips::DSRA:
200  case Mips::DROTR:
201  case Mips::DSLL_MM64R6:
202  case Mips::DSRL_MM64R6:
203  case Mips::DSRA_MM64R6:
204  case Mips::DROTR_MM64R6:
205  LowerLargeShift(TmpInst);
206  break;
207  // Double extract instruction is chosen by pos and size operands
208  case Mips::DINS:
209  LowerDins(TmpInst);
210  break;
211  // Compact branches, enforce encoding restrictions.
212  case Mips::BEQC:
213  case Mips::BNEC:
214  case Mips::BEQC64:
215  case Mips::BNEC64:
216  case Mips::BOVC:
217  case Mips::BOVC_MMR6:
218  case Mips::BNVC:
219  case Mips::BNVC_MMR6:
220  LowerCompactBranch(TmpInst);
221  }
222 
223  unsigned long N = Fixups.size();
224  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
225 
226  // Check for unimplemented opcodes.
227  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
228  // so we have to special check for them.
229  unsigned Opcode = TmpInst.getOpcode();
230  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
231  (Opcode != Mips::SLL_MM) && !Binary)
232  llvm_unreachable("unimplemented opcode in encodeInstruction()");
233 
234  int NewOpcode = -1;
235  if (isMicroMips(STI)) {
236  if (isMips32r6(STI)) {
237  NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
238  if (NewOpcode == -1)
239  NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
240  }
241  else
242  NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
243 
244  // Check whether it is Dsp instruction.
245  if (NewOpcode == -1)
246  NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
247 
248  if (NewOpcode != -1) {
249  if (Fixups.size() > N)
250  Fixups.pop_back();
251 
252  Opcode = NewOpcode;
253  TmpInst.setOpcode (NewOpcode);
254  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
255  }
256  }
257 
258  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
259 
260  // Get byte count of instruction
261  unsigned Size = Desc.getSize();
262  if (!Size)
263  llvm_unreachable("Desc.getSize() returns 0");
264 
265  EmitInstruction(Binary, Size, STI, OS);
266 }
267 
268 /// getBranchTargetOpValue - Return binary encoding of the branch
269 /// target operand. If the machine operand requires relocation,
270 /// record the relocation and return zero.
271 unsigned MipsMCCodeEmitter::
272 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
273  SmallVectorImpl<MCFixup> &Fixups,
274  const MCSubtargetInfo &STI) const {
275 
276  const MCOperand &MO = MI.getOperand(OpNo);
277 
278  // If the destination is an immediate, divide by 4.
279  if (MO.isImm()) return MO.getImm() >> 2;
280 
281  assert(MO.isExpr() &&
282  "getBranchTargetOpValue expects only expressions or immediates");
283 
284  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
285  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
286  Fixups.push_back(MCFixup::create(0, FixupExpression,
287  MCFixupKind(Mips::fixup_Mips_PC16)));
288  return 0;
289 }
290 
291 /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
292 /// target operand. If the machine operand requires relocation,
293 /// record the relocation and return zero.
294 unsigned MipsMCCodeEmitter::
295 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
296  SmallVectorImpl<MCFixup> &Fixups,
297  const MCSubtargetInfo &STI) const {
298 
299  const MCOperand &MO = MI.getOperand(OpNo);
300 
301  // If the destination is an immediate, divide by 2.
302  if (MO.isImm()) return MO.getImm() >> 1;
303 
304  assert(MO.isExpr() &&
305  "getBranchTargetOpValue expects only expressions or immediates");
306 
307  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
308  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
309  Fixups.push_back(MCFixup::create(0, FixupExpression,
310  MCFixupKind(Mips::fixup_Mips_PC16)));
311  return 0;
312 }
313 
314 /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
315 /// target operand. If the machine operand requires relocation,
316 /// record the relocation and return zero.
317 unsigned MipsMCCodeEmitter::
318 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
319  SmallVectorImpl<MCFixup> &Fixups,
320  const MCSubtargetInfo &STI) const {
321 
322  const MCOperand &MO = MI.getOperand(OpNo);
323 
324  // If the destination is an immediate, divide by 2.
325  if (MO.isImm())
326  return MO.getImm() >> 1;
327 
328  assert(MO.isExpr() &&
329  "getBranchTargetOpValueMMR6 expects only expressions or immediates");
330 
331  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
332  MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx);
333  Fixups.push_back(MCFixup::create(0, FixupExpression,
334  MCFixupKind(Mips::fixup_Mips_PC16)));
335  return 0;
336 }
337 
338 /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
339 /// target operand. If the machine operand requires relocation,
340 /// record the relocation and return zero.
341 unsigned MipsMCCodeEmitter::
342 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
343  SmallVectorImpl<MCFixup> &Fixups,
344  const MCSubtargetInfo &STI) const {
345 
346  const MCOperand &MO = MI.getOperand(OpNo);
347 
348  // If the destination is an immediate, divide by 4.
349  if (MO.isImm())
350  return MO.getImm() >> 2;
351 
352  assert(MO.isExpr() &&
353  "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
354 
355  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
356  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
357  Fixups.push_back(MCFixup::create(0, FixupExpression,
358  MCFixupKind(Mips::fixup_Mips_PC16)));
359  return 0;
360 }
361 
362 /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
363 /// target operand. If the machine operand requires relocation,
364 /// record the relocation and return zero.
365 unsigned MipsMCCodeEmitter::
366 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
367  SmallVectorImpl<MCFixup> &Fixups,
368  const MCSubtargetInfo &STI) const {
369 
370  const MCOperand &MO = MI.getOperand(OpNo);
371 
372  // If the destination is an immediate, divide by 2.
373  if (MO.isImm()) return MO.getImm() >> 1;
374 
375  assert(MO.isExpr() &&
376  "getBranchTargetOpValueMM expects only expressions or immediates");
377 
378  const MCExpr *Expr = MO.getExpr();
379  Fixups.push_back(MCFixup::create(0, Expr,
380  MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
381  return 0;
382 }
383 
384 /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
385 /// 10-bit branch target operand. If the machine operand requires relocation,
386 /// record the relocation and return zero.
387 unsigned MipsMCCodeEmitter::
388 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
389  SmallVectorImpl<MCFixup> &Fixups,
390  const MCSubtargetInfo &STI) const {
391 
392  const MCOperand &MO = MI.getOperand(OpNo);
393 
394  // If the destination is an immediate, divide by 2.
395  if (MO.isImm()) return MO.getImm() >> 1;
396 
397  assert(MO.isExpr() &&
398  "getBranchTargetOpValuePC10 expects only expressions or immediates");
399 
400  const MCExpr *Expr = MO.getExpr();
401  Fixups.push_back(MCFixup::create(0, Expr,
402  MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
403  return 0;
404 }
405 
406 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
407 /// target operand. If the machine operand requires relocation,
408 /// record the relocation and return zero.
409 unsigned MipsMCCodeEmitter::
410 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
411  SmallVectorImpl<MCFixup> &Fixups,
412  const MCSubtargetInfo &STI) const {
413 
414  const MCOperand &MO = MI.getOperand(OpNo);
415 
416  // If the destination is an immediate, divide by 2.
417  if (MO.isImm()) return MO.getImm() >> 1;
418 
419  assert(MO.isExpr() &&
420  "getBranchTargetOpValueMM expects only expressions or immediates");
421 
422  const MCExpr *Expr = MO.getExpr();
423  Fixups.push_back(MCFixup::create(0, Expr,
424  MCFixupKind(Mips::
425  fixup_MICROMIPS_PC16_S1)));
426  return 0;
427 }
428 
429 /// getBranchTarget21OpValue - Return binary encoding of the branch
430 /// target operand. If the machine operand requires relocation,
431 /// record the relocation and return zero.
432 unsigned MipsMCCodeEmitter::
433 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
434  SmallVectorImpl<MCFixup> &Fixups,
435  const MCSubtargetInfo &STI) const {
436 
437  const MCOperand &MO = MI.getOperand(OpNo);
438 
439  // If the destination is an immediate, divide by 4.
440  if (MO.isImm()) return MO.getImm() >> 2;
441 
442  assert(MO.isExpr() &&
443  "getBranchTarget21OpValue expects only expressions or immediates");
444 
445  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
446  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
447  Fixups.push_back(MCFixup::create(0, FixupExpression,
448  MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
449  return 0;
450 }
451 
452 /// getBranchTarget21OpValueMM - Return binary encoding of the branch
453 /// target operand for microMIPS. If the machine operand requires
454 /// relocation, record the relocation and return zero.
455 unsigned MipsMCCodeEmitter::
456 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
457  SmallVectorImpl<MCFixup> &Fixups,
458  const MCSubtargetInfo &STI) const {
459 
460  const MCOperand &MO = MI.getOperand(OpNo);
461 
462  // If the destination is an immediate, divide by 4.
463  if (MO.isImm()) return MO.getImm() >> 2;
464 
465  assert(MO.isExpr() &&
466  "getBranchTarget21OpValueMM expects only expressions or immediates");
467 
468  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
469  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
470  Fixups.push_back(MCFixup::create(0, FixupExpression,
471  MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1)));
472  return 0;
473 }
474 
475 /// getBranchTarget26OpValue - Return binary encoding of the branch
476 /// target operand. If the machine operand requires relocation,
477 /// record the relocation and return zero.
478 unsigned MipsMCCodeEmitter::
479 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
480  SmallVectorImpl<MCFixup> &Fixups,
481  const MCSubtargetInfo &STI) const {
482 
483  const MCOperand &MO = MI.getOperand(OpNo);
484 
485  // If the destination is an immediate, divide by 4.
486  if (MO.isImm()) return MO.getImm() >> 2;
487 
488  assert(MO.isExpr() &&
489  "getBranchTarget26OpValue expects only expressions or immediates");
490 
491  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
492  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
493  Fixups.push_back(MCFixup::create(0, FixupExpression,
494  MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
495  return 0;
496 }
497 
498 /// getBranchTarget26OpValueMM - Return binary encoding of the branch
499 /// target operand. If the machine operand requires relocation,
500 /// record the relocation and return zero.
501 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
502  const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
503  const MCSubtargetInfo &STI) const {
504 
505  const MCOperand &MO = MI.getOperand(OpNo);
506 
507  // If the destination is an immediate, divide by 2.
508  if (MO.isImm())
509  return MO.getImm() >> 1;
510 
511  assert(MO.isExpr() &&
512  "getBranchTarget26OpValueMM expects only expressions or immediates");
513 
514  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
515  MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
516  Fixups.push_back(MCFixup::create(0, FixupExpression,
517  MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1)));
518  return 0;
519 }
520 
521 /// getJumpOffset16OpValue - Return binary encoding of the jump
522 /// target operand. If the machine operand requires relocation,
523 /// record the relocation and return zero.
524 unsigned MipsMCCodeEmitter::
525 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
526  SmallVectorImpl<MCFixup> &Fixups,
527  const MCSubtargetInfo &STI) const {
528 
529  const MCOperand &MO = MI.getOperand(OpNo);
530 
531  if (MO.isImm()) return MO.getImm();
532 
533  assert(MO.isExpr() &&
534  "getJumpOffset16OpValue expects only expressions or an immediate");
535 
536  // TODO: Push fixup.
537  return 0;
538 }
539 
540 /// getJumpTargetOpValue - Return binary encoding of the jump
541 /// target operand. If the machine operand requires relocation,
542 /// record the relocation and return zero.
543 unsigned MipsMCCodeEmitter::
544 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
545  SmallVectorImpl<MCFixup> &Fixups,
546  const MCSubtargetInfo &STI) const {
547 
548  const MCOperand &MO = MI.getOperand(OpNo);
549  // If the destination is an immediate, divide by 4.
550  if (MO.isImm()) return MO.getImm()>>2;
551 
552  assert(MO.isExpr() &&
553  "getJumpTargetOpValue expects only expressions or an immediate");
554 
555  const MCExpr *Expr = MO.getExpr();
556  Fixups.push_back(MCFixup::create(0, Expr,
557  MCFixupKind(Mips::fixup_Mips_26)));
558  return 0;
559 }
560 
561 unsigned MipsMCCodeEmitter::
562 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
563  SmallVectorImpl<MCFixup> &Fixups,
564  const MCSubtargetInfo &STI) const {
565 
566  const MCOperand &MO = MI.getOperand(OpNo);
567  // If the destination is an immediate, divide by 2.
568  if (MO.isImm()) return MO.getImm() >> 1;
569 
570  assert(MO.isExpr() &&
571  "getJumpTargetOpValueMM expects only expressions or an immediate");
572 
573  const MCExpr *Expr = MO.getExpr();
574  Fixups.push_back(MCFixup::create(0, Expr,
575  MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
576  return 0;
577 }
578 
579 unsigned MipsMCCodeEmitter::
580 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
581  SmallVectorImpl<MCFixup> &Fixups,
582  const MCSubtargetInfo &STI) const {
583 
584  const MCOperand &MO = MI.getOperand(OpNo);
585  if (MO.isImm()) {
586  // The immediate is encoded as 'immediate << 2'.
587  unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
588  assert((Res & 3) == 0);
589  return Res >> 2;
590  }
591 
592  assert(MO.isExpr() &&
593  "getUImm5Lsl2Encoding expects only expressions or an immediate");
594 
595  return 0;
596 }
597 
598 unsigned MipsMCCodeEmitter::
599 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
600  SmallVectorImpl<MCFixup> &Fixups,
601  const MCSubtargetInfo &STI) const {
602 
603  const MCOperand &MO = MI.getOperand(OpNo);
604  if (MO.isImm()) {
605  int Value = MO.getImm();
606  return Value >> 2;
607  }
608 
609  return 0;
610 }
611 
612 unsigned MipsMCCodeEmitter::
613 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
614  SmallVectorImpl<MCFixup> &Fixups,
615  const MCSubtargetInfo &STI) const {
616 
617  const MCOperand &MO = MI.getOperand(OpNo);
618  if (MO.isImm()) {
619  unsigned Value = MO.getImm();
620  return Value >> 2;
621  }
622 
623  return 0;
624 }
625 
626 unsigned MipsMCCodeEmitter::
627 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
628  SmallVectorImpl<MCFixup> &Fixups,
629  const MCSubtargetInfo &STI) const {
630 
631  const MCOperand &MO = MI.getOperand(OpNo);
632  if (MO.isImm()) {
633  unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
634  return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
635  }
636 
637  return 0;
638 }
639 
640 unsigned MipsMCCodeEmitter::
641 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
642  const MCSubtargetInfo &STI) const {
643  int64_t Res;
644 
645  if (Expr->evaluateAsAbsolute(Res))
646  return Res;
647 
648  MCExpr::ExprKind Kind = Expr->getKind();
649  if (Kind == MCExpr::Constant) {
650  return cast<MCConstantExpr>(Expr)->getValue();
651  }
652 
653  if (Kind == MCExpr::Binary) {
654  unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
655  Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
656  return Res;
657  }
658 
659  if (Kind == MCExpr::Target) {
660  const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
661 
662  Mips::Fixups FixupKind = Mips::Fixups(0);
663  switch (MipsExpr->getKind()) {
664  case MipsMCExpr::MEK_None:
665  case MipsMCExpr::MEK_Special:
666  llvm_unreachable("Unhandled fixup kind!");
667  break;
668  case MipsMCExpr::MEK_CALL_HI16:
669  FixupKind = Mips::fixup_Mips_CALL_HI16;
670  break;
671  case MipsMCExpr::MEK_CALL_LO16:
672  FixupKind = Mips::fixup_Mips_CALL_LO16;
673  break;
674  case MipsMCExpr::MEK_DTPREL_HI:
675  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
676  : Mips::fixup_Mips_DTPREL_HI;
677  break;
678  case MipsMCExpr::MEK_DTPREL_LO:
679  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
680  : Mips::fixup_Mips_DTPREL_LO;
681  break;
682  case MipsMCExpr::MEK_GOTTPREL:
683  FixupKind = Mips::fixup_Mips_GOTTPREL;
684  break;
685  case MipsMCExpr::MEK_GOT:
686  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
687  : Mips::fixup_Mips_GOT;
688  break;
689  case MipsMCExpr::MEK_GOT_CALL:
690  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
691  : Mips::fixup_Mips_CALL16;
692  break;
693  case MipsMCExpr::MEK_GOT_DISP:
694  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
695  : Mips::fixup_Mips_GOT_DISP;
696  break;
697  case MipsMCExpr::MEK_GOT_HI16:
698  FixupKind = Mips::fixup_Mips_GOT_HI16;
699  break;
700  case MipsMCExpr::MEK_GOT_LO16:
701  FixupKind = Mips::fixup_Mips_GOT_LO16;
702  break;
703  case MipsMCExpr::MEK_GOT_PAGE:
704  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
705  : Mips::fixup_Mips_GOT_PAGE;
706  break;
707  case MipsMCExpr::MEK_GOT_OFST:
708  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
709  : Mips::fixup_Mips_GOT_OFST;
710  break;
711  case MipsMCExpr::MEK_GPREL:
712  FixupKind = Mips::fixup_Mips_GPREL16;
713  break;
714  case MipsMCExpr::MEK_LO: {
715  // Check for %lo(%neg(%gp_rel(X)))
716  if (MipsExpr->isGpOff()) {
717  FixupKind = Mips::fixup_Mips_GPOFF_LO;
718  break;
719  }
720  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
721  : Mips::fixup_Mips_LO16;
722  break;
723  }
724  case MipsMCExpr::MEK_HIGHEST:
725  FixupKind = Mips::fixup_Mips_HIGHEST;
726  break;
727  case MipsMCExpr::MEK_HIGHER:
728  FixupKind = Mips::fixup_Mips_HIGHER;
729  break;
730  case MipsMCExpr::MEK_HI:
731  // Check for %hi(%neg(%gp_rel(X)))
732  if (MipsExpr->isGpOff()) {
733  FixupKind = Mips::fixup_Mips_GPOFF_HI;
734  break;
735  }
736  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
737  : Mips::fixup_Mips_HI16;
738  break;
739  case MipsMCExpr::MEK_PCREL_HI16:
740  FixupKind = Mips::fixup_MIPS_PCHI16;
741  break;
742  case MipsMCExpr::MEK_PCREL_LO16:
743  FixupKind = Mips::fixup_MIPS_PCLO16;
744  break;
745  case MipsMCExpr::MEK_TLSGD:
746  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
747  : Mips::fixup_Mips_TLSGD;
748  break;
749  case MipsMCExpr::MEK_TLSLDM:
750  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
751  : Mips::fixup_Mips_TLSLDM;
752  break;
753  case MipsMCExpr::MEK_TPREL_HI:
754  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
755  : Mips::fixup_Mips_TPREL_HI;
756  break;
757  case MipsMCExpr::MEK_TPREL_LO:
758  FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
759  : Mips::fixup_Mips_TPREL_LO;
760  break;
761  case MipsMCExpr::MEK_NEG:
762  FixupKind =
763  isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
764  break;
765  }
766  Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
767  return 0;
768  }
769 
770  if (Kind == MCExpr::SymbolRef) {
771  Mips::Fixups FixupKind = Mips::Fixups(0);
772 
773  switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
774  default: llvm_unreachable("Unknown fixup kind!");
775  break;
776  case MCSymbolRefExpr::VK_None:
777  FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
778  break;
779  } // switch
780 
781  Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
782  return 0;
783  }
784  return 0;
785 }
786 
787 /// getMachineOpValue - Return binary encoding of operand. If the machine
788 /// operand requires relocation, record the relocation and return zero.
789 unsigned MipsMCCodeEmitter::
790 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
791  SmallVectorImpl<MCFixup> &Fixups,
792  const MCSubtargetInfo &STI) const {
793  if (MO.isReg()) {
794  unsigned Reg = MO.getReg();
795  unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
796  return RegNo;
797  } else if (MO.isImm()) {
798  return static_cast<unsigned>(MO.getImm());
799  } else if (MO.isFPImm()) {
800  return static_cast<unsigned>(APFloat(MO.getFPImm())
801  .bitcastToAPInt().getHiBits(32).getLimitedValue());
802  }
803  // MO must be an Expr.
804  assert(MO.isExpr());
805  return getExprOpValue(MO.getExpr(),Fixups, STI);
806 }
807 
808 /// Return binary encoding of memory related operand.
809 /// If the offset operand requires relocation, record the relocation.
810 template <unsigned ShiftAmount>
811 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
812  SmallVectorImpl<MCFixup> &Fixups,
813  const MCSubtargetInfo &STI) const {
814  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
815  assert(MI.getOperand(OpNo).isReg());
816  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
817  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
818 
819  // Apply the scale factor if there is one.
820  OffBits >>= ShiftAmount;
821 
822  return (OffBits & 0xFFFF) | RegBits;
823 }
824 
825 unsigned MipsMCCodeEmitter::
826 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
827  SmallVectorImpl<MCFixup> &Fixups,
828  const MCSubtargetInfo &STI) const {
829  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
830  assert(MI.getOperand(OpNo).isReg());
831  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
832  Fixups, STI) << 4;
833  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
834  Fixups, STI);
835 
836  return (OffBits & 0xF) | RegBits;
837 }
838 
839 unsigned MipsMCCodeEmitter::
840 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
841  SmallVectorImpl<MCFixup> &Fixups,
842  const MCSubtargetInfo &STI) const {
843  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
844  assert(MI.getOperand(OpNo).isReg());
845  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
846  Fixups, STI) << 4;
847  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
848  Fixups, STI) >> 1;
849 
850  return (OffBits & 0xF) | RegBits;
851 }
852 
853 unsigned MipsMCCodeEmitter::
854 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
855  SmallVectorImpl<MCFixup> &Fixups,
856  const MCSubtargetInfo &STI) const {
857  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
858  assert(MI.getOperand(OpNo).isReg());
859  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
860  Fixups, STI) << 4;
861  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
862  Fixups, STI) >> 2;
863 
864  return (OffBits & 0xF) | RegBits;
865 }
866 
867 unsigned MipsMCCodeEmitter::
868 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
869  SmallVectorImpl<MCFixup> &Fixups,
870  const MCSubtargetInfo &STI) const {
871  // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
872  assert(MI.getOperand(OpNo).isReg() &&
873  (MI.getOperand(OpNo).getReg() == Mips::SP ||
874  MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
875  "Unexpected base register!");
876  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
877  Fixups, STI) >> 2;
878 
879  return OffBits & 0x1F;
880 }
881 
882 unsigned MipsMCCodeEmitter::
883 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
884  SmallVectorImpl<MCFixup> &Fixups,
885  const MCSubtargetInfo &STI) const {
886  // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
887  assert(MI.getOperand(OpNo).isReg() &&
888  MI.getOperand(OpNo).getReg() == Mips::GP &&
889  "Unexpected base register!");
890 
891  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
892  Fixups, STI) >> 2;
893 
894  return OffBits & 0x7F;
895 }
896 
897 unsigned MipsMCCodeEmitter::
898 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
899  SmallVectorImpl<MCFixup> &Fixups,
900  const MCSubtargetInfo &STI) const {
901  // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
902  assert(MI.getOperand(OpNo).isReg());
903  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
904  STI) << 16;
905  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
906 
907  return (OffBits & 0x1FF) | RegBits;
908 }
909 
910 unsigned MipsMCCodeEmitter::
911 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
912  SmallVectorImpl<MCFixup> &Fixups,
913  const MCSubtargetInfo &STI) const {
914  // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
915  assert(MI.getOperand(OpNo).isReg());
916  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
917  STI) << 16;
918  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
919 
920  return (OffBits & 0x07FF) | RegBits;
921 }
922 
923 unsigned MipsMCCodeEmitter::
924 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
925  SmallVectorImpl<MCFixup> &Fixups,
926  const MCSubtargetInfo &STI) const {
927  // opNum can be invalid if instruction had reglist as operand.
928  // MemOperand is always last operand of instruction (base + offset).
929  switch (MI.getOpcode()) {
930  default:
931  break;
932  case Mips::SWM32_MM:
933  case Mips::LWM32_MM:
934  OpNo = MI.getNumOperands() - 2;
935  break;
936  }
937 
938  // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
939  assert(MI.getOperand(OpNo).isReg());
940  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
941  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
942 
943  return (OffBits & 0x0FFF) | RegBits;
944 }
945 
946 unsigned MipsMCCodeEmitter::
947 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
948  SmallVectorImpl<MCFixup> &Fixups,
949  const MCSubtargetInfo &STI) const {
950  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
951  assert(MI.getOperand(OpNo).isReg());
952  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
953  STI) << 16;
954  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
955 
956  return (OffBits & 0xFFFF) | RegBits;
957 }
958 
959 unsigned MipsMCCodeEmitter::
960 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
961  SmallVectorImpl<MCFixup> &Fixups,
962  const MCSubtargetInfo &STI) const {
963  // opNum can be invalid if instruction had reglist as operand
964  // MemOperand is always last operand of instruction (base + offset)
965  switch (MI.getOpcode()) {
966  default:
967  break;
968  case Mips::SWM16_MM:
969  case Mips::SWM16_MMR6:
970  case Mips::LWM16_MM:
971  case Mips::LWM16_MMR6:
972  OpNo = MI.getNumOperands() - 2;
973  break;
974  }
975 
976  // Offset is encoded in bits 4-0.
977  assert(MI.getOperand(OpNo).isReg());
978  // Base register is always SP - thus it is not encoded.
979  assert(MI.getOperand(OpNo+1).isImm());
980  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
981 
982  return ((OffBits >> 2) & 0x0F);
983 }
984 
985 // FIXME: should be called getMSBEncoding
986 //
987 unsigned
988 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
989  SmallVectorImpl<MCFixup> &Fixups,
990  const MCSubtargetInfo &STI) const {
991  assert(MI.getOperand(OpNo-1).isImm());
992  assert(MI.getOperand(OpNo).isImm());
993  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
994  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
995 
996  return Position + Size - 1;
997 }
998 
999 template <unsigned Bits, int Offset>
1000 unsigned
1001 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
1002  SmallVectorImpl<MCFixup> &Fixups,
1003  const MCSubtargetInfo &STI) const {
1004  assert(MI.getOperand(OpNo).isImm());
1005  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
1006  Value -= Offset;
1007  return Value;
1008 }
1009 
1010 unsigned
1011 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1012  SmallVectorImpl<MCFixup> &Fixups,
1013  const MCSubtargetInfo &STI) const {
1014  const MCOperand &MO = MI.getOperand(OpNo);
1015  if (MO.isImm()) {
1016  // The immediate is encoded as 'immediate << 2'.
1017  unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
1018  assert((Res & 3) == 0);
1019  return Res >> 2;
1020  }
1021 
1022  assert(MO.isExpr() &&
1023  "getSimm19Lsl2Encoding expects only expressions or an immediate");
1024 
1025  const MCExpr *Expr = MO.getExpr();
1026  Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
1027  : Mips::fixup_MIPS_PC19_S2;
1028  Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1029  return 0;
1030 }
1031 
1032 unsigned
1033 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
1034  SmallVectorImpl<MCFixup> &Fixups,
1035  const MCSubtargetInfo &STI) const {
1036  const MCOperand &MO = MI.getOperand(OpNo);
1037  if (MO.isImm()) {
1038  // The immediate is encoded as 'immediate << 3'.
1039  unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
1040  assert((Res & 7) == 0);
1041  return Res >> 3;
1042  }
1043 
1044  assert(MO.isExpr() &&
1045  "getSimm18Lsl2Encoding expects only expressions or an immediate");
1046 
1047  const MCExpr *Expr = MO.getExpr();
1048  Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
1049  : Mips::fixup_MIPS_PC18_S3;
1050  Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1051  return 0;
1052 }
1053 
1054 unsigned
1055 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
1056  SmallVectorImpl<MCFixup> &Fixups,
1057  const MCSubtargetInfo &STI) const {
1058  assert(MI.getOperand(OpNo).isImm());
1059  const MCOperand &MO = MI.getOperand(OpNo);
1060  return MO.getImm() % 8;
1061 }
1062 
1063 unsigned
1064 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1065  SmallVectorImpl<MCFixup> &Fixups,
1066  const MCSubtargetInfo &STI) const {
1067  assert(MI.getOperand(OpNo).isImm());
1068  const MCOperand &MO = MI.getOperand(OpNo);
1069  unsigned Value = MO.getImm();
1070  switch (Value) {
1071  case 128: return 0x0;
1072  case 1: return 0x1;
1073  case 2: return 0x2;
1074  case 3: return 0x3;
1075  case 4: return 0x4;
1076  case 7: return 0x5;
1077  case 8: return 0x6;
1078  case 15: return 0x7;
1079  case 16: return 0x8;
1080  case 31: return 0x9;
1081  case 32: return 0xa;
1082  case 63: return 0xb;
1083  case 64: return 0xc;
1084  case 255: return 0xd;
1085  case 32768: return 0xe;
1086  case 65535: return 0xf;
1087  }
1088  llvm_unreachable("Unexpected value");
1089 }
1090 
1091 unsigned
1092 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1093  SmallVectorImpl<MCFixup> &Fixups,
1094  const MCSubtargetInfo &STI) const {
1095  unsigned res = 0;
1096 
1097  // Register list operand is always first operand of instruction and it is
1098  // placed before memory operand (register + imm).
1099 
1100  for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1101  unsigned Reg = MI.getOperand(I).getReg();
1102  unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1103  if (RegNo != 31)
1104  res++;
1105  else
1106  res |= 0x10;
1107  }
1108  return res;
1109 }
1110 
1111 unsigned
1112 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1113  SmallVectorImpl<MCFixup> &Fixups,
1114  const MCSubtargetInfo &STI) const {
1115  return (MI.getNumOperands() - 4);
1116 }
1117 
1118 unsigned
1119 MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
1120  SmallVectorImpl<MCFixup> &Fixups,
1121  const MCSubtargetInfo &STI) const {
1122  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
1123 }
1124 
1125 unsigned
1126 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1127  SmallVectorImpl<MCFixup> &Fixups,
1128  const MCSubtargetInfo &STI) const {
1129  unsigned res = 0;
1130 
1131  if (MI.getOperand(0).getReg() == Mips::A1 &&
1132  MI.getOperand(1).getReg() == Mips::A2)
1133  res = 0;
1134  else if (MI.getOperand(0).getReg() == Mips::A1 &&
1135  MI.getOperand(1).getReg() == Mips::A3)
1136  res = 1;
1137  else if (MI.getOperand(0).getReg() == Mips::A2 &&
1138  MI.getOperand(1).getReg() == Mips::A3)
1139  res = 2;
1140  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1141  MI.getOperand(1).getReg() == Mips::S5)
1142  res = 3;
1143  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1144  MI.getOperand(1).getReg() == Mips::S6)
1145  res = 4;
1146  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1147  MI.getOperand(1).getReg() == Mips::A1)
1148  res = 5;
1149  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1150  MI.getOperand(1).getReg() == Mips::A2)
1151  res = 6;
1152  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1153  MI.getOperand(1).getReg() == Mips::A3)
1154  res = 7;
1155 
1156  return res;
1157 }
1158 
1159 unsigned
1160 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1161  SmallVectorImpl<MCFixup> &Fixups,
1162  const MCSubtargetInfo &STI) const {
1163  const MCOperand &MO = MI.getOperand(OpNo);
1164  assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1165  // The immediate is encoded as 'immediate >> 2'.
1166  unsigned Res = static_cast<unsigned>(MO.getImm());
1167  assert((Res & 3) == 0);
1168  return Res >> 2;
1169 }
1170 
1171 #include "MipsGenMCCodeEmitter.inc"
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
static void LowerDins(MCInst &InstIn)
dot regions only
Context object for machine code objects.
Definition: MCContext.h:51
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
MCCodeEmitter * createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isImm() const
Definition: MCInst.h:57
void setImm(int64_t Val)
Definition: MCInst.h:78
unsigned const MachineRegisterInfo * MRI
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:23
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setOpcode(unsigned Op)
Definition: MCInst.h:158
static void LowerLargeShift(MCInst &Inst)
void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx=nullptr)
Adjusts a value to fix up the immediate of an LDI Rd, K instruction.
unsigned getOpcode() const
Definition: MCInst.h:159
MCCodeEmitter * createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
int64_t getImm() const
Definition: MCInst.h:74
unsigned getNumOperands() const
Definition: MCInst.h:166
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164