@@ -363,71 +363,85 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
363
363
SM.recordPatchPoint (MI);
364
364
PatchPointOpers Opers (&MI);
365
365
366
- int64_t CallTarget = Opers.getMetaOper (PatchPointOpers::TargetPos).getImm ();
367
366
unsigned EncodedBytes = 0 ;
368
- if (CallTarget) {
369
- assert ((CallTarget & 0xFFFFFFFFFFFF ) == CallTarget &&
370
- " High 16 bits of call target should be zero." );
371
- unsigned ScratchReg = MI.getOperand (Opers.getNextScratchIdx ()).getReg ();
372
- EncodedBytes = 0 ;
373
- // Materialize the jump address:
374
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LI8)
375
- .addReg (ScratchReg)
376
- .addImm ((CallTarget >> 32 ) & 0xFFFF ));
377
- ++EncodedBytes;
378
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::RLDIC)
379
- .addReg (ScratchReg)
380
- .addReg (ScratchReg)
381
- .addImm (32 ).addImm (16 ));
382
- ++EncodedBytes;
383
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::ORIS8)
384
- .addReg (ScratchReg)
385
- .addReg (ScratchReg)
386
- .addImm ((CallTarget >> 16 ) & 0xFFFF ));
387
- ++EncodedBytes;
388
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::ORI8)
389
- .addReg (ScratchReg)
390
- .addReg (ScratchReg)
391
- .addImm (CallTarget & 0xFFFF ));
392
-
393
- // Save the current TOC pointer before the remote call.
394
- int TOCSaveOffset = Subtarget->isELFv2ABI () ? 24 : 40 ;
395
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::STD)
396
- .addReg (PPC::X2)
397
- .addImm (TOCSaveOffset)
398
- .addReg (PPC::X1));
399
- ++EncodedBytes;
400
-
401
-
402
- // If we're on ELFv1, then we need to load the actual function pointer from
403
- // the function descriptor.
404
- if (!Subtarget->isELFv2ABI ()) {
405
- // Load the new TOC pointer and the function address, but not r11
406
- // (needing this is rare, and loading it here would prevent passing it
407
- // via a 'nest' parameter.
408
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LD)
367
+ const MachineOperand &CalleeMO =
368
+ Opers.getMetaOper (PatchPointOpers::TargetPos);
369
+
370
+ if (CalleeMO.isImm ()) {
371
+ int64_t CallTarget = Opers.getMetaOper (PatchPointOpers::TargetPos).getImm ();
372
+ if (CallTarget) {
373
+ assert ((CallTarget & 0xFFFFFFFFFFFF ) == CallTarget &&
374
+ " High 16 bits of call target should be zero." );
375
+ unsigned ScratchReg = MI.getOperand (Opers.getNextScratchIdx ()).getReg ();
376
+ EncodedBytes = 0 ;
377
+ // Materialize the jump address:
378
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LI8)
379
+ .addReg (ScratchReg)
380
+ .addImm ((CallTarget >> 32 ) & 0xFFFF ));
381
+ ++EncodedBytes;
382
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::RLDIC)
383
+ .addReg (ScratchReg)
384
+ .addReg (ScratchReg)
385
+ .addImm (32 ).addImm (16 ));
386
+ ++EncodedBytes;
387
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::ORIS8)
388
+ .addReg (ScratchReg)
389
+ .addReg (ScratchReg)
390
+ .addImm ((CallTarget >> 16 ) & 0xFFFF ));
391
+ ++EncodedBytes;
392
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::ORI8)
393
+ .addReg (ScratchReg)
394
+ .addReg (ScratchReg)
395
+ .addImm (CallTarget & 0xFFFF ));
396
+
397
+ // Save the current TOC pointer before the remote call.
398
+ int TOCSaveOffset = Subtarget->isELFv2ABI () ? 24 : 40 ;
399
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::STD)
409
400
.addReg (PPC::X2)
410
- .addImm (8 )
401
+ .addImm (TOCSaveOffset)
402
+ .addReg (PPC::X1));
403
+ ++EncodedBytes;
404
+
405
+
406
+ // If we're on ELFv1, then we need to load the actual function pointer
407
+ // from the function descriptor.
408
+ if (!Subtarget->isELFv2ABI ()) {
409
+ // Load the new TOC pointer and the function address, but not r11
410
+ // (needing this is rare, and loading it here would prevent passing it
411
+ // via a 'nest' parameter.
412
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LD)
413
+ .addReg (PPC::X2)
414
+ .addImm (8 )
415
+ .addReg (ScratchReg));
416
+ ++EncodedBytes;
417
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LD)
418
+ .addReg (ScratchReg)
419
+ .addImm (0 )
420
+ .addReg (ScratchReg));
421
+ ++EncodedBytes;
422
+ }
423
+
424
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::MTCTR8)
411
425
.addReg (ScratchReg));
412
426
++EncodedBytes;
427
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::BCTRL8));
428
+ ++EncodedBytes;
429
+
430
+ // Restore the TOC pointer after the call.
413
431
EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LD)
414
- .addReg (ScratchReg )
415
- .addImm (0 )
416
- .addReg (ScratchReg ));
432
+ .addReg (PPC::X2 )
433
+ .addImm (TOCSaveOffset )
434
+ .addReg (PPC::X1 ));
417
435
++EncodedBytes;
418
436
}
437
+ } else if (CalleeMO.isGlobal ()) {
438
+ const GlobalValue *GValue = CalleeMO.getGlobal ();
439
+ MCSymbol *MOSymbol = getSymbol (GValue);
440
+ const MCExpr *SymVar = MCSymbolRefExpr::create (MOSymbol, OutContext);
419
441
420
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::MTCTR8).addReg (ScratchReg));
421
- ++EncodedBytes;
422
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::BCTRL8));
423
- ++EncodedBytes;
424
-
425
- // Restore the TOC pointer after the call.
426
- EmitToStreamer (OutStreamer, MCInstBuilder (PPC::LD)
427
- .addReg (PPC::X2)
428
- .addImm (TOCSaveOffset)
429
- .addReg (PPC::X1));
430
- ++EncodedBytes;
442
+ EmitToStreamer (OutStreamer, MCInstBuilder (PPC::BL8_NOP)
443
+ .addExpr (SymVar));
444
+ EncodedBytes += 2 ;
431
445
}
432
446
433
447
// Each instruction is 4 bytes.
0 commit comments