1 //===-- MipsDirectObjLower.cpp - Mips LLVM direct object lowering -----===// 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 contains code to lower Mips MCInst records that are normally 11 // left to the assembler to lower such as large shifts. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "MipsInstrInfo.h" 15 #include "MCTargetDesc/MipsDirectObjLower.h" 16 #include "llvm/MC/MCInst.h" 17 #include "llvm/MC/MCStreamer.h" 18 19 using namespace llvm; 20 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) { 24 25 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 26 assert(Inst.getOperand(2).isImm()); 27 28 int64_t Shift = Inst.getOperand(2).getImm(); 29 if (Shift <= 31) 30 return; // Do nothing 31 Shift -= 32; 32 33 // saminus32 34 Inst.getOperand(2).setImm(Shift); 35 36 switch (Inst.getOpcode()) { 37 default: 38 // Calling function is not synchronized 39 llvm_unreachable("Unexpected shift instruction"); 40 case Mips::DSLL: 41 Inst.setOpcode(Mips::DSLL32); 42 return; 43 case Mips::DSRL: 44 Inst.setOpcode(Mips::DSRL32); 45 return; 46 case Mips::DSRA: 47 Inst.setOpcode(Mips::DSRA32); 48 return; 49 } 50 } 51 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(); 55 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!"); 62 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(); 67 68 if (size <= 32) { 69 if (pos < 32) // DEXT/DINS, do nothing 70 return; 71 // DEXTU/DINSU 72 InstIn.getOperand(2).setImm(pos - 32); 73 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 74 return; 75 } 76 // DEXTM/DINSM 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); 80 return; 81 } 82