blob: b6dfadce14e9d611891dddeadbfd01975d39dc78 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ---------===//
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +00002//
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 Mips MachineInstrs to their corresponding
11// MCInst records.
12//
13//===----------------------------------------------------------------------===//
Craig Topperb25fda92012-03-17 18:46:09 +000014#include "MipsMCInstLower.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "MCTargetDesc/MipsBaseInfo.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000016#include "MipsAsmPrinter.h"
17#include "MipsInstrInfo.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000018#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/MachineOperand.h"
21#include "llvm/MC/MCContext.h"
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +000022#include "llvm/MC/MCExpr.h"
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000023#include "llvm/MC/MCInst.h"
24#include "llvm/Target/Mangler.h"
Akira Hatanaka049e9e42011-11-23 22:19:28 +000025
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000026using namespace llvm;
27
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000028MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)
29 : AsmPrinter(asmprinter) {}
30
Rafael Espindola7d78b2a2013-10-29 16:24:21 +000031void MipsMCInstLower::Initialize(MCContext *C) {
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +000032 Ctx = C;
33}
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000034
35MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
Akira Hatanaka6520b982011-08-16 02:15:03 +000036 MachineOperandType MOTy,
37 unsigned Offset) const {
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +000038 MCSymbolRefExpr::VariantKind Kind;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000039 const MCSymbol *Symbol;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000040
41 switch(MO.getTargetFlags()) {
Craig Toppere55c5562012-02-07 02:50:20 +000042 default: llvm_unreachable("Invalid target flag!");
Akira Hatanaka9e1d3692011-12-19 19:52:25 +000043 case MipsII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break;
44 case MipsII::MO_GPREL: Kind = MCSymbolRefExpr::VK_Mips_GPREL; break;
45 case MipsII::MO_GOT_CALL: Kind = MCSymbolRefExpr::VK_Mips_GOT_CALL; break;
46 case MipsII::MO_GOT16: Kind = MCSymbolRefExpr::VK_Mips_GOT16; break;
47 case MipsII::MO_GOT: Kind = MCSymbolRefExpr::VK_Mips_GOT; break;
48 case MipsII::MO_ABS_HI: Kind = MCSymbolRefExpr::VK_Mips_ABS_HI; break;
49 case MipsII::MO_ABS_LO: Kind = MCSymbolRefExpr::VK_Mips_ABS_LO; break;
50 case MipsII::MO_TLSGD: Kind = MCSymbolRefExpr::VK_Mips_TLSGD; break;
51 case MipsII::MO_TLSLDM: Kind = MCSymbolRefExpr::VK_Mips_TLSLDM; break;
52 case MipsII::MO_DTPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_HI; break;
53 case MipsII::MO_DTPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_LO; break;
54 case MipsII::MO_GOTTPREL: Kind = MCSymbolRefExpr::VK_Mips_GOTTPREL; break;
55 case MipsII::MO_TPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_TPREL_HI; break;
56 case MipsII::MO_TPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_TPREL_LO; break;
57 case MipsII::MO_GPOFF_HI: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_HI; break;
58 case MipsII::MO_GPOFF_LO: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_LO; break;
59 case MipsII::MO_GOT_DISP: Kind = MCSymbolRefExpr::VK_Mips_GOT_DISP; break;
60 case MipsII::MO_GOT_PAGE: Kind = MCSymbolRefExpr::VK_Mips_GOT_PAGE; break;
61 case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break;
Akira Hatanaka6035fe72012-07-21 03:09:04 +000062 case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break;
63 case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break;
Akira Hatanakabb6e74a2012-11-21 20:40:38 +000064 case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break;
65 case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break;
66 case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break;
67 case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000068 }
69
70 switch (MOTy) {
Akira Hatanaka049e9e42011-11-23 22:19:28 +000071 case MachineOperand::MO_MachineBasicBlock:
72 Symbol = MO.getMBB()->getSymbol();
73 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000074
Akira Hatanaka049e9e42011-11-23 22:19:28 +000075 case MachineOperand::MO_GlobalAddress:
Rafael Espindola79858aa2013-10-29 17:07:16 +000076 Symbol = AsmPrinter.getSymbol(MO.getGlobal());
Akira Hatanaka56bf0232012-06-02 00:02:11 +000077 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +000078 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000079
Akira Hatanaka049e9e42011-11-23 22:19:28 +000080 case MachineOperand::MO_BlockAddress:
81 Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
Akira Hatanaka56bf0232012-06-02 00:02:11 +000082 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +000083 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000084
Akira Hatanaka049e9e42011-11-23 22:19:28 +000085 case MachineOperand::MO_ExternalSymbol:
86 Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
Akira Hatanaka56bf0232012-06-02 00:02:11 +000087 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +000088 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000089
Akira Hatanaka049e9e42011-11-23 22:19:28 +000090 case MachineOperand::MO_JumpTableIndex:
91 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
92 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000093
Akira Hatanaka049e9e42011-11-23 22:19:28 +000094 case MachineOperand::MO_ConstantPoolIndex:
95 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
Akira Hatanaka56bf0232012-06-02 00:02:11 +000096 Offset += MO.getOffset();
Akira Hatanaka049e9e42011-11-23 22:19:28 +000097 break;
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +000098
Akira Hatanaka049e9e42011-11-23 22:19:28 +000099 default:
100 llvm_unreachable("<unknown operand type>");
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000101 }
Jia Liuf54f60f2012-02-28 07:46:26 +0000102
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +0000103 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
Bruno Cardoso Lopesd5edb382011-11-08 22:26:47 +0000104
105 if (!Offset)
106 return MCOperand::CreateExpr(MCSym);
107
108 // Assume offset is never negative.
109 assert(Offset > 0);
Jia Liuf54f60f2012-02-28 07:46:26 +0000110
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +0000111 const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx);
Akira Hatanaka5fd22482012-06-14 21:10:56 +0000112 const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
113 return MCOperand::CreateExpr(Add);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000114}
115
Akira Hatanakaa1b142f2012-06-14 01:20:12 +0000116/*
Akira Hatanaka5fd22482012-06-14 21:10:56 +0000117static void CreateMCInst(MCInst& Inst, unsigned Opc, const MCOperand &Opnd0,
118 const MCOperand &Opnd1,
119 const MCOperand &Opnd2 = MCOperand()) {
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +0000120 Inst.setOpcode(Opc);
121 Inst.addOperand(Opnd0);
122 Inst.addOperand(Opnd1);
123 if (Opnd2.isValid())
124 Inst.addOperand(Opnd2);
125}
Akira Hatanakaa1b142f2012-06-14 01:20:12 +0000126*/
Akira Hatanaka34ee3ff2012-03-28 00:22:50 +0000127
Akira Hatanaka5fd22482012-06-14 21:10:56 +0000128MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
Jia Liuf54f60f2012-02-28 07:46:26 +0000129 unsigned offset) const {
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000130 MachineOperandType MOTy = MO.getType();
Jia Liuf54f60f2012-02-28 07:46:26 +0000131
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000132 switch (MOTy) {
Craig Toppere55c5562012-02-07 02:50:20 +0000133 default: llvm_unreachable("unknown operand type");
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000134 case MachineOperand::MO_Register:
135 // Ignore all implicit register operands.
136 if (MO.isImplicit()) break;
137 return MCOperand::CreateReg(MO.getReg());
138 case MachineOperand::MO_Immediate:
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000139 return MCOperand::CreateImm(MO.getImm() + offset);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000140 case MachineOperand::MO_MachineBasicBlock:
141 case MachineOperand::MO_GlobalAddress:
142 case MachineOperand::MO_ExternalSymbol:
143 case MachineOperand::MO_JumpTableIndex:
144 case MachineOperand::MO_ConstantPoolIndex:
145 case MachineOperand::MO_BlockAddress:
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000146 return LowerSymbolOperand(MO, MOTy, offset);
Jakob Stoklund Olesenf1fb1d22012-01-18 23:52:19 +0000147 case MachineOperand::MO_RegisterMask:
148 break;
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000149 }
150
151 return MCOperand();
152}
153
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000154void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
155 OutMI.setOpcode(MI->getOpcode());
Jia Liuf54f60f2012-02-28 07:46:26 +0000156
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000157 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
158 const MachineOperand &MO = MI->getOperand(i);
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000159 MCOperand MCOp = LowerOperand(MO);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000160
Akira Hatanaka77f1fd52011-08-16 02:21:03 +0000161 if (MCOp.isValid())
162 OutMI.addOperand(MCOp);
Akira Hatanaka77a9e6e2011-07-07 20:24:54 +0000163 }
164}
Jack Carterf6490432012-07-16 15:14:51 +0000165