20
20
#include " llvm/MC/MCExpr.h"
21
21
#include " llvm/MC/MCInst.h"
22
22
#include " llvm/MC/MCInstBuilder.h"
23
+ #include " llvm/MC/MCObjectFileInfo.h"
23
24
#include " llvm/MC/MCParser/MCAsmLexer.h"
24
25
#include " llvm/MC/MCParser/MCParsedAsmOperand.h"
25
26
#include " llvm/MC/MCParser/MCTargetAsmParser.h"
@@ -78,9 +79,18 @@ class RISCVAsmParser : public MCTargetAsmParser {
78
79
// synthesize the desired immedate value into the destination register.
79
80
void emitLoadImm (unsigned DestReg, int64_t Value, MCStreamer &Out);
80
81
82
+ // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
83
+ // helpers such as emitLoadLocalAddress and emitLoadAddress.
84
+ void emitAuipcInstPair (MCOperand DestReg, MCOperand TmpReg,
85
+ const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
86
+ unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
87
+
81
88
// Helper to emit pseudo instruction "lla" used in PC-rel addressing.
82
89
void emitLoadLocalAddress (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
83
90
91
+ // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
92
+ void emitLoadAddress (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
93
+
84
94
// / Helper for processing MC instructions that have been successfully matched
85
95
// / by MatchAndEmitInstruction. Modifications to the emitted instructions,
86
96
// / like the expansion of pseudo instructions (e.g., "li"), can be performed
@@ -1409,42 +1419,82 @@ void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1409
1419
}
1410
1420
}
1411
1421
1412
- void RISCVAsmParser::emitLoadLocalAddress (MCInst &Inst, SMLoc IDLoc ,
1413
- MCStreamer &Out) {
1414
- // The local load address pseudo-instruction "lla" is used in PC-relative
1415
- // addressing of symbols:
1416
- // lla rdest, symbol
1417
- // expands to
1418
- // TmpLabel: AUIPC rdest, %pcrel_hi (symbol)
1419
- // ADDI rdest , %pcrel_lo(TmpLabel)
1422
+ void RISCVAsmParser::emitAuipcInstPair (MCOperand DestReg, MCOperand TmpReg ,
1423
+ const MCExpr *Symbol,
1424
+ RISCVMCExpr::VariantKind VKHi,
1425
+ unsigned SecondOpcode, SMLoc IDLoc,
1426
+ MCStreamer &Out) {
1427
+ // A pair of instructions for PC-relative addressing; expands to
1428
+ // TmpLabel: AUIPC TmpReg, VKHi (symbol)
1429
+ // OP DestReg, TmpReg , %pcrel_lo(TmpLabel)
1420
1430
MCContext &Ctx = getContext ();
1421
1431
1422
1432
MCSymbol *TmpLabel = Ctx.createTempSymbol (
1423
1433
" pcrel_hi" , /* AlwaysAddSuffix */ true , /* CanBeUnnamed */ false );
1424
1434
Out.EmitLabel (TmpLabel);
1425
1435
1426
- MCOperand DestReg = Inst.getOperand (0 );
1427
- const RISCVMCExpr *Symbol = RISCVMCExpr::create (
1428
- Inst.getOperand (1 ).getExpr (), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx);
1429
-
1436
+ const RISCVMCExpr *SymbolHi = RISCVMCExpr::create (Symbol, VKHi, Ctx);
1430
1437
emitToStreamer (
1431
- Out, MCInstBuilder (RISCV::AUIPC).addOperand (DestReg ).addExpr (Symbol ));
1438
+ Out, MCInstBuilder (RISCV::AUIPC).addOperand (TmpReg ).addExpr (SymbolHi ));
1432
1439
1433
1440
const MCExpr *RefToLinkTmpLabel =
1434
1441
RISCVMCExpr::create (MCSymbolRefExpr::create (TmpLabel, Ctx),
1435
1442
RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1436
1443
1437
- emitToStreamer (Out, MCInstBuilder (RISCV::ADDI)
1438
- .addOperand (DestReg)
1444
+ emitToStreamer (Out, MCInstBuilder (SecondOpcode)
1439
1445
.addOperand (DestReg)
1446
+ .addOperand (TmpReg)
1440
1447
.addExpr (RefToLinkTmpLabel));
1441
1448
}
1442
1449
1450
+ void RISCVAsmParser::emitLoadLocalAddress (MCInst &Inst, SMLoc IDLoc,
1451
+ MCStreamer &Out) {
1452
+ // The load local address pseudo-instruction "lla" is used in PC-relative
1453
+ // addressing of local symbols:
1454
+ // lla rdest, symbol
1455
+ // expands to
1456
+ // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1457
+ // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1458
+ MCOperand DestReg = Inst.getOperand (0 );
1459
+ const MCExpr *Symbol = Inst.getOperand (1 ).getExpr ();
1460
+ emitAuipcInstPair (DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
1461
+ RISCV::ADDI, IDLoc, Out);
1462
+ }
1463
+
1464
+ void RISCVAsmParser::emitLoadAddress (MCInst &Inst, SMLoc IDLoc,
1465
+ MCStreamer &Out) {
1466
+ // The load address pseudo-instruction "la" is used in PC-relative and
1467
+ // GOT-indirect addressing of global symbols:
1468
+ // la rdest, symbol
1469
+ // expands to either (for non-PIC)
1470
+ // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1471
+ // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1472
+ // or (for PIC)
1473
+ // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
1474
+ // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
1475
+ MCOperand DestReg = Inst.getOperand (0 );
1476
+ const MCExpr *Symbol = Inst.getOperand (1 ).getExpr ();
1477
+ unsigned SecondOpcode;
1478
+ RISCVMCExpr::VariantKind VKHi;
1479
+ // FIXME: Should check .option (no)pic when implemented
1480
+ if (getContext ().getObjectFileInfo ()->isPositionIndependent ()) {
1481
+ SecondOpcode = isRV64 () ? RISCV::LD : RISCV::LW;
1482
+ VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
1483
+ } else {
1484
+ SecondOpcode = RISCV::ADDI;
1485
+ VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
1486
+ }
1487
+ emitAuipcInstPair (DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
1488
+ }
1489
+
1443
1490
bool RISCVAsmParser::processInstruction (MCInst &Inst, SMLoc IDLoc,
1444
1491
MCStreamer &Out) {
1445
1492
Inst.setLoc (IDLoc);
1446
1493
1447
- if (Inst.getOpcode () == RISCV::PseudoLI) {
1494
+ switch (Inst.getOpcode ()) {
1495
+ default :
1496
+ break ;
1497
+ case RISCV::PseudoLI: {
1448
1498
unsigned Reg = Inst.getOperand (0 ).getReg ();
1449
1499
const MCOperand &Op1 = Inst.getOperand (1 );
1450
1500
if (Op1.isExpr ()) {
@@ -1464,9 +1514,13 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1464
1514
Imm = SignExtend64<32 >(Imm);
1465
1515
emitLoadImm (Reg, Imm, Out);
1466
1516
return false ;
1467
- } else if (Inst.getOpcode () == RISCV::PseudoLLA) {
1517
+ }
1518
+ case RISCV::PseudoLLA:
1468
1519
emitLoadLocalAddress (Inst, IDLoc, Out);
1469
1520
return false ;
1521
+ case RISCV::PseudoLA:
1522
+ emitLoadAddress (Inst, IDLoc, Out);
1523
+ return false ;
1470
1524
}
1471
1525
1472
1526
emitToStreamer (Out, Inst);
0 commit comments