diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2006-01-12 22:56:25 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-13 05:16:23 -0500 |
commit | e58c3495e6007af59382540bb21ee941e470d88d (patch) | |
tree | 24b559cb768bfa5cf4bdef69f2943b081a1f5afa /include/asm-powerpc | |
parent | 7e78e5e502d4f220d24c6f738f2fdb078ad33607 (diff) |
[PATCH] powerpc: Cleanup LOADADDR etc. asm macros
This patch consolidates the variety of macros used for loading 32 or
64-bit constants in assembler (LOADADDR, LOADBASE, SET_REG_TO_*). The
idea is to make the set of macros consistent across 32 and 64 bit and
to make it more obvious which is the appropriate one to use in a given
situation. The new macros and their semantics are described in the
comments in ppc_asm.h.
In the process, we change several places that were unnecessarily using
immediate loads on ppc64 to use the GOT/TOC. Likewise we cleanup a
couple of places where we were clumsily subtracting PAGE_OFFSET with
asm instructions to use assemble-time arithmetic or the toreal() macro
instead.
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r-- | include/asm-powerpc/ppc_asm.h | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 0dc798d46ea4..ab8688d39024 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h | |||
@@ -156,52 +156,56 @@ n: | |||
156 | #endif | 156 | #endif |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * LOADADDR( rn, name ) | 159 | * LOAD_REG_IMMEDIATE(rn, expr) |
160 | * loads the address of 'name' into 'rn' | 160 | * Loads the value of the constant expression 'expr' into register 'rn' |
161 | * using immediate instructions only. Use this when it's important not | ||
162 | * to reference other data (i.e. on ppc64 when the TOC pointer is not | ||
163 | * valid). | ||
161 | * | 164 | * |
162 | * LOADBASE( rn, name ) | 165 | * LOAD_REG_ADDR(rn, name) |
163 | * loads the address (possibly without the low 16 bits) of 'name' into 'rn' | 166 | * Loads the address of label 'name' into register 'rn'. Use this when |
164 | * suitable for base+disp addressing | 167 | * you don't particularly need immediate instructions only, but you need |
168 | * the whole address in one register (e.g. it's a structure address and | ||
169 | * you want to access various offsets within it). On ppc32 this is | ||
170 | * identical to LOAD_REG_IMMEDIATE. | ||
171 | * | ||
172 | * LOAD_REG_ADDRBASE(rn, name) | ||
173 | * ADDROFF(name) | ||
174 | * LOAD_REG_ADDRBASE loads part of the address of label 'name' into | ||
175 | * register 'rn'. ADDROFF(name) returns the remainder of the address as | ||
176 | * a constant expression. ADDROFF(name) is a signed expression < 16 bits | ||
177 | * in size, so is suitable for use directly as an offset in load and store | ||
178 | * instructions. Use this when loading/storing a single word or less as: | ||
179 | * LOAD_REG_ADDRBASE(rX, name) | ||
180 | * ld rY,ADDROFF(name)(rX) | ||
165 | */ | 181 | */ |
166 | #ifdef __powerpc64__ | 182 | #ifdef __powerpc64__ |
167 | #define LOADADDR(rn,name) \ | 183 | #define LOAD_REG_IMMEDIATE(reg,expr) \ |
168 | lis rn,name##@highest; \ | 184 | lis (reg),(expr)@highest; \ |
169 | ori rn,rn,name##@higher; \ | 185 | ori (reg),(reg),(expr)@higher; \ |
170 | rldicr rn,rn,32,31; \ | 186 | rldicr (reg),(reg),32,31; \ |
171 | oris rn,rn,name##@h; \ | 187 | oris (reg),(reg),(expr)@h; \ |
172 | ori rn,rn,name##@l | 188 | ori (reg),(reg),(expr)@l; |
173 | 189 | ||
174 | #define LOADBASE(rn,name) \ | 190 | #define LOAD_REG_ADDR(reg,name) \ |
175 | ld rn,name@got(r2) | 191 | ld (reg),name@got(r2) |
176 | 192 | ||
177 | #define OFF(name) 0 | 193 | #define LOAD_REG_ADDRBASE(reg,name) LOAD_REG_ADDR(reg,name) |
178 | 194 | #define ADDROFF(name) 0 | |
179 | #define SET_REG_TO_CONST(reg, value) \ | ||
180 | lis reg,(((value)>>48)&0xFFFF); \ | ||
181 | ori reg,reg,(((value)>>32)&0xFFFF); \ | ||
182 | rldicr reg,reg,32,31; \ | ||
183 | oris reg,reg,(((value)>>16)&0xFFFF); \ | ||
184 | ori reg,reg,((value)&0xFFFF); | ||
185 | |||
186 | #define SET_REG_TO_LABEL(reg, label) \ | ||
187 | lis reg,(label)@highest; \ | ||
188 | ori reg,reg,(label)@higher; \ | ||
189 | rldicr reg,reg,32,31; \ | ||
190 | oris reg,reg,(label)@h; \ | ||
191 | ori reg,reg,(label)@l; | ||
192 | 195 | ||
193 | /* offsets for stack frame layout */ | 196 | /* offsets for stack frame layout */ |
194 | #define LRSAVE 16 | 197 | #define LRSAVE 16 |
195 | 198 | ||
196 | #else /* 32-bit */ | 199 | #else /* 32-bit */ |
197 | #define LOADADDR(rn,name) \ | ||
198 | lis rn,name@ha; \ | ||
199 | addi rn,rn,name@l | ||
200 | 200 | ||
201 | #define LOADBASE(rn,name) \ | 201 | #define LOAD_REG_IMMEDIATE(reg,expr) \ |
202 | lis rn,name@ha | 202 | lis (reg),(expr)@ha; \ |
203 | addi (reg),(reg),(expr)@l; | ||
204 | |||
205 | #define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE(reg, name) | ||
203 | 206 | ||
204 | #define OFF(name) name@l | 207 | #define LOAD_REG_ADDRBASE(reg, name) lis (reg),name@ha |
208 | #define ADDROFF(name) name@l | ||
205 | 209 | ||
206 | /* offsets for stack frame layout */ | 210 | /* offsets for stack frame layout */ |
207 | #define LRSAVE 4 | 211 | #define LRSAVE 4 |