|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 |
| -#include "PPCMCAsmInfo.h" |
14 |
| -#include "PPCMCExpr.h" |
| 13 | +#include "MCTargetDesc/PPCMCAsmInfo.h" |
15 | 14 | #include "llvm/MC/MCExpr.h"
|
16 | 15 | #include "llvm/Support/raw_ostream.h"
|
17 | 16 | #include "llvm/TargetParser/Triple.h"
|
@@ -99,6 +98,66 @@ const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
|
99 | 98 | {PPC::S_U, "u"},
|
100 | 99 | };
|
101 | 100 |
|
| 101 | +static std::optional<int64_t> evaluateAsInt64(uint16_t specifier, |
| 102 | + int64_t Value) { |
| 103 | + switch (specifier) { |
| 104 | + case PPC::S_LO: |
| 105 | + return Value & 0xffff; |
| 106 | + case PPC::S_HI: |
| 107 | + return (Value >> 16) & 0xffff; |
| 108 | + case PPC::S_HA: |
| 109 | + return ((Value + 0x8000) >> 16) & 0xffff; |
| 110 | + case PPC::S_HIGH: |
| 111 | + return (Value >> 16) & 0xffff; |
| 112 | + case PPC::S_HIGHA: |
| 113 | + return ((Value + 0x8000) >> 16) & 0xffff; |
| 114 | + case PPC::S_HIGHER: |
| 115 | + return (Value >> 32) & 0xffff; |
| 116 | + case PPC::S_HIGHERA: |
| 117 | + return ((Value + 0x8000) >> 32) & 0xffff; |
| 118 | + case PPC::S_HIGHEST: |
| 119 | + return (Value >> 48) & 0xffff; |
| 120 | + case PPC::S_HIGHESTA: |
| 121 | + return ((Value + 0x8000) >> 48) & 0xffff; |
| 122 | + default: |
| 123 | + return {}; |
| 124 | + } |
| 125 | +} |
| 126 | + |
| 127 | +bool PPC::evaluateAsConstant(const MCSpecifierExpr &Expr, int64_t &Res) { |
| 128 | + MCValue Value; |
| 129 | + |
| 130 | + if (!Expr.getSubExpr()->evaluateAsRelocatable(Value, nullptr)) |
| 131 | + return false; |
| 132 | + |
| 133 | + if (!Value.isAbsolute()) |
| 134 | + return false; |
| 135 | + auto Tmp = evaluateAsInt64(Expr.getSpecifier(), Value.getConstant()); |
| 136 | + if (!Tmp) |
| 137 | + return false; |
| 138 | + Res = *Tmp; |
| 139 | + return true; |
| 140 | +} |
| 141 | + |
| 142 | +static bool evaluateAsRelocatable(const MCSpecifierExpr &Expr, MCValue &Res, |
| 143 | + const MCAssembler *Asm) { |
| 144 | + if (!Expr.getSubExpr()->evaluateAsRelocatable(Res, Asm)) |
| 145 | + return false; |
| 146 | + |
| 147 | + // The signedness of the result is dependent on the instruction operand. E.g. |
| 148 | + // in addis 3,3,65535@l, 65535@l is signed. In the absence of information at |
| 149 | + // parse time (!Asm), disable the folding. |
| 150 | + std::optional<int64_t> MaybeInt = |
| 151 | + evaluateAsInt64(Expr.getSpecifier(), Res.getConstant()); |
| 152 | + if (Res.isAbsolute() && MaybeInt) { |
| 153 | + Res = MCValue::get(*MaybeInt); |
| 154 | + } else { |
| 155 | + Res.setSpecifier(Expr.getSpecifier()); |
| 156 | + } |
| 157 | + |
| 158 | + return true; |
| 159 | +} |
| 160 | + |
102 | 161 | PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
|
103 | 162 | // FIXME: This is not always needed. For example, it is not needed in the
|
104 | 163 | // v2 abi.
|
@@ -146,7 +205,7 @@ void PPCELFMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
|
146 | 205 | bool PPCELFMCAsmInfo::evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr,
|
147 | 206 | MCValue &Res,
|
148 | 207 | const MCAssembler *Asm) const {
|
149 |
| - return PPC::evaluateAsRelocatableImpl(Expr, Res, Asm); |
| 208 | + return evaluateAsRelocatable(Expr, Res, Asm); |
150 | 209 | }
|
151 | 210 |
|
152 | 211 | void PPCXCOFFMCAsmInfo::anchor() {}
|
@@ -181,5 +240,5 @@ void PPCXCOFFMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
|
181 | 240 |
|
182 | 241 | bool PPCXCOFFMCAsmInfo::evaluateAsRelocatableImpl(
|
183 | 242 | const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm) const {
|
184 |
| - return PPC::evaluateAsRelocatableImpl(Expr, Res, Asm); |
| 243 | + return evaluateAsRelocatable(Expr, Res, Asm); |
185 | 244 | }
|
0 commit comments