@@ -474,6 +474,63 @@ static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type) {
474
474
}
475
475
}
476
476
477
+ static CodeModel::Model getCodeModel (const PPCSubtarget &S,
478
+ const TargetMachine &TM,
479
+ const MachineOperand &MO) {
480
+ assert (S.isAIXABI () && " ELF per global code model not supported yet" );
481
+
482
+ CodeModel::Model ModuleModel = TM.getCodeModel ();
483
+
484
+ // If the operand is not a global address then there is no
485
+ // global variable to carry an attribute.
486
+ if (!(MO.getType () == MachineOperand::MO_GlobalAddress))
487
+ return ModuleModel;
488
+
489
+ const GlobalValue *GV = MO.getGlobal ();
490
+ assert (GV && " expected global for MO_GlobalAddress" );
491
+
492
+ if (!isa<GlobalVariable>(GV))
493
+ return ModuleModel;
494
+
495
+ std::optional<CodeModel::Model> MaybeCodeModel =
496
+ dyn_cast<GlobalVariable>(GV)->getCodeModel ();
497
+ if (MaybeCodeModel)
498
+ return *MaybeCodeModel;
499
+
500
+ return ModuleModel;
501
+ }
502
+
503
+ static void checkPerGlobalCodeModel (const GlobalValue *GV, MCSymbol *Sym) {
504
+ // ELF per global code model not supported yet.
505
+ if (!isa<MCSymbolXCOFF>(Sym))
506
+ return ;
507
+
508
+ // Symbols that aren't global variables cannot have the attribute.
509
+ if (!isa<GlobalVariable>(GV))
510
+ return ;
511
+
512
+ const GlobalVariable *GVar = cast<GlobalVariable>(GV);
513
+ std::optional<CodeModel::Model> MaybeCM = GVar->getCodeModel ();
514
+
515
+ // No overriding atribute.
516
+ if (!MaybeCM)
517
+ return ;
518
+
519
+ CodeModel::Model CM = *MaybeCM;
520
+
521
+ MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(Sym);
522
+ switch (CM) {
523
+ case CodeModel::Large:
524
+ XSym->setPerSymbolCodeModel (MCSymbolXCOFF::CM_Large);
525
+ return ;
526
+ case CodeModel::Small:
527
+ XSym->setPerSymbolCodeModel (MCSymbolXCOFF::CM_Small);
528
+ return ;
529
+ default :
530
+ report_fatal_error (" Invlaid code model for AIX" );
531
+ }
532
+ }
533
+
477
534
// / lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
478
535
// / exists for it. If not, create one. Then return a symbol that references
479
536
// / the TOC entry.
@@ -723,8 +780,12 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
723
780
static MCSymbol *getMCSymbolForTOCPseudoMO (const MachineOperand &MO,
724
781
AsmPrinter &AP) {
725
782
switch (MO.getType ()) {
726
- case MachineOperand::MO_GlobalAddress:
727
- return AP.getSymbol (MO.getGlobal ());
783
+ case MachineOperand::MO_GlobalAddress: {
784
+ const GlobalValue *GV = MO.getGlobal ();
785
+ MCSymbol *Sym = AP.getSymbol (GV);
786
+ checkPerGlobalCodeModel (GV, Sym);
787
+ return Sym;
788
+ }
728
789
case MachineOperand::MO_ConstantPoolIndex:
729
790
return AP.GetCPISymbol (MO.getIndex ());
730
791
case MachineOperand::MO_JumpTableIndex:
@@ -1014,7 +1075,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1014
1075
// relative to the toc-base.
1015
1076
if (IsAIX) {
1016
1077
assert (
1017
- TM. getCodeModel () == CodeModel::Small &&
1078
+ getCodeModel (*Subtarget, TM, MO ) == CodeModel::Small &&
1018
1079
" This pseudo should only be selected for 32-bit small code model." );
1019
1080
Exp = getTOCEntryLoadingExprForXCOFF (MOSymbol, Exp, VK);
1020
1081
TmpInst.getOperand (1 ) = MCOperand::createExpr (Exp);
@@ -1098,7 +1159,12 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1098
1159
return ;
1099
1160
}
1100
1161
case PPC::ADDIStocHA: {
1101
- assert ((IsAIX && !IsPPC64 && TM.getCodeModel () == CodeModel::Large) &&
1162
+ const MachineOperand &MO = MI->getOperand (2 );
1163
+
1164
+ assert ((MO.isGlobal () || MO.isCPI () || MO.isJTI () || MO.isBlockAddress ()) &&
1165
+ " Invalid operand for ADDIStocHA." );
1166
+ assert ((IsAIX && !IsPPC64 &&
1167
+ getCodeModel (*Subtarget, TM, MO) == CodeModel::Large) &&
1102
1168
" This pseudo should only be selected for 32-bit large code model on"
1103
1169
" AIX." );
1104
1170
@@ -1108,10 +1174,6 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1108
1174
// Change the opcode to ADDIS.
1109
1175
TmpInst.setOpcode (PPC::ADDIS);
1110
1176
1111
- const MachineOperand &MO = MI->getOperand (2 );
1112
- assert ((MO.isGlobal () || MO.isCPI () || MO.isJTI () || MO.isBlockAddress ()) &&
1113
- " Invalid operand for ADDIStocHA." );
1114
-
1115
1177
// Map the machine operand to its corresponding MCSymbol.
1116
1178
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO (MO, *this );
1117
1179
@@ -1131,7 +1193,12 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1131
1193
return ;
1132
1194
}
1133
1195
case PPC::LWZtocL: {
1134
- assert (IsAIX && !IsPPC64 && TM.getCodeModel () == CodeModel::Large &&
1196
+ const MachineOperand &MO = MI->getOperand (1 );
1197
+
1198
+ assert ((MO.isGlobal () || MO.isCPI () || MO.isJTI () || MO.isBlockAddress ()) &&
1199
+ " Invalid operand for LWZtocL." );
1200
+ assert (IsAIX && !IsPPC64 &&
1201
+ getCodeModel (*Subtarget, TM, MO) == CodeModel::Large &&
1135
1202
" This pseudo should only be selected for 32-bit large code model on"
1136
1203
" AIX." );
1137
1204
@@ -1141,10 +1208,6 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1141
1208
// Change the opcode to lwz.
1142
1209
TmpInst.setOpcode (PPC::LWZ);
1143
1210
1144
- const MachineOperand &MO = MI->getOperand (1 );
1145
- assert ((MO.isGlobal () || MO.isCPI () || MO.isJTI () || MO.isBlockAddress ()) &&
1146
- " Invalid operand for LWZtocL." );
1147
-
1148
1211
// Map the machine operand to its corresponding MCSymbol.
1149
1212
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO (MO, *this );
1150
1213
@@ -1183,8 +1246,12 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1183
1246
1184
1247
const bool GlobalToc =
1185
1248
MO.isGlobal () && Subtarget->isGVIndirectSymbol (MO.getGlobal ());
1249
+
1250
+ const CodeModel::Model CM =
1251
+ IsAIX ? getCodeModel (*Subtarget, TM, MO) : TM.getCodeModel ();
1252
+
1186
1253
if (GlobalToc || MO.isJTI () || MO.isBlockAddress () ||
1187
- (MO.isCPI () && TM. getCodeModel () == CodeModel::Large))
1254
+ (MO.isCPI () && CM == CodeModel::Large))
1188
1255
MOSymbol = lookUpOrCreateTOCEntry (MOSymbol, getTOCEntryTypeForMO (MO), VK);
1189
1256
1190
1257
VK = IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA;
@@ -1225,8 +1292,9 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
1225
1292
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO (MO, *this );
1226
1293
1227
1294
MCSymbolRefExpr::VariantKind VK = GetVKForMO (MO);
1228
-
1229
- if (!MO.isCPI () || TM.getCodeModel () == CodeModel::Large)
1295
+ CodeModel::Model CM =
1296
+ IsAIX ? getCodeModel (*Subtarget, TM, MO) : TM.getCodeModel ();
1297
+ if (!MO.isCPI () || CM == CodeModel::Large)
1230
1298
MOSymbol = lookUpOrCreateTOCEntry (MOSymbol, getTOCEntryTypeForMO (MO), VK);
1231
1299
1232
1300
VK = IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO;
0 commit comments