1 //===-- MipsDirectObjLower.cpp - Mips LLVM direct object lowering -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains code to lower Mips MCInst records that are normally
11 // left to the assembler to lower such as large shifts.
13 //===----------------------------------------------------------------------===//
14 #include "MipsInstrInfo.h"
15 #include "MCTargetDesc/MipsDirectObjLower.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCStreamer.h"
21 // If the D<shift> instruction has a shift amount that is greater
22 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
23 void Mips::LowerLargeShift(MCInst& Inst) {
25 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
26 assert(Inst.getOperand(2).isImm());
28 int64_t Shift = Inst.getOperand(2).getImm();
34 Inst.getOperand(2).setImm(Shift);
36 switch (Inst.getOpcode()) {
38 // Calling function is not synchronized
39 llvm_unreachable("Unexpected shift instruction");
41 Inst.setOpcode(Mips::DSLL32);
44 Inst.setOpcode(Mips::DSRL32);
47 Inst.setOpcode(Mips::DSRA32);
52 // Pick a DEXT or DINS instruction variant based on the pos and size operands
53 void Mips::LowerDextDins(MCInst& InstIn) {
54 int Opcode = InstIn.getOpcode();
56 if (Opcode == Mips::DEXT)
57 assert(InstIn.getNumOperands() == 4 &&
58 "Invalid no. of machine operands for DEXT!");
59 else // Only DEXT and DINS are possible
60 assert(InstIn.getNumOperands() == 5 &&
61 "Invalid no. of machine operands for DINS!");
63 assert(InstIn.getOperand(2).isImm());
64 int64_t pos = InstIn.getOperand(2).getImm();
65 assert(InstIn.getOperand(3).isImm());
66 int64_t size = InstIn.getOperand(3).getImm();
69 if (pos < 32) // DEXT/DINS, do nothing
72 InstIn.getOperand(2).setImm(pos - 32);
73 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
77 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
78 InstIn.getOperand(3).setImm(size - 32);
79 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);