1 /** @file
2   Macros to work around lack of Clang support for LDR register, =expr
3 
4   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5   Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
6 
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 
18 #ifndef __MACRO_IO_LIBV8_H__
19 #define __MACRO_IO_LIBV8_H__
20 
21 #define SetPrimaryStack(StackTop, GlobalSize, Tmp, Tmp1)  \
22   ands    Tmp, GlobalSize, #15        ;                   \
23   mov     Tmp1, #16                   ;                   \
24   sub     Tmp1, Tmp1, Tmp             ;                   \
25   csel    Tmp, Tmp1, Tmp, ne          ;                   \
26   add     GlobalSize, GlobalSize, Tmp ;                   \
27   sub     sp, StackTop, GlobalSize    ;                   \
28                                       ;                   \
29   mov     Tmp, sp                     ;                   \
30   mov     GlobalSize, #0x0            ;                   \
31 _SetPrimaryStackInitGlobals:          ;                   \
32   cmp     Tmp, StackTop               ;                   \
33   b.eq    _SetPrimaryStackEnd         ;                   \
34   str     GlobalSize, [Tmp], #8       ;                   \
35   b       _SetPrimaryStackInitGlobals ;                   \
36 _SetPrimaryStackEnd:
37 
38 // Initialize the Global Variable with '0'
39 #define InitializePrimaryStack(GlobalSize, Tmp1, Tmp2) \
40   and     Tmp1, GlobalSize, #15       ;             \
41   mov     Tmp2, #16                   ;             \
42   sub     Tmp2, Tmp2, Tmp1            ;             \
43   add     GlobalSize, GlobalSize, Tmp2 ;            \
44                                       ;             \
45   mov     Tmp1, sp                    ;             \
46   sub     sp, sp, GlobalSize          ;             \
47   mov     GlobalSize, #0x0            ;             \
48 _InitializePrimaryStackLoop:          ;             \
49   mov     Tmp2, sp                    ;             \
50   cmp     Tmp1, Tmp2                  ;             \
51   bls     _InitializePrimaryStackEnd  ;             \
52   str     GlobalSize, [Tmp1, #-8]!    ;             \
53   b       _InitializePrimaryStackLoop ;             \
54 _InitializePrimaryStackEnd:
55 
56 // CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1
57 // This only selects between EL1 and EL2, else we die.
58 // Provide the Macro with a safe temp xreg to use.
59 #define EL1_OR_EL2(SAFE_XREG)        \
60         mrs    SAFE_XREG, CurrentEL ;\
61         cmp    SAFE_XREG, #0x8      ;\
62         b.eq   2f                   ;\
63         cmp    SAFE_XREG, #0x4      ;\
64         b.ne   .                    ;// We should never get here
65 // EL1 code starts here
66 
67 // CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1
68 // This only selects between EL1 and EL2 and EL3, else we die.
69 // Provide the Macro with a safe temp xreg to use.
70 #define EL1_OR_EL2_OR_EL3(SAFE_XREG) \
71         mrs    SAFE_XREG, CurrentEL ;\
72         cmp    SAFE_XREG, #0xC      ;\
73         b.eq   3f                   ;\
74         cmp    SAFE_XREG, #0x8      ;\
75         b.eq   2f                   ;\
76         cmp    SAFE_XREG, #0x4      ;\
77         b.ne   .                    ;// We should never get here
78 // EL1 code starts here
79 #if defined(__clang__)
80 
81 // load x0 with _Data
82 #define LoadConstant(_Data)              \
83   ldr  x0, 1f                          ; \
84   b    2f                              ; \
85 .align(8)                              ; \
86 1:                                       \
87   .8byte (_Data)                       ; \
88 2:
89 
90 // load _Reg with _Data
91 #define LoadConstantToReg(_Data, _Reg)    \
92   ldr  _Reg, 1f                         ; \
93   b    2f                               ; \
94 .align(8)                               ; \
95 1:                                        \
96   .8byte (_Data)                        ; \
97 2:
98 
99 #elif defined (__GNUC__)
100 
101 #define LoadConstant(Data) \
102   ldr  x0, =Data
103 
104 #define LoadConstantToReg(Data, Reg) \
105   ldr  Reg, =Data
106 
107 #endif // __GNUC__
108 
109 #endif // __MACRO_IO_LIBV8_H__
110 
111