Skip to content

Commit edb9d84

Browse files
committed
add targetoperand flags for jump tables, constant pool and block address
nodes to indicate when ha16/lo16 modifiers should be used. This lets us pass PowerPC/indirectbr.ll. The one annoying thing about this patch is that the MCSymbolExpr isn't expressive enough to represent ha16(label1-label2) which we need on PowerPC. I have a terrible hack in the meantime, but this will have to be revisited at some point. Last major conversion item left is global variable references. llvm-svn: 119105
1 parent e75bb34 commit edb9d84

File tree

9 files changed

+141
-118
lines changed

9 files changed

+141
-118
lines changed

llvm/include/llvm/MC/MCExpr.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ class MCSymbolRefExpr : public MCExpr {
152152
VK_ARM_TPOFF,
153153
VK_ARM_GOTTPOFF,
154154

155-
VK_PPC_TOC
155+
VK_PPC_TOC,
156+
VK_PPC_HA16, // ha16(symbol)
157+
VK_PPC_LO16 // lo16(symbol)
156158
};
157159

158160
private:

llvm/lib/MC/MCExpr.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,21 @@ void MCExpr::print(raw_ostream &OS) const {
3939
case MCExpr::SymbolRef: {
4040
const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this);
4141
const MCSymbol &Sym = SRE.getSymbol();
42+
// Parenthesize names that start with $ so that they don't look like
43+
// absolute names.
44+
bool UseParens = Sym.getName()[0] == '$';
4245

4346
if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_HI16 ||
4447
SRE.getKind() == MCSymbolRefExpr::VK_ARM_LO16)
4548
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
4649

47-
// Parenthesize names that start with $ so that they don't look like
48-
// absolute names.
49-
if (Sym.getName()[0] == '$')
50+
if (SRE.getKind() == MCSymbolRefExpr::VK_PPC_HA16 ||
51+
SRE.getKind() == MCSymbolRefExpr::VK_PPC_LO16) {
52+
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
53+
UseParens = true;
54+
}
55+
56+
if (UseParens)
5057
OS << '(' << Sym << ')';
5158
else
5259
OS << Sym;
@@ -60,7 +67,9 @@ void MCExpr::print(raw_ostream &OS) const {
6067
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
6168
else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
6269
SRE.getKind() != MCSymbolRefExpr::VK_ARM_HI16 &&
63-
SRE.getKind() != MCSymbolRefExpr::VK_ARM_LO16)
70+
SRE.getKind() != MCSymbolRefExpr::VK_ARM_LO16 &&
71+
SRE.getKind() != MCSymbolRefExpr::VK_PPC_HA16 &&
72+
SRE.getKind() != MCSymbolRefExpr::VK_PPC_LO16)
6473
OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
6574

6675
return;
@@ -197,6 +206,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
197206
case VK_ARM_GOTTPOFF: return "(gottpoff)";
198207
case VK_ARM_TLSGD: return "(tldgd)";
199208
case VK_PPC_TOC: return "toc";
209+
case VK_PPC_HA16: return "ha16";
210+
case VK_PPC_LO16: return "lo16";
200211
}
201212
}
202213

llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp

+22-4
Original file line numberDiff line numberDiff line change
@@ -270,17 +270,35 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
270270
void PPCInstPrinter::printSymbolLo(const MCInst *MI, unsigned OpNo,
271271
raw_ostream &O) {
272272
if (MI->getOperand(OpNo).isImm())
273-
printS16ImmOperand(MI, OpNo, O);
274-
else
273+
return printS16ImmOperand(MI, OpNo, O);
274+
275+
// FIXME: This is a terrible hack because we can't encode lo16() as an operand
276+
// flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower.
277+
if (MI->getOperand(OpNo).isExpr() &&
278+
isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) {
279+
O << "lo16(";
275280
printOperand(MI, OpNo, O);
281+
O << ')';
282+
} else {
283+
printOperand(MI, OpNo, O);
284+
}
276285
}
277286

278287
void PPCInstPrinter::printSymbolHi(const MCInst *MI, unsigned OpNo,
279288
raw_ostream &O) {
280289
if (MI->getOperand(OpNo).isImm())
281-
printS16ImmOperand(MI, OpNo, O);
282-
else
290+
return printS16ImmOperand(MI, OpNo, O);
291+
292+
// FIXME: This is a terrible hack because we can't encode lo16() as an operand
293+
// flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower.
294+
if (MI->getOperand(OpNo).isExpr() &&
295+
isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) {
296+
O << "ha16(";
283297
printOperand(MI, OpNo, O);
298+
O << ')';
299+
} else {
300+
printOperand(MI, OpNo, O);
301+
}
284302
}
285303

286304

llvm/lib/Target/PowerPC/PPC.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,23 @@ extern Target ThePPC64Target;
5050
/// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the
5151
/// reference is actually to the "FOO$stub" symbol. This is used for calls
5252
/// and jumps to external functions on Tiger and earlier.
53-
MO_DARWIN_STUB
53+
MO_DARWIN_STUB,
5454

55+
/// MO_LO16 - On a symbol operand, this represents a relocation containing
56+
/// lower 16 bit of the address.
57+
MO_LO16,
58+
59+
/// MO_HA16 - On a symbol operand, this represents a relocation containing
60+
/// higher 16 bit of the address.
61+
MO_HA16,
62+
63+
/// MO_LO16_PIC - On a symbol operand, this represents a relocation
64+
/// containing lower 16 bit of the address with the picbase subtracted.
65+
MO_LO16_PIC,
66+
67+
/// MO_HA16_PIC - On a symbol operand, this represents a relocation
68+
/// containing higher 16 bit of the address with the picbase subtracted.
69+
MO_HA16_PIC
5570
};
5671
} // end namespace PPCII
5772

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

+66-96
Original file line numberDiff line numberDiff line change
@@ -1098,78 +1098,63 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
10981098
// LowerOperation implementation
10991099
//===----------------------------------------------------------------------===//
11001100

1101+
/// GetLabelAccessInfo - Return true if we should reference labels using a
1102+
/// PICBase, set the HiOpFlags and LoOpFlags to the target MO flags.
1103+
static bool GetLabelAccessInfo(const TargetMachine &TM, unsigned &HiOpFlags,
1104+
unsigned &LoOpFlags) {
1105+
// Don't use the pic base if not in PIC relocation model. Or if we are on a
1106+
// non-darwin platform. We don't support PIC on other platforms yet.
1107+
bool isPIC = TM.getRelocationModel() == Reloc::PIC_ &&
1108+
TM.getSubtarget<PPCSubtarget>().isDarwin();
1109+
1110+
HiOpFlags = isPIC ? PPCII::MO_HA16_PIC : PPCII::MO_HA16;
1111+
LoOpFlags = isPIC ? PPCII::MO_LO16_PIC : PPCII::MO_LO16;
1112+
return isPIC;
1113+
}
1114+
1115+
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC,
1116+
SelectionDAG &DAG) {
1117+
EVT PtrVT = HiPart.getValueType();
1118+
SDValue Zero = DAG.getConstant(0, PtrVT);
1119+
DebugLoc DL = HiPart.getDebugLoc();
1120+
1121+
SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, HiPart, Zero);
1122+
SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, LoPart, Zero);
1123+
1124+
// With PIC, the first instruction is actually "GR+hi(&G)".
1125+
if (isPIC)
1126+
Hi = DAG.getNode(ISD::ADD, DL, PtrVT,
1127+
DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT), Hi);
1128+
1129+
// Generate non-pic code that has direct accesses to the constant pool.
1130+
// The address of the global is just (hi(&g)+lo(&g)).
1131+
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
1132+
}
1133+
11011134
SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
11021135
SelectionDAG &DAG) const {
11031136
EVT PtrVT = Op.getValueType();
11041137
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
11051138
const Constant *C = CP->getConstVal();
1106-
SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
1107-
SDValue Zero = DAG.getConstant(0, PtrVT);
1108-
// FIXME there isn't really any debug info here
1109-
DebugLoc dl = Op.getDebugLoc();
1110-
1111-
const TargetMachine &TM = DAG.getTarget();
1112-
1113-
SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, CPI, Zero);
1114-
SDValue Lo = DAG.getNode(PPCISD::Lo, dl, PtrVT, CPI, Zero);
1115-
1116-
// If this is a non-darwin platform, we don't support non-static relo models
1117-
// yet.
1118-
if (TM.getRelocationModel() == Reloc::Static ||
1119-
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
1120-
// Generate non-pic code that has direct accesses to the constant pool.
1121-
// The address of the global is just (hi(&g)+lo(&g)).
1122-
return DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1123-
}
1124-
1125-
if (TM.getRelocationModel() == Reloc::PIC_) {
1126-
// With PIC, the first instruction is actually "GR+hi(&G)".
1127-
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
1128-
DAG.getNode(PPCISD::GlobalBaseReg,
1129-
DebugLoc(), PtrVT), Hi);
1130-
}
11311139

1132-
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1133-
return Lo;
1140+
unsigned MOHiFlag, MOLoFlag;
1141+
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
1142+
SDValue CPIHi =
1143+
DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0, MOHiFlag);
1144+
SDValue CPILo =
1145+
DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0, MOLoFlag);
1146+
return LowerLabelRef(CPIHi, CPILo, isPIC, DAG);
11341147
}
11351148

11361149
SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
11371150
EVT PtrVT = Op.getValueType();
11381151
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1139-
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1140-
SDValue Zero = DAG.getConstant(0, PtrVT);
1141-
// FIXME there isn't really any debug loc here
1142-
DebugLoc dl = Op.getDebugLoc();
1143-
1144-
const TargetMachine &TM = DAG.getTarget();
1145-
1146-
SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, JTI, Zero);
1147-
SDValue Lo = DAG.getNode(PPCISD::Lo, dl, PtrVT, JTI, Zero);
1148-
1149-
// If this is a non-darwin platform, we don't support non-static relo models
1150-
// yet.
1151-
if (TM.getRelocationModel() == Reloc::Static ||
1152-
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
1153-
// Generate non-pic code that has direct accesses to the constant pool.
1154-
// The address of the global is just (hi(&g)+lo(&g)).
1155-
return DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1156-
}
1157-
1158-
if (TM.getRelocationModel() == Reloc::PIC_) {
1159-
// With PIC, the first instruction is actually "GR+hi(&G)".
1160-
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
1161-
DAG.getNode(PPCISD::GlobalBaseReg,
1162-
DebugLoc(), PtrVT), Hi);
1163-
}
1164-
1165-
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1166-
return Lo;
1167-
}
1168-
1169-
SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1170-
SelectionDAG &DAG) const {
1171-
llvm_unreachable("TLS not implemented for PPC.");
1172-
return SDValue(); // Not reached
1152+
1153+
unsigned MOHiFlag, MOLoFlag;
1154+
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
1155+
SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag);
1156+
SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOLoFlag);
1157+
return LowerLabelRef(JTIHi, JTILo, isPIC, DAG);
11731158
}
11741159

11751160
SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
@@ -1178,77 +1163,62 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
11781163
DebugLoc DL = Op.getDebugLoc();
11791164

11801165
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1181-
SDValue TgtBA = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true);
1182-
SDValue Zero = DAG.getConstant(0, PtrVT);
1183-
SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, TgtBA, Zero);
1184-
SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, TgtBA, Zero);
1185-
1186-
// If this is a non-darwin platform, we don't support non-static relo models
1187-
// yet.
1188-
const TargetMachine &TM = DAG.getTarget();
1189-
if (TM.getRelocationModel() == Reloc::Static ||
1190-
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
1191-
// Generate non-pic code that has direct accesses to globals.
1192-
// The address of the global is just (hi(&g)+lo(&g)).
1193-
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
1194-
}
1195-
1196-
if (TM.getRelocationModel() == Reloc::PIC_) {
1197-
// With PIC, the first instruction is actually "GR+hi(&G)".
1198-
Hi = DAG.getNode(ISD::ADD, DL, PtrVT,
1199-
DAG.getNode(PPCISD::GlobalBaseReg,
1200-
DebugLoc(), PtrVT), Hi);
1201-
}
1202-
1203-
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
1166+
1167+
unsigned MOHiFlag, MOLoFlag;
1168+
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
1169+
SDValue TgtBAHi = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOHiFlag);
1170+
SDValue TgtBALo = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOLoFlag);
1171+
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
12041172
}
12051173

12061174
SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
12071175
SelectionDAG &DAG) const {
12081176
EVT PtrVT = Op.getValueType();
12091177
GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
1210-
// FIXME there isn't really any debug info here
1211-
DebugLoc dl = GSDN->getDebugLoc();
1178+
DebugLoc DL = GSDN->getDebugLoc();
12121179
const GlobalValue *GV = GSDN->getGlobal();
1213-
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, GSDN->getOffset());
1214-
SDValue Zero = DAG.getConstant(0, PtrVT);
12151180

12161181
const TargetMachine &TM = DAG.getTarget();
12171182

12181183
// 64-bit SVR4 ABI code is always position-independent.
12191184
// The actual address of the GlobalValue is stored in the TOC.
12201185
if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) {
1221-
return DAG.getNode(PPCISD::TOC_ENTRY, dl, MVT::i64, GA,
1186+
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset());
1187+
return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i64, GA,
12221188
DAG.getRegister(PPC::X2, MVT::i64));
12231189
}
12241190

1225-
SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, GA, Zero);
1226-
SDValue Lo = DAG.getNode(PPCISD::Lo, dl, PtrVT, GA, Zero);
1191+
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset());
1192+
1193+
1194+
SDValue Zero = DAG.getConstant(0, PtrVT);
1195+
SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, GA, Zero);
1196+
SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, GA, Zero);
12271197

12281198
// If this is a non-darwin platform, we don't support non-static relo models
12291199
// yet.
12301200
if (TM.getRelocationModel() == Reloc::Static ||
12311201
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
12321202
// Generate non-pic code that has direct accesses to globals.
12331203
// The address of the global is just (hi(&g)+lo(&g)).
1234-
return DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1204+
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
12351205
}
12361206

12371207
if (TM.getRelocationModel() == Reloc::PIC_) {
12381208
// With PIC, the first instruction is actually "GR+hi(&G)".
1239-
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
1209+
Hi = DAG.getNode(ISD::ADD, DL, PtrVT,
12401210
DAG.getNode(PPCISD::GlobalBaseReg,
12411211
DebugLoc(), PtrVT), Hi);
12421212
}
12431213

1244-
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
1214+
Lo = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
12451215

12461216
if (!TM.getSubtarget<PPCSubtarget>().hasLazyResolverStub(GV, TM))
12471217
return Lo;
12481218

12491219
// If the global is weak or external, we have to go through the lazy
12501220
// resolution stub.
1251-
return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Lo, MachinePointerInfo(),
1221+
return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Lo, MachinePointerInfo(),
12521222
false, false, 0);
12531223
}
12541224

@@ -4413,7 +4383,7 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
44134383
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
44144384
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
44154385
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
4416-
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
4386+
case ISD::GlobalTLSAddress: llvm_unreachable("TLS not implemented for PPC");
44174387
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
44184388
case ISD::SETCC: return LowerSETCC(Op, DAG);
44194389
case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG);

llvm/lib/Target/PowerPC/PPCISelLowering.h

-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ namespace llvm {
389389
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
390390
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
391391
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
392-
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
393392
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
394393
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
395394
SDValue LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)