@@ -374,72 +374,90 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
374374 }
375375}
376376
377+ static SDValue getTargetNode (GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
378+ SelectionDAG &DAG, unsigned Flags) {
379+ return DAG.getTargetGlobalAddress (N->getGlobal (), DL, Ty, 0 , Flags);
380+ }
381+
382+ static SDValue getTargetNode (BlockAddressSDNode *N, SDLoc DL, EVT Ty,
383+ SelectionDAG &DAG, unsigned Flags) {
384+ return DAG.getTargetBlockAddress (N->getBlockAddress (), Ty, N->getOffset (),
385+ Flags);
386+ }
387+
388+ static SDValue getTargetNode (ConstantPoolSDNode *N, SDLoc DL, EVT Ty,
389+ SelectionDAG &DAG, unsigned Flags) {
390+ return DAG.getTargetConstantPool (N->getConstVal (), Ty, N->getAlignment (),
391+ N->getOffset (), Flags);
392+ }
393+
394+ template <class NodeTy >
395+ SDValue RISCVTargetLowering::getAddr (NodeTy *N, SelectionDAG &DAG) const {
396+ SDLoc DL (N);
397+ EVT Ty = getPointerTy (DAG.getDataLayout ());
398+
399+ switch (getTargetMachine ().getCodeModel ()) {
400+ default :
401+ report_fatal_error (" Unsupported code model for lowering" );
402+ case CodeModel::Small: {
403+ // Generate a sequence for accessing addresses within the first 2 GiB of
404+ // address space. This generates the pattern (addi (lui %hi(sym)) %lo(sym)).
405+ SDValue AddrHi = getTargetNode (N, DL, Ty, DAG, RISCVII::MO_HI);
406+ SDValue AddrLo = getTargetNode (N, DL, Ty, DAG, RISCVII::MO_LO);
407+ SDValue MNHi = SDValue (DAG.getMachineNode (RISCV::LUI, DL, Ty, AddrHi), 0 );
408+ return SDValue (DAG.getMachineNode (RISCV::ADDI, DL, Ty, MNHi, AddrLo), 0 );
409+ }
410+ case CodeModel::Medium: {
411+ // Generate a sequence for accessing addresses within any 2GiB range within
412+ // the address space. This generates the pattern (PseudoLLA sym), which
413+ // expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
414+ SDValue Addr = getTargetNode (N, DL, Ty, DAG, 0 );
415+ return SDValue (DAG.getMachineNode (RISCV::PseudoLLA, DL, Ty, Addr), 0 );
416+ }
417+ }
418+ }
419+
377420SDValue RISCVTargetLowering::lowerGlobalAddress (SDValue Op,
378421 SelectionDAG &DAG) const {
379422 SDLoc DL (Op);
380423 EVT Ty = Op.getValueType ();
381424 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
382- const GlobalValue *GV = N->getGlobal ();
383425 int64_t Offset = N->getOffset ();
384426 MVT XLenVT = Subtarget.getXLenVT ();
385427
386428 if (isPositionIndependent ())
387429 report_fatal_error (" Unable to lowerGlobalAddress" );
430+
431+ SDValue Addr = getAddr (N, DAG);
432+
388433 // In order to maximise the opportunity for common subexpression elimination,
389434 // emit a separate ADD node for the global address offset instead of folding
390435 // it in the global address node. Later peephole optimisations may choose to
391436 // fold it back in when profitable.
392- SDValue GAHi = DAG.getTargetGlobalAddress (GV, DL, Ty, 0 , RISCVII::MO_HI);
393- SDValue GALo = DAG.getTargetGlobalAddress (GV, DL, Ty, 0 , RISCVII::MO_LO);
394- SDValue MNHi = SDValue (DAG.getMachineNode (RISCV::LUI, DL, Ty, GAHi), 0 );
395- SDValue MNLo =
396- SDValue (DAG.getMachineNode (RISCV::ADDI, DL, Ty, MNHi, GALo), 0 );
397437 if (Offset != 0 )
398- return DAG.getNode (ISD::ADD, DL, Ty, MNLo ,
438+ return DAG.getNode (ISD::ADD, DL, Ty, Addr ,
399439 DAG.getConstant (Offset, DL, XLenVT));
400- return MNLo ;
440+ return Addr ;
401441}
402442
403443SDValue RISCVTargetLowering::lowerBlockAddress (SDValue Op,
404444 SelectionDAG &DAG) const {
405- SDLoc DL (Op);
406- EVT Ty = Op.getValueType ();
407445 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
408- const BlockAddress *BA = N->getBlockAddress ();
409- int64_t Offset = N->getOffset ();
410446
411447 if (isPositionIndependent ())
412448 report_fatal_error (" Unable to lowerBlockAddress" );
413449
414- SDValue BAHi = DAG.getTargetBlockAddress (BA, Ty, Offset, RISCVII::MO_HI);
415- SDValue BALo = DAG.getTargetBlockAddress (BA, Ty, Offset, RISCVII::MO_LO);
416- SDValue MNHi = SDValue (DAG.getMachineNode (RISCV::LUI, DL, Ty, BAHi), 0 );
417- SDValue MNLo =
418- SDValue (DAG.getMachineNode (RISCV::ADDI, DL, Ty, MNHi, BALo), 0 );
419- return MNLo;
450+ return getAddr (N, DAG);
420451}
421452
422453SDValue RISCVTargetLowering::lowerConstantPool (SDValue Op,
423454 SelectionDAG &DAG) const {
424- SDLoc DL (Op);
425- EVT Ty = Op.getValueType ();
426455 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
427- const Constant *CPA = N->getConstVal ();
428- int64_t Offset = N->getOffset ();
429- unsigned Alignment = N->getAlignment ();
430-
431- if (!isPositionIndependent ()) {
432- SDValue CPAHi =
433- DAG.getTargetConstantPool (CPA, Ty, Alignment, Offset, RISCVII::MO_HI);
434- SDValue CPALo =
435- DAG.getTargetConstantPool (CPA, Ty, Alignment, Offset, RISCVII::MO_LO);
436- SDValue MNHi = SDValue (DAG.getMachineNode (RISCV::LUI, DL, Ty, CPAHi), 0 );
437- SDValue MNLo =
438- SDValue (DAG.getMachineNode (RISCV::ADDI, DL, Ty, MNHi, CPALo), 0 );
439- return MNLo;
440- } else {
456+
457+ if (isPositionIndependent ())
441458 report_fatal_error (" Unable to lowerConstantPool" );
442- }
459+
460+ return getAddr (N, DAG);
443461}
444462
445463SDValue RISCVTargetLowering::lowerSELECT (SDValue Op, SelectionDAG &DAG) const {
0 commit comments