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/AVRMCAsmInfo.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 = AVRMCExpr::create(Subtarget.hasEIJMPCALL() ? AVR::S_LO8_GS 46 : AVR::S_PM_LO8, 47 Expr, IsNegated, Ctx); 48 } else { 49 Expr = AVRMCExpr::create(AVR::S_LO8, Expr, IsNegated, Ctx); 50 } 51 } else if (TF & AVRII::MO_HI) { 52 if (IsFunction) { 53 Expr = AVRMCExpr::create(Subtarget.hasEIJMPCALL() ? AVR::S_HI8_GS 54 : AVR::S_PM_HI8, 55 Expr, IsNegated, Ctx); 56 } else { 57 Expr = AVRMCExpr::create(AVR::S_HI8, Expr, IsNegated, Ctx); 58 } 59 } else if (TF != 0) { 60 llvm_unreachable("Unknown target flag on symbol operand"); 61 } 62 63 return MCOperand::createExpr(Expr); 64 } 65 66 void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, 67 MCInst &OutMI) const { 68 auto &Subtarget = MI.getParent()->getParent()->getSubtarget<AVRSubtarget>(); 69 OutMI.setOpcode(MI.getOpcode()); 70 71 for (MachineOperand const &MO : MI.operands()) { 72 MCOperand MCOp; 73 74 switch (MO.getType()) { 75 default: 76 MI.print(errs()); 77 llvm_unreachable("unknown operand type"); 78 case MachineOperand::MO_Register: 79 // Ignore all implicit register operands. 80 if (MO.isImplicit()) 81 continue; 82 MCOp = MCOperand::createReg(MO.getReg()); 83 break; 84 case MachineOperand::MO_Immediate: 85 MCOp = MCOperand::createImm(MO.getImm()); 86 break; 87 case MachineOperand::MO_GlobalAddress: 88 MCOp = 89 lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal()), Subtarget); 90 break; 91 case MachineOperand::MO_ExternalSymbol: 92 MCOp = lowerSymbolOperand( 93 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName()), Subtarget); 94 break; 95 case MachineOperand::MO_MachineBasicBlock: 96 MCOp = MCOperand::createExpr( 97 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 98 break; 99 case MachineOperand::MO_RegisterMask: 100 continue; 101 case MachineOperand::MO_BlockAddress: 102 MCOp = lowerSymbolOperand( 103 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()), Subtarget); 104 break; 105 case MachineOperand::MO_JumpTableIndex: 106 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()), 107 Subtarget); 108 break; 109 case MachineOperand::MO_ConstantPoolIndex: 110 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()), 111 Subtarget); 112 break; 113 } 114 115 OutMI.addOperand(MCOp); 116 } 117 } 118 119 } // end of namespace llvm 120