19cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
29cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
39cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//                     The LLVM Compiler Infrastructure
49cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
59cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file is distributed under the University of Illinois Open Source
69cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// License. See LICENSE.TXT for details.
79cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
89cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===//
99cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
109cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file contains code to lower ARM MachineInstrs to their corresponding
119cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// MCInst records.
129cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
139cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===//
149cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner
15112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner#include "ARM.h"
16baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#include "ARMAsmPrinter.h"
17ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
1896bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner#include "llvm/CodeGen/MachineBasicBlock.h"
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
206f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCExpr.h"
219cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner#include "llvm/MC/MCInst.h"
22d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
239cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnerusing namespace llvm;
249cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner
251612a619f18cbb328df5b2d8d268dd5e02a4a483Chris Lattner
2653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim GrosbachMCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
2753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                      const MCSymbol *Symbol) {
28de36af4c157b0df6fd089b8fe965904761c2b5e1Chris Lattner  const MCExpr *Expr;
29292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner  switch (MO.getTargetFlags()) {
307597212abced110723f2fee985a7d60557c092ecEvan Cheng  default: {
3153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
3253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                   OutContext);
337597212abced110723f2fee985a7d60557c092ecEvan Cheng    switch (MO.getTargetFlags()) {
34bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unknown target flag on symbol operand");
357597212abced110723f2fee985a7d60557c092ecEvan Cheng    case 0:
367597212abced110723f2fee985a7d60557c092ecEvan Cheng      break;
377597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMII::MO_LO16:
3853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
3953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                     OutContext);
4053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
417597212abced110723f2fee985a7d60557c092ecEvan Cheng      break;
427597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMII::MO_HI16:
4353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
4453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                     OutContext);
4553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
467597212abced110723f2fee985a7d60557c092ecEvan Cheng      break;
477597212abced110723f2fee985a7d60557c092ecEvan Cheng    }
48637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
497597212abced110723f2fee985a7d60557c092ecEvan Cheng  }
507597212abced110723f2fee985a7d60557c092ecEvan Cheng
51637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case ARMII::MO_PLT:
5253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
5353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                   OutContext);
54637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
55292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner  }
56d309b413a5a246e006a63f61aa9052effd8b4c7eJim Grosbach
57c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  if (!MO.isJTI() && MO.getOffset())
58c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    Expr = MCBinaryExpr::CreateAdd(Expr,
5953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                   MCConstantExpr::Create(MO.getOffset(),
6053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                                          OutContext),
6153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                   OutContext);
62c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  return MCOperand::CreateExpr(Expr);
63d309b413a5a246e006a63f61aa9052effd8b4c7eJim Grosbach
64c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach}
65c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach
6653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbachbool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
6753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                 MCOperand &MCOp) {
6853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  switch (MO.getType()) {
69bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unknown operand type");
7053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_Register:
7153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    // Ignore all non-CPSR implicit register operands.
7253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
7353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      return false;
7453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
7553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = MCOperand::CreateReg(MO.getReg());
7653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
7753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_Immediate:
7853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = MCOperand::CreateImm(MO.getImm());
7953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
8053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_MachineBasicBlock:
8153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
8253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach        MO.getMBB()->getSymbol(), OutContext));
8353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
8453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_GlobalAddress:
8553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal()));
8653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
8753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_ExternalSymbol:
8853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach   MCOp = GetSymbolRef(MO,
8953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                        GetExternalSymbolSymbol(MO.getSymbolName()));
9053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
9153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_JumpTableIndex:
9253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
9353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
9453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_ConstantPoolIndex:
9553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
9653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
9753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_BlockAddress:
9853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
9953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
10053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  case MachineOperand::MO_FPImmediate: {
10153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    APFloat Val = MO.getFPImm()->getValueAPF();
10253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    bool ignored;
10353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
10453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
10553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    break;
10653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  }
10771f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen  case MachineOperand::MO_RegisterMask:
10871f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    // Ignore call clobbers.
10971f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    return false;
11053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  }
11153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  return true;
11253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach}
11353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
11430e2cc254be72601b11383dda01f495741ffd56cChris Lattnervoid llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
115baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach                                        ARMAsmPrinter &AP) {
1169cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  OutMI.setOpcode(MI->getOpcode());
117fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1189cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1199cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    const MachineOperand &MO = MI->getOperand(i);
120fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1219cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    MCOperand MCOp;
12253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach    if (AP.lowerOperand(MO, MCOp))
12353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach      OutMI.addOperand(MCOp);
1249cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  }
1259cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner}
126