blob: d9c5bcd4f4888f846642a9b6161098d428f32766 [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
15#include "ARMMCInstLower.h"
Chris Lattner112f2392010-11-14 20:31:06 +000016#include "ARM.h"
Chris Lattner96bc2172009-10-20 00:52:47 +000017#include "llvm/CodeGen/AsmPrinter.h"
Jim Grosbach26edbcb2010-09-15 18:47:08 +000018#include "llvm/Constants.h"
Chris Lattner96bc2172009-10-20 00:52:47 +000019#include "llvm/CodeGen/MachineBasicBlock.h"
Chris Lattner6f997762009-10-19 21:53:00 +000020#include "llvm/MC/MCAsmInfo.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000023#include "llvm/MC/MCInst.h"
Chris Lattnerd62f1b42010-03-12 21:19:23 +000024#include "llvm/Target/Mangler.h"
Chris Lattner6f997762009-10-19 21:53:00 +000025#include "llvm/Support/raw_ostream.h"
Chris Lattner6f997762009-10-19 21:53:00 +000026#include "llvm/ADT/SmallString.h"
Chris Lattner9cf0eb52009-10-19 20:21:05 +000027using namespace llvm;
28
Jim Grosbachc686e332010-09-17 18:25:25 +000029MCSymbol *ARMMCInstLower::GetGlobalAddressSymbol(const GlobalValue *GV) const {
30 return Printer.Mang->getSymbol(GV);
31}
32
Jim Grosbachc686e332010-09-17 18:25:25 +000033MCOperand ARMMCInstLower::
Chris Lattnerde36af42010-11-14 20:40:08 +000034GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol) const {
35 const MCExpr *Expr;
36 switch (MO.getTargetFlags()) {
37 default: assert(0 && "Unknown target flag on symbol operand");
38 case 0:
39 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
40 break;
41 case ARMII::MO_LO16:
42 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
43 break;
44 case ARMII::MO_HI16:
45 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx);
46 break;
47 case ARMII::MO_PLT:
48 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
49 break;
50 }
51
Jim Grosbachc686e332010-09-17 18:25:25 +000052 if (!MO.isJTI() && MO.getOffset())
53 Expr = MCBinaryExpr::CreateAdd(Expr,
54 MCConstantExpr::Create(MO.getOffset(), Ctx),
55 Ctx);
56 return MCOperand::CreateExpr(Expr);
Chris Lattnerde36af42010-11-14 20:40:08 +000057
Jim Grosbachc686e332010-09-17 18:25:25 +000058}
59
Chris Lattner9cf0eb52009-10-19 20:21:05 +000060void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
61 OutMI.setOpcode(MI->getOpcode());
Jim Grosbachfc16a892010-09-13 18:25:42 +000062
Chris Lattner9cf0eb52009-10-19 20:21:05 +000063 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
64 const MachineOperand &MO = MI->getOperand(i);
Jim Grosbachfc16a892010-09-13 18:25:42 +000065
Chris Lattner9cf0eb52009-10-19 20:21:05 +000066 MCOperand MCOp;
67 switch (MO.getType()) {
68 default:
69 MI->dump();
70 assert(0 && "unknown operand type");
71 case MachineOperand::MO_Register:
Jim Grosbach1685caf2010-09-14 20:41:27 +000072 // Ignore all non-CPSR implicit register operands.
73 if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
Anton Korobeynikove8ea0112009-11-07 15:20:32 +000074 assert(!MO.getSubReg() && "Subregs should be eliminated!");
Chris Lattner9cf0eb52009-10-19 20:21:05 +000075 MCOp = MCOperand::CreateReg(MO.getReg());
76 break;
77 case MachineOperand::MO_Immediate:
78 MCOp = MCOperand::CreateImm(MO.getImm());
79 break;
Chris Lattner9cf0eb52009-10-19 20:21:05 +000080 case MachineOperand::MO_MachineBasicBlock:
81 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
Chris Lattner1b2eb0e2010-03-13 21:04:28 +000082 MO.getMBB()->getSymbol(), Ctx));
Chris Lattner9cf0eb52009-10-19 20:21:05 +000083 break;
84 case MachineOperand::MO_GlobalAddress:
Chris Lattnerde36af42010-11-14 20:40:08 +000085 MCOp = GetSymbolRef(MO, GetGlobalAddressSymbol(MO.getGlobal()));
Chris Lattner9cf0eb52009-10-19 20:21:05 +000086 break;
87 case MachineOperand::MO_ExternalSymbol:
Chris Lattnerde36af42010-11-14 20:40:08 +000088 MCOp = GetSymbolRef(MO,
89 Printer.GetExternalSymbolSymbol(MO.getSymbolName()));
Chris Lattner9cf0eb52009-10-19 20:21:05 +000090 break;
91 case MachineOperand::MO_JumpTableIndex:
Chris Lattnerde36af42010-11-14 20:40:08 +000092 MCOp = GetSymbolRef(MO, Printer.GetJTISymbol(MO.getIndex()));
Chris Lattner9cf0eb52009-10-19 20:21:05 +000093 break;
94 case MachineOperand::MO_ConstantPoolIndex:
Chris Lattnerde36af42010-11-14 20:40:08 +000095 MCOp = GetSymbolRef(MO, Printer.GetCPISymbol(MO.getIndex()));
Chris Lattner9cf0eb52009-10-19 20:21:05 +000096 break;
Bob Wilsonddb16df2009-10-30 05:45:42 +000097 case MachineOperand::MO_BlockAddress:
Chris Lattnerde36af42010-11-14 20:40:08 +000098 MCOp = GetSymbolRef(MO,
99 Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
Bob Wilsonddb16df2009-10-30 05:45:42 +0000100 break;
Jim Grosbach26edbcb2010-09-15 18:47:08 +0000101 case MachineOperand::MO_FPImmediate:
Jim Grosbach1d51c412010-09-16 17:37:30 +0000102 APFloat Val = MO.getFPImm()->getValueAPF();
103 bool ignored;
104 Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
105 MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
Jim Grosbach26edbcb2010-09-15 18:47:08 +0000106 break;
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000107 }
Jim Grosbachfc16a892010-09-13 18:25:42 +0000108
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000109 OutMI.addOperand(MCOp);
110 }
Jim Grosbachfc16a892010-09-13 18:25:42 +0000111
Chris Lattner9cf0eb52009-10-19 20:21:05 +0000112}