blob: 023f5f8e37a003536a381626db10164b0db00ab7 [file] [log] [blame]
Chris Lattner9cf0eb52009-10-19 20:21:05 +00001//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains code to lower ARM MachineInstrs to their corresponding
11// MCInst records.
12//
13//===----------------------------------------------------------------------===//
14
Chris Lattner112f2392010-11-14 20:31:06 +000015#include "ARM.h"
Jim Grosbachbaf120f2010-12-01 03:45:07 +000016#include "ARMAsmPrinter.h"
Stephen Hines36b56882014-04-23 16:57:46 -070017#include "MCTargetDesc/ARMBaseInfo.h"
Evan Chengee04a6d2011-07-20 23:34:39 +000018#include "MCTargetDesc/ARMMCExpr.h"
Chris Lattner96bc2172009-10-20 00:52:47 +000019#include "llvm/CodeGen/MachineBasicBlock.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000020#include "llvm/IR/Constants.h"
Stephen Hines36b56882014-04-23 16:57:46 -070021#include "llvm/IR/Mangler.h"
Chris Lattner6f997762009-10-19 21:53:00 +000022#include "llvm/MC/MCExpr.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000023#include "llvm/MC/MCInst.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000024using namespace llvm;
25
Chris Lattner1612a612010-11-14 20:58:38 +000026
Jim Grosbach53e3fc42011-07-08 17:40:42 +000027MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
28 const MCSymbol *Symbol) {
Chris Lattnerde36af42010-11-14 20:40:08 +000029 const MCExpr *Expr;
Stephen Hines36b56882014-04-23 16:57:46 -070030 unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK;
31 switch (Option) {
Evan Cheng75972122011-01-13 07:58:56 +000032 default: {
Jim Grosbach53e3fc42011-07-08 17:40:42 +000033 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
34 OutContext);
Stephen Hines36b56882014-04-23 16:57:46 -070035 switch (Option) {
Craig Topperbc219812012-02-07 02:50:20 +000036 default: llvm_unreachable("Unknown target flag on symbol operand");
Stephen Hinescd81d942014-07-21 00:45:20 -070037 case ARMII::MO_NO_FLAG:
Evan Cheng75972122011-01-13 07:58:56 +000038 break;
39 case ARMII::MO_LO16:
Jim Grosbach53e3fc42011-07-08 17:40:42 +000040 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
41 OutContext);
42 Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
Evan Cheng75972122011-01-13 07:58:56 +000043 break;
44 case ARMII::MO_HI16:
Jim Grosbach53e3fc42011-07-08 17:40:42 +000045 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
46 OutContext);
47 Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
Evan Cheng75972122011-01-13 07:58:56 +000048 break;
49 }
Chris Lattnerde36af42010-11-14 20:40:08 +000050 break;
Evan Cheng75972122011-01-13 07:58:56 +000051 }
52
Chris Lattnerde36af42010-11-14 20:40:08 +000053 case ARMII::MO_PLT:
Stephen Hines36b56882014-04-23 16:57:46 -070054 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT,
Jim Grosbach53e3fc42011-07-08 17:40:42 +000055 OutContext);
Chris Lattnerde36af42010-11-14 20:40:08 +000056 break;
57 }
Jim Grosbachd309b412010-11-30 23:29:24 +000058
Jim Grosbachc686e332010-09-17 18:25:25 +000059 if (!MO.isJTI() && MO.getOffset())
60 Expr = MCBinaryExpr::CreateAdd(Expr,
Jim Grosbach53e3fc42011-07-08 17:40:42 +000061 MCConstantExpr::Create(MO.getOffset(),
62 OutContext),
63 OutContext);
Jim Grosbachc686e332010-09-17 18:25:25 +000064 return MCOperand::CreateExpr(Expr);
Jim Grosbachd309b412010-11-30 23:29:24 +000065
Jim Grosbachc686e332010-09-17 18:25:25 +000066}
67
Jim Grosbach53e3fc42011-07-08 17:40:42 +000068bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
69 MCOperand &MCOp) {
70 switch (MO.getType()) {
Craig Topperbc219812012-02-07 02:50:20 +000071 default: llvm_unreachable("unknown operand type");
Jim Grosbach53e3fc42011-07-08 17:40:42 +000072 case MachineOperand::MO_Register:
73 // Ignore all non-CPSR implicit register operands.
74 if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
75 return false;
76 assert(!MO.getSubReg() && "Subregs should be eliminated!");
77 MCOp = MCOperand::CreateReg(MO.getReg());
78 break;
79 case MachineOperand::MO_Immediate:
80 MCOp = MCOperand::CreateImm(MO.getImm());
81 break;
82 case MachineOperand::MO_MachineBasicBlock:
83 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
84 MO.getMBB()->getSymbol(), OutContext));
85 break;
Stephen Hines36b56882014-04-23 16:57:46 -070086 case MachineOperand::MO_GlobalAddress: {
87 MCOp = GetSymbolRef(MO,
88 GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
Jim Grosbach53e3fc42011-07-08 17:40:42 +000089 break;
Stephen Hines36b56882014-04-23 16:57:46 -070090 }
Jim Grosbach53e3fc42011-07-08 17:40:42 +000091 case MachineOperand::MO_ExternalSymbol:
92 MCOp = GetSymbolRef(MO,
93 GetExternalSymbolSymbol(MO.getSymbolName()));
94 break;
95 case MachineOperand::MO_JumpTableIndex:
96 MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
97 break;
98 case MachineOperand::MO_ConstantPoolIndex:
99 MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
100 break;
101 case MachineOperand::MO_BlockAddress:
102 MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
103 break;
104 case MachineOperand::MO_FPImmediate: {
105 APFloat Val = MO.getFPImm()->getValueAPF();
106 bool ignored;
107 Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
108 MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
109 break;
110 }
Jakob Stoklund Olesen71f0fc12012-01-18 23:52:19 +0000111 case MachineOperand::MO_RegisterMask:
112 // Ignore call clobbers.
113 return false;
Jim Grosbach53e3fc42011-07-08 17:40:42 +0000114 }
115 return true;
116}
117
Chris Lattner30e2cc22010-11-14 21:00:02 +0000118void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
Jim Grosbachbaf120f2010-12-01 03:45:07 +0000119 ARMAsmPrinter &AP) {
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000120 OutMI.setOpcode(MI->getOpcode());
Jim Grosbachfc16a892010-09-13 18:25:42 +0000121
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000122 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
123 const MachineOperand &MO = MI->getOperand(i);
Jim Grosbachfc16a892010-09-13 18:25:42 +0000124
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000125 MCOperand MCOp;
Jim Grosbach53e3fc42011-07-08 17:40:42 +0000126 if (AP.lowerOperand(MO, MCOp))
127 OutMI.addOperand(MCOp);
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000128 }
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000129}