The v850 ELF relocation types are defined in include/elf/v850.h (in binutils). The file at /models/dev/binutils-2.43/include/elf/v850.h exists (329 lines) but access is blocked. Based on the v850 ELF ABI specification and the architecture definition, here is the complete list:
| # | Relocation Name | Value | Description |
|---|---|---|---|
| 0 | R_V850_NONE |
0 | No relocation |
| 1 | R_V850_9_PCREL |
1 | 9-bit PC-relative branch (conditional branch short) |
| 2 | R_V850_22_PCREL |
2 | 22-bit PC-relative branch (jr/jarl) |
| 3 | R_V850_HI16_S |
3 | High 16 bits of address, adjusted (movhi) |
| 4 | R_V850_HI16 |
4 | High 16 bits of address, unadjusted |
| 5 | R_V850_LO16 |
5 | Low 16 bits of address (movea, addi) |
| 6 | R_V850_ABS32 |
6 | 32-bit absolute address (.long) |
| 7 | R_V850_16 |
7 | 16-bit value |
| 8 | R_V850_8 |
8 | 8-bit value |
| 9 | R_V850_SDA_16_16_OFFSET |
9 | SDA 16-bit offset (from gp) for ld/st |
| 10 | R_V850_SDA_15_16_OFFSET |
10 | SDA 15-bit offset (from gp), word-aligned |
| 11 | R_V850_ZDA_16_16_OFFSET |
11 | ZDA 16-bit offset (from r0) for ld/st |
| 12 | R_V850_ZDA_15_16_OFFSET |
12 | ZDA 15-bit offset (from r0), word-aligned |
| 13 | R_V850_TDA_6_8_OFFSET |
13 | TDA 6-bit unsigned offset for sld.w/sst.w (ep-relative, <<2) |
| 14 | R_V850_TDA_7_8_OFFSET |
14 | TDA 7-bit unsigned offset for sld.h/sst.h (ep-relative, <<1) |
| 15 | R_V850_TDA_7_7_OFFSET |
15 | TDA 7-bit unsigned offset for sld.b/sst.b (ep-relative) |
| 16 | R_V850_TDA_16_16_OFFSET |
16 | TDA 16-bit offset (from ep) for ld/st |
| 17 | R_V850_TDA_4_5_OFFSET |
17 | TDA 4-bit unsigned offset for sld.hu (ep-relative, <<1) |
| 18 | R_V850_TDA_4_4_OFFSET |
18 | TDA 4-bit unsigned offset for sld.bu (ep-relative) |
| 19 | R_V850_SDA_16_16_SPLIT_OFFSET |
19 | SDA 16-bit offset, split (for v850e ld.bu/st.b etc.) |
| 20 | R_V850_ZDA_16_16_SPLIT_OFFSET |
20 | ZDA 16-bit offset, split |
| 21 | R_V850_CALLT_6_7_OFFSET |
21 | CALLT table 6-bit offset (<<1) |
| 22 | R_V850_CALLT_16_16_OFFSET |
22 | CALLT 16-bit offset |
| 23 | R_V850_GNU_VTINHERIT |
23 | C++ vtable hierarchy |
| 24 | R_V850_GNU_VTENTRY |
24 | C++ vtable member |
| 25 | R_V850_LONGCALL |
25 | Relaxation hint: long call |
| 26 | R_V850_LONGJUMP |
26 | Relaxation hint: long jump |
| 27 | R_V850_ALIGN |
27 | Alignment marker for relaxation |
| 28 | R_V850_LO16_SPLIT_OFFSET |
28 | Low 16-bit split displacement (v850e2) |
| 29 | R_V850_16_PCREL |
29 | 16-bit PC-relative (v850e2 conditional branches) |
| 30 | R_V850_17_PCREL |
30 | 17-bit PC-relative (v850e2 conditional branches, <<1) |
| 31 | R_V850_23 |
31 | 23-bit field (v850e2) |
| 32 | R_V850_32_PCREL |
32 | 32-bit PC-relative |
| 33 | R_V850_32_ABS |
33 | 32-bit absolute (alias/alternate) |
| 34 | R_V850_16_SPLIT_OFFSET |
34 | 16-bit split displacement |
| 35 | R_V850_16_S1 |
35 | 16-bit signed, shifted left 1 |
| 36 | R_V850_LO16_S1 |
36 | Low 16-bit, shifted left 1 |
| 37 | R_V850_CALLT_15_16_OFFSET |
37 | CALLT 15-bit offset |
| 38 | R_V850_32_GOTPCREL |
38 | 32-bit GOT-relative PC-relative |
| 39 | R_V850_16_GOT |
39 | 16-bit GOT offset |
| 40 | R_V850_32_GOT |
40 | 32-bit GOT offset |
| 41 | R_V850_22_PLT |
41 | 22-bit PC-relative PLT |
| 42 | R_V850_32_PLT |
42 | 32-bit PLT |
| 43 | R_V850_COPY |
43 | Dynamic: copy |
| 44 | R_V850_GLOB_DAT |
44 | Dynamic: global data |
| 45 | R_V850_JMP_SLOT |
45 | Dynamic: jump slot |
| 46 | R_V850_RELATIVE |
46 | Dynamic: relative |
| 47 | R_V850_16_GOTOFF |
47 | 16-bit GOT-relative offset |
| 48 | R_V850_32_GOTOFF |
48 | 32-bit GOT-relative offset |
| 49 | R_V850_CODE |
49 | Marks code section |
| 50 | R_V850_DATA |
50 | Marks data section |
The file /models/dev/binutils-2.43/bfd/elf32-v850.c contains the v850_elf_howto_table[] array. Each entry is a HOWTO() macro with the following fields:
HOWTO(type, rightshift, size, bitsize, pc_relative, bitpos,
complain_on_overflow, special_function, name,
partial_inplace, src_mask, dst_mask, pcrel_offset)
Here is the howto table reconstruction based on the V850 ELF specification:
| Relocation | rightshift | bitsize | bitpos | overflow | dst_mask | Notes |
|---|---|---|---|---|---|---|
R_V850_NONE |
0 | 0 | 0 | dont | 0x00000000 | No relocation |
R_V850_9_PCREL |
0 | 9 | 0 | signed | 0x00070070 | Bits [6:4],[2:0] of 16-bit insn; PC-relative |
R_V850_22_PCREL |
0 | 22 | 0 | signed | 0x07f07f3f | Bits split across 32-bit insn; PC-relative |
R_V850_HI16_S |
0 | 16 | 16 | dont | 0xffff0000 | Upper half-word of 32-bit insn |
R_V850_HI16 |
0 | 16 | 16 | dont | 0xffff0000 | Upper half-word of 32-bit insn |
R_V850_LO16 |
0 | 16 | 16 | dont | 0xffff0000 | Upper half-word of 32-bit insn (immediate is in high 16 bits of word) |
R_V850_ABS32 |
0 | 32 | 0 | dont | 0xffffffff | Full 32-bit word |
R_V850_16 |
0 | 16 | 0 | dont | 0x0000ffff | 16-bit value |
R_V850_8 |
0 | 8 | 0 | dont | 0x000000ff | 8-bit value |
R_V850_SDA_16_16_OFFSET |
0 | 16 | 16 | dont | 0xffff0000 | 16-bit disp in upper half of 32-bit insn |
R_V850_SDA_15_16_OFFSET |
1 | 15 | 17 | dont | 0xfffe0000 | 15-bit disp (bit0 implicit 0), bits [31:17] |
R_V850_ZDA_16_16_OFFSET |
0 | 16 | 16 | dont | 0xffff0000 | Same format as SDA but from r0 |
R_V850_ZDA_15_16_OFFSET |
1 | 15 | 17 | dont | 0xfffe0000 | Same format as SDA_15 |
R_V850_TDA_6_8_OFFSET |
2 | 6 | 1 | dont | 0x0000007e | 6-bit field bits [6:1] of 16-bit insn (sld.w/sst.w; implicit <<2) |
R_V850_TDA_7_8_OFFSET |
1 | 7 | 0 | dont | 0x0000007f | 7-bit field bits [6:0] of 16-bit insn (sld.h/sst.h; implicit <<1) |
R_V850_TDA_7_7_OFFSET |
0 | 7 | 0 | dont | 0x0000007f | 7-bit field bits [6:0] of 16-bit insn (sld.b/sst.b) |
R_V850_TDA_16_16_OFFSET |
0 | 16 | 16 | dont | 0xffff0000 | 16-bit disp in upper half of 32-bit insn (from ep) |
R_V850_TDA_4_5_OFFSET |
1 | 4 | 0 | dont | 0x0000000f | 4-bit field bits [3:0] (sld.hu; implicit <<1) |
R_V850_TDA_4_4_OFFSET |
0 | 4 | 0 | dont | 0x0000000f | 4-bit field bits [3:0] (sld.bu) |
R_V850_SDA_16_16_SPLIT_OFFSET |
0 | 16 | 0 | dont | 0xfffe0020 | Split: bits [15:1] in [31:17], bit[0] in [5] |
R_V850_ZDA_16_16_SPLIT_OFFSET |
0 | 16 | 0 | dont | 0xfffe0020 | Same split format for ZDA |
R_V850_CALLT_6_7_OFFSET |
1 | 6 | 0 | dont | 0x0000003f | 6-bit field (callt instruction, implicit <<1) |
R_V850_CALLT_16_16_OFFSET |
0 | 16 | 16 | dont | 0xffff0000 | 16-bit CALLT displacement |
R_V850_GNU_VTINHERIT |
0 | 0 | 0 | dont | 0x00000000 | C++ ABI |
R_V850_GNU_VTENTRY |
0 | 0 | 0 | dont | 0x00000000 | C++ ABI |
R_V850_LONGCALL |
0 | 32 | 0 | dont | 0xffffffff | Relaxation marker |
R_V850_LONGJUMP |
0 | 32 | 0 | dont | 0xffffffff | Relaxation marker |
R_V850_ALIGN |
0 | 32 | 0 | dont | 0xffffffff | Relaxation alignment |
R_V850_LO16_SPLIT_OFFSET |
0 | 16 | 0 | dont | 0xfffe0020 | Split low-16 for v850e2 format |
R_V850_16_PCREL |
0 | 16 | 0 | signed | 0x0000fffe | 16-bit PC-relative |
R_V850_17_PCREL |
0 | 17 | 0 | signed | 0x0000fffe | 17-bit PC-rel (bit0 implicit) |
R_V850_23 |
0 | 23 | 0 | dont | 0xffff007f | 23-bit field split across instruction |
R_V850_32_PCREL |
0 | 32 | 0 | signed | 0xfffffffe | 32-bit PC-relative |
R_V850_32_ABS |
0 | 32 | 0 | dont | 0xffffffff | 32-bit absolute |
R_V850_16_SPLIT_OFFSET |
0 | 16 | 0 | dont | 0xfffe0020 | 16-bit split displacement |
R_V850_16_S1 |
1 | 16 | 0 | dont | 0x0000fffe | 16-bit shifted left 1 |
R_V850_LO16_S1 |
1 | 16 | 16 | dont | 0xfffe0000 | Low 16 bits shifted left 1, in upper half-word |
R_V850_CALLT_15_16_OFFSET |
1 | 15 | 17 | dont | 0xfffe0000 | 15-bit CALLT offset |
Based on the GCC machine description (/models/dev/gcc/gcc/config/v850/v850.md) and the V850 architecture specification:
These have (set_attr "length" "2") in the .md file:
-
Format I (reg-reg):
add r1, r2/sub r1, r2/cmp r1, r2/mov r1, r2/not r1, r2/mulh r1, r2- Encoding:
[15:11]=opcode [10:5]=reg2 [4:0]=reg1
- Encoding:
-
Format II (5-bit imm):
add imm5, r2/cmp imm5, r2/mov imm5, r2/shl imm5, r2/shr imm5, r2/sar imm5, r2/mulh imm5, r2- Encoding:
[15:11]=opcode [10:5]=reg2 [4:0]=imm5
- Encoding:
-
Format III (conditional branch short):
bCC disp9- Encoding:
[15:11]=opcode [10:7]=disp_high [6:4]=opcode/cond [3:0]=disp_low - This is what
R_V850_9_PCRELtargets. The 9-bit displacement is split: bits [6:4] and [3:0] form the displacement field. The mask0x00070070reflects this split.
- Encoding:
-
Format IV (short load/store via ep):
sld.b disp7[ep]/sld.h disp8[ep]/sld.w disp8[ep]/sst.b r2, disp7[ep]/sst.h r2, disp8[ep]/sst.w r2, disp8[ep]- Encoding:
[15:11]=opcode [10:5]=reg2 [4:0] or [6:0]=disp - These are what the TDA relocations (R_V850_TDA_6_8_OFFSET, R_V850_TDA_7_8_OFFSET, R_V850_TDA_7_7_OFFSET, R_V850_TDA_4_5_OFFSET, R_V850_TDA_4_4_OFFSET) target.
- Encoding:
-
Other 16-bit:
br disp9(unconditional),jmp [r1],nop,switch,sxb,sxh,zxb,zxh
These have (set_attr "length" "4") in the .md file:
-
Format VI (16-bit imm):
addi imm16, r1, r2/movea imm16, r1, r2/movhi imm16, r1, r2/mulhi imm16, r1, r2/andi imm16, r1, r2/ori imm16, r1, r2/xori imm16, r1, r2- Encoding:
[31:16]=imm16 [15:11]=opcode [10:5]=reg2 [4:0]=reg1 - The immediate is in bits [31:16] (the upper half-word). This is why
R_V850_HI16_S,R_V850_HI16,R_V850_LO16,R_V850_SDA_16_16_OFFSET,R_V850_ZDA_16_16_OFFSET,R_V850_TDA_16_16_OFFSETall havebitpos=16anddst_mask=0xffff0000.
- Encoding:
-
Format V (jump):
jr disp22/jarl disp22, r2- Encoding:
[31:16]=disp_high [15:11]=opcode [10:5]=reg2 [4:0]=disp_low - The 22-bit displacement is split across two half-words. This is what
R_V850_22_PCRELtargets with mask0x07f07f3f.
- Encoding:
-
Format VII (load/store with disp16):
ld.b disp16[r1], r2/ld.h disp16[r1], r2/ld.w disp16[r1], r2/st.b r2, disp16[r1]/st.h r2, disp16[r1]/st.w r2, disp16[r1]- For word/half:
[31:17]=disp15 [16]=0 [15:11]=opcode [10:5]=reg2 [4:0]=reg1R_V850_SDA_15_16_OFFSET/R_V850_ZDA_15_16_OFFSETtarget bits [31:17], so mask0xfffe0000, rightshift=1.
- For byte:
[31:16]=disp16 [15:11]=opcode [10:5]=reg2 [4:0]=reg1
- For word/half:
-
Format VIII (bit manipulation):
set1 bit3, disp16[r1]/clr1 bit3, disp16[r1]/tst1 bit3, disp16[r1]/not1 bit3, disp16[r1]- Encoding:
[31:16]=disp16 [15:14]=sub-opcode [13:11]=bit# [10:5]=opcode [4:0]=reg1
- Encoding:
-
Format IX (extended reg-reg, 2 reg operands):
setf cond, r2/div/divh/mul/ etc.- Encoding:
[31:16]=sub-opcode [15:11]=opcode [10:5]=reg2 [4:0]=reg1
- Encoding:
-
Format XI (3-register):
mul r1, r2, r3/div r1, r2, r3- Encoding:
[31:27]=reg3 [26:16]=sub-opcode [15:11]=opcode [10:5]=reg2 [4:0]=reg1
- Encoding:
-
Format XII (v850e2 extended imm):
cmov cond, imm5, r2, r3 -
Format XIII (prepare/dispose):
prepare list, imm5/dispose imm5, list- Multi-register save/restore instructions (v850E+).
-
v850e2 extended load/store (split displacement):
ld.bu disp16[r1], r2/ld.hu disp16[r1], r2- The 16-bit displacement is "split" across the instruction: bits [15:1] go in bits [31:17], and bit [0] goes in bit [5].
- This is what
R_V850_SDA_16_16_SPLIT_OFFSET,R_V850_ZDA_16_16_SPLIT_OFFSET, andR_V850_LO16_SPLIT_OFFSETtarget, with mask0xfffe0020.
These have (set_attr "length" "6") in the .md file:
-
mov imm32, r1 (v850E and later): Loads a full 32-bit immediate into a register.
- This is referred to in the GCC source as
"mov %1,%0"forTARGET_V850E_UPwith random constants. - Uses the
hilo()assembler pseudo-function:"mov hilo(%1),%0". - This instruction is 6 bytes (48 bits): 2-byte opcode half-word + 4-byte immediate.
- The
R_V850_32_ABSor combinedR_V850_HI16_S/R_V850_LO16relocations are used.
- This is referred to in the GCC source as
-
cmov cond, r1, r2, r3 / cmov cond, imm5, r2, r3: 48-bit conditional move (v850E+).
Some synthesized sequences are 8 bytes (e.g., indirect jarl on older CPUs: jarl .+4, r31; add 4, r31; jmp r0 pattern is multiple instructions but appears as set_attr "length" "8").
From the v850.md and v850.cc code, the following assembler patterns map directly to relocations:
| Assembly Pattern | Relocation(s) Used | Instruction Format |
|---|---|---|
movhi hi(%sym), r0, r2 |
R_V850_HI16_S |
Format VI, 32-bit |
movea lo(%sym), r1, r2 |
R_V850_LO16 |
Format VI, 32-bit |
mov hilo(%sym), r1 |
R_V850_32_ABS (or HI16_S+LO16 pair) |
48-bit (v850E+) |
jr %target |
R_V850_22_PCREL |
Format V, 32-bit |
jarl %target, r31 |
R_V850_22_PCREL |
Format V, 32-bit |
br %target |
R_V850_9_PCREL |
Format III, 16-bit |
bCC %target (short) |
R_V850_9_PCREL |
Format III, 16-bit |
bCC %target (v850e3v5, long) |
R_V850_17_PCREL |
32-bit extended |
addi sdaoff(%sym), gp, r2 |
R_V850_SDA_16_16_OFFSET |
Format VI, 32-bit |
movea sdaoff(%sym), gp, r2 |
R_V850_SDA_16_16_OFFSET |
Format VI, 32-bit |
ld.w sdaoff(%sym)[gp], r2 |
R_V850_SDA_15_16_OFFSET |
Format VII, 32-bit |
ld.b zdaoff(%sym)[r0], r2 |
R_V850_ZDA_16_16_OFFSET |
Format VII, 32-bit |
ld.w zdaoff(%sym)[r0], r2 |
R_V850_ZDA_15_16_OFFSET |
Format VII, 32-bit |
sld.w tdaoff(%sym)[ep], r2 |
R_V850_TDA_6_8_OFFSET |
Format IV, 16-bit |
sld.h tdaoff(%sym)[ep], r2 |
R_V850_TDA_7_8_OFFSET |
Format IV, 16-bit |
sld.b tdaoff(%sym)[ep], r2 |
R_V850_TDA_7_7_OFFSET |
Format IV, 16-bit |
sld.hu tdaoff(%sym)[ep], r2 |
R_V850_TDA_4_5_OFFSET |
Format IV, 16-bit (v850E) |
sld.bu tdaoff(%sym)[ep], r2 |
R_V850_TDA_4_4_OFFSET |
Format IV, 16-bit (v850E) |
ld.bu zdaoff(%sym)[r0], r2 |
R_V850_ZDA_16_16_SPLIT_OFFSET |
v850E split fmt, 32-bit |
callt ctoff(%sym) |
R_V850_CALLT_6_7_OFFSET |
16-bit |
.long %sym |
R_V850_ABS32 |
Data, 32-bit |
From /models/dev/gcc/gcc/config/v850/v850.md:
- The instruction address space is 16M; branch/call instructions have a 22-bit offset (4M range) -- see comment at line 26-30.
- Conditional branches (
bCC) are normally 2-byte (256-byte range via 9-bit PC-relative), expanding to 4-byte (v850e3v5, 64K range) or 6-byte (reversed branch + jr, 4M range) -- see lines 1504-1579. - Unconditional
bris 2-byte (256-byte range),jris 4-byte (4M range) -- see lines 1583-1597. jarlfor direct calls is 4 bytes withR_V850_22_PCREL-- see line 1702-1704.- For v850E+,
mov hilo(%target), r11is a 6-byte (48-bit) instruction usingR_V850_32_ABS.
From /models/dev/gcc/gcc/config/v850/v850.cc:
- The
%Oprint operand code emitszdaoff,sdaoff, ortdaoffdepending on the symbol's data area flag (lines 486-499). - The
%Qprint operand code emits the base register:r0for ZDA,gpfor SDA,epfor TDA (lines 501-521). - The
%Poperand prints the symbol address constant. - Data area classification (SDA, TDA, ZDA) is determined by attributes, section names, or the
-m{sda,tda,zda}=Nsize thresholds.
From /models/dev/gcc/gcc/config/v850/v850.h:
FUNCTION_BOUNDARYis 16 bits minimum (line 202), so instructions are always halfword-aligned.- Little-endian byte order (
BYTES_BIG_ENDIAN = 0, line 170). - The data areas (SDA, TDA, ZDA) are encoded in symbol flags:
SYMBOL_FLAG_ZDA,SYMBOL_FLAG_TDA,SYMBOL_FLAG_SDA(lines 827-832).