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 40e5d89e80SDylan McKay if (TF & AVRII::MO_LO) { 41e5d89e80SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); 42e5d89e80SDylan McKay } else if (TF & AVRII::MO_HI) { 43e5d89e80SDylan McKay Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); 44e5d89e80SDylan McKay } else if (TF != 0) { 45e5d89e80SDylan McKay llvm_unreachable("Unknown target flag on symbol operand"); 46e5d89e80SDylan McKay } 47e5d89e80SDylan McKay 48e5d89e80SDylan McKay return MCOperand::createExpr(Expr); 49e5d89e80SDylan McKay } 50e5d89e80SDylan McKay 51e5d89e80SDylan McKay void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const { 52e5d89e80SDylan McKay OutMI.setOpcode(MI.getOpcode()); 53e5d89e80SDylan McKay 54e5d89e80SDylan McKay for (MachineOperand const &MO : MI.operands()) { 55e5d89e80SDylan McKay MCOperand MCOp; 56e5d89e80SDylan McKay 57e5d89e80SDylan McKay switch (MO.getType()) { 58e5d89e80SDylan McKay default: 59*0acfafdbSDylan McKay MI.print(errs()); 60e5d89e80SDylan McKay llvm_unreachable("unknown operand type"); 61e5d89e80SDylan McKay case MachineOperand::MO_Register: 62e5d89e80SDylan McKay // Ignore all implicit register operands. 63e5d89e80SDylan McKay if (MO.isImplicit()) 64e5d89e80SDylan McKay continue; 65e5d89e80SDylan McKay MCOp = MCOperand::createReg(MO.getReg()); 66e5d89e80SDylan McKay break; 67e5d89e80SDylan McKay case MachineOperand::MO_Immediate: 68e5d89e80SDylan McKay MCOp = MCOperand::createImm(MO.getImm()); 69e5d89e80SDylan McKay break; 70e5d89e80SDylan McKay case MachineOperand::MO_GlobalAddress: 71e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 72e5d89e80SDylan McKay break; 73e5d89e80SDylan McKay case MachineOperand::MO_ExternalSymbol: 74e5d89e80SDylan McKay MCOp = lowerSymbolOperand( 75e5d89e80SDylan McKay MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 76e5d89e80SDylan McKay break; 77e5d89e80SDylan McKay case MachineOperand::MO_MachineBasicBlock: 78e5d89e80SDylan McKay MCOp = MCOperand::createExpr( 79e5d89e80SDylan McKay MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 80e5d89e80SDylan McKay break; 81e5d89e80SDylan McKay case MachineOperand::MO_RegisterMask: 82e5d89e80SDylan McKay continue; 83e5d89e80SDylan McKay case MachineOperand::MO_BlockAddress: 84e5d89e80SDylan McKay MCOp = lowerSymbolOperand( 85e5d89e80SDylan McKay MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 86e5d89e80SDylan McKay break; 87e5d89e80SDylan McKay case MachineOperand::MO_JumpTableIndex: 88e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 89e5d89e80SDylan McKay break; 90e5d89e80SDylan McKay case MachineOperand::MO_ConstantPoolIndex: 91e5d89e80SDylan McKay MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 92e5d89e80SDylan McKay break; 93e5d89e80SDylan McKay } 94e5d89e80SDylan McKay 95e5d89e80SDylan McKay OutMI.addOperand(MCOp); 96e5d89e80SDylan McKay } 97e5d89e80SDylan McKay } 98e5d89e80SDylan McKay 99e5d89e80SDylan McKay } // end of namespace llvm 100e5d89e80SDylan McKay 101