Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[linux-2.6-microblaze.git] / arch / arm / include / asm / assembler.h
index feac2c8..6ed3042 100644 (file)
  */
 #define ALT_UP(instr...)                                       \
        .pushsection ".alt.smp.init", "a"                       ;\
-       .long   9998b                                           ;\
+       .long   9998b - .                                       ;\
 9997:  instr                                                   ;\
        .if . - 9997b == 2                                      ;\
                nop                                             ;\
        .popsection
 #define ALT_UP_B(label)                                        \
        .pushsection ".alt.smp.init", "a"                       ;\
-       .long   9998b                                           ;\
+       .long   9998b - .                                       ;\
        W(b)    . + (label - 9998b)                                     ;\
        .popsection
 #else
@@ -494,4 +494,88 @@ THUMB(     orr     \reg , \reg , #PSR_T_BIT        )
 #define _ASM_NOKPROBE(entry)
 #endif
 
+       .macro          __adldst_l, op, reg, sym, tmp, c
+       .if             __LINUX_ARM_ARCH__ < 7
+       ldr\c           \tmp, .La\@
+       .subsection     1
+       .align          2
+.La\@: .long           \sym - .Lpc\@
+       .previous
+       .else
+       .ifnb           \c
+ THUMB(        ittt            \c                      )
+       .endif
+       movw\c          \tmp, #:lower16:\sym - .Lpc\@
+       movt\c          \tmp, #:upper16:\sym - .Lpc\@
+       .endif
+
+#ifndef CONFIG_THUMB2_KERNEL
+       .set            .Lpc\@, . + 8                   // PC bias
+       .ifc            \op, add
+       add\c           \reg, \tmp, pc
+       .else
+       \op\c           \reg, [pc, \tmp]
+       .endif
+#else
+.Lb\@: add\c           \tmp, \tmp, pc
+       /*
+        * In Thumb-2 builds, the PC bias depends on whether we are currently
+        * emitting into a .arm or a .thumb section. The size of the add opcode
+        * above will be 2 bytes when emitting in Thumb mode and 4 bytes when
+        * emitting in ARM mode, so let's use this to account for the bias.
+        */
+       .set            .Lpc\@, . + (. - .Lb\@)
+
+       .ifnc           \op, add
+       \op\c           \reg, [\tmp]
+       .endif
+#endif
+       .endm
+
+       /*
+        * mov_l - move a constant value or [relocated] address into a register
+        */
+       .macro          mov_l, dst:req, imm:req
+       .if             __LINUX_ARM_ARCH__ < 7
+       ldr             \dst, =\imm
+       .else
+       movw            \dst, #:lower16:\imm
+       movt            \dst, #:upper16:\imm
+       .endif
+       .endm
+
+       /*
+        * adr_l - adr pseudo-op with unlimited range
+        *
+        * @dst: destination register
+        * @sym: name of the symbol
+        * @cond: conditional opcode suffix
+        */
+       .macro          adr_l, dst:req, sym:req, cond
+       __adldst_l      add, \dst, \sym, \dst, \cond
+       .endm
+
+       /*
+        * ldr_l - ldr <literal> pseudo-op with unlimited range
+        *
+        * @dst: destination register
+        * @sym: name of the symbol
+        * @cond: conditional opcode suffix
+        */
+       .macro          ldr_l, dst:req, sym:req, cond
+       __adldst_l      ldr, \dst, \sym, \dst, \cond
+       .endm
+
+       /*
+        * str_l - str <literal> pseudo-op with unlimited range
+        *
+        * @src: source register
+        * @sym: name of the symbol
+        * @tmp: mandatory scratch register
+        * @cond: conditional opcode suffix
+        */
+       .macro          str_l, src:req, sym:req, tmp:req, cond
+       __adldst_l      str, \src, \sym, \tmp, \cond
+       .endm
+
 #endif /* __ASM_ASSEMBLER_H__ */