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 ; The target architecture. Supported versions are 5 and 15
27 #define PSM_BRC spr848
29 #define ECOND_MAC_ON 0x24
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
44 sub. r0,r1,r2 ; sub, set carry
45 subc r0,r1,r2 ; sub with carry
46 subc. r0,r1,r2 ; sub with carry, set carry
48 sra r0,r1,r2 ; arithmetic rightshift
50 ; Logical instructions
51 or r0,r1,r2 ; bitwise OR
52 and r0,r1,r2 ; bitwise AND
53 xor r0,r1,r2 ; bitwise XOR
54 sr r0,r1,r2 ; rightshift
55 sl r0,r1,r2 ; leftshift
57 srx 7,8,r0,r1,r2 ; eXtended right shift (two input regs)
59 rl r0,r1,r2 ; rotate left
60 rr r0,r1,r2 ; rotate right
61 nand r0,r1,r2 ; clear bits (notmask + and)
63 orx 7,8,r0,r1,r2 ; eXtended OR
65 ; Copy instruction. This is a virtual instruction
66 ; translated to more lowlevel stuff like OR.
70 jmp label ; unconditional jump
71 jand r0,r1,label ; jump if binary AND
72 jnand r0,r1,label ; jump if not binary AND
73 js r0,r1,label ; jump if all bits set
74 jns r0,r1,label ; jump if not all bits set
75 je r0,r1,label ; jump if equal
76 jne r0,r1,label ; jump if not equal
77 jls r0,r1,label ; jump if less (signed)
78 jges r0,r1,label ; jump if greater or equal (signed)
79 jgs r0,r1,label ; jump if greater (signed)
80 jles r0,r1,label ; jump if less or equal (signed)
81 jl r0,r1,label ; jump if less
82 jge r0,r1,label ; jump if greater or equal
83 jg r0,r1,label ; jump if greater
84 jle r0,r1,label ; jump if less or equal
86 jzx 7,8,r0,r1,label ; Jump if zero after shift and mask
87 jnzx 7,8,r0,r1,label ; Jump if nonzero after shift and mask
89 ; jump on external conditions
90 jext ECOND_MAC_ON,r0,r0,label ; jump if external condition is TRUE
91 jnext ECOND_MAC_ON,r0,r0,label ; jump if external condition is FALSE
94 call lr0,label ; store PC in lr0, call func at label
95 ret lr0,lr1 ; store PC in lr0, return to lr1
96 ; Both link registers can be the same
97 ; and don't interfere.
100 tkiph r0,r2 ; Lookup high
101 tkiphs r0,r2 ; Lookup high, byteswap
102 tkipl r0,r2 ; Lookup low
103 tkipls r0,r2 ; Lookup low, byteswap
105 nap ; sleep until event
108 @160 r0,r1,r2 ; equivalent to or r0,r1,r2
109 @1C0 @C11, @C22, @BC3
112 ; Support for directional jumps.
113 ; Directional jumps can be used to conveniently jump inside of
114 ; functions without using function specific label prefixes. Note
115 ; that this does not establish a sub-namespace, though. "loop"
116 ; and "out" are still in the global namespace and can't be used
117 ; anymore for absolute jumps (Assembler will warn about duplication).
135 ; The assembler has support for fancy assemble-time
136 ; immediate constant expansion. This is called "complex immediates".
137 ; Complex immediates are _always_ clamped by parentheses. There is no
138 ; operator precedence. You must use parentheses to tell precedence.
149 mov (1 << (0x3 + 2)),r0
150 mov (1 + (2 + (3 + 4))),r0
151 mov (4 >> (((((~5 | 0x21)))) | (~((10) & 2)))),r0
154 ; Some regression testing for the assembler follows
155 mov 2,off0 ; test memory stuff
156 xor 0x124,r1,[0x0,off0] ; test memory stuff
157 xor 0x124,r0,[0x0] ; test memory stuff
158 mov -34,r0 ; negative dec numbers are supported
159 or r0,r1,@BC2 ; We also support single raw operands
160 mov 0xEEEE,r0 ; MOV supports up to 16bit
161 jand 0x3800,r0,label ; This is emulated by jnzx
162 jnand 0x3800,r0,label ; This is emulated by jzx
163 or spr06c,0,spr06c ; Can have one spr input and one spr output
164 or [0],0,[0] ; Can have one mem input and one mem output
165 mov testlabel, r0 ; Can use label as immediate value
168 ; The .initvals section generates an "Initial Values" file
169 ; with the name "foobar" in this example, which is uploaded
170 ; by the kernel driver on load. This is useful for writing ucode
171 ; specific values to the chip without bloating the small ucode
172 ; memory space with this initialization stuff.
173 ; Values are written in order they appear here.
175 mmio16 0x1234, 0xABC ; Write 0x1234 to MMIO register 0xABC
176 mmio32 0x12345678, 0xABC ; Write 0x12345678 to MMIO register 0xABC
177 phy 0x1234, 0xABC ; Write 0x1234 to PHY register 0xABC
178 radio 0x1234, 0xABC ; Write 0x1234 to RADIO register 0xABC
179 shm16 0x1234, 0x0001, 0x0002 ; Write 0x1234 to SHM routing 0x0001, register 0x0002
180 shm32 0x12345678, 0x0001, 0x0002 ; Write 0x12345678 to SHM routing 0x0001, register 0x0002