blob: e8512cd2332583dfa7a739c96a9e6139de403236 [file] [log] [blame]
Ulrich Weigand41789de2013-05-23 22:26:41 +00001//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
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
Ulrich Weigand41789de2013-05-23 22:26:41 +000010#include "PPCMCExpr.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000011#include "llvm/MC/MCAsmInfo.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000012#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
Rafael Espindola2be12812014-06-25 15:29:54 +000014#include "llvm/MC/MCObjectStreamer.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000015
16using namespace llvm;
17
Chandler Carruth84e68b22014-04-22 02:41:26 +000018#define DEBUG_TYPE "ppcmcexpr"
19
Ulrich Weigand41789de2013-05-23 22:26:41 +000020const PPCMCExpr*
21PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
Ulrich Weigand266db7f2013-07-08 20:20:51 +000022 bool isDarwin, MCContext &Ctx) {
23 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
Ulrich Weigand41789de2013-05-23 22:26:41 +000024}
25
26void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
Ulrich Weigand96e65782013-06-20 16:23:52 +000027 if (isDarwinSyntax()) {
28 switch (Kind) {
29 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000030 case VK_PPC_LO: OS << "lo16"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000031 case VK_PPC_HI: OS << "hi16"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000032 case VK_PPC_HA: OS << "ha16"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000033 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000034
Ulrich Weigand96e65782013-06-20 16:23:52 +000035 OS << '(';
36 getSubExpr()->print(OS);
37 OS << ')';
38 } else {
39 getSubExpr()->print(OS);
40
41 switch (Kind) {
42 default: llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000043 case VK_PPC_LO: OS << "@l"; break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000044 case VK_PPC_HI: OS << "@h"; break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000045 case VK_PPC_HA: OS << "@ha"; break;
Ulrich Weigande9126f52013-06-21 14:43:42 +000046 case VK_PPC_HIGHER: OS << "@higher"; break;
47 case VK_PPC_HIGHERA: OS << "@highera"; break;
48 case VK_PPC_HIGHEST: OS << "@highest"; break;
49 case VK_PPC_HIGHESTA: OS << "@highesta"; break;
Ulrich Weigand96e65782013-06-20 16:23:52 +000050 }
51 }
Ulrich Weigand41789de2013-05-23 22:26:41 +000052}
53
54bool
55PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
Joerg Sonnenberger752b91b2014-08-10 11:35:12 +000056 const MCAsmLayout *Layout,
57 const MCFixup *Fixup) const {
Ulrich Weigand41789de2013-05-23 22:26:41 +000058 MCValue Value;
59
Joerg Sonnenberger752b91b2014-08-10 11:35:12 +000060 if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup))
Ulrich Weigand41789de2013-05-23 22:26:41 +000061 return false;
62
63 if (Value.isAbsolute()) {
64 int64_t Result = Value.getConstant();
65 switch (Kind) {
66 default:
67 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000068 case VK_PPC_LO:
Ulrich Weigand41789de2013-05-23 22:26:41 +000069 Result = Result & 0xffff;
70 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +000071 case VK_PPC_HI:
72 Result = (Result >> 16) & 0xffff;
73 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000074 case VK_PPC_HA:
Ulrich Weigande9126f52013-06-21 14:43:42 +000075 Result = ((Result + 0x8000) >> 16) & 0xffff;
76 break;
77 case VK_PPC_HIGHER:
78 Result = (Result >> 32) & 0xffff;
79 break;
80 case VK_PPC_HIGHERA:
81 Result = ((Result + 0x8000) >> 32) & 0xffff;
82 break;
83 case VK_PPC_HIGHEST:
84 Result = (Result >> 48) & 0xffff;
85 break;
86 case VK_PPC_HIGHESTA:
87 Result = ((Result + 0x8000) >> 48) & 0xffff;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +000088 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +000089 }
90 Res = MCValue::get(Result);
Alexey Samsonova3a037d2013-08-28 08:30:47 +000091 } else {
Rafael Espindola3d5d4642014-03-12 16:55:59 +000092 if (!Layout)
93 return false;
94
Ulrich Weigand41789de2013-05-23 22:26:41 +000095 MCContext &Context = Layout->getAssembler().getContext();
96 const MCSymbolRefExpr *Sym = Value.getSymA();
97 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
98 if (Modifier != MCSymbolRefExpr::VK_None)
99 return false;
100 switch (Kind) {
101 default:
102 llvm_unreachable("Invalid kind!");
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000103 case VK_PPC_LO:
104 Modifier = MCSymbolRefExpr::VK_PPC_LO;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000105 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +0000106 case VK_PPC_HI:
107 Modifier = MCSymbolRefExpr::VK_PPC_HI;
108 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +0000109 case VK_PPC_HA:
110 Modifier = MCSymbolRefExpr::VK_PPC_HA;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000111 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +0000112 case VK_PPC_HIGHERA:
113 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
114 break;
115 case VK_PPC_HIGHER:
116 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
117 break;
118 case VK_PPC_HIGHEST:
119 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
120 break;
121 case VK_PPC_HIGHESTA:
122 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
123 break;
Ulrich Weigand41789de2013-05-23 22:26:41 +0000124 }
125 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
126 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
Alexey Samsonova3a037d2013-08-28 08:30:47 +0000127 }
Ulrich Weigand41789de2013-05-23 22:26:41 +0000128
129 return true;
130}
131
Rafael Espindolae2c66242014-06-25 15:45:33 +0000132void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Rafael Espindola2be12812014-06-25 15:29:54 +0000133 Streamer.visitUsedExpr(*getSubExpr());
Ulrich Weigand41789de2013-05-23 22:26:41 +0000134}