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) { IsNegated = true; } 33 34 if (!MO.isJTI() && MO.getOffset()) { 35 Expr = MCBinaryExpr::createAdd( 36 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 37 } 38 39 bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal()); 40 41 if (TF & AVRII::MO_LO) { 42 if (IsFunction) { 43 // N.B. Should we use _GS fixups here to cope with >128k progmem? 44 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx); 45 } else { 46 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); 47 } 48 } else if (TF & AVRII::MO_HI) { 49 if (IsFunction) { 50 // N.B. Should we use _GS fixups here to cope with >128k progmem? 51 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx); 52 } else { 53 Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); 54 } 55 } else if (TF != 0) { 56 llvm_unreachable("Unknown target flag on symbol operand"); 57 } 58 59 return MCOperand::createExpr(Expr); 60 } 61 62 void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const { 63 OutMI.setOpcode(MI.getOpcode()); 64 65 for (MachineOperand const &MO : MI.operands()) { 66 MCOperand MCOp; 67 68 switch (MO.getType()) { 69 default: 70 MI.print(errs()); 71 llvm_unreachable("unknown operand type"); 72 case MachineOperand::MO_Register: 73 // Ignore all implicit register operands. 74 if (MO.isImplicit()) 75 continue; 76 MCOp = MCOperand::createReg(MO.getReg()); 77 break; 78 case MachineOperand::MO_Immediate: 79 MCOp = MCOperand::createImm(MO.getImm()); 80 break; 81 case MachineOperand::MO_GlobalAddress: 82 MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 83 break; 84 case MachineOperand::MO_ExternalSymbol: 85 MCOp = lowerSymbolOperand( 86 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 87 break; 88 case MachineOperand::MO_MachineBasicBlock: 89 MCOp = MCOperand::createExpr( 90 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 91 break; 92 case MachineOperand::MO_RegisterMask: 93 continue; 94 case MachineOperand::MO_BlockAddress: 95 MCOp = lowerSymbolOperand( 96 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 97 break; 98 case MachineOperand::MO_JumpTableIndex: 99 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 100 break; 101 case MachineOperand::MO_ConstantPoolIndex: 102 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 103 break; 104 } 105 106 OutMI.addOperand(MCOp); 107 } 108 } 109 110 } // end of namespace llvm 111 112