mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-20 00:52:33 +00:00
88 lines
3.4 KiB
Odin
88 lines
3.4 KiB
Odin
package rexcode_ppc_vle
|
|
|
|
// =============================================================================
|
|
// PowerPC VLE Relocations
|
|
// =============================================================================
|
|
//
|
|
// VLE-specific branch and immediate relocation forms.
|
|
//
|
|
// Branch displacements (from binutils):
|
|
// BD8 (16-bit): 8-bit signed << 1, PC-rel, ±256 bytes (se_b, se_bl)
|
|
// BD8IO (16-bit): same width, with BO/BI baked
|
|
// BD15 (32-bit): 15-bit signed << 1, PC-rel, ±32KB (e_bc, e_bcl)
|
|
// EBD15/EBD15BI (32-bit): same width, with BO/BI baked
|
|
// BD24 (32-bit): 24-bit signed << 1, PC-rel, ±16MB (e_b, e_bl)
|
|
//
|
|
// ELF relocation types (binutils elf/ppc.h R_PPC_VLE_*):
|
|
// REL8/REL15/REL24 PC-relative branches (matches BD8/BD15/BD24)
|
|
// LO16A/HI16A/HA16A 16-bit immediate halves, A-form (I16A imm position)
|
|
// LO16D/HI16D/HA16D 16-bit immediate halves, D-form (32-bit D-form)
|
|
// SDA21 21-bit small data area (e_add16i_sda variant)
|
|
// SDAREL_*16{A,D} SDA-relative variants of LO/HI/HA
|
|
// ADDR20 20-bit absolute address (LI20 form)
|
|
|
|
Relocation_Type :: enum u8 {
|
|
NONE = 0,
|
|
|
|
// Internal (encoder-resolved) branch relocations
|
|
BRANCH_BD8, // 8-bit signed << 1 at bits 7..0 of halfword
|
|
BRANCH_BD15, // 15-bit signed << 1 at bits 1..15 of low halfword
|
|
BRANCH_BD24, // 24-bit signed << 1 at bits 1..24 of word
|
|
|
|
// ELF-spec relocations (linker-bound — encoder emits them but doesn't
|
|
// resolve them locally)
|
|
R_PPC_VLE_REL8, // 216 — like BRANCH_BD8 but ELF-emitted
|
|
R_PPC_VLE_REL15, // 217
|
|
R_PPC_VLE_REL24, // 218
|
|
R_PPC_VLE_LO16A, // 219 — low 16 bits, A-form imm (I16A bit positions)
|
|
R_PPC_VLE_LO16D, // 220 — low 16 bits, D-form imm
|
|
R_PPC_VLE_HI16A, // 221 — high 16 bits, A-form
|
|
R_PPC_VLE_HI16D, // 222 — high 16 bits, D-form
|
|
R_PPC_VLE_HA16A, // 223 — high-adjusted 16 bits, A-form
|
|
R_PPC_VLE_HA16D, // 224 — high-adjusted 16 bits, D-form
|
|
R_PPC_VLE_SDA21, // 225 — 21-bit small-data-area
|
|
R_PPC_VLE_SDA21_LO, // 226 — like SDA21 but no overflow check
|
|
R_PPC_VLE_SDAREL_LO16A, // 227
|
|
R_PPC_VLE_SDAREL_LO16D, // 228
|
|
R_PPC_VLE_SDAREL_HI16A, // 229
|
|
R_PPC_VLE_SDAREL_HI16D, // 230
|
|
R_PPC_VLE_SDAREL_HA16A, // 231
|
|
R_PPC_VLE_SDAREL_HA16D, // 232
|
|
R_PPC_VLE_ADDR20, // 233 — 20-bit absolute (LI20)
|
|
}
|
|
|
|
// Mapping table — each VLE reloc's official ELF number.
|
|
elf_reloc_number :: proc(t: Relocation_Type) -> u32 {
|
|
#partial switch t {
|
|
case .R_PPC_VLE_REL8: return 216
|
|
case .R_PPC_VLE_REL15: return 217
|
|
case .R_PPC_VLE_REL24: return 218
|
|
case .R_PPC_VLE_LO16A: return 219
|
|
case .R_PPC_VLE_LO16D: return 220
|
|
case .R_PPC_VLE_HI16A: return 221
|
|
case .R_PPC_VLE_HI16D: return 222
|
|
case .R_PPC_VLE_HA16A: return 223
|
|
case .R_PPC_VLE_HA16D: return 224
|
|
case .R_PPC_VLE_SDA21: return 225
|
|
case .R_PPC_VLE_SDA21_LO: return 226
|
|
case .R_PPC_VLE_SDAREL_LO16A: return 227
|
|
case .R_PPC_VLE_SDAREL_LO16D: return 228
|
|
case .R_PPC_VLE_SDAREL_HI16A: return 229
|
|
case .R_PPC_VLE_SDAREL_HI16D: return 230
|
|
case .R_PPC_VLE_SDAREL_HA16A: return 231
|
|
case .R_PPC_VLE_SDAREL_HA16D: return 232
|
|
case .R_PPC_VLE_ADDR20: return 233
|
|
}
|
|
return 0
|
|
}
|
|
|
|
Relocation :: struct #packed {
|
|
offset: u32,
|
|
label_id: u32,
|
|
addend: i32,
|
|
type: Relocation_Type,
|
|
size: u8,
|
|
inst_idx: u16,
|
|
}
|
|
#assert(size_of(Relocation) == 16)
|