pb_cg_emit_expr (pb_codegen.c:5091)mov rax, <value> ; immediate constant
; Stack local: mov rax, [rbp - offset] ; BYREF parameter (pointer dereference): mov r11, [rbp - offset] ; get pointer mov rax, [r11] ; dereference ; STATIC/GLOBAL: mov rax, [label]
; Evaluate left -> RAX, save to temp ; Evaluate right -> RAX mov r10, rax ; right operand mov rax, [rbp - left_offset] ; reload left ; ADD (+) add rax, r10 ; SUB (-) sub rax, r10 ; MUL (*) imul r10 ; RDX:RAX = RAX * r10 ; DIV (/) cqo ; sign-extend RAX -> RDX:RAX idiv r10 ; RAX = quotient ; Integer division (\) ; Same as DIV but uses signed division ; MOD cqo idiv r10 mov rax, rdx ; remainder in RDX ; AND (bitwise) and rax, r10 ; OR (bitwise) or rax, r10
; Negation (-) mov r10, 0 sub r10, rax mov rax, r10 ; NOT (logical) test rax, rax je __pb_not_true_N xor rax, rax ; 0 (was true -> false) jmp __pb_not_end_N __pb_not_true_N: mov rax, 1 ; 1 (was false -> true) __pb_not_end_N:
; Compare left and right, set RAX to 0 or 1 mov r10, rax ; right mov rax, [rbp - left_offset] ; left cmp rax, r10 ; then conditional set: sete al ; EQ setne al ; NE setl al ; LT setle al ; LE setg al ; GT setge al ; GE movzx rax, al ; extend to 64-bit
String comparisons (=, <>, <, >) are implemented using memcmp for performance. The result is normalized to 0 or 1.
; s1$ = "Hello", s2$ = "World" ; IF s1$ = s2$ THEN ; Load string pointers mov rcx, [rbp - s1_ptr] mov rdx, [rbp - s2_ptr] ; Compare lengths first (optimization) mov r8, [rbp - s1_len] mov r9, [rbp - s2_len] cmp r8, r9 jne __pb_str_cmp_len_fail ; Compare content via memcmp mov r10, r8 ; length call [__imp_memcmp] test eax, eax sete al ; 0 if equal, else non-zero movzx rax, al ; normalize to 0 or 1
| Precedence | Operators |
|---|---|
| 1 (highest) | () parentheses, ^ exponent |
| 2 | Unary -, NOT |
| 3 | * / \ MOD |
| 4 | + - (binary), & (string concat) |
| 5 | = <> < > <= >= |
| 6 | AND (bitwise) |
| 7 (lowest) | OR (bitwise) |