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