[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>
This commit is contained in:

committed by
Paul Mackerras

parent
7e78e5e502
commit
e58c3495e6
@@ -156,52 +156,56 @@ n:
|
||||
#endif
|
||||
|
||||
/*
|
||||
* LOADADDR( rn, name )
|
||||
* loads the address of 'name' into 'rn'
|
||||
* LOAD_REG_IMMEDIATE(rn, expr)
|
||||
* Loads the value of the constant expression 'expr' into register 'rn'
|
||||
* using immediate instructions only. Use this when it's important not
|
||||
* to reference other data (i.e. on ppc64 when the TOC pointer is not
|
||||
* valid).
|
||||
*
|
||||
* LOADBASE( rn, name )
|
||||
* loads the address (possibly without the low 16 bits) of 'name' into 'rn'
|
||||
* suitable for base+disp addressing
|
||||
* LOAD_REG_ADDR(rn, name)
|
||||
* Loads the address of label 'name' into register 'rn'. Use this when
|
||||
* you don't particularly need immediate instructions only, but you need
|
||||
* the whole address in one register (e.g. it's a structure address and
|
||||
* you want to access various offsets within it). On ppc32 this is
|
||||
* identical to LOAD_REG_IMMEDIATE.
|
||||
*
|
||||
* LOAD_REG_ADDRBASE(rn, name)
|
||||
* ADDROFF(name)
|
||||
* LOAD_REG_ADDRBASE loads part of the address of label 'name' into
|
||||
* register 'rn'. ADDROFF(name) returns the remainder of the address as
|
||||
* a constant expression. ADDROFF(name) is a signed expression < 16 bits
|
||||
* in size, so is suitable for use directly as an offset in load and store
|
||||
* instructions. Use this when loading/storing a single word or less as:
|
||||
* LOAD_REG_ADDRBASE(rX, name)
|
||||
* ld rY,ADDROFF(name)(rX)
|
||||
*/
|
||||
#ifdef __powerpc64__
|
||||
#define LOADADDR(rn,name) \
|
||||
lis rn,name##@highest; \
|
||||
ori rn,rn,name##@higher; \
|
||||
rldicr rn,rn,32,31; \
|
||||
oris rn,rn,name##@h; \
|
||||
ori rn,rn,name##@l
|
||||
#define LOAD_REG_IMMEDIATE(reg,expr) \
|
||||
lis (reg),(expr)@highest; \
|
||||
ori (reg),(reg),(expr)@higher; \
|
||||
rldicr (reg),(reg),32,31; \
|
||||
oris (reg),(reg),(expr)@h; \
|
||||
ori (reg),(reg),(expr)@l;
|
||||
|
||||
#define LOADBASE(rn,name) \
|
||||
ld rn,name@got(r2)
|
||||
#define LOAD_REG_ADDR(reg,name) \
|
||||
ld (reg),name@got(r2)
|
||||
|
||||
#define OFF(name) 0
|
||||
|
||||
#define SET_REG_TO_CONST(reg, value) \
|
||||
lis reg,(((value)>>48)&0xFFFF); \
|
||||
ori reg,reg,(((value)>>32)&0xFFFF); \
|
||||
rldicr reg,reg,32,31; \
|
||||
oris reg,reg,(((value)>>16)&0xFFFF); \
|
||||
ori reg,reg,((value)&0xFFFF);
|
||||
|
||||
#define SET_REG_TO_LABEL(reg, label) \
|
||||
lis reg,(label)@highest; \
|
||||
ori reg,reg,(label)@higher; \
|
||||
rldicr reg,reg,32,31; \
|
||||
oris reg,reg,(label)@h; \
|
||||
ori reg,reg,(label)@l;
|
||||
#define LOAD_REG_ADDRBASE(reg,name) LOAD_REG_ADDR(reg,name)
|
||||
#define ADDROFF(name) 0
|
||||
|
||||
/* offsets for stack frame layout */
|
||||
#define LRSAVE 16
|
||||
|
||||
#else /* 32-bit */
|
||||
#define LOADADDR(rn,name) \
|
||||
lis rn,name@ha; \
|
||||
addi rn,rn,name@l
|
||||
|
||||
#define LOADBASE(rn,name) \
|
||||
lis rn,name@ha
|
||||
#define LOAD_REG_IMMEDIATE(reg,expr) \
|
||||
lis (reg),(expr)@ha; \
|
||||
addi (reg),(reg),(expr)@l;
|
||||
|
||||
#define OFF(name) name@l
|
||||
#define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE(reg, name)
|
||||
|
||||
#define LOAD_REG_ADDRBASE(reg, name) lis (reg),name@ha
|
||||
#define ADDROFF(name) name@l
|
||||
|
||||
/* offsets for stack frame layout */
|
||||
#define LRSAVE 4
|
||||
|
Reference in New Issue
Block a user