↑ Top, → Constants, → Operators
Type | Example | Description | |
---|---|---|---|
decimal | -42 | int |
Integer constant, 32 bit signed or unsigned |
hexadecimal | -0xa4 | int |
Hexadecimal constant, 32 bit signed or unsigned |
octal | -0377 | int |
Octal constant, indicated by leading zero |
binary | 0b10010 | int |
Binary constant |
floating point | 1.0 1.4e6 |
float | Floating point value Note that this must include a decimal dot. |
per element constant | [0,2,3...] | int2[16] | 2 bit integer per QPU element. |
accumulator |
r1 | register | r0 ... r5 On write r5 need to be named r5quad or r5rep respectively. |
memory register | ra25 | register | ra0 ... ra31, rb0 ... rb31. The numbers rx32 ... rx63 also work, but this is normally not recommended because it prevents vc4asm from choosing from any the register file automatically for peripheral registers where this does not matter. |
I/O register | vary irq |
register | Access to peripheral hardware, see table below. |
packed register experssion | ra0.8csf | register | Register that should be packed and/or unpacked. This can be
assigned to a symbol to define aliases for register slices, e.g. .set back_color, ra0.8ai |
semaphore | sacq15 srel2 |
register | Semaphore access, read only. Depending on the name an acquire
or release instruction is issued. This syntax is only provided for compatibility with Broadcom source codes. Normally you should prefer the sacq and srel instructions. |
label | :loop | label | label receiving the absolute number of bytes from the start of the assembly. |
internal raw register | :[0,1,0,3] | register | Internal register constant. It consists of the fields register number, register type, vector rotation and pack/unpack mode. The latter two are optional and by default zero. This syntax is for internal use only and subject to change. |
Number | read |
write | ||
---|---|---|---|---|
file A | file B | file A | file B | |
32 | unif | r0 | ||
33 | |
|
r1 | |
34 |
|
|
r2 | |
35 |
vary | r3 | ||
36 |
|
|
tmurs | |
37 |
|
|
r5quad | r5rep |
38 |
elem_num | qpu_num | irq interrupt |
|
39 |
|
|
|
|
40 |
|
|
unif_addr | unif_addr_rel |
41 |
x_coord | y_coord | x_coord | y_coord |
42 |
ms_mask | rev_flag | ms_mask | rev_flag |
43 |
|
|
stencil | |
44 |
|
|
tlbz | |
45 |
|
|
tlbm | |
46 |
|
|
tlbc | |
47 |
|
|
tlbam | |
48 |
vpm | |||
49 |
vr_busy | vw_busy | vr_setup | vw_setup |
50 |
vr_wait | vw_wait | vr_addr | vw_addr |
51 |
mutex mutex_acq |
mutex mutex_rel |
||
52 |
|
|
recip | |
53 |
|
|
recipsqrt | |
54 |
|
|
exp | |
55 |
|
|
log | |
56 |
|
|
t0s | |
57 |
|
|
t0t | |
58 |
|
|
t0r | |
59 |
|
|
t0b | |
60 |
|
|
t1s | |
61 |
|
|
t1t | |
62 |
|
|
t1r | |
63 |
|
|
t1b |
The operators share mainly the same precedence as for the C language.
Precedence | Type | Operator | Description | |
---|---|---|---|---|
1 | brace | ( ) | all |
|
2 |
unary | + | all |
identity operation |
- | int → int float → float |
negative value | ||
~ | int → int |
binary not | ||
! | int → int | logical not, 1 if operand is zero, otherwise 0 | ||
unary math |
abs | int → int float → float |
absolute value |x| | |
ceil | float → int | smallest integer not less than value | ||
floor | largest integer not greater than value | |||
unary exponential |
exp | int → float float → float |
natural exponential function | |
exp2 | binary exponential function | |||
exp10 | common exponential function | |||
log | natural logarithm | |||
log2 | binary logarithm | |||
log10 | common logarithm | |||
unary trigonometric |
cos | int → float float → float |
cosine | |
sin | sine | |||
tan | tangent | |||
acos | arc cosine | |||
asin | arc sine | |||
atan | arc tangent | |||
unary hyperbolic |
cosh | int → float float → float |
hyperbolic cosine | |
sinh | hyperbolic sine | |||
tanh | hyperbolic tangent | |||
acosh | arc hyperbolic cosine | |||
asinh | arc hyperbolic sine | |||
atanh | arc hyperbolic tangent | |||
unary extended math |
erf | int → float float → float |
error function | |
erfc | complementary error function | |||
3 |
binary power |
** | int, int → int float, float → float int, float → float float, int → float |
power, xy |
4 |
binary multiplicative |
* | multiplication |
|
/ | division | |||
% | modulus | |||
5 |
binary additive |
+ | int, int → int float, float → float int, float → float float, int → float reg, int → reg |
addition In case the left operand is a register the register number changes. The resulting number must not exceed the range for the given register type. The operation never changes the type of a register. |
- | subtraction In case the left operand is a register the register number changes. The resulting number must not exceed the range for the given register type. The operation never changes the type of a register. |
|||
6 | binary bit shift |
<< | int, int → int float, int → float reg, int → reg reg, reg → reg |
arithmetic shift left (signed) Arithmetic shift left is basically the same than logical shift left unless the right operand is negative where the shift direction turns to right. If the left operand is float, only the exponent is shifted, i.e. the number is multiplied by the power of two indicated by the right operand. If the left operand is a register, the rotate unit of the MUL ALU is activated by small immediate values ≥ 48. The right operand need to be an integer constant or register r5. |
>> | arithmetic shift right (signed) If the left operand is float, only the exponent is shifted, i.e. the number is multiplied by the power of two indicated by the right operand. If the left operand is a register, the rotate unit of the MUL ALU is activated by small immediate values ≥ 48. The right operand need to be an integer constant or register r5. |
|||
<<< | int, int → int | logical shift left (unsigned shifted by signed) Logical shift left is basically the same than arithmetic shift left unless the right operand is negative where the shift direction turns to right. |
||
>>> | logical shift right (unsigned shifted by signed) | |||
binary rotate |
><< | int, int → int | 32 bit rotate left | |
>>< | 32 bit rotate right | |||
><<< | 64 bit rotate left | |||
>>>< | 64 bit rotate right | |||
7 | binary relational |
> | all, all → int | greater than |
>= | greater than or equal | |||
< | less than | |||
<= | less than or equal | |||
<=> | full comparison, evaluates to -1 if less than, +1 if greater, 0 if equal and -0x80000000 if indeterminate | |||
8 |
binary equality |
== | all, all → int | equal |
!= | not equal | |||
=== | identical, not just equal, e.g. NaN === NaN but NaN != NaN | |||
!== | not identical, e.g. 1.0 !== 1 but 1.0 == 1 and also 1.00 === 1.0 | |||
9 | binary bitwise |
& | int, int → int | binary and |
10 | ^ | binary exclusive or | ||
!^ | binary exclusive nor | |||
11 | | | binary inclusive or | ||
12 | binary logical |
&& | int, int → int | logical and |
13 | ^^ | logical exclusive or | ||
!^^ | logical exclusive nor | |||
14 | || | logical inclusive or |
If the left and right hand side of a relational or equality operator has a different data type, e.g. register vs. integer the following sequence applies. Types with higher ordinals below always compare greater.
Some operators can be applied to registers rather than constants. This operators will not modify the value at runtime, instead they have a special meaning at compile time.
Note that vc4asm treats mathematical functions like log as unary operators rather than functions. I.e. the basic syntax is log 7 rather than log(7). However, since braces are always allowed around expression the latter will work as well although the braces are no function call operator.