1 //===-- MSP430MCInstLower.cpp - Convert MSP430 MachineInstr to an MCInst --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains code to lower MSP430 MachineInstrs to their corresponding 10 // MCInst records. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MSP430MCInstLower.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/CodeGen/AsmPrinter.h" 17 #include "llvm/CodeGen/MachineBasicBlock.h" 18 #include "llvm/CodeGen/MachineInstr.h" 19 #include "llvm/IR/DataLayout.h" 20 #include "llvm/IR/Mangler.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCInst.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include "llvm/Target/TargetMachine.h" 28 using namespace llvm; 29 30 MCSymbol *MSP430MCInstLower:: 31 GetGlobalAddressSymbol(const MachineOperand &MO) const { 32 switch (MO.getTargetFlags()) { 33 default: llvm_unreachable("Unknown target flag on GV operand"); 34 case 0: break; 35 } 36 37 return Printer.getSymbol(MO.getGlobal()); 38 } 39 40 MCSymbol *MSP430MCInstLower:: 41 GetExternalSymbolSymbol(const MachineOperand &MO) const { 42 switch (MO.getTargetFlags()) { 43 default: llvm_unreachable("Unknown target flag on GV operand"); 44 case 0: break; 45 } 46 47 return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 48 } 49 50 MCSymbol *MSP430MCInstLower:: 51 GetJumpTableSymbol(const MachineOperand &MO) const { 52 const DataLayout &DL = Printer.getDataLayout(); 53 SmallString<256> Name; 54 raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "JTI" 55 << Printer.getFunctionNumber() << '_' 56 << MO.getIndex(); 57 58 switch (MO.getTargetFlags()) { 59 default: llvm_unreachable("Unknown target flag on GV operand"); 60 case 0: break; 61 } 62 63 // Create a symbol for the name. 64 return Ctx.getOrCreateSymbol(Name); 65 } 66 67 MCSymbol *MSP430MCInstLower:: 68 GetConstantPoolIndexSymbol(const MachineOperand &MO) const { 69 const DataLayout &DL = Printer.getDataLayout(); 70 SmallString<256> Name; 71 raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "CPI" 72 << Printer.getFunctionNumber() << '_' 73 << MO.getIndex(); 74 75 switch (MO.getTargetFlags()) { 76 default: llvm_unreachable("Unknown target flag on GV operand"); 77 case 0: break; 78 } 79 80 // Create a symbol for the name. 81 return Ctx.getOrCreateSymbol(Name); 82 } 83 84 MCSymbol *MSP430MCInstLower:: 85 GetBlockAddressSymbol(const MachineOperand &MO) const { 86 switch (MO.getTargetFlags()) { 87 default: llvm_unreachable("Unknown target flag on GV operand"); 88 case 0: break; 89 } 90 91 return Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 92 } 93 94 MCOperand MSP430MCInstLower:: 95 LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { 96 // FIXME: We would like an efficient form for this, so we don't have to do a 97 // lot of extra uniquing. 98 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); 99 100 switch (MO.getTargetFlags()) { 101 default: llvm_unreachable("Unknown target flag on GV operand"); 102 case 0: break; 103 } 104 105 if (!MO.isJTI() && MO.getOffset()) 106 Expr = MCBinaryExpr::createAdd(Expr, 107 MCConstantExpr::create(MO.getOffset(), Ctx), 108 Ctx); 109 return MCOperand::createExpr(Expr); 110 } 111 112 #define GET_REGINFO_ENUM 113 #include "MSP430GenRegisterInfo.inc" 114 115 void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 116 OutMI.setOpcode(MI->getOpcode()); 117 118 for (const MachineOperand &MO : MI->operands()) { 119 MCOperand MCOp; 120 switch (MO.getType()) { 121 default: 122 MI->print(errs()); 123 llvm_unreachable("unknown operand type"); 124 case MachineOperand::MO_Register: 125 // Ignore all implicit register operands. 126 if (MO.isImplicit()) continue; 127 MCOp = MCOperand::createReg(MO.getReg()); 128 break; 129 case MachineOperand::MO_Immediate: 130 MCOp = MCOperand::createImm(MO.getImm()); 131 break; 132 case MachineOperand::MO_MachineBasicBlock: 133 MCOp = MCOperand::createExpr(MCSymbolRefExpr::create( 134 MO.getMBB()->getSymbol(), Ctx)); 135 break; 136 case MachineOperand::MO_GlobalAddress: 137 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); 138 break; 139 case MachineOperand::MO_ExternalSymbol: 140 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 141 break; 142 case MachineOperand::MO_JumpTableIndex: 143 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 144 break; 145 case MachineOperand::MO_ConstantPoolIndex: 146 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 147 break; 148 case MachineOperand::MO_BlockAddress: 149 MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); 150 break; 151 case MachineOperand::MO_RegisterMask: 152 continue; 153 } 154 155 OutMI.addOperand(MCOp); 156 } 157 } 158