Linux x86_64 implementation of libglitch : https://github.com/erlehmann/libglitch.git
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. ; yaglitch : Yet Another Glitch
  2. ; Copyright (C) 2018 Weber Yann
  3. ;
  4. ; This program is free software; you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation; either version 3 of the License, or
  7. ; any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;
  17. [bits 64]
  18. %include "sdl.asm"
  19. %include "utils.asm"
  20. %define STACK_SZ 256
  21. %define MAX_FILE_SZ (16 * 17) ; 16 lines of 16 chars + newline chr
  22. %define NL "!"
  23. section .data
  24. op_ptrs: ; pointers on OP functions
  25. dq OP.t ; a
  26. dq OP.put ; b
  27. dq OP.drop ; c
  28. dq OP.mul ; d
  29. dq OP.div ; e
  30. dq OP.add ; f
  31. dq OP.sub ; g
  32. dq OP.mod ; h
  33. dq 0 ; i : syntax error
  34. dq OP.lshift ; j
  35. dq OP.rshift ; k
  36. dq OP.and ; l
  37. dq OP.or ; m
  38. dq OP.xor ; n
  39. dq OP.not ; o
  40. dq OP.dup ; p
  41. dq OP.pick ; q
  42. dq OP.swap ; r
  43. dq OP.lt ; s
  44. dq OP.gt ; t
  45. dq OP.eq ; u
  46. audiospec_wanted: ; SDL_audio configuration
  47. dd 8000 ; freq
  48. dw AUDIO_U8 ; format
  49. db 1 ; channels
  50. db 0 ; silence
  51. dw 4096 ; samples
  52. dd 0 ; size
  53. dw 0 ; allign
  54. dq audio_cllbck
  55. dq 0 ; userdata
  56. ; text messages
  57. def_str usage, "Usage : "
  58. def_str opts, {" FILE.glitch",0xA}
  59. def_str openerr, {'Error opening file : "', 0xA}
  60. def_str syntax_error, {"Syntax error", 0xA}
  61. def_str bigline_error, {"Line with more than 16 tokens !", 0xA}
  62. def_str nl_error, {"Character \n is not the last one", 0xA}
  63. def_str badop_error, {"Bad OP", 0xA}
  64. section .bss
  65. ; glitch name (1st line) : len 16 + \0
  66. glitch_name: resb 17
  67. ; program internal repr for stack machine
  68. ; each token uses 2 words : 1st for the callback address 2nd for
  69. ; optional value
  70. glitch_pgm: resq 16 * 16 * 2
  71. ; stack machine ring buffer
  72. stack_buff: resd STACK_SZ
  73. ; top of stack pointer
  74. tosp: resq 1
  75. ; stack machine rgister
  76. t: resd 1
  77. ; audiospec returned from SDL
  78. audiospec_recv: resb 32
  79. ; Event receveid from SDL
  80. event: resb 24
  81. section .text
  82. global _start
  83. _start:
  84. ; checking args
  85. mov rcx, [rsp]
  86. cmp rcx, 2
  87. jne exit.badarg
  88. mov rax, 0x2 ; sys_open
  89. mov rdi, [rsp+16] ; argv[1]
  90. xor rsi, rsi ; no flags
  91. xor rdx, rdx ; O_RDONLY
  92. syscall
  93. cmp rax, 0
  94. jl exit.err_open
  95. push rax ; source fd
  96. mov rax, 0xc ; brk
  97. xor rdi, rdi
  98. syscall
  99. push rax ; heap start
  100. mov rdi, rax
  101. add rdi, MAX_FILE_SZ ; new heap end
  102. mov rax, 0xc ; brk
  103. syscall
  104. pop rsi ; heap start
  105. mov r14, rsi
  106. xor rax, rax ; sys_read
  107. mov rdi, [rsp] ; source_fd
  108. mov rdx, MAX_FILE_SZ
  109. syscall
  110. cmp rax, 0
  111. jl exit.err_open
  112. mov r15, rax
  113. mov rax, 0x3 ; sys_close
  114. pop rdi ; source_fd
  115. syscall
  116. mov rbx, r15 ;read size
  117. mov rdi, r14 ; heap start
  118. add rdi, rbx ; heap end
  119. mov r15, rdi
  120. mov rax, 0xc ; brk
  121. syscall ; shrink heap to read size
  122. ; init program space
  123. mov rdi, glitch_pgm
  124. xor rax, rax
  125. stosq
  126. stosq
  127. mov rsi, r14
  128. push rsi
  129. xor r13, r13
  130. xor rbx, rbx
  131. parse:
  132. ; go trhough file , with rsi current ptr, r15 file stop
  133. ; r13 will contain updated lineno and rbx chr in current line
  134. ; rdi store the destination pointer
  135. ; parse glitch name
  136. mov rcx, 16
  137. mov rdi, glitch_name
  138. .name_loop:
  139. inc rbx
  140. lodsb
  141. test al, al ; EOF
  142. jz .no_nl
  143. cmp al, 0xA
  144. je .trailing_nl
  145. cmp al, "!" ; EOL
  146. je .name_end
  147. cmp al, "_"
  148. je .chrname
  149. cmp al, "0"
  150. jl exit.syntax_error
  151. cmp al, "9"
  152. jle .chrname
  153. cmp al, "a"
  154. jl exit.syntax_error
  155. cmp al, "z"
  156. jg exit.syntax_error
  157. .chrname:
  158. stosb
  159. loop .name_loop
  160. jmp exit.bigline
  161. .name_end:
  162. inc r13 ; lineno
  163. xor rbx, rbx
  164. xor al, al
  165. stosb
  166. ; parsing tokens
  167. xor edx, edx ; 32bits numeric token value
  168. xor eax, eax
  169. xor r10, r10 ; numeric token flag (1 mean in numeric token)
  170. xor r11, r11 ; numeric token len
  171. mov rcx, r15
  172. sub rcx, r14
  173. mov rdi, glitch_pgm
  174. .parse_loop:
  175. inc rbx
  176. lodsb
  177. test al, al
  178. jz .no_nl
  179. cmp al, 0xA
  180. je .trailing_nl
  181. cmp al, "!" ; EOL
  182. je .next_line
  183. cmp al, "." ; token separator
  184. je .next_token
  185. cmp al, "0"
  186. jl exit.syntax_error
  187. cmp al, "9"
  188. jle .dec_token
  189. cmp al, "A"
  190. jl exit.syntax_error
  191. cmp al, "F"
  192. jle .hex_token
  193. jmp .op_match ; allowing loop near jump
  194. .end_op:
  195. stosq
  196. xor rax, rax
  197. stosq
  198. loop .parse_loop
  199. .hex_token:
  200. sub al, "A" - 10
  201. jmp .numeric_token
  202. .dec_token:
  203. sub al, "0"
  204. .numeric_token:
  205. cmp r11, 8
  206. je exit.syntax_error ; Numeric constant OF
  207. inc r11
  208. mov r10, 1
  209. shl edx, 4
  210. add edx, eax
  211. loop .parse_loop
  212. .next_token:
  213. test r10, r10 ; check for numeric constant
  214. jnz .add_numeric
  215. loop .parse_loop
  216. .next_line:
  217. inc r13
  218. xor rbx, rbx
  219. .loop_parse_loop:
  220. loop .parse_loop
  221. .add_numeric:
  222. mov rax, OP.numeric
  223. stosq
  224. xor rax, rax
  225. xor r11, r11
  226. xor r10, r10
  227. xchg rax, rdx
  228. shl rax, 32
  229. stosq
  230. xor rax, rax
  231. jmp .loop_parse_loop
  232. .trailing_nl:
  233. ; check that NL is the last chr, else syntax error
  234. cmp rsi, r15
  235. jne exit.nl_not_last
  236. jmp .parse_end
  237. .op_match:
  238. ; allow loop .parse_loop near jump
  239. cmp al, "a"
  240. jl exit.syntax_error
  241. cmp al, "u"
  242. jg exit.syntax_error
  243. ; OP shortand matching
  244. ; checking for previous numeric token to write
  245. test r10, r10
  246. jz .match_op
  247. push rax
  248. ; add previous numeric token
  249. mov rax, OP.numeric
  250. stosq
  251. xor rax, rax
  252. xor r11, r11 ; numeric token length raz
  253. xor r10, r10 ; numeric token flag raz
  254. xchg rax, rdx
  255. shl rax, 32 ; shl to allow reading as dword ?
  256. stosq
  257. pop rax
  258. .match_op:
  259. sub al, "a"
  260. shl rax, 3 ; mul by 8 (size of ptr)
  261. add rax, op_ptrs
  262. mov rax, [rax]
  263. test rax, rax
  264. jz exit.bad_op
  265. jmp .end_op
  266. .no_nl: ; TODO : print warning
  267. ; no NL at EOF
  268. .parse_end:
  269. ; clean heap
  270. mov rax, 0xc
  271. pop rdi
  272. syscall
  273. ; print glitch name
  274. mov rax, "Playing "
  275. push rax
  276. mov rax, 1
  277. mov rdi, 1
  278. mov rsi, rsp
  279. mov rdx, 8
  280. syscall
  281. pop rax
  282. mov rdi, glitch_name
  283. call strlen
  284. mov rdx, rax
  285. mov rax, 1
  286. mov rdi, 1
  287. mov rsi, glitch_name
  288. syscall
  289. mov rax, `\n`
  290. push rax
  291. mov rax, 1
  292. mov rdi, 1
  293. mov rsi, rsp
  294. mov rdx, 1
  295. syscall
  296. pop rax
  297. ; init stack machine runtime
  298. stack_init:
  299. mov rcx, STACK_SZ
  300. mov rdi, stack_buff
  301. xor rax, rax
  302. mov [t], eax
  303. .loop_buff_init:
  304. stosd
  305. loop .loop_buff_init
  306. mov eax, (STACK_SZ - 1) * 4
  307. mov [tosp], eax
  308. sdl_init:
  309. mov rdi, 0x0000FFFF
  310. call SDL_Init
  311. mov rdi, audiospec_wanted
  312. mov rsi, audiospec_recv
  313. call SDL_OpenAudio
  314. ;mov rdi, 256
  315. ;mov rsi, 255
  316. ;mov rdx, 32
  317. ;;mov rcx, SDL_SWSURFACE
  318. ;xor rcx, rcx
  319. ;call SDL_SetVideoMode
  320. audio_start:
  321. ;start audio
  322. xor rdi, rdi
  323. call SDL_PauseAudio
  324. ;0x00010001
  325. ;0x00020001
  326. ;0x00020101
  327. ;0x00010101
  328. ;mov rdi, 15000
  329. ;call SDL_Delay
  330. ;xor rdi, rdi
  331. loop_event:
  332. mov rdi, event
  333. call SDL_WaitEvent
  334. dbg:
  335. xor rdi, rdi
  336. mov edi, [event]
  337. mov rsi, 1
  338. cmp edi, 0
  339. jl exit ; SIGINT
  340. cmp edi, 0x00010001 ; SDL_QUIT PRESS ?
  341. je exit
  342. jmp loop_event
  343. exit:
  344. call SDL_Quit
  345. xor rdi, rdi
  346. mov rax, 0x3c
  347. syscall
  348. .err_open:
  349. mov rax, 1
  350. mov rdi, 2
  351. mov rsi, openerr
  352. mov rdx, openerr_len - 1
  353. syscall
  354. mov rdi, [rsp+16]
  355. push rdi
  356. call strlen
  357. mov rdx, rax
  358. mov rax, 1
  359. mov rdi, 2
  360. pop rsi
  361. syscall
  362. mov rax, 1
  363. mov rdi, 2
  364. mov rsi, openerr + openerr_len - 2
  365. mov rdx, 2
  366. syscall
  367. .badarg:
  368. mov rax, 1
  369. mov rdi, 2
  370. mov rsi, usage
  371. mov rdx, usage_len
  372. syscall
  373. mov rdi, [rsp+8]
  374. call strlen
  375. mov rdx, rax
  376. mov rax, 1
  377. mov rdi, 2
  378. mov rsi, [rsp+8]
  379. syscall
  380. mov rax, 1
  381. mov rdi, 2
  382. mov rsi, opts
  383. mov rdx, opts_len
  384. syscall
  385. mov rdi, 1
  386. .exit_err: ; with rdi error code
  387. mov rax, 0x3c ; exit
  388. syscall
  389. ; expect : r13 lineno, rbx chr num in line
  390. ; TODO: real error message
  391. .nl_not_last:
  392. mov rsi, nl_error
  393. mov rsi, nl_error_len
  394. push qword 3
  395. jmp exit.parse_error
  396. .syntax_error:
  397. mov rsi, syntax_error
  398. mov rdx, syntax_error_len
  399. push qword 2
  400. jmp exit.parse_error
  401. .bigline:
  402. mov rsi, bigline_error
  403. mov rdx, bigline_error_len
  404. push qword 2
  405. jmp exit.parse_error
  406. .bad_op:
  407. mov rsi, badop_error
  408. mov rdx, badop_error_len
  409. push qword 2
  410. jmp exit.parse_error
  411. .parse_error:
  412. ; print error lineno & chrno
  413. push rsi ; source ptr
  414. push rdx
  415. push rbx ; chrno in line
  416. sub r14, rsi ; chr count
  417. push 14
  418. mov rdi, "chr:0x"
  419. mov rsi, 6
  420. call short_err
  421. pop rdi ; chr count
  422. mov rsi, 2
  423. call print_hnum
  424. mov rdi, ",line:0x"
  425. mov rsi, 8
  426. call short_err
  427. mov rdi, r13
  428. mov rsi, 2
  429. call print_hnum
  430. mov rdi, ",col:0x"
  431. mov rsi, 7
  432. call short_err
  433. pop rdi
  434. mov rsi, 2
  435. call print_hnum
  436. mov rdi, ` :\t`
  437. mov rsi, 3
  438. call short_err
  439. pop rdx
  440. pop rsi
  441. mov rax, 1
  442. mov rdi, 2
  443. syscall
  444. pop rdi
  445. jmp exit.exit_err
  446. short_err:
  447. ; rdi is the message (less than 8 chr)
  448. ; rsi is message len
  449. push rdi
  450. mov rdx, rsi
  451. mov rsi, rsp
  452. mov rax, 1
  453. mov rdi, 1
  454. syscall
  455. pop rdi
  456. ret
  457. strlen:
  458. ; rdi containing str pointer
  459. ; rax will contain strlen and rdi is unchanged
  460. mov rsi, rdi
  461. xor rdx, rdx
  462. pushf
  463. cld
  464. .loop:
  465. inc rdx
  466. lodsb
  467. mov cl, al
  468. test al, al
  469. jnz .loop
  470. dec rdx
  471. mov rax, rdx
  472. popf
  473. ret
  474. print_hnum:
  475. ; rdi : number to print
  476. ; rsi : output fd
  477. pushf
  478. mov rax, rdi
  479. xor rcx, rcx
  480. push rcx ; using stack as buffer
  481. std
  482. lea rdi, [rsp + 8]
  483. .loop:
  484. test rax, rax
  485. jz .endloop
  486. inc rcx
  487. inc rcx
  488. push rax
  489. and al, 0x0F
  490. call .al2digit
  491. stosb
  492. mov rax, [rsp]
  493. shr al, 4
  494. call .al2digit
  495. stosb
  496. pop rax
  497. shr rax, 8
  498. jmp .loop
  499. .endloop:
  500. mov rax, 1
  501. xchg rdi, rsi
  502. inc rsi
  503. ;mov rdi, rsi
  504. ;mov rsi, rsp
  505. mov rdx, rcx
  506. syscall
  507. pop rax
  508. popf
  509. ret
  510. .al2digit:
  511. cmp al, 9
  512. jg .hex
  513. add al, "0"
  514. ret
  515. .hex:
  516. add al, "A" - 10
  517. ret
  518. audio_cllbck:
  519. ; rdi -> *userdata
  520. ; rsi -> *stream
  521. ; rdx -> stream_len
  522. mov rcx, rdx
  523. mov rdi, rsi
  524. .loop:
  525. push rcx
  526. push rdi
  527. call run_glitch
  528. pop rdi
  529. stosb
  530. pop rcx
  531. inc dword [t]
  532. loop .loop
  533. ret
  534. run_glitch:
  535. ; Run the glitch_pgm
  536. ; return TOSP value in eax
  537. mov rsi, glitch_pgm
  538. .loop:
  539. lodsq
  540. test rax, rax
  541. jz .end_glitch
  542. push rax
  543. lodsq
  544. mov rdi, rax
  545. pop rax
  546. push rsi
  547. call rax
  548. pop rsi
  549. jmp .loop
  550. .end_glitch:
  551. xor rbx, rbx
  552. mov ebx, [tosp]
  553. lea rdi, [stack_buff + rbx]
  554. mov eax, [rdi]
  555. ; DEBUG
  556. ;push rax
  557. ;xor rdi, rdi
  558. ;mov rdi, rax
  559. ;mov rsi, 1
  560. ;call print_hnum
  561. ;mov rax, " "
  562. ;push rax
  563. ;mov rax, 1
  564. ;mov rdi, 1
  565. ;mov rsi, rsp
  566. ;mov rdx, 1
  567. ;syscall
  568. ;pop rax
  569. ;pop rax
  570. ; /DEBUG
  571. ret
  572. OP:
  573. .numeric:
  574. ; rdi contain the number
  575. shr rdi, 32
  576. ._push:
  577. ; push rdi (edi) on stack_buff
  578. mov eax, edi
  579. xor rbx, rbx
  580. mov ebx, [tosp]
  581. add ebx, 4
  582. cmp ebx, STACK_SZ * 4
  583. jl .go_push
  584. mov ebx, 0
  585. .go_push:
  586. mov [tosp], ebx
  587. lea rdi, [stack_buff+rbx]
  588. stosd
  589. ret
  590. .drop: ; drop just calls pop
  591. ._pop:
  592. ; pop eax from stack_buff
  593. xor rbx, rbx
  594. mov ebx, [tosp]
  595. lea rsi, [stack_buff+rbx]
  596. xor rax, rax
  597. lodsd
  598. test ebx, ebx
  599. jz .pop_no_dec
  600. sub ebx, 4
  601. jmp .pop_end
  602. .pop_no_dec:
  603. mov ebx, (STACK_SZ-1) * 4
  604. .pop_end:
  605. mov [tosp], ebx
  606. ret
  607. .t: ; push t on the stack
  608. mov edi, [t]
  609. call ._push
  610. ret
  611. .put:
  612. pushf
  613. cld
  614. xor rbx, rbx
  615. xor rax, rax
  616. mov ebx, [tosp]
  617. lea rsi, [stack_buff+rbx]
  618. lodsd
  619. and eax, 0xFF
  620. inc eax
  621. mov edx, eax
  622. lodsd
  623. neg rdx
  624. lea rdi, [stack_buff + rdx]
  625. stosq
  626. call OP._pop
  627. popf
  628. ret
  629. .mul:
  630. call .prep_2arg
  631. mul ebx
  632. mov edi, eax
  633. call OP._push
  634. ret
  635. .div:
  636. call .prep_2arg
  637. test ebx, ebx
  638. jz .nodiv
  639. xor rdx, rdx
  640. div ebx
  641. jmp .divend
  642. .nodiv:
  643. xor eax, eax
  644. .divend:
  645. mov edi, eax
  646. call OP._push
  647. ret
  648. .add:
  649. call .prep_2arg
  650. add eax, ebx
  651. mov edi, eax
  652. call OP._push
  653. ret
  654. .sub:
  655. call .prep_2arg
  656. sub eax, ebx
  657. mov edi, eax
  658. call OP._push
  659. ret
  660. .mod:
  661. call .prep_2arg
  662. test rbx, rbx
  663. jz .nomod
  664. xor edx, edx
  665. div ebx
  666. jmp .endmod
  667. .nomod:
  668. xor edx, edx
  669. .endmod:
  670. mov edi, edx
  671. call OP._push
  672. ret
  673. .lshift:
  674. call OP._pop
  675. push rax
  676. call OP._pop
  677. pop rcx
  678. shl eax, cl
  679. mov edi, eax
  680. call OP._push
  681. ret
  682. .rshift:
  683. call OP._pop
  684. push rax
  685. call OP._pop
  686. pop rcx
  687. shr eax, cl
  688. mov edi, eax
  689. call OP._push
  690. ret
  691. .and:
  692. call .prep_2arg
  693. and eax, ebx
  694. mov edi, eax
  695. call OP._push
  696. ret
  697. .or:
  698. call .prep_2arg
  699. or eax, ebx
  700. mov edi, eax
  701. call OP._push
  702. ret
  703. .xor:
  704. call .prep_2arg
  705. xor eax, ebx
  706. mov edi, eax
  707. call OP._push
  708. ret
  709. .not:
  710. call OP._pop
  711. not eax
  712. mov edi, eax
  713. call OP._push
  714. ret
  715. .dup:
  716. call OP._pop
  717. push rax
  718. mov edi, eax
  719. call OP._push
  720. pop rdi
  721. call OP._push
  722. ret
  723. .pick:
  724. call OP._pop
  725. inc eax
  726. and eax, 0xFF
  727. mov ebx, 4
  728. mov ecx, [tosp]
  729. mul ebx ; mul by data size
  730. cmp eax, [tosp]
  731. jg .pick_loop
  732. sub ecx, eax
  733. jmp .pick_lea
  734. .pick_loop: ; eax > tosp
  735. sub eax, ecx
  736. mov ecx, (STACK_SZ - 1) * 4
  737. sub ecx, eax
  738. .pick_lea:
  739. lea rsi, [stack_buff+ecx]
  740. lodsd
  741. push rax
  742. call OP._pop
  743. pop rdi
  744. call OP._push
  745. ret
  746. .swap:
  747. call OP._pop
  748. push rax
  749. call OP._pop
  750. xchg rax, [rsp]
  751. mov edi, eax
  752. call OP._push
  753. pop rdi
  754. call OP._push
  755. ret
  756. .lt:
  757. call .prep_2arg
  758. xor rdi, rdi
  759. cmp eax, ebx
  760. jge .lt_false
  761. not rdi
  762. .lt_false:
  763. call OP._push
  764. ret
  765. .gt:
  766. call .prep_2arg
  767. xor rdi, rdi
  768. cmp eax, ebx
  769. jle .gt_false
  770. not rdi
  771. .gt_false:
  772. call OP._push
  773. ret
  774. .eq:
  775. call .prep_2arg
  776. xor rdi, rdi
  777. cmp eax, ebx
  778. jne .eq_false
  779. not rdi
  780. .eq_false:
  781. call OP._push
  782. ret
  783. .prep_2arg:
  784. ; utils that pop both arguments V1 in eax, V2 in ebx
  785. call OP._pop
  786. push rax
  787. call OP._pop
  788. pop rbx
  789. ret