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