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 16 #include "AVRInstrInfo.h" 17 #include "MCTargetDesc/AVRMCExpr.h" 18 19 #include "llvm/CodeGen/AsmPrinter.h" 20 #include "llvm/IR/Mangler.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/Support/ErrorHandling.h" 23 24 namespace llvm { 25 26 MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO, 27 MCSymbol *Sym) 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 // N.B. Should we use _GS fixups here to cope with >128k progmem? 46 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx); 47 } else { 48 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); 49 } 50 } else if (TF & AVRII::MO_HI) { 51 if (IsFunction) { 52 // N.B. Should we use _GS fixups here to cope with >128k progmem? 53 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx); 54 } else { 55 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); 56 } 57 } else if (TF != 0) { 58 llvm_unreachable("Unknown target flag on symbol operand"); 59 } 60 61 return MCOperand::createExpr(Expr); 62 } 63 64 void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, 65 MCInst &OutMI) const { 66 OutMI.setOpcode(MI.getOpcode()); 67 68 for (MachineOperand const &MO : MI.operands()) { 69 MCOperand MCOp; 70 71 switch (MO.getType()) { 72 default: 73 MI.print(errs()); 74 llvm_unreachable("unknown operand type"); 75 case MachineOperand::MO_Register: 76 // Ignore all implicit register operands. 77 if (MO.isImplicit()) 78 continue; 79 MCOp = MCOperand::createReg(MO.getReg()); 80 break; 81 case MachineOperand::MO_Immediate: 82 MCOp = MCOperand::createImm(MO.getImm()); 83 break; 84 case MachineOperand::MO_GlobalAddress: 85 MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 86 break; 87 case MachineOperand::MO_ExternalSymbol: 88 MCOp = lowerSymbolOperand( 89 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 90 break; 91 case MachineOperand::MO_MachineBasicBlock: 92 MCOp = MCOperand::createExpr( 93 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 94 break; 95 case MachineOperand::MO_RegisterMask: 96 continue; 97 case MachineOperand::MO_BlockAddress: 98 MCOp = lowerSymbolOperand( 99 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 100 break; 101 case MachineOperand::MO_JumpTableIndex: 102 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 103 break; 104 case MachineOperand::MO_ConstantPoolIndex: 105 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 106 break; 107 } 108 109 OutMI.addOperand(MCOp); 110 } 111 } 112 113 } // end of namespace llvm 114