1e5d89e80SDylan McKay //===-- AVRMCInstLower.cpp - Convert AVR MachineInstr to an MCInst --------===// 2e5d89e80SDylan McKay // 3e5d89e80SDylan McKay // The LLVM Compiler Infrastructure 4e5d89e80SDylan McKay // 5e5d89e80SDylan McKay // This file is distributed under the University of Illinois Open Source 6e5d89e80SDylan McKay // License. See LICENSE.TXT for details. 7e5d89e80SDylan McKay // 8e5d89e80SDylan McKay //===----------------------------------------------------------------------===// 9e5d89e80SDylan McKay // 10e5d89e80SDylan McKay // This file contains code to lower AVR MachineInstrs to their corresponding 11e5d89e80SDylan McKay // MCInst records. 12e5d89e80SDylan McKay // 13e5d89e80SDylan McKay //===----------------------------------------------------------------------===// 14e5d89e80SDylan McKay 15e5d89e80SDylan McKay #include "AVRMCInstLower.h" 16e5d89e80SDylan McKay 17e5d89e80SDylan McKay #include "AVRInstrInfo.h" 18e5d89e80SDylan McKay #include "MCTargetDesc/AVRMCExpr.h" 19e5d89e80SDylan McKay 20e5d89e80SDylan McKay #include "llvm/CodeGen/AsmPrinter.h" 21e5d89e80SDylan McKay #include "llvm/IR/Mangler.h" 22e5d89e80SDylan McKay #include "llvm/MC/MCInst.h" 23e5d89e80SDylan McKay #include "llvm/Support/ErrorHandling.h" 24e5d89e80SDylan McKay 25e5d89e80SDylan McKay namespace llvm { 26e5d89e80SDylan McKay 27e5d89e80SDylan McKay MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO, 28e5d89e80SDylan McKay MCSymbol *Sym) const { 29e5d89e80SDylan McKay unsigned char TF = MO.getTargetFlags(); 30e5d89e80SDylan McKay const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); 31e5d89e80SDylan McKay 32e5d89e80SDylan McKay bool IsNegated = false; 33e5d89e80SDylan McKay if (TF & AVRII::MO_NEG) { IsNegated = true; } 34e5d89e80SDylan McKay 35e5d89e80SDylan McKay if (!MO.isJTI() && MO.getOffset()) { 36e5d89e80SDylan McKay Expr = MCBinaryExpr::createAdd( 37e5d89e80SDylan McKay Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 38e5d89e80SDylan McKay } 39e5d89e80SDylan McKay 40*9fb04071SDylan McKay bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal()); 41*9fb04071SDylan McKay 42e5d89e80SDylan McKay if (TF & AVRII::MO_LO) { 43*9fb04071SDylan McKay if (IsFunction) { 44*9fb04071SDylan McKay // N.B. Should we use _GS fixups here to cope with >128k progmem? 45*9fb04071SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx); 46*9fb04071SDylan McKay } else { 47e5d89e80SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); 48*9fb04071SDylan McKay } 49e5d89e80SDylan McKay } else if (TF & AVRII::MO_HI) { 50*9fb04071SDylan McKay if (IsFunction) { 51*9fb04071SDylan McKay // N.B. Should we use _GS fixups here to cope with >128k progmem? 52*9fb04071SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx); 53*9fb04071SDylan McKay } else { 54e5d89e80SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); 55*9fb04071SDylan McKay } 56e5d89e80SDylan McKay } else if (TF != 0) { 57e5d89e80SDylan McKay llvm_unreachable("Unknown target flag on symbol operand"); 58e5d89e80SDylan McKay } 59e5d89e80SDylan McKay 60e5d89e80SDylan McKay return MCOperand::createExpr(Expr); 61e5d89e80SDylan McKay } 62e5d89e80SDylan McKay 63e5d89e80SDylan McKay void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const { 64e5d89e80SDylan McKay OutMI.setOpcode(MI.getOpcode()); 65e5d89e80SDylan McKay 66e5d89e80SDylan McKay for (MachineOperand const &MO : MI.operands()) { 67e5d89e80SDylan McKay MCOperand MCOp; 68e5d89e80SDylan McKay 69e5d89e80SDylan McKay switch (MO.getType()) { 70e5d89e80SDylan McKay default: 710acfafdbSDylan McKay MI.print(errs()); 72e5d89e80SDylan McKay llvm_unreachable("unknown operand type"); 73e5d89e80SDylan McKay case MachineOperand::MO_Register: 74e5d89e80SDylan McKay // Ignore all implicit register operands. 75e5d89e80SDylan McKay if (MO.isImplicit()) 76e5d89e80SDylan McKay continue; 77e5d89e80SDylan McKay MCOp = MCOperand::createReg(MO.getReg()); 78e5d89e80SDylan McKay break; 79e5d89e80SDylan McKay case MachineOperand::MO_Immediate: 80e5d89e80SDylan McKay MCOp = MCOperand::createImm(MO.getImm()); 81e5d89e80SDylan McKay break; 82e5d89e80SDylan McKay case MachineOperand::MO_GlobalAddress: 83e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 84e5d89e80SDylan McKay break; 85e5d89e80SDylan McKay case MachineOperand::MO_ExternalSymbol: 86e5d89e80SDylan McKay MCOp = lowerSymbolOperand( 87e5d89e80SDylan McKay MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 88e5d89e80SDylan McKay break; 89e5d89e80SDylan McKay case MachineOperand::MO_MachineBasicBlock: 90e5d89e80SDylan McKay MCOp = MCOperand::createExpr( 91e5d89e80SDylan McKay MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 92e5d89e80SDylan McKay break; 93e5d89e80SDylan McKay case MachineOperand::MO_RegisterMask: 94e5d89e80SDylan McKay continue; 95e5d89e80SDylan McKay case MachineOperand::MO_BlockAddress: 96e5d89e80SDylan McKay MCOp = lowerSymbolOperand( 97e5d89e80SDylan McKay MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 98e5d89e80SDylan McKay break; 99e5d89e80SDylan McKay case MachineOperand::MO_JumpTableIndex: 100e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 101e5d89e80SDylan McKay break; 102e5d89e80SDylan McKay case MachineOperand::MO_ConstantPoolIndex: 103e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 104e5d89e80SDylan McKay break; 105e5d89e80SDylan McKay } 106e5d89e80SDylan McKay 107e5d89e80SDylan McKay OutMI.addOperand(MCOp); 108e5d89e80SDylan McKay } 109e5d89e80SDylan McKay } 110e5d89e80SDylan McKay 111e5d89e80SDylan McKay } // end of namespace llvm 112e5d89e80SDylan McKay 113