1 //===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===// 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 Sparc MachineInstrs to their corresponding 11 // MCInst records. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "Sparc.h" 16 #include "MCTargetDesc/SparcBaseInfo.h" 17 #include "MCTargetDesc/SparcMCExpr.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/CodeGen/AsmPrinter.h" 20 #include "llvm/CodeGen/MachineFunction.h" 21 #include "llvm/CodeGen/MachineInstr.h" 22 #include "llvm/CodeGen/MachineOperand.h" 23 #include "llvm/IR/Mangler.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCExpr.h" 27 #include "llvm/MC/MCInst.h" 28 29 using namespace llvm; 30 31 32 static MCOperand LowerSymbolOperand(const MachineInstr *MI, 33 const MachineOperand &MO, 34 AsmPrinter &AP) { 35 36 SparcMCExpr::VariantKind Kind; 37 const MCSymbol *Symbol = 0; 38 39 unsigned TF = MO.getTargetFlags(); 40 41 switch(TF) { 42 default: llvm_unreachable("Unknown target flags on operand"); 43 case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break; 44 case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break; 45 case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break; 46 case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break; 47 case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break; 48 case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break; 49 case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break; 50 case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break; 51 case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break; 52 case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break; 53 case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break; 54 case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break; 55 case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break; 56 case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break; 57 case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break; 58 case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break; 59 case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break; 60 case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break; 61 case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break; 62 case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break; 63 case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break; 64 case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break; 65 case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break; 66 case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break; 67 case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break; 68 case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break; 69 } 70 71 switch(MO.getType()) { 72 default: llvm_unreachable("Unknown type in LowerSymbolOperand"); 73 case MachineOperand::MO_MachineBasicBlock: 74 Symbol = MO.getMBB()->getSymbol(); 75 break; 76 77 case MachineOperand::MO_GlobalAddress: 78 Symbol = AP.getSymbol(MO.getGlobal()); 79 break; 80 81 case MachineOperand::MO_BlockAddress: 82 Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress()); 83 break; 84 85 case MachineOperand::MO_ExternalSymbol: 86 Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName()); 87 break; 88 89 case MachineOperand::MO_ConstantPoolIndex: 90 Symbol = AP.GetCPISymbol(MO.getIndex()); 91 break; 92 } 93 94 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, 95 AP.OutContext); 96 const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, 97 AP.OutContext); 98 return MCOperand::CreateExpr(expr); 99 } 100 101 static MCOperand LowerOperand(const MachineInstr *MI, 102 const MachineOperand &MO, 103 AsmPrinter &AP) { 104 switch(MO.getType()) { 105 default: llvm_unreachable("unknown operand type"); break; 106 case MachineOperand::MO_Register: 107 if (MO.isImplicit()) 108 break; 109 return MCOperand::CreateReg(MO.getReg()); 110 111 case MachineOperand::MO_Immediate: 112 return MCOperand::CreateImm(MO.getImm()); 113 114 case MachineOperand::MO_MachineBasicBlock: 115 case MachineOperand::MO_GlobalAddress: 116 case MachineOperand::MO_BlockAddress: 117 case MachineOperand::MO_ExternalSymbol: 118 case MachineOperand::MO_ConstantPoolIndex: 119 return LowerSymbolOperand(MI, MO, AP); 120 121 case MachineOperand::MO_RegisterMask: break; 122 123 } 124 return MCOperand(); 125 } 126 127 void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI, 128 MCInst &OutMI, 129 AsmPrinter &AP) 130 { 131 132 OutMI.setOpcode(MI->getOpcode()); 133 134 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 135 const MachineOperand &MO = MI->getOperand(i); 136 MCOperand MCOp = LowerOperand(MI, MO, AP); 137 138 if (MCOp.isValid()) 139 OutMI.addOperand(MCOp); 140 } 141 } 142