1 ; This is a bcm43xx microcode assembly example.
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.
10 ; Offset Registers: off0 - off5
13 ; To access memory, two methods can be used. Examples follow.
16 ; Indirect through Offset Register (pointer):
21 %arch bcm43xx_newworld ; or bcm43xx-oldworld
24 #define PSM_BRC spr848
26 #define ECOND_MAC_ON 0x24
34 add. r0,r1,r2 ; add, set carry
35 addc r0,r1,r2 ; add with carry
36 addc. r0,r1,r2 ; add with carry, set carry
41 sub. r0,r1,r2 ; sub, set carry
42 subc r0,r1,r2 ; sub with carry
43 subc. r0,r1,r2 ; sub with carry, set carry
45 sra r0,r1,r2 ; arithmetic rightshift
47 ; Logical instructions
48 or r0,r1,r2 ; bitwise OR
49 and r0,r1,r2 ; bitwise AND
50 xor r0,r1,r2 ; bitwise XOR
51 sr r0,r1,r2 ; rightshift
52 sl r0,r1,r2 ; leftshift
54 srx 7,8,r0,r1,r2 ; eXtended right shift (two input regs)
56 rl r0,r1,r2 ; rotate left
57 rr r0,r1,r2 ; rotate right
58 nand r0,r1,r2 ; clear bits (notmask + and)
60 orx 7,8,r0,r1,r2 ; eXtended OR
62 ; Copy instruction. This is a virtual instruction
63 ; translated to more lowlevel stuff like OR.
67 jmp label ; unconditional jump
68 jand r0,r1,label ; jump if binary AND
69 jnand r0,r1,label ; jump if not binary AND
70 js r0,r1,label ; jump if all bits set
71 jns r0,r1,label ; jump if not all bits set
72 je r0,r1,label ; jump if equal
73 jne r0,r1,label ; jump if not equal
74 jls r0,r1,label ; jump if less (signed)
75 jges r0,r1,label ; jump if greater or equal (signed)
76 jgs r0,r1,label ; jump if greater (signed)
77 jles r0,r1,label ; jump if less or equal (signed)
78 jl r0,r1,label ; jump if less
79 jge r0,r1,label ; jump if greater or equal
80 jg r0,r1,label ; jump if greater
81 jle r0,r1,label ; jump if less or equal
83 jzx 7,8,r0,r1,label ; Jump if zero after shift and mask
84 jnzx 7,8,r0,r1,label ; Jump if nonzero after shift and mask
86 ; jump on external conditions
87 jext ECOND_MAC_ON,r0,r0,label ; jump if external condition is TRUE
88 jnext ECOND_MAC_ON,r0,r0,label ; jump if external condition is FALSE
91 call lr0,label ; store PC in lr0, call func at label
92 ret lr0,lr1 ; store PC in lr0, return to lr1
93 ; Both link registers can be the same
94 ; and don't interfere.
97 tkiph r0,r2 ; Lookup high
98 tkiphs r0,r2 ; Lookup high, byteswap
99 tkipl r0,r2 ; Lookup low
100 tkipls r0,r2 ; Lookup low, byteswap
102 nap ; sleep until event
105 @160 r0,r1,r2 ; equivalent to or r0,r1,r2
106 @1C0 @C11, @C22, @BC3
109 ; Support for directional jumps.
110 ; Directional jumps can be used to conveniently jump inside of
111 ; functions without using function specific label prefixes. Note
112 ; that this does not establish a sub-namespace, though. "loop"
113 ; and "out" are still in the global namespace and can't be used
114 ; anymore for absolute jumps (Assembler will warn about duplication).
132 ; The assembler has support for fancy assemble-time
133 ; immediate constant expansion. This is called "complex immediates".
134 ; Complex immediates are _always_ clamped by parentheses. There is no
135 ; operator precedence. You must use parentheses to tell precedence.
146 mov (1 << (0x3 + 2)),r0
147 mov (1 + (2 + (3 + 4))),r0
148 mov (4 >> (((((~5 | 0x21)))) | (~((10) & 2)))),r0
151 ; Some regression testing for the assembler follows
152 mov 2,off0 ; test memory stuff
153 xor 0x124,r1,[0x0,off0] ; test memory stuff
154 xor 0x124,r0,[0x0] ; test memory stuff
155 mov -34,r0 ; negative dec numbers are supported
156 or r0,r1,@BC2 ; We also support single raw operands
157 mov 0xEEEE,r0 ; MOV supports up to 16bit
158 jand 0x3800,r0,label ; This is emulated by jnzx
159 jnand 0x3800,r0,label ; This is emulated by jzx
160 or spr06c,0,spr06c ; Can have one spr input and one spr output
161 or [0],0,[0] ; Can have one mem input and one mem output
162 mov testlabel, r0 ; Can use label as immediate value
165 ; The .initvals section generates an "Initial Values" file
166 ; with the name "foobar" in this example, which is uploaded
167 ; by the kernel driver on load. This is useful for writing ucode
168 ; specific values to the chip without bloating the small ucode
169 ; memory space with this initialization stuff.
170 ; Values are written in order they appear here.
172 mmio16 0x1234, 0xABC ; Write 0x1234 to MMIO register 0xABC
173 mmio32 0x12345678, 0xABC ; Write 0x12345678 to MMIO register 0xABC
174 phy 0x1234, 0xABC ; Write 0x1234 to PHY register 0xABC
175 radio 0x1234, 0xABC ; Write 0x1234 to RADIO register 0xABC
176 shm16 0x1234, 0x0001, 0x0002 ; Write 0x1234 to SHM routing 0x0001, register 0x0002
177 shm32 0x12345678, 0x0001, 0x0002 ; Write 0x12345678 to SHM routing 0x0001, register 0x0002