b1f3f147b01267d520f7ce287aefc3b36abe7c79
[b43-tools.git] / assembler / test.asm
1 /* This is a bcm43xx microcode assembly example.
2  *
3  * In this example file, r0 and r1 are always input
4  * registers and r2 is output.
5  * For input we can always have constant values or (one) memory
6  * operand instead of the input registers shown here.
7  *
8  * Registers:
9  *      GPRs:                   r0 - r63
10  *      Offset Registers:       off0 - off5
11  *      SPRs:                   spr000
12  *
13  * To access memory, two methods can be used. Examples follow.
14  * Direct linear:
15  *      mov r0,[0xCA]
16  * Indirect through Offset Register (pointer):
17  *      mov r0,[0xCA,off0]
18  */
19
20
21 /* The target architecture. Supported versions are 5 and 15 */
22 %arch   5
23
24 /* Program entry point */
25 %start  testlabel
26
27 #define PSM_BRC         spr848
28
29 #define ECOND_MAC_ON    (0x20 | 4)
30
31
32 .text
33
34 label:
35         /* ADD instructions */
36         add     r0,r1,r2        /* add */
37         add.    r0,r1,r2        /* add, set carry */
38         addc    r0,r1,r2        /* add with carry */
39         addc.   r0,r1,r2        /* add with carry, set carry */
40
41 or 0x1000, r0, r0
42 testlabel:
43         /* SUB instructions */
44         sub     r0,r1,r2        /* sub */
45         sub.    r0,r1,r2        /* sub, set carry */
46         subc    r0,r1,r2        /* sub with carry */
47         subc.   r0,r1,r2        /* sub with carry, set carry */
48
49         sra     r0,r1,r2        /* arithmetic rightshift */
50
51         /* Logical instructions */
52         or      r0,r1,r2        /* bitwise OR */
53         and     r0,r1,r2        /* bitwise AND */
54         xor     r0,r1,r2        /* bitwise XOR */
55         sr      r0,r1,r2        /* rightshift */
56         sl      r0,r1,r2        /* leftshift */
57
58         srx     7,8,r0,r1,r2    /* eXtended right shift (two input regs) */
59
60         rl      r0,r1,r2        /* rotate left */
61         rr      r0,r1,r2        /* rotate right */
62         nand    r0,r1,r2        /* clear bits (notmask + and) */
63
64         orx     7,8,r0,r1,r2    /* eXtended OR */
65
66         /* Copy instruction. This is a virtual instruction
67          * translated to more lowlevel stuff like OR. */
68         mov     r0,r2           /* copy data */
69
70         /* Jumps */
71         jmp     label           /* unconditional jump */
72         jand    r0,r1,label     /* jump if binary AND */
73         jnand   r0,r1,label     /* jump if not binary AND */
74         js      r0,r1,label     /* jump if all bits set */
75         jns     r0,r1,label     /* jump if not all bits set */
76         je      r0,r1,label     /* jump if equal */
77         jne     r0,r1,label     /* jump if not equal */
78         jls     r0,r1,label     /* jump if less (signed) */
79         jges    r0,r1,label     /* jump if greater or equal (signed) */
80         jgs     r0,r1,label     /* jump if greater (signed) */
81         jles    r0,r1,label     /* jump if less or equal (signed) */
82         jl      r0,r1,label     /* jump if less */
83         jge     r0,r1,label     /* jump if greater or equal */
84         jg      r0,r1,label     /* jump if greater */
85         jle     r0,r1,label     /* jump if less or equal */
86
87         jzx     7,8,r0,r1,label /* Jump if zero after shift and mask */
88         jnzx    7,8,r0,r1,label /* Jump if nonzero after shift and mask */
89
90         /* jump on external conditions */
91         jext    ECOND_MAC_ON,r0,r0,label  /* jump if external condition is TRUE */
92         jnext   ECOND_MAC_ON,r0,r0,label  /* jump if external condition is FALSE */
93
94         /* Subroutines */
95         call    lr0,label       /* store PC in lr0, call func at label */
96         ret     lr0,lr1         /* store PC in lr0, return to lr1
97                                  * Both link registers can be the same
98                                  * and don't interfere. */
99
100         /* TKIP sbox lookup */
101         tkiph   r0,r2           /* Lookup high */
102         tkiphs  r0,r2           /* Lookup high, byteswap */
103         tkipl   r0,r2           /* Lookup low */
104         tkipls  r0,r2           /* Lookup low, byteswap */
105
106         nap                     /* sleep until event */
107
108         /* raw instruction */
109         @160    r0,r1,r2        /* equivalent to  or r0,r1,r2 */
110         @1C0    @C11, @C22, @BC3
111
112
113         /* Support for directional jumps.
114          * Directional jumps can be used to conveniently jump inside of
115          * functions without using function specific label prefixes. Note
116          * that this does not establish a sub-namespace, though. "loop"
117          * and "out" are still in the global namespace and can't be used
118          * anymore for absolute jumps (Assembler will warn about duplication).
119          */
120 function_a:
121         jl r0, r1, out+
122  loop:
123         nap
124         jmp loop-
125  out:
126         ret lr0, lr1
127
128 function_b:
129         jl r0, r1, out+
130  loop:
131         nap
132         jmp loop-
133  out:
134         ret lr0, lr1
135
136
137 /* The assembler has support for fancy assemble-time
138  * immediate constant expansion. This is called "complex immediates".
139  * Complex immediates are _always_ clamped by parentheses. There is no
140  * operator precedence. You must use parentheses to tell precedence.
141  */
142         mov     (2 + 3),r0
143         mov     (6 - 2),r0
144         mov     (2 * 3),r0
145         mov     (10 / 5),r0
146         mov     (1 | 2),r0
147         mov     (3 & 2),r0
148         mov     (3 ^ 2),r0
149         mov     (~1),r0
150         mov     (2 << 3),r0
151         mov     (8 >> 2),r0
152         mov     (1 << (0x3 + 2)),r0
153         mov     (1 + (2 + (3 + 4))),r0
154         mov     (4 >> (((((~5 | 0x21)))) | (~((10) & 2)))),r0
155
156
157 /* Some regression testing for the assembler follows */
158         mov     2,off0                  /* test memory stuff */
159         xor     0x124,r1,[0x0,off0]     /* test memory stuff */
160         xor     0x124,r0,[0x0]          /* test memory stuff */
161         mov     -34,r0                  /* negative dec numbers are supported */
162         or      r0,r1,@BC2              /* We also support single raw operands */
163         mov     0xEEEE,r0               /* MOV supports up to 16bit */
164         jand    0x3800,r0,label         /* This is emulated by jnzx */
165         jnand   0x3800,r0,label         /* This is emulated by jzx */
166         or      spr06c,0,spr06c         /* Can have one spr input and one spr output */
167         or      [0],0,[0]               /* Can have one mem input and one mem output */
168         mov     testlabel, r0           /* Can use label as immediate value */
169         mov r0,r1;mov r2, r3            /* ; does split instructions */
170         mov     [(1+1)],[(2+2),off0]    /* Can use complex immediates as memory offsets */
171
172
173 /* The .initvals section generates an "Initial Values" file
174  * with the name "foobar" in this example, which is uploaded
175  * by the kernel driver on load. This is useful for writing ucode
176  * specific values to the chip without bloating the small ucode
177  * memory space with this initialization stuff.
178  * Values are written in order they appear here.
179  */
180 .initvals(foobar)
181         mmio16  0x1234, 0xABC                   /* Write 0x1234 to MMIO register 0xABC */
182         mmio32  0x12345678, 0xABC               /* Write 0x12345678 to MMIO register 0xABC */
183         phy     0x1234, 0xABC                   /* Write 0x1234 to PHY register 0xABC */
184         radio   0x1234, 0xABC                   /* Write 0x1234 to RADIO register 0xABC */
185         shm16   0x1234, 0x0001, 0x0002          /* Write 0x1234 to SHM routing 0x0001, register 0x0002 */
186         shm32   0x12345678, 0x0001, 0x0002      /* Write 0x12345678 to SHM routing 0x0001, register 0x0002 */
187
188
189 // vim: syntax=b43 ts=8