1262261Sdim//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
2262261Sdim//
3262261Sdim//                     The LLVM Compiler Infrastructure
4262261Sdim//
5262261Sdim// This file is distributed under the University of Illinois Open Source
6262261Sdim// License. See LICENSE.TXT for details.
7262261Sdim//
8262261Sdim//===----------------------------------------------------------------------===//
9262261Sdim//
10262261Sdim// This file contains code to lower Sparc MachineInstrs to their corresponding
11262261Sdim// MCInst records.
12262261Sdim//
13262261Sdim//===----------------------------------------------------------------------===//
14262261Sdim
15262261Sdim#include "Sparc.h"
16262261Sdim#include "MCTargetDesc/SparcMCExpr.h"
17262261Sdim#include "llvm/CodeGen/AsmPrinter.h"
18262261Sdim#include "llvm/CodeGen/MachineFunction.h"
19262261Sdim#include "llvm/CodeGen/MachineInstr.h"
20262261Sdim#include "llvm/CodeGen/MachineOperand.h"
21262261Sdim#include "llvm/MC/MCContext.h"
22262261Sdim#include "llvm/MC/MCAsmInfo.h"
23262261Sdim#include "llvm/MC/MCExpr.h"
24262261Sdim#include "llvm/MC/MCInst.h"
25262261Sdim#include "llvm/Target/Mangler.h"
26262261Sdim#include "llvm/ADT/SmallString.h"
27262261Sdim
28262261Sdimusing namespace llvm;
29262261Sdim
30262261Sdim
31262261Sdimstatic MCOperand LowerSymbolOperand(const MachineInstr *MI,
32262261Sdim                                    const MachineOperand &MO,
33262261Sdim                                    AsmPrinter &AP) {
34262261Sdim
35262261Sdim  SparcMCExpr::VariantKind Kind =
36262261Sdim    (SparcMCExpr::VariantKind)MO.getTargetFlags();
37262261Sdim  const MCSymbol *Symbol = 0;
38262261Sdim
39262261Sdim  switch(MO.getType()) {
40262261Sdim  default: llvm_unreachable("Unknown type in LowerSymbolOperand");
41262261Sdim  case MachineOperand::MO_MachineBasicBlock:
42262261Sdim    Symbol = MO.getMBB()->getSymbol();
43262261Sdim    break;
44262261Sdim
45262261Sdim  case MachineOperand::MO_GlobalAddress:
46262261Sdim    Symbol = AP.getSymbol(MO.getGlobal());
47262261Sdim    break;
48262261Sdim
49262261Sdim  case MachineOperand::MO_BlockAddress:
50262261Sdim    Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
51262261Sdim    break;
52262261Sdim
53262261Sdim  case MachineOperand::MO_ExternalSymbol:
54262261Sdim    Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
55262261Sdim    break;
56262261Sdim
57262261Sdim  case MachineOperand::MO_ConstantPoolIndex:
58262261Sdim    Symbol = AP.GetCPISymbol(MO.getIndex());
59262261Sdim    break;
60262261Sdim  }
61262261Sdim
62262261Sdim  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
63262261Sdim                                                         AP.OutContext);
64262261Sdim  const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
65262261Sdim                                                AP.OutContext);
66262261Sdim  return MCOperand::CreateExpr(expr);
67262261Sdim}
68262261Sdim
69262261Sdimstatic MCOperand LowerOperand(const MachineInstr *MI,
70262261Sdim                              const MachineOperand &MO,
71262261Sdim                              AsmPrinter &AP) {
72262261Sdim  switch(MO.getType()) {
73262261Sdim  default: llvm_unreachable("unknown operand type"); break;
74262261Sdim  case MachineOperand::MO_Register:
75262261Sdim    if (MO.isImplicit())
76262261Sdim      break;
77262261Sdim    return MCOperand::CreateReg(MO.getReg());
78262261Sdim
79262261Sdim  case MachineOperand::MO_Immediate:
80262261Sdim    return MCOperand::CreateImm(MO.getImm());
81262261Sdim
82262261Sdim  case MachineOperand::MO_MachineBasicBlock:
83262261Sdim  case MachineOperand::MO_GlobalAddress:
84262261Sdim  case MachineOperand::MO_BlockAddress:
85262261Sdim  case MachineOperand::MO_ExternalSymbol:
86262261Sdim  case MachineOperand::MO_ConstantPoolIndex:
87262261Sdim    return LowerSymbolOperand(MI, MO, AP);
88262261Sdim
89262261Sdim  case MachineOperand::MO_RegisterMask:   break;
90262261Sdim
91262261Sdim  }
92262261Sdim  return MCOperand();
93262261Sdim}
94262261Sdim
95262261Sdimvoid llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
96262261Sdim                                          MCInst &OutMI,
97262261Sdim                                          AsmPrinter &AP)
98262261Sdim{
99262261Sdim
100262261Sdim  OutMI.setOpcode(MI->getOpcode());
101262261Sdim
102262261Sdim  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
103262261Sdim    const MachineOperand &MO = MI->getOperand(i);
104262261Sdim    MCOperand MCOp = LowerOperand(MI, MO, AP);
105262261Sdim
106262261Sdim    if (MCOp.isValid())
107262261Sdim      OutMI.addOperand(MCOp);
108262261Sdim  }
109262261Sdim}
110