-
-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Assembler] Add %pcrel_hi16 and %pcrel_lo16 MIPS relocations
Return the 16 MSB and 16 LSB
- Loading branch information
1 parent
6082d75
commit 8c56c93
Showing
1 changed file
with
70 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#pragma once | ||
|
||
#include "QDebug" | ||
#include "VSRTL/interface/vsrtl_binutils.h" | ||
#include "relocation.h" | ||
|
||
namespace Ripes { | ||
namespace Assembler { | ||
|
||
// pcrel_lo/hi are restricted to 32-bit absolute addresses, so keep computations | ||
// in this base. | ||
inline uint32_t pcrel_hi16(const uint32_t val, const uint32_t reloc_addr) { | ||
return ((val - (reloc_addr % 0xFFFFF000) + 0x800) >> 16); | ||
} | ||
|
||
template <typename Reg_T> | ||
Relocation<Reg_T> mips_pcrel_hi() { | ||
return Relocation<Reg_T>("%pcrel_hi16", | ||
[](const Reg_T val, const Reg_T reloc_addr) | ||
-> HandleRelocationRes<Reg_T> { | ||
const uint32_t _hi16 = pcrel_hi16(val, reloc_addr); | ||
return {_hi16}; | ||
}); | ||
} | ||
|
||
template <typename Reg_T> | ||
Relocation<Reg_T> mips_pcrel_lo() { | ||
return Relocation<Reg_T>( | ||
"%pcrel_lo16", | ||
[](const Reg_T val, | ||
const Reg_T reloc_addr) -> HandleRelocationRes<Reg_T> { | ||
using Reg_T_S = typename std::make_signed<Reg_T>::type; | ||
const uint32_t _hi16 = pcrel_hi16(val, reloc_addr); | ||
const uint32_t lo16 = val & 0x0000FFF; | ||
return {static_cast<Reg_T>( | ||
static_cast<Reg_T_S>(vsrtl::signextend(lo16, 16)))}; | ||
}); | ||
} | ||
|
||
template <typename Reg_T> | ||
Relocation<Reg_T> mips_hi() { | ||
return Relocation<Reg_T>( | ||
"%hi", | ||
[](const Reg_T val, const Reg_T /*reloc_addr*/) | ||
-> HandleRelocationRes<Reg_T> { return {val >> 16 & 0xFFFFFF}; }); | ||
} | ||
|
||
template <typename Reg_T> | ||
Relocation<Reg_T> mips_lo() { | ||
return Relocation<Reg_T>( | ||
"%lo", | ||
[](const Reg_T val, const Reg_T /*reloc_addr*/) | ||
-> HandleRelocationRes<Reg_T> { return {val & 0xFFF}; }); | ||
} | ||
|
||
template <typename Reg_T> | ||
RelocationsVec<Reg_T> mipsRelocations() { | ||
RelocationsVec<Reg_T> relocations; | ||
|
||
relocations.push_back( | ||
std::make_shared<Relocation<Reg_T>>(mips_pcrel_hi<Reg_T>())); | ||
relocations.push_back( | ||
std::make_shared<Relocation<Reg_T>>(mips_pcrel_lo<Reg_T>())); | ||
relocations.push_back(std::make_shared<Relocation<Reg_T>>(mips_hi<Reg_T>())); | ||
relocations.push_back(std::make_shared<Relocation<Reg_T>>(mips_lo<Reg_T>())); | ||
|
||
return relocations; | ||
} | ||
} // namespace Assembler | ||
} // namespace Ripes |