diff --git a/llvm/cmake/config.guess b/llvm/cmake/config.guess index 96cc554f181ab..27b55bd166edc 100644 --- a/llvm/cmake/config.guess +++ b/llvm/cmake/config.guess @@ -1003,7 +1003,7 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-gnu exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) + riscv32:Linux:*:* | riscv64:Linux:*:* | riscv32be:Linux:*:* | riscv64be:Linux:*:*) LIBC=gnu eval $set_cc_for_build # Do not check for __GLIBC__ because uclibc defines it too diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index d19ef923ef740..739dcc7f4c868 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -247,6 +247,8 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, break; case Triple::riscv32: case Triple::riscv64: + case Triple::riscv32be: + case Triple::riscv64be: LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index d71c42c0a5fc1..c87362a1b4e87 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -4053,4 +4053,6 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { RegisterMCAsmParser X(getTheRISCV32Target()); RegisterMCAsmParser Y(getTheRISCV64Target()); + RegisterMCAsmParser A(getTheRISCV32beTarget()); + RegisterMCAsmParser B(getTheRISCV64beTarget()); } diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 67cc01e647a04..c535dc0891f9c 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -72,6 +72,10 @@ LLVMInitializeRISCVDisassembler() { createRISCVDisassembler); TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), createRISCVDisassembler); + TargetRegistry::RegisterMCDisassembler(getTheRISCV32beTarget(), + createRISCVDisassembler); + TargetRegistry::RegisterMCDisassembler(getTheRISCV64beTarget(), + createRISCVDisassembler); } static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 95ec42f960105..d38e3601fbd7e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -33,9 +33,11 @@ static cl::opt ULEB128Reloc( cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate")); RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, - bool Is64Bit, const MCTargetOptions &Options) - : MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI), - Is64Bit(Is64Bit), TargetOptions(Options) { + bool Is64Bit, bool IsLittleEndian, + const MCTargetOptions &Options) + : MCAsmBackend(IsLittleEndian ? llvm::endianness::little + : llvm::endianness::big), + STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) { RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits()); } @@ -361,7 +363,7 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F, } else { PCBytes = 2; OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc); - support::endian::write(OS, 0, llvm::endianness::little); + support::endian::write(OS, 0, Endian); } auto Offset = OS.tell() - PCBytes; @@ -415,15 +417,15 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const { AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6}); } else if (isUInt<8>(Value)) { OS << uint8_t(dwarf::DW_CFA_advance_loc1); - support::endian::write(OS, 0, llvm::endianness::little); + support::endian::write(OS, 0, Endian); AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8}); } else if (isUInt<16>(Value)) { OS << uint8_t(dwarf::DW_CFA_advance_loc2); - support::endian::write(OS, 0, llvm::endianness::little); + support::endian::write(OS, 0, Endian); AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16}); } else if (isUInt<32>(Value)) { OS << uint8_t(dwarf::DW_CFA_advance_loc4); - support::endian::write(OS, 0, llvm::endianness::little); + support::endian::write(OS, 0, Endian); AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32}); } else { llvm_unreachable("unsupported CFA encoding"); @@ -869,6 +871,41 @@ bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup, return false; } +// Data should be swapped for big endian cores. +static bool isDataFixup(unsigned Kind) { + switch (Kind) { + default: + llvm_unreachable("Unknown fixup kind!"); + + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + case FK_Data_8: + return true; + + case RISCV::fixup_riscv_hi20: + case RISCV::fixup_riscv_lo12_i: + case RISCV::fixup_riscv_lo12_s: + case RISCV::fixup_riscv_pcrel_hi20: + case RISCV::fixup_riscv_pcrel_lo12_i: + case RISCV::fixup_riscv_pcrel_lo12_s: + case RISCV::fixup_riscv_jal: + case RISCV::fixup_riscv_branch: + case RISCV::fixup_riscv_call: + case RISCV::fixup_riscv_call_plt: + case RISCV::fixup_riscv_rvc_jump: + case RISCV::fixup_riscv_rvc_branch: + case RISCV::fixup_riscv_12_i: + case RISCV::fixup_riscv_rvc_imm: + case RISCV::fixup_riscv_qc_e_branch: + case RISCV::fixup_riscv_qc_e_32: + case RISCV::fixup_riscv_qc_abs20_u: + case RISCV::fixup_riscv_qc_e_call_plt: + case RISCV::fixup_riscv_nds_branch_10: + return false; + } +} + void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved) { @@ -892,8 +929,11 @@ void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, // For each byte of the fragment that the fixup touches, mask in the // bits from the fixup value. + // For big endian cores, data fixup should be swapped. + bool SwapValue = Endian == llvm::endianness::big && isDataFixup(Kind); for (unsigned i = 0; i != NumBytes; ++i) { - Data[i] |= uint8_t((Value >> (i * 8)) & 0xff); + unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i; + Data[Idx] |= uint8_t((Value >> (i * 8)) & 0xff); } } @@ -908,5 +948,6 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T, const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); + return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), TT.isLittleEndian(), + Options); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index adec1ec699da0..3a5214a5f350f 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -35,7 +35,7 @@ class RISCVAsmBackend : public MCAsmBackend { public: RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, - const MCTargetOptions &Options); + bool IsLittleEndian, const MCTargetOptions &Options); ~RISCVAsmBackend() override = default; std::optional evaluateFixup(const MCFragment &, MCFixup &, MCValue &, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp index 090d331d99cab..77f65d814ce7a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp @@ -21,6 +21,7 @@ using namespace llvm; void RISCVMCAsmInfo::anchor() {} RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) { + IsLittleEndian = TT.isLittleEndian(); CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4; CommentString = "#"; AlignmentIsInBytes = false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp index 61ecfb278a7d3..d917ef4129791 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -376,7 +376,8 @@ static MCInstrAnalysis *createRISCVInstrAnalysis(const MCInstrInfo *Info) { extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTargetMC() { - for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) { + for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target(), + &getTheRISCV32beTarget(), &getTheRISCV64beTarget()}) { TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo); TargetRegistry::RegisterMCObjectFileInfo(*T, createRISCVMCObjectFileInfo); TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo); diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 2f32e2ac3eba3..83566b1c57782 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -611,6 +611,8 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter() { RegisterAsmPrinter X(getTheRISCV32Target()); RegisterAsmPrinter Y(getTheRISCV64Target()); + RegisterAsmPrinter A(getTheRISCV32beTarget()); + RegisterAsmPrinter B(getTheRISCV64beTarget()); } void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) { diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index da6ac2f6f31e9..d2446c43e3a08 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -117,6 +117,8 @@ static cl::opt extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { RegisterTargetMachine X(getTheRISCV32Target()); RegisterTargetMachine Y(getTheRISCV64Target()); + RegisterTargetMachine A(getTheRISCV32beTarget()); + RegisterTargetMachine B(getTheRISCV64beTarget()); auto *PR = PassRegistry::getPassRegistry(); initializeGlobalISel(*PR); initializeRISCVO0PreLegalizerCombinerPass(*PR); @@ -150,21 +152,33 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVAsmPrinterPass(*PR); } -static StringRef computeDataLayout(const Triple &TT, - const TargetOptions &Options) { - StringRef ABIName = Options.MCOptions.getABIName(); - if (TT.isArch64Bit()) { - if (ABIName == "lp64e") - return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"; +static std::string computeDataLayout(const Triple &TT, + const TargetOptions &Opts) { + std::string Endianness = TT.isLittleEndian() ? "e" : "E"; + + std::string PointerAndIntegerLayout; + std::string NativeIntegerWidths; - return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"; + if (TT.isArch64Bit()) { + PointerAndIntegerLayout = "p:64:64-i64:64-i128:128"; + NativeIntegerWidths = "n32:64"; + } else { + assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported"); + PointerAndIntegerLayout = "p:32:32-i64:64"; + NativeIntegerWidths = "n32"; } - assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported"); - if (ABIName == "ilp32e") - return "e-m:e-p:32:32-i64:64-n32-S32"; + StringRef ABI = Opts.MCOptions.getABIName(); + std::string StackAlignment; + + if (TT.isArch64Bit()) { + StackAlignment = (ABI == "lp64e") ? "S64" : "S128"; + } else { + StackAlignment = (ABI == "ilp32e") ? "S32" : "S128"; + } - return "e-m:e-p:32:32-i64:64-n32-S128"; + return Endianness + "-m:e-" + PointerAndIntegerLayout + "-" + + NativeIntegerWidths + "-" + StackAlignment; } static Reloc::Model getEffectiveRelocModel(const Triple &TT, diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp index fc0965d263a8a..7b0afe46971a3 100644 --- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp +++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp @@ -21,10 +21,24 @@ Target &llvm::getTheRISCV64Target() { return TheRISCV64Target; } +Target &llvm::getTheRISCV32beTarget() { + static Target TheRISCV32beTarget; + return TheRISCV32beTarget; +} + +Target &llvm::getTheRISCV64beTarget() { + static Target TheRISCV64beTarget; + return TheRISCV64beTarget; +} + extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTargetInfo() { RegisterTarget X( getTheRISCV32Target(), "riscv32", "32-bit RISC-V", "RISCV"); RegisterTarget Y( getTheRISCV64Target(), "riscv64", "64-bit RISC-V", "RISCV"); + RegisterTarget A(getTheRISCV32beTarget(), "riscv32be", + "32-bit big endian RISC-V", "RISCV"); + RegisterTarget B(getTheRISCV64beTarget(), "riscv64be", + "64-bit big endian RISC-V", "RISCV"); } diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h index ed00a01fa1a2a..9b9fd2cca2fd0 100644 --- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h +++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h @@ -15,6 +15,8 @@ class Target; Target &getTheRISCV32Target(); Target &getTheRISCV64Target(); +Target &getTheRISCV32beTarget(); +Target &getTheRISCV64beTarget(); } // namespace llvm diff --git a/llvm/test/MC/Disassembler/RISCV/bigendian.txt b/llvm/test/MC/Disassembler/RISCV/bigendian.txt new file mode 100644 index 0000000000000..54930f94b75ed --- /dev/null +++ b/llvm/test/MC/Disassembler/RISCV/bigendian.txt @@ -0,0 +1,29 @@ +# RUN: llvm-mc --disassemble %s -triple=riscv32be -mattr=+c 2>&1 | FileCheck %s +# RUN: llvm-mc --disassemble %s -triple=riscv64be -mattr=+c 2>&1 | FileCheck %s + +# Test basic disassembly for big-endian RISC-V +# Instructions are always little-endian encoded in RISC-V + +[0x13,0x05,0x45,0x06] +# CHECK: addi a0, a0, 100 + +[0xb7,0x52,0x34,0x12] +# CHECK: lui t0, 74565 + +[0x03,0x26,0x05,0x00] +# CHECK: lw a2, 0(a0) + +[0x23,0x22,0xc5,0x00] +# CHECK: sw a2, 4(a0) + +[0xef,0x00,0x00,0x00] +# CHECK: jal 0 + +[0x63,0x00,0xb5,0x00] +# CHECK: beq a0, a1, 0 + +[0x01,0x00] +# CHECK: nop + +[0x05,0x05] +# CHECK: addi a0, a0, 1 diff --git a/llvm/test/MC/RISCV/bigendian-data-directives.s b/llvm/test/MC/RISCV/bigendian-data-directives.s new file mode 100644 index 0000000000000..54dd9211e2b64 --- /dev/null +++ b/llvm/test/MC/RISCV/bigendian-data-directives.s @@ -0,0 +1,36 @@ +# RUN: llvm-mc -filetype=obj -triple=riscv32be %s -o %t.32be.o +# RUN: llvm-objdump -s %t.32be.o | FileCheck -check-prefix=RV32BE %s +# RUN: llvm-mc -filetype=obj -triple=riscv64be %s -o %t.64be.o +# RUN: llvm-objdump -s %t.64be.o | FileCheck -check-prefix=RV64BE %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32le.o +# RUN: llvm-objdump -s %t.32le.o | FileCheck -check-prefix=RV32LE %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64le.o +# RUN: llvm-objdump -s %t.64le.o | FileCheck -check-prefix=RV64LE %s + +# Test that data directives are properly byte-swapped on big-endian RISC-V + +.data + +byte_data: + .byte 0x11 + .byte 0x22 + .half 0x3344 + .word 0x55667788 + .long 0x99aabbcc + .quad 0x1122334455667788 + +# RV32BE: Contents of section .data: +# RV32BE-NEXT: 0000 11223344 55667788 99aabbcc 11223344 +# RV32BE-NEXT: 0010 55667788 + +# RV64BE: Contents of section .data: +# RV64BE-NEXT: 0000 11223344 55667788 99aabbcc 11223344 +# RV64BE-NEXT: 0010 55667788 + +# RV32LE: Contents of section .data: +# RV32LE-NEXT: 0000 11224433 88776655 ccbbaa99 88776655 +# RV32LE-NEXT: 0010 44332211 + +# RV64LE: Contents of section .data: +# RV64LE-NEXT: 0000 11224433 88776655 ccbbaa99 88776655 +# RV64LE-NEXT: 0010 44332211 diff --git a/llvm/test/MC/RISCV/bigendian-fixups.s b/llvm/test/MC/RISCV/bigendian-fixups.s new file mode 100644 index 0000000000000..8c9f448e83b5e --- /dev/null +++ b/llvm/test/MC/RISCV/bigendian-fixups.s @@ -0,0 +1,60 @@ +# RUN: llvm-mc -filetype=obj -triple=riscv32be < %s \ +# RUN: | llvm-objdump --no-print-imm-hex -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INSTR %s +# RUN: llvm-mc -filetype=obj -triple=riscv32be %s \ +# RUN: | llvm-readobj -r - | FileCheck %s -check-prefix=CHECK-REL +# RUN: llvm-mc -filetype=obj -triple=riscv64be < %s \ +# RUN: | llvm-objdump --no-print-imm-hex -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INSTR %s +# RUN: llvm-mc -filetype=obj -triple=riscv64be %s \ +# RUN: | llvm-readobj -r - | FileCheck %s -check-prefix=CHECK-REL + +# Test that fixups work correctly on big-endian RISC-V targets + +.LBB0: +lui t1, %hi(val) +# CHECK-INSTR: lui t1, 74565 + +lw a0, %lo(val)(t1) +# CHECK-INSTR: lw a0, 1656(t1) +addi a1, t1, %lo(val) +# CHECK-INSTR: addi a1, t1, 1656 +sw a0, %lo(val)(t1) +# CHECK-INSTR: sw a0, 1656(t1) + +1: +auipc t1, %pcrel_hi(.LBB0) +# CHECK-INSTR: auipc t1, 0 +addi t1, t1, %pcrel_lo(1b) +# CHECK-INSTR: addi t1, t1, -16 +sw t1, %pcrel_lo(1b)(t1) +# CHECK-INSTR: sw t1, -16(t1) + +jal zero, .LBB0 +# CHECK-INSTR: jal zero, 0x0 +jal zero, .LBB2 +# CHECK-INSTR: jal zero, 0x50d14 +beq a0, a1, .LBB0 +# CHECK-INSTR: beq a0, a1, 0x0 +blt a0, a1, .LBB1 +# CHECK-INSTR: blt a0, a1, 0x47c + +.fill 1104 + +.LBB1: + +.fill 329876 +addi zero, zero, 0 +.LBB2: + +.set val, 0x12345678 + +# CHECK-REL-NOT: R_RISCV + +# Test data fixups +.data +.align 3 +data_label: + .word val + .long val + .quad val diff --git a/llvm/test/MC/RISCV/elf-bigendian.s b/llvm/test/MC/RISCV/elf-bigendian.s new file mode 100644 index 0000000000000..da12a14aea142 --- /dev/null +++ b/llvm/test/MC/RISCV/elf-bigendian.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc %s -filetype=obj -triple=riscv32be | llvm-readobj -h - \ +# RUN: | FileCheck -check-prefix=RV32BE %s +# RUN: llvm-mc %s -filetype=obj -triple=riscv64be | llvm-readobj -h - \ +# RUN: | FileCheck -check-prefix=RV64BE %s + +# Test that RISC-V big-endian targets produce correct ELF headers + +# RV32BE: Format: elf32-bigriscv +# RV32BE: Arch: riscv32 +# RV32BE: AddressSize: 32bit +# RV32BE: ElfHeader { +# RV32BE: Ident { +# RV32BE: Magic: (7F 45 4C 46) +# RV32BE: Class: 32-bit (0x1) +# RV32BE: DataEncoding: BigEndian (0x2) +# RV32BE: FileVersion: 1 +# RV32BE: OS/ABI: SystemV (0x0) +# RV32BE: ABIVersion: 0 +# RV32BE: } +# RV32BE: Type: Relocatable (0x1) +# RV32BE: Machine: EM_RISCV (0xF3) +# RV32BE: Version: 1 +# RV32BE: Flags [ (0x0) +# RV32BE: ] +# RV32BE: } + +# RV64BE: Format: elf64-bigriscv +# RV64BE: Arch: riscv64 +# RV64BE: AddressSize: 64bit +# RV64BE: ElfHeader { +# RV64BE: Ident { +# RV64BE: Magic: (7F 45 4C 46) +# RV64BE: Class: 64-bit (0x2) +# RV64BE: DataEncoding: BigEndian (0x2) +# RV64BE: FileVersion: 1 +# RV64BE: OS/ABI: SystemV (0x0) +# RV64BE: ABIVersion: 0 +# RV64BE: } +# RV64BE: Type: Relocatable (0x1) +# RV64BE: Machine: EM_RISCV (0xF3) +# RV64BE: Version: 1 +# RV64BE: Flags [ (0x0) +# RV64BE: ] +# RV64BE: } + +nop