mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
[PowerPC] Clean up generation of ha16() / lo16() markers
When targeting the Darwin assembler, we need to generate markers ha16() and lo16() to designate the high and low parts of a (symbolic) immediate. This is necessary not just for plain symbols, but also for certain symbolic expression, typically along the lines of ha16(A - B). The latter doesn't work when simply using VariantKind flags on the symbol reference. This is why the current back-end uses hacks (explicitly called out as such via multiple FIXMEs) in the symbolLo/symbolHi print methods. This patch uses target-defined MCExpr codes to represent the Darwin ha16/lo16 constructs, following along the lines of the equivalent solution used by the ARM back end to handle their :upper16: / :lower16: markers. This allows us to get rid of special handling both in the symbolLo/symbolHi print method and in the common code MCExpr::print routine. Instead, the ha16 / lo16 markers are printed simply in a custom print routine for the target MCExpr types. (As a result, the symbolLo/symbolHi print methods can now replaced by a single printS16ImmOperand routine that also handles symbolic operands.) The patch also provides a EvaluateAsRelocatableImpl routine to handle ha16/lo16 constructs. This is not actually used at the moment by any in-tree code, but is provided as it makes merging into David Fang's out-of-tree Mach-O object writer simpler. Since there is no longer any need to treat VK_PPC_GAS_HA16 and VK_PPC_DARWIN_HA16 differently, they are merged into a single VK_PPC_ADDR16_HA (and likewise for the _LO16 types). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182616 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PPC.h"
|
||||
#include "MCTargetDesc/PPCMCExpr.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
@ -110,32 +111,32 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
|
||||
unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
|
||||
|
||||
switch (access) {
|
||||
case PPCII::MO_HA16: RefKind = isDarwin ?
|
||||
MCSymbolRefExpr::VK_PPC_DARWIN_HA16 :
|
||||
MCSymbolRefExpr::VK_PPC_GAS_HA16;
|
||||
break;
|
||||
case PPCII::MO_LO16: RefKind = isDarwin ?
|
||||
MCSymbolRefExpr::VK_PPC_DARWIN_LO16 :
|
||||
MCSymbolRefExpr::VK_PPC_GAS_LO16;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_HA: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
|
||||
break;
|
||||
case PPCII::MO_DTPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
|
||||
break;
|
||||
case PPCII::MO_TLSLD16_LO: RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
|
||||
break;
|
||||
case PPCII::MO_TOC16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
|
||||
break;
|
||||
}
|
||||
if (!isDarwin) {
|
||||
switch (access) {
|
||||
case PPCII::MO_HA16:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_HA;
|
||||
break;
|
||||
case PPCII::MO_LO16:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_LO;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_HA:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_LO:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
|
||||
break;
|
||||
case PPCII::MO_DTPREL16_LO:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
|
||||
break;
|
||||
case PPCII::MO_TLSLD16_LO:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
|
||||
break;
|
||||
case PPCII::MO_TOC16_LO:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This isn't right, but we don't have a good way to express this in
|
||||
// the MC Level, see below.
|
||||
if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG)
|
||||
RefKind = MCSymbolRefExpr::VK_None;
|
||||
|
||||
const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
|
||||
|
||||
if (!MO.isJTI() && MO.getOffset())
|
||||
@ -149,10 +150,20 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
|
||||
const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);
|
||||
Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
|
||||
// FIXME: We have no way to make the result be VK_PPC_LO16/VK_PPC_HA16,
|
||||
// since it is not a symbol!
|
||||
}
|
||||
|
||||
|
||||
// Add Darwin ha16() / lo16() markers if required.
|
||||
if (isDarwin) {
|
||||
switch (access) {
|
||||
case PPCII::MO_HA16:
|
||||
Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
|
||||
break;
|
||||
case PPCII::MO_LO16:
|
||||
Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MCOperand::CreateExpr(Expr);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user