1 //===-- AVRMCInstLower.cpp - Convert AVR 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 AVR MachineInstrs to their corresponding 10 // MCInst records. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AVRMCInstLower.h" 15 #include "AVRInstrInfo.h" 16 #include "MCTargetDesc/AVRMCExpr.h" 17 18 #include "llvm/CodeGen/AsmPrinter.h" 19 #include "llvm/IR/Mangler.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/Support/ErrorHandling.h" 22 23 namespace llvm { 24 25 MCOperand 26 AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, 27 const AVRSubtarget &Subtarget) const { 28 unsigned char TF = MO.getTargetFlags(); 29 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); 30 31 bool IsNegated = false; 32 if (TF & AVRII::MO_NEG) { 33 IsNegated = true; 34 } 35 36 if (!MO.isJTI() && MO.getOffset()) { 37 Expr = MCBinaryExpr::createAdd( 38 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 39 } 40 41 bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal()); 42 43 if (TF & AVRII::MO_LO) { 44 if (IsFunction) { 45 Expr = 46 AVRMCExpr::create(Subtarget.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_LO8_GS 47 : AVRMCExpr::VK_AVR_PM_LO8, 48 Expr, IsNegated, Ctx); 49 } else { 50 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); 51 } 52 } else if (TF & AVRII::MO_HI) { 53 if (IsFunction) { 54 Expr = 55 AVRMCExpr::create(Subtarget.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_HI8_GS 56 : AVRMCExpr::VK_AVR_PM_HI8, 57 Expr, IsNegated, Ctx); 58 } else { 59 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); 60 } 61 } else if (TF != 0) { 62 llvm_unreachable("Unknown target flag on symbol operand"); 63 } 64 65 return MCOperand::createExpr(Expr); 66 } 67 68 void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, 69 MCInst &OutMI) const { 70 auto &Subtarget = MI.getParent()->getParent()->getSubtarget<AVRSubtarget>(); 71 OutMI.setOpcode(MI.getOpcode()); 72 73 for (MachineOperand const &MO : MI.operands()) { 74 MCOperand MCOp; 75 76 switch (MO.getType()) { 77 default: 78 MI.print(errs()); 79 llvm_unreachable("unknown operand type"); 80 case MachineOperand::MO_Register: 81 // Ignore all implicit register operands. 82 if (MO.isImplicit()) 83 continue; 84 MCOp = MCOperand::createReg(MO.getReg()); 85 break; 86 case MachineOperand::MO_Immediate: 87 MCOp = MCOperand::createImm(MO.getImm()); 88 break; 89 case MachineOperand::MO_GlobalAddress: 90 MCOp = 91 lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal()), Subtarget); 92 break; 93 case MachineOperand::MO_ExternalSymbol: 94 MCOp = lowerSymbolOperand( 95 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName()), Subtarget); 96 break; 97 case MachineOperand::MO_MachineBasicBlock: 98 MCOp = MCOperand::createExpr( 99 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 100 break; 101 case MachineOperand::MO_RegisterMask: 102 continue; 103 case MachineOperand::MO_BlockAddress: 104 MCOp = lowerSymbolOperand( 105 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()), Subtarget); 106 break; 107 case MachineOperand::MO_JumpTableIndex: 108 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()), 109 Subtarget); 110 break; 111 case MachineOperand::MO_ConstantPoolIndex: 112 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()), 113 Subtarget); 114 break; 115 } 116 117 OutMI.addOperand(MCOp); 118 } 119 } 120 121 } // end of namespace llvm 122