• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Immediate Range Limits in VIXL
2==============================
3
4VIXL's macro assembler tries to increase the range of branches and literal loads
5automatically for you, but applications must still be aware of these extended
6limits, and stay within them, in order to ensure valid code is generated.
7
8In debug builds, assertions prevent exceeding these limits at run time. In
9release builds, for performance reasons, the application is responsible for
10staying within the limits.
11
12You should decide what corrections should be applied in your application if it
13exceeds these limits.
14
15Terms
16-----
17
18**Bind** assigning an address to a label such that the instructions that refer
19to the label can be assigned PC-relative offsets.
20
21**Forward** a forward branch or load literal will refer to a location that will
22be bound later in code generation, ie. at a higher address.
23
24**Backward** a backward branch or load literal refers to a location that has
25already been bound earlier in code generation, ie. at a lower address.
26
27**Instruction range** the range of values that can be encoded in the instruction
28to be generated. Outside the instruction range, additional instructions may be
29generated to increase the range, branching further than would be possible in
30one instruction, for example.
31
32**Veneer** a sequence of additional instructions produced to increase the
33instruction range.
34
35**Adjusted PC** the PC including its architecturally-defined offset. In AArch32
36T32, this is the current PC plus four bytes. In AArch64, there is no adjustment;
37Adjusted PC is equal to PC.
38
39AArch64
40-------
41
42### Branches
43
44All instructions and targets must be aligned to the instruction size, four
45bytes.
46
47#### Unconditional immediate branches (`B`)
48
49* Unconditional immediate branches have an instruction range of -134,217,728 to
50+134,217,724 bytes from the current PC.
51* No veneers are applied to unconditional immediate branches to extend their
52instruction range.
53* Callers can use the function `IsValidImmPCOffset(UncondBranchType, offset)` to
54check `offset` (in units of instruction) is within the instruction range.
55
56#### Conditional branches (`B.cond`) and compare-and-branch (`CBZ`, `CBNZ`)
57
58* Conditional branch and compare-and-branch instructions have the same
59instruction range.
60* The instruction range is -1,048,576 to +1,048,574 bytes from the current PC.
61* Veneers are applied to extend the range to -134,217,724 to +135,266,298 bytes
62from the current PC.
63  * Unconditional branch range minus one instruction backwards.
64  * Unconditional branch range plus conditional branch range forwards.
65* Callers can use the functions `IsValidImmPCOffset(CondBranchType, offset)` and
66`IsValidImmPCOffset(CompareBranchType, offset)` to check `offset` (in units of
67instruction) is within the instruction range.
68
69#### Test-and-branch (`TBZ`, `TBNZ`)
70
71* Test-and-branch instructions have an instruction range of -32,768 to 32,764
72bytes from the current PC.
73* Veneers are applied to extend the range to -134,217,728 to +135,299,062 bytes
74from the current PC.
75  * Unconditional branch range minus one instruction backwards.
76  * Unconditional branch range plus test-and-branch range forwards.
77* Callers can use the function `IsValidImmPCOffset(TestBranchType, offset)` to
78check `offset` (in units of instruction) is within the instruction range.
79
80### Literals
81
82#### Compute PC-relative address (`ADR`)
83
84* Compute PC-relative address instructions have an instruction range of
85-1,048,576 to +1,048,575 bytes from the current PC.
86* No veneers are applied to extend the instruction range.
87* Callers can use `IsInt21(offset)` to check `offset` (in bytes) is within the
88instruction range.
89
90#### Load from PC-relative address (`LDR`)
91
92* Load from PC-relative address instructions have an instruction range of
93-1,048,576 to +1,048,572 bytes from the current PC. The offset must be four-byte
94aligned.
95* Automatically-placed literals (eg. those created by `Ldr(reg, literal_value)`)
96will be emitted into code such that they are in range of the instructions that
97refer to them.
98* Veneers are not applied to manually-placed literals, ie. those created by
99`Literal<T> x(value)` and emitted by `place()`.
100* Callers can use `IsInt19(offset)` to check `offset` (in units of instruction)
101is within the instruction range.
102
103AArch32
104-------
105
106Limits stated in this section relate to the T32 instruction encodings only.
107
108### Branches
109
110#### Unconditional immediate branches (`B`)
111
112* Unconditional immediate branches have an instruction range of -16,777,216 to
113+16,777,214 bytes from the current adjusted PC.
114* Veneers are applied to forward branches to extend them to an unlimited range.
115* No veneers are applied to backward branches.
116
117#### Conditional immediate branches (`B`)
118
119* Conditional immediate branches have an instruction range of -1,048,576 to
120+1,048,574 bytes from the current adjusted PC.
121* Veneers are applied to forward branches to extend them to an unlimited range.
122* Veneers are applied to backward branches to extend the range to that of
123unconditional immediate branches, -16,777,216 bytes from the current adjusted
124PC.
125
126#### Compare and branch (`CBZ`, `CBNZ`)
127
128* Compare and branch has an instruction range of 0 to +126 bytes from the
129current adjusted PC.
130* Veneers are applied to forward branches to extend them to an unlimited range.
131* Veneers are applied to backward branches to extend the range to that of
132unconditional immediate branches, -16,777,216 bytes from the current adjusted
133PC.
134
135### Literals
136
137#### Compute/load PC-relative address (`ADR`, `LDR`)
138
139* Compute and load PC-relative address instructions have the same instruction
140range.
141* The instruction range is -4,095 to +4,095 bytes from the current adjusted PC.
142The PC is aligned down to a four-byte boundary before the offset is added.
143* Automatically-placed literals (ie. those created by `Literal<T> x(value)`)
144will be emitted into code such that they are in range of the instructions that
145refer to them.
146* Veneers are not applied to manually-placed literals, ie. those created by
147`Literal<T> x(value, RawLiteral::kManuallyPlaced)` and emitted by `Place()`.
148
149