@@ -38,9 +38,11 @@ static cl::opt<bool>
3838 " bytes of NOPs even in norvc code" ));
3939
4040RISCVAsmBackend::RISCVAsmBackend (const MCSubtargetInfo &STI, uint8_t OSABI,
41- bool Is64Bit, const MCTargetOptions &Options)
42- : MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI),
43- Is64Bit(Is64Bit), TargetOptions(Options) {
41+ bool Is64Bit, bool IsLittleEndian,
42+ const MCTargetOptions &Options)
43+ : MCAsmBackend(IsLittleEndian ? llvm::endianness::little
44+ : llvm::endianness::big),
45+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
4446 RISCVFeatures::validate (STI.getTargetTriple (), STI.getFeatureBits ());
4547}
4648
@@ -374,7 +376,7 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F,
374376 } else {
375377 PCBytes = 2 ;
376378 OS << uint8_t (dwarf::DW_LNS_fixed_advance_pc);
377- support::endian::write<uint16_t >(OS, 0 , llvm::endianness::little );
379+ support::endian::write<uint16_t >(OS, 0 , Endian );
378380 }
379381 auto Offset = OS.tell () - PCBytes;
380382
@@ -428,15 +430,15 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
428430 AddFixups (0 , {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
429431 } else if (isUInt<8 >(Value)) {
430432 OS << uint8_t (dwarf::DW_CFA_advance_loc1);
431- support::endian::write<uint8_t >(OS, 0 , llvm::endianness::little );
433+ support::endian::write<uint8_t >(OS, 0 , Endian );
432434 AddFixups (1 , {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
433435 } else if (isUInt<16 >(Value)) {
434436 OS << uint8_t (dwarf::DW_CFA_advance_loc2);
435- support::endian::write<uint16_t >(OS, 0 , llvm::endianness::little );
437+ support::endian::write<uint16_t >(OS, 0 , Endian );
436438 AddFixups (1 , {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
437439 } else if (isUInt<32 >(Value)) {
438440 OS << uint8_t (dwarf::DW_CFA_advance_loc4);
439- support::endian::write<uint32_t >(OS, 0 , llvm::endianness::little );
441+ support::endian::write<uint32_t >(OS, 0 , Endian );
440442 AddFixups (1 , {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
441443 } else {
442444 llvm_unreachable (" unsupported CFA encoding" );
@@ -909,6 +911,22 @@ bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
909911 return false ;
910912}
911913
914+ // Data fixups should be swapped for big endian cores.
915+ // Instruction fixups should not be swapped as RISC-V instructions
916+ // are always little-endian.
917+ static bool isDataFixup (unsigned Kind) {
918+ switch (Kind) {
919+ default :
920+ return false ;
921+
922+ case FK_Data_1:
923+ case FK_Data_2:
924+ case FK_Data_4:
925+ case FK_Data_8:
926+ return true ;
927+ }
928+ }
929+
912930void RISCVAsmBackend::applyFixup (const MCFragment &F, const MCFixup &Fixup,
913931 const MCValue &Target, uint8_t *Data,
914932 uint64_t Value, bool IsResolved) {
@@ -932,8 +950,11 @@ void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
932950
933951 // For each byte of the fragment that the fixup touches, mask in the
934952 // bits from the fixup value.
953+ // For big endian cores, data fixup should be swapped.
954+ bool SwapValue = Endian == llvm::endianness::big && isDataFixup (Kind);
935955 for (unsigned i = 0 ; i != NumBytes; ++i) {
936- Data[i] |= uint8_t ((Value >> (i * 8 )) & 0xff );
956+ unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i;
957+ Data[Idx] |= uint8_t ((Value >> (i * 8 )) & 0xff );
937958 }
938959}
939960
@@ -948,5 +969,6 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
948969 const MCTargetOptions &Options) {
949970 const Triple &TT = STI.getTargetTriple ();
950971 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI (TT.getOS ());
951- return new RISCVAsmBackend (STI, OSABI, TT.isArch64Bit (), Options);
972+ return new RISCVAsmBackend (STI, OSABI, TT.isArch64Bit (), TT.isLittleEndian (),
973+ Options);
952974}
0 commit comments