1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains code to lower ARM MachineInstrs to their corresponding
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// MCInst records.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ARM.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ARMAsmPrinter.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MCTargetDesc/ARMMCExpr.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Constants.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineBasicBlock.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCExpr.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCInst.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/Mangler.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      const MCSymbol *Symbol) {
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCExpr *Expr;
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (MO.getTargetFlags()) {
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default: {
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   OutContext);
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (MO.getTargetFlags()) {
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(0 && "Unknown target flag on symbol operand");
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case 0:
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARMII::MO_LO16:
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     OutContext);
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ARMII::MO_HI16:
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     OutContext);
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case ARMII::MO_PLT:
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   OutContext);
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MO.isJTI() && MO.getOffset())
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Expr = MCBinaryExpr::CreateAdd(Expr,
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   MCConstantExpr::Create(MO.getOffset(),
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                          OutContext),
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   OutContext);
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return MCOperand::CreateExpr(Expr);
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 MCOperand &MCOp) {
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (MO.getType()) {
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(0 && "unknown operand type");
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_Register:
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Ignore all non-CPSR implicit register operands.
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(!MO.getSubReg() && "Subregs should be eliminated!");
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = MCOperand::CreateReg(MO.getReg());
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_Immediate:
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = MCOperand::CreateImm(MO.getImm());
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_MachineBasicBlock:
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MO.getMBB()->getSymbol(), OutContext));
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_GlobalAddress:
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal()));
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_ExternalSymbol:
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   MCOp = GetSymbolRef(MO,
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        GetExternalSymbolSymbol(MO.getSymbolName()));
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_JumpTableIndex:
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_ConstantPoolIndex:
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_BlockAddress:
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MachineOperand::MO_FPImmediate: {
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    APFloat Val = MO.getFPImm()->getValueAPF();
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ignored;
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        ARMAsmPrinter &AP) {
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  OutMI.setOpcode(MI->getOpcode());
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const MachineOperand &MO = MI->getOperand(i);
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCOperand MCOp;
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (AP.lowerOperand(MO, MCOp))
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutMI.addOperand(MCOp);
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
126